Compare commits

..

116 Commits

Author SHA1 Message Date
Claude Bot
c2403a8d46 fix: correct JSONLineBuffer import path after rebase
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 09:17:43 +00:00
autofix-ci[bot]
e6db5003e0 [autofix.ci] apply automated fixes 2025-12-31 09:02:51 +00:00
Claude Bot
e48a9985cf docs: update CLAUDE.md with new source organization
Completely rewrite the Code Architecture section to reflect the
reorganized source structure. Now includes:

- Quick-reference table mapping tasks to directories
- Full directory tree showing the organized buntime/ structure
- Updated paths (src/buntime/ instead of src/bun.js/)
- Removed references to dissolved directories (bindings/, webcore/)

The goal: Claude should be able to GUESS where code lives.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
3a1be14392 refactor: rename transpiler files with js_ prefix for consistency
Rename files in src/transpiler/ to have consistent js_ prefix:
- parser.zig → js_parser.zig
- printer.zig → js_printer.zig
- lexer.zig → js_lexer.zig
- lexer_tables.zig → js_lexer_tables.zig

Update all imports across the codebase:
- bun.zig
- renamer.zig
- ast.zig
- ast/Expr.zig
- logger.zig
- string/MutableString.zig
- bundler/bundle_v2.zig
- bundler/LinkerContext.zig
- transpiler/js_lexer.zig (internal import)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
fd57125842 refactor: complete core/ dissolution and fix documentation paths
Move remaining core/ files to organized jsc/ subdirectories:
- BunClientData, BunIDL*, CPUFeatures, JSCTaskScheduler, coroutine → jsc/interop/
- BunGCOutputConstraint, MimallocWTFMalloc.h, bmalloc_heap_ref.h → jsc/gc/
- RegularExpression → jsc/types/

Fix outdated file paths in documentation:
- STREAMS.md: webcore/ → web/streams/
- event_loop/README.md: bindings/JSNextTickQueue → node/process/
- compat/v8/CLAUDE.md and AGENTS.md: bindings/v8/ → compat/v8/
- node/http/llhttp/README.md: bindings/ProcessBindingHTTPParser → api/process/

Fix cmake BuildBun.cmake issues:
- Remove duplicate directory entries in BUN_ERROR_CODE_SOURCES
- Remove directory (not file) arguments from WEBKIT_ADD_SOURCE_DEPENDENCIES

Update Zig imports for moved files in jsc.zig and crash_handler.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
9e71f4453e refactor: move event_loop/ from core/ to buntime/ root
Per PLAN.md's Final Structure, event_loop should be at the buntime/
root level. This move:
- Moves the event_loop directory from core/event_loop/ to buntime/event_loop/
- Moves event_loop.zig and related C++ files (EventLoopTask.h,
  EventLoopTaskNoContext.cpp/h, BunJSCEventLoop.cpp)
- Updates imports in jsc.zig, GeneratedJS2Native.zig, rare_data.zig
- Fixes relative paths in event_loop.zig and Task.zig
- Updates cmake Sources.json and BuildBun.cmake with new paths

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
b40b442c62 refactor: organize node/ C++ files into domain subdirectories
Move C++ files from node/ root into organized subdirectories:
- node/buffer/ - Buffer and StringDecoder
- node/process/ - NextTickQueue
- node/vm/ - VM, VMScript
- node/crypto/ - All crypto bindings (renamed from crypto_bindings/)
- node/http/ - HTTP server socket, NodeHTTP
- node/fs/ - Dirent, stat bindings
- node/os/ - OsBinding
- node/path/ - Path utilities
- node/util/ - NodeValidator
- node/timers/ - Timer objects
- node/async_hooks/ - AsyncContextFrame, AsyncHooks
- node/perf_hooks/ - Performance histogram
- node/constants/ - NodeConstants

Also moves global scope files to jsc/global/:
- BunGlobalScope, BunObject, BunWorkerGlobalScope
- ZigSourceProvider

Updates cmake Sources.json and BuildBun.cmake with new paths.
Fixes include paths in NodeBufferModule.h and NodeStringDecoderModule.h.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
ab2f5a20d3 refactor: dissolve webcore/ directory into jsc/interop/
Move all JSDOM infrastructure from webcore/ to jsc/interop/:
- ActiveDOMObject, ContextDestructionObserver
- JSDOMConvert*, JSDOMPromise, JSDOMIterator
- JSDOMWrapper*, JSDOMConstructor*, JSDOMBuiltin*
- DOMJITHelpers, DOMIsoSubspaces, DOMClientIsoSubspaces
- WebCoreTypedArrayController, BufferSource
- All other JSDOM binding utilities

Also:
- Move AutoFlusher.zig to jsc/interop/
- Move ScriptExecutionContext.zig to jsc/global/
- Update cmake Sources.json to remove webcore/ glob
- Fix missing JSDOMGlobalObject.h include in JSPerformanceObserverCallback.h
- Fix JSC::JSValue qualification in JSAbortAlgorithm.h

The webcore/ directory is now fully dissolved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
d07c1bba42 refactor: dissolve bindings/ into jsc/ directory with subdirectories
Move bindings/ directory to jsc/ with the following organization:
- jsc/types/ - JSValue types (JSArray, JSObject, JSPromise, etc.)
- jsc/global/ - Global objects (ZigGlobalObject, ScriptExecutionContext, etc.)
- jsc/gc/ - GC-related files (StrongRef, Weak, MarkingConstraint, etc.)
- jsc/interop/ - C++/Zig interop (bindings.cpp, helpers.cpp, etc.)
- jsc/generated/ - Generated code (GeneratedBindings, JS2Native, etc.)

Also:
- Move uv polyfills to compat/libuv/
- Move v8 fixture to compat/v8/
- Move Windows files to compat/windows/
- Move bindgen_test.bind.ts to jsc/interop/
- Update cmake Sources.json and BuildBun.cmake for new paths
- Update codegen scripts to generate correct relative import paths
- Fix Zig imports throughout the codebase

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:25 +00:00
Claude Bot
fedccb4b6d refactor: move HTMLEntryPoint.cpp to src/bake/
Per PLAN.md section 4.90, this bundler-related file belongs in bake/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
c7ed08f4ff refactor: move string utility files to src/string/
Move string-related C++ files per PLAN.md section 4.80:
- bun-simdutf.cpp, bun-simdutf.zig
- BunString.cpp, BunString.h
- BunCommonStrings.cpp, BunCommonStrings.h
- DoubleFormatter.cpp
- highway_strings.cpp
- StringBuilderBinding.cpp
- stripANSI.cpp, stripANSI.h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
00ba82605a refactor: move webcrypto from webcore/ to web/
According to PLAN.md, webcrypto should be under web/ as a Web Standard API,
not under webcore/ which is for core JSDOM infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
1fa3829f55 refactor: move VirtualMachine and virtual_machine_exports to core/
These are core runtime infrastructure files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
e7c861c643 refactor: move bindgen files and JSC C API to bindings/
Move bindgen.zig, bindgen_test.zig, javascript_core_c_api.zig to bindings/
since they are all binding-related files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
6e5ef1bedb refactor: move rare_data.zig and hot_reloader.zig to core/
These are core runtime infrastructure files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
456176deef refactor: move jsc/ files to bindings/ and remove jsc/ directory
Move RefString.zig, array_buffer.zig, dom_call.zig, host_fn.zig to bindings/
since they are JSC binding utilities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
44727cbd44 refactor: move event_loop.zig and event_loop/ to core/
Event loop is core runtime infrastructure that belongs in the core/ directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
9dab6a8843 refactor: move Strong.zig, Weak.zig, DeprecatedStrong.zig to bindings/
These are JSC reference management utilities that belong with other bindings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
fd84244b3d refactor: move SavedSourceMap.zig to module/
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
941986868a refactor: move ModuleLoader, AsyncModule, RuntimeTranspilerStore/Cache to module/
Move module loading related files to the module/ subdirectory:
- ModuleLoader.zig
- AsyncModule.zig
- RuntimeTranspilerStore.zig
- RuntimeTranspilerCache.zig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
b9a2852d53 chore: move Algo/Tuple.h to core/Algo/
Generic tuple algorithms belong in core utilities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
a7797a7339 chore: move debug-helpers.h to api/inspector/
Debugger helpers belong with inspector/profiling code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
6c5f83417e chore: move string utility headers to src/string/
Move StringAdaptors.h, MiString.h, and ConcatCStrings.h to the existing
src/string/ directory where other string utilities live.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
2a40325984 chore: move string utility headers to core/
String adaptors and utilities belong in core infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
53b587ad74 chore: move memory allocator headers to core/
bmalloc and mimalloc integration belongs in core infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
2936b29a73 chore: move CachedScript.h to module/
Script caching belongs with module loading infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
6f4fcfaeb9 chore: move generated_perf_trace_events.h to api/inspector/
Performance trace events belong with profiling/inspector code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
7ceb58fc8b chore: move uv-posix-polyfills.h to compat/libuv/
libuv polyfills belong with libuv compatibility layer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
316087d3be chore: move dh-primes.h to node/crypto_bindings/
Diffie-Hellman primes belong with crypto infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
158d805751 chore: move ares_build.h to api/bun/
c-ares DNS config belongs with DNS functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
e4a34a4b23 chore: move Sink.h and StreamGlobals.h to web/streams/
Stream-related header files belong with web streams infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
d4adbae015 chore: move ZigSourceProvider files to module/
Source provider is part of module loading infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
0847104330 chore: move EventLoopTask files to core/
Event loop infrastructure belongs in core.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
fca5b782d5 chore: move BakeAdditionsToGlobalObject files to bake/
Bake-specific global object additions belong with other bake code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
0d11a4e4c0 chore: move JSBakeResponse.cpp to bake/
JSBakeResponse is Bake/DevServer infrastructure - keep with header file.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
695db55b77 chore: move coroutine.cpp to core/
Low-level coroutine support belongs in core infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
ef906c38bb chore: move linux_perf_tracing.cpp to api/inspector/
Linux perf tracing belongs with other profiling/inspector code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
5bdb625281 chore: move spawn.cpp to api/bun/
Spawn functionality belongs with other subprocess code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
793682ba43 chore: move ZigException.cpp to api/error/
Keep C++ file alongside the Zig file it implements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
c88d0d2ab5 chore: move config.zig to core/
Core config belongs in core infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
601e9dbceb chore: move Counters.zig to core/
Internal counters/metrics belong in core infrastructure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
790887eb7b chore: move HardcodedModule.zig to module/
Hardcoded module definitions belong with other module-related code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
eede4efac9 chore: move ResolveMessage.zig to api/error/
Resolve error message belongs with other error-related code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
795264752b chore: move BuildMessage.zig to api/error/
Build error message belongs with other error-related code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
cef59deb21 chore: move ipc.zig to api/ipc/
IPC functionality belongs in the api/ipc directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
e4a2d75e4a chore: move web_worker.zig to web/workers/
Web Worker functionality belongs with the workers directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
1f47e3fd00 chore: move ProcessAutoKiller.zig to api/process/
Process-related utilities belong in api/process/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
2ad1284442 chore: move Debugger.zig to api/inspector/
Debugger functionality belongs with inspector/profiling tools.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
03c3949648 chore: move uuid.zig to webcore/webcrypto/
UUID functionality is primarily used for crypto operations. Moving it to
webcore/webcrypto/ makes its purpose clearer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:24 +00:00
Claude Bot
872a5a335d chore: move ZigException and ZigStackFrame files to api/error/
Moved:
- ZigException.zig -> api/error/
- ZigStackFrame.zig -> api/error/
- ZigStackFrameCode.zig -> api/error/
- ZigStackFramePosition.zig -> api/error/
- ZigStackTrace.zig -> api/error/

Updated imports in jsc.zig, Exception.zig and within the moved files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
655038a408 Move JSCTaskScheduler to core/
Move JSCTaskScheduler.cpp, JSCTaskScheduler.h from bindings/ to core/.
Core task scheduling utility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
ff2ba59f4a Move stripANSI to api/console/
Move stripANSI.cpp, stripANSI.h from bindings/ to api/console/.
Related to console output formatting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
25be9ea0ae Move highway_strings to core/
Move highway_strings.cpp from bindings/ to core/.
SIMD string utilities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
07d6e07e87 Move simdutf files to core/
Move bun-simdutf.cpp, bun-simdutf.zig from bindings/ to core/.
String/unicode utilities.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
0efcfaa464 Move CachedBytecode to module/
Move CachedBytecode.zig from bindings/ to module/.
Related to module bytecode caching.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
877c36108d Move DoubleFormatter to core/
Move DoubleFormatter.cpp from bindings/ to core/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
289c26a164 Move RegularExpression to core/
Move RegularExpression.cpp, RegularExpression.zig from bindings/ to core/.
Updated import in jsc.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
2dfbeec70d Move CPUFeatures to core/
Move CPUFeatures.cpp, CPUFeatures.zig from bindings/ to core/.
Updated import in crash_handler.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
ae4dd4ee08 Move prompt.zig to api/console/
Move prompt.zig from webcore/ to api/console/.
Related to console input functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
24b38f1a9b Move Crypto.zig to webcore/webcrypto/
Move Crypto.zig from webcore/ to webcore/webcrypto/.
Updated uuid.zig import paths and webcore.zig import.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
c41207374b Move BunProcessReportObjectWindows to api/process/
Move BunProcessReportObjectWindows.cpp from bindings/ to api/process/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
e137723de0 Move JSEnvironmentVariableMap to api/process/
Move JSEnvironmentVariableMap.cpp/h from bindings/ to api/process/.
Related to process.env functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
f2ce862308 Move JSNextTickQueue to node/
Move JSNextTickQueue.cpp, JSNextTickQueue.h from bindings/ to node/.
Related to Node.js process.nextTick functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
9a1791d53d Move DOMException to api/error/
Move DOMException.cpp, DOMException.h from bindings/ to api/error/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
5c76c0f7fa Move OsBinding.cpp to node/
Move OsBinding.cpp from bindings/ to node/.
Related to node:os module.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
8e8d8548a9 Move CodeCoverage.cpp to api/test/
Move CodeCoverage.cpp from bindings/ to api/test/.
Related to test coverage functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
31cf2e9692 Move Serialization.cpp to web/serialization/
Move Serialization.cpp from bindings/ to web/serialization/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
8cf859f460 Move ImportMetaObject to module/
Move ImportMetaObject.cpp, ImportMetaObject.h from bindings/
to module/. Related to ES module import.meta functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
ef9f4af60f Move JSSocketAddressDTO to api/server/
Move JSSocketAddressDTO.cpp, JSSocketAddressDTO.h from bindings/
to api/server/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
dc1bf7b2b8 Move AsyncContextFrame to node/
Move AsyncContextFrame.cpp, AsyncContextFrame.h from bindings/ to node/.
Related to Node.js async_hooks functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
0f2441febd Move CallSite/StackTrace files to api/error/
Move CallSite, CallSitePrototype, FormatStackTraceForJS from bindings/
to api/error/. All error/stack trace related files now together.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
64c75fedb7 Move Cookie C++ files to api/cookie/
Move Cookie.cpp, Cookie.h, CookieMap.cpp, CookieMap.h from bindings/
to api/cookie/. Now all cookie-related files are together.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
f66d82a296 Move debugger/profiler files to api/inspector/
Move BunCPUProfiler, BunDebugger, BunInjectedScriptHost from bindings/
to api/inspector/. Update imports in bun.js.zig and VirtualMachine.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
49fd4dc56e Move ncrypto files to node/crypto_bindings/
Move AsymmetricKeyValue, ncrypto from bindings/ to node/crypto_bindings/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
8fa79c2b5f Move X509Certificate files to node/crypto_bindings/
Move JSX509Certificate, Constructor, and Prototype from bindings/
to node/crypto_bindings/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
742b0f0ad6 Move Path files to node/
Move Path.cpp, Path.h, PathInlines.h from bindings/ to node/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
a02748ef11 Move Buffer-related C++ files to node/
Move BufferEncodingType, JSBuffer, JSBufferEncodingType, JSBufferList,
JSStringDecoder from bindings/ to node/.
Updated BuildBun.cmake and NodeBufferModule.h, NodeStringDecoderModule.h.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
70daa60d0b Move JSNodePerformanceHooksHistogram files to node/
Move JSNodePerformanceHooksHistogram, Constructor, and Prototype
from bindings/ to node/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
ff72b9566d Move Node-related C++ files to node/
Move NodeAsyncHooks, NodeConstants, NodeDirent, NodeFSStatBinding,
NodeFSStatFSBinding, NodeHTTP, NodeTLS, NodeTimerObject, NodeVM,
NodeVMScript, NodeVMScriptFetcher, NodeValidator from bindings/ to node/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
8c2ce7f15d Move error-related files to api/error/
Move ErrorCallback, ExceptionDetails, JSErrorCallback, JSErrorHandler,
JSDOMException from webcore/ to api/error/. Now all error-related
files are together.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
e993178e6e Move QueuingStrategy files to web/streams/
Move JSByteLengthQueuingStrategy, JSCountQueuingStrategy from
webcore/ to web/streams/. Now all stream-related files are together.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
018f9e0946 Move AbortController/AbortSignal C++ files to web/events/
Move AbortController, AbortSignal, AbortAlgorithm, JSAbortController,
JSAbortSignal, JSAbortAlgorithm from webcore/ to web/events/.
Now all abort-related files are together.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
834605e5c5 Move FileReader.zig to web/blob/
Move FileReader.zig from webcore/ to web/blob/.
Update import in webcore.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
02a022f143 Move CookieMap.zig to api/cookie/
Move CookieMap.zig from webcore/ to api/cookie/.
Update import in webcore.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
16e98547c9 Move HTTP parser files to web/http/
Move HTTPParsers, HeaderFieldTokenizer, RFC7230 from webcore/ to web/http/.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:23 +00:00
Claude Bot
e3cb63ec8e Move serialization files to web/serialization/
Move SerializedScriptValue, StructuredClone, StructuredSerializeOptions,
JSStructuredSerializeOptions, JSDOMConvertSerializedScriptValue
from webcore/ to web/serialization/.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
f040a828d3 Move MIME files to web/mime/
Move JSMIMEBindings, JSMIMEParams, JSMIMEType from webcore/ to web/mime/.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
2194724425 Move MessageChannel files to web/messaging/
Move MessageChannel, JSMessageChannel files from webcore/ to web/messaging/.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
313f714b6d Move Worker files to web/workers/
Move Worker, JSWorker, JSWorkerOptions, WorkerOptions, JSServiceWorker
from webcore/ to web/workers/.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
8696c55595 Move S3 Zig files to api/s3/
Move S3Client.zig, S3File.zig, S3Stat.zig from webcore/ to api/s3/.
Update imports in webcore.zig and Blob.zig.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
9ffbb5c99c Move WebSocket files to web/websocket/
Move 8 WebSocket-related files from webcore/ to web/websocket/.
Includes WebSocket core, JSWebSocket bindings, and helpers.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
52407bca9c Move Performance files to web/performance/
Move 60 performance-related files from webcore/ to web/performance/.
Includes Performance API, PerformanceObserver, Timing, Marks, Measures,
ResourceTiming, ServerTiming, and NetworkLoadMetrics.

Added JSDOMWrapperCache.h include to JSPerformanceEntryCustom.cpp.
Updated cmake/Sources.json and cmake/targets/BuildBun.cmake.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
5a33924475 Move blob files to web/blob/
Move Blob.zig, ByteBlobLoader.zig and blob/ subdirectory files from
webcore/ to web/blob/. Update relative imports for env.zig, S3File.zig,
and Store/read_file/write_file/copy_file references.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
c67d6182f7 refactor: move Response/Request/Body files to web/http/
Move Response.zig, Request.zig, Body.zig, BakeResponse.zig,
and response.classes.ts from webcore/ to web/http/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
c9bb8b16c1 refactor: move stream-related files to web/streams/
Move ReadableStream, WritableStream, TransformStream, Sink,
FileSink, ByteStream, ResumableSink, JS* stream files from
webcore/ to web/streams/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
cf86901409 refactor: move event-related files to web/events/
Move Event*, MessagePort*, BroadcastChannel*, AbortSignal,
EventTarget, EventEmitter, JS* event files from bindings/
and webcore/ to web/events/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
f13396c8d2 refactor: move compression files to web/compression/
Move JSCompressionStream and JSDecompressionStream from bindings/
to web/compression/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
f066c98c2a refactor: move encoding-related files to web/encoding/
Move Base64Helpers, TextCodec*, TextEncoder*, TextDecoder*,
EncodingLabel, encoding.zig and related files from bindings/
and webcore/ to web/encoding/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
f0db7ce4e9 refactor: move blob-related files to web/blob/
Move blob.cpp, DOMFormData, JSDOMFile, and JSDOMFormData
from bindings/ and webcore/ to web/blob/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
a8a15feb8e refactor: move URL-related files to web/url/
Move DOMURL, URLSearchParams, URLPattern*, EncodeURIComponent,
decodeURIComponentSIMD, ObjectURLRegistry, NodeURL and related
files from bindings/ and webcore/ to web/url/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
57a92ae359 refactor: move fetch-related files to web/fetch/
Move FetchHeaders, FetchTasklet, HTTPHeader*, JSFetchHeaders,
NodeFetch, Undici, and fetch.zig from bindings/ and webcore/
to web/fetch/.

This groups all fetch-related functionality in one directory
for easier navigation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
0197c54a2c refactor: move Bun core files to core/
Move BunClientData, BunCommonStrings, BunGCOutputConstraint,
BunGlobalScope, BunIDL*, BunJSCEventLoop, BunObject, BunString,
and BunWorkerGlobalScope from bindings/ to core/.

This makes the purpose of these files clearer - they are core Bun
runtime infrastructure rather than JavaScript bindings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
73abb99ea3 refactor: move process files to api/process/
Move process-related files from bindings/ to api/process/:
- BunProcess, ProcessBindingBuffer, ProcessBindingConstants
- ProcessBindingFs, ProcessBindingHTTPParser, ProcessBindingNatives
- ProcessBindingTTYWrap, ProcessBindingUV, ProcessIdentifier
- bun-spawn

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
b9af431178 refactor: move napi and module files to dedicated directories
- Move napi files from bindings/ to compat/napi/
- Move module loader files from bindings/ to module/
  - InternalModuleRegistry, JSModuleLoader, JSCommonJSModule, etc.
- Update all import paths and cmake configurations

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
c4205a4a3a refactor: move libuv and webcore to dedicated directories
- Move bindings/libuv/ to compat/libuv/ for libuv compatibility layer
- Move bindings/webcore/ to webcore/ (438 files)
- Update all include paths for webcore/ prefix removal
- Fix relative includes in webcrypto files

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:22 +00:00
Claude Bot
772533afd8 refactor: move node bindings to buntime/node/
Consolidate node compatibility files:
- Move node C++ files from bindings/node/ to buntime/node/
- Rename bindings/node/crypto to node/crypto_bindings for clarity
- Move webcrypto from bindings/ to webcore/webcrypto/
- Update cmake include paths and source patterns

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
ced6ba6c82 refactor: move webcrypto to webcore/webcrypto/
Move webcrypto directory from bindings/ to webcore/webcrypto/ for
better organization of web-related APIs.

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
d8b43c28da refactor: move v8 compat to compat/v8/
Move v8 directory from bindings/ to compat/v8/ for better organization
of compatibility layers.

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
bfc99fa5de refactor: reorganize api/ subdirectories (step 4.5-4.14)
Move domain-specific files from bindings/ to api/ subdirectories:
- api/s3/: S3 client and error handling
- api/secrets/: Platform secrets management
- api/ffi/: Foreign Function Interface
- api/sqlite/: SQLite bindings (moved from bindings/sqlite/)
- api/sql/: SQL client
- api/shell/: Shell bindings
- api/ipc/: IPC bindings
- api/test/: Testing utilities
- api/server/: HTTP server bindings
- api/plugin/: Bundler plugin system

Part of source code reorganization to make code location "guessable".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
e306d9dbda refactor: move cookie files to api/cookie/
Step 4.4 of source reorganization - move cookie-related files:
- JSCookie.cpp/h
- JSCookieMap.cpp/h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
0620ff58fe refactor: move error files to api/error/
Step 4.3 of source reorganization - move error-related files:
- DeferredError.zig
- ErrorCode.cpp/h/ts/zig
- ErrorStackFrame.cpp/h
- ErrorStackTrace.cpp/h
- Errorable.zig
- JSErrorCode.zig
- SystemError.zig
- ZigErrorType.zig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
7227eef0ff refactor: move inspector files to api/inspector/
Step 4.2 of source reorganization - move inspector-related files:
- BunInspector.cpp
- InspectorBunFrontendDevServerAgent.cpp/h
- InspectorHTTPServerAgent.cpp/h
- InspectorLifecycleAgent.cpp/h
- InspectorTestReporterAgent.cpp/h

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
781a3f9508 refactor: move console files to api/console/
Step 4.1 of source reorganization - move console-related files:
- ConsoleObject.cpp/h
- UtilInspect.cpp/h
- ConsoleObject.zig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
5fea6eb184 refactor: create src/test_runner/ for bun:test
Step 3 of source reorganization - move test runner files from
src/buntime/test/ to src/test_runner/ for better discoverability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
e0ae7683a7 refactor: create src/transpiler/ for JS/TS transpiler
Step 2 of source reorganization - move js_parser, js_lexer, js_printer,
and transpiler files to src/transpiler/ directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:21 +00:00
Claude Bot
e84b4b4847 refactor: rename src/bun.js/ to src/buntime/
Step 1 of source reorganization - rename the JavaScript runtime
directory from bun.js to buntime for better discoverability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-31 08:53:12 +00:00
2365 changed files with 25724 additions and 225705 deletions

View File

@@ -26,7 +26,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
wget curl git python3 python3-pip ninja-build \
software-properties-common apt-transport-https \
ca-certificates gnupg lsb-release unzip \
libxml2-dev ruby ruby-dev bison gawk perl make golang ccache qemu-user-static \
libxml2-dev ruby ruby-dev bison gawk perl make golang ccache \
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y gcc-13 g++-13 libgcc-13-dev libstdc++-13-dev \

View File

@@ -114,8 +114,6 @@ const buildPlatforms = [
{ 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" },
// TODO: Enable when Windows ARM64 CI runners are ready
// { os: "windows", arch: "aarch64", release: "2019" },
];
/**
@@ -138,8 +136,6 @@ const testPlatforms = [
{ 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" },
// TODO: Enable when Windows ARM64 CI runners are ready
// { os: "windows", arch: "aarch64", release: "2019", tier: "oldest" },
];
/**
@@ -537,109 +533,6 @@ function getLinkBunStep(platform, options) {
};
}
/**
* Returns the artifact triplet for a platform, e.g. "bun-linux-aarch64" or "bun-linux-x64-musl-baseline".
* Matches the naming convention in cmake/targets/BuildBun.cmake.
* @param {Platform} platform
* @returns {string}
*/
function getTargetTriplet(platform) {
const { os, arch, abi, baseline } = platform;
let triplet = `bun-${os}-${arch}`;
if (abi === "musl") {
triplet += "-musl";
}
if (baseline) {
triplet += "-baseline";
}
return triplet;
}
/**
* Returns true if a platform needs QEMU-based baseline CPU verification.
* x64 baseline builds verify no AVX/AVX2 instructions snuck in.
* aarch64 builds verify no LSE/SVE instructions snuck in.
* @param {Platform} platform
* @returns {boolean}
*/
function needsBaselineVerification(platform) {
const { os, arch, baseline } = platform;
if (os !== "linux") return false;
return (arch === "x64" && baseline) || arch === "aarch64";
}
/**
* @param {Platform} platform
* @param {PipelineOptions} options
* @returns {Step}
*/
function getVerifyBaselineStep(platform, options) {
const { arch } = platform;
const targetKey = getTargetKey(platform);
const archArg = arch === "x64" ? "x64" : "aarch64";
return {
key: `${targetKey}-verify-baseline`,
label: `${getTargetLabel(platform)} - verify-baseline`,
depends_on: [`${targetKey}-build-bun`],
agents: getLinkBunAgent(platform, options),
retry: getRetry(),
cancel_on_build_failing: isMergeQueue(),
timeout_in_minutes: 5,
command: [
`buildkite-agent artifact download '*.zip' . --step ${targetKey}-build-bun`,
`unzip -o '${getTargetTriplet(platform)}.zip'`,
`unzip -o '${getTargetTriplet(platform)}-profile.zip'`,
`chmod +x ${getTargetTriplet(platform)}/bun ${getTargetTriplet(platform)}-profile/bun-profile`,
`./scripts/verify-baseline-cpu.sh --arch ${archArg} --binary ${getTargetTriplet(platform)}/bun`,
`./scripts/verify-baseline-cpu.sh --arch ${archArg} --binary ${getTargetTriplet(platform)}-profile/bun-profile`,
],
};
}
/**
* Returns true if the PR modifies SetupWebKit.cmake (WebKit version changes).
* JIT stress tests under QEMU should run when WebKit is updated to catch
* JIT-generated code that uses unsupported CPU instructions.
* @param {PipelineOptions} options
* @returns {boolean}
*/
function hasWebKitChanges(options) {
const { changedFiles = [] } = options;
return changedFiles.some(file => file.includes("SetupWebKit.cmake"));
}
/**
* Returns a step that runs JSC JIT stress tests under QEMU.
* This verifies that JIT-compiled code doesn't use CPU instructions
* beyond the baseline target (no AVX on x64, no LSE on aarch64).
* @param {Platform} platform
* @param {PipelineOptions} options
* @returns {Step}
*/
function getJitStressTestStep(platform, options) {
const { arch } = platform;
const targetKey = getTargetKey(platform);
const archArg = arch === "x64" ? "x64" : "aarch64";
return {
key: `${targetKey}-jit-stress-qemu`,
label: `${getTargetLabel(platform)} - jit-stress-qemu`,
depends_on: [`${targetKey}-build-bun`],
agents: getLinkBunAgent(platform, options),
retry: getRetry(),
cancel_on_build_failing: isMergeQueue(),
// JIT stress tests are slow under QEMU emulation
timeout_in_minutes: 30,
command: [
`buildkite-agent artifact download '*.zip' . --step ${targetKey}-build-bun`,
`unzip -o '${getTargetTriplet(platform)}.zip'`,
`chmod +x ${getTargetTriplet(platform)}/bun`,
`./scripts/verify-jit-stress-qemu.sh --arch ${archArg} --binary ${getTargetTriplet(platform)}/bun`,
],
};
}
/**
* @param {Platform} platform
* @param {PipelineOptions} options
@@ -695,7 +588,7 @@ function getTestBunStep(platform, options, testOptions = {}) {
agents: getTestAgent(platform, options),
retry: getRetry(),
cancel_on_build_failing: isMergeQueue(),
parallelism: os === "darwin" ? 2 : 20,
parallelism: os === "darwin" ? 2 : 10,
timeout_in_minutes: profile === "asan" || os === "windows" ? 45 : 30,
env: {
ASAN_OPTIONS: "allow_user_segv_handler=1:disable_coredump=0:detect_leaks=0",
@@ -877,7 +770,6 @@ function getBenchmarkStep() {
* @property {Platform[]} [buildPlatforms]
* @property {Platform[]} [testPlatforms]
* @property {string[]} [testFiles]
* @property {string[]} [changedFiles]
*/
/**
@@ -1230,14 +1122,6 @@ async function getPipeline(options = {}) {
steps.push(getBuildZigStep(target, options));
steps.push(getLinkBunStep(target, options));
if (needsBaselineVerification(target)) {
steps.push(getVerifyBaselineStep(target, options));
// Run JIT stress tests under QEMU when WebKit is updated
if (hasWebKitChanges(options)) {
steps.push(getJitStressTestStep(target, options));
}
}
return getStepWithDependsOn(
{
key: getTargetKey(target),
@@ -1335,7 +1219,6 @@ async function main() {
console.log(`- PR is only docs, skipping tests!`);
return;
}
options.changedFiles = allFiles;
}
startGroup("Generating pipeline...");

View File

@@ -36,20 +36,16 @@ function Log-Debug {
}
}
# Detect system architecture
$script:IsARM64 = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64
$script:VsArch = if ($script:IsARM64) { "arm64" } else { "amd64" }
# Load Visual Studio environment if not already loaded
function Ensure-VSEnvironment {
if ($null -eq $env:VSINSTALLDIR) {
Log-Info "Loading Visual Studio environment for $script:VsArch..."
Log-Info "Loading Visual Studio environment..."
$vswhere = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"
if (!(Test-Path $vswhere)) {
throw "Command not found: vswhere (did you install Visual Studio?)"
}
$vsDir = & $vswhere -prerelease -latest -property installationPath
if ($null -eq $vsDir) {
$vsDir = Get-ChildItem -Path "C:\Program Files\Microsoft Visual Studio\2022" -Directory -ErrorAction SilentlyContinue
@@ -58,20 +54,20 @@ function Ensure-VSEnvironment {
}
$vsDir = $vsDir.FullName
}
Push-Location $vsDir
try {
$vsShell = Join-Path -Path $vsDir -ChildPath "Common7\Tools\Launch-VsDevShell.ps1"
. $vsShell -Arch $script:VsArch -HostArch $script:VsArch
. $vsShell -Arch amd64 -HostArch amd64
} finally {
Pop-Location
}
Log-Success "Visual Studio environment loaded"
}
if ($env:VSCMD_ARG_TGT_ARCH -eq "x86") {
throw "Visual Studio environment is targeting 32 bit x86, but only 64-bit architectures (x64/arm64) are supported."
throw "Visual Studio environment is targeting 32 bit, but only 64 bit is supported."
}
}
@@ -190,10 +186,8 @@ function Install-KeyLocker {
}
# Download MSI installer
# Note: KeyLocker tools currently only available for x64, but works on ARM64 via emulation
$msiArch = "x64"
$msiUrl = "https://bun-ci-assets.bun.sh/Keylockertools-windows-${msiArch}.msi"
$msiPath = Join-Path $env:TEMP "Keylockertools-windows-${msiArch}.msi"
$msiUrl = "https://bun-ci-assets.bun.sh/Keylockertools-windows-x64.msi"
$msiPath = Join-Path $env:TEMP "Keylockertools-windows-x64.msi"
Log-Info "Downloading MSI from: $msiUrl"
Log-Info "Downloading to: $msiPath"

View File

@@ -219,9 +219,6 @@ function create_release() {
bun-windows-x64-profile.zip
bun-windows-x64-baseline.zip
bun-windows-x64-baseline-profile.zip
# TODO: Enable when Windows ARM64 CI runners are ready
# bun-windows-aarch64.zip
# bun-windows-aarch64-profile.zip
)
function upload_artifact() {

View File

@@ -22,7 +22,7 @@ Bun reports a Node.js version for compatibility with the Node.js ecosystem. This
- `NODEJS_ABI_VERSION` - The ABI version number (find using command below)
### 3. Version Strings
- `src/bun.js/bindings/BunProcess.cpp`
- `src/buntime/bindings/BunProcess.cpp`
- Update `Bun__versions_node` with the Node.js version
- Update `Bun__versions_v8` with the V8 version (find using command below)
@@ -33,7 +33,7 @@ Bun reports a Node.js version for compatibility with the Node.js ecosystem. This
## Files That May Need Updates
Only check these if the build fails or tests crash after updating version numbers:
- V8 compatibility files in `src/bun.js/bindings/v8/` (if V8 API changed)
- V8 compatibility files in `src/buntime/bindings/v8/` (if V8 API changed)
- Test files (if Node.js requires newer C++ standard)
## Quick Commands to Find Version Info

View File

@@ -6,7 +6,8 @@ To do that:
- git fetch upstream
- git merge upstream main
- Fix the merge conflicts
- bun build.ts debug
- cd ../../ (back to bun)
- make jsc-build (this will take about 7 minutes)
- While it compiles, in another task review the JSC commits between the last version of Webkit and the new version. Write up a summary of the webkit changes in a file called "webkit-changes.md"
- bun run build:local (build a build of Bun with the new Webkit, make sure it compiles)
- After making sure it compiles, run some code to make sure things work. something like ./build/debug-local/bun-debug --print '42' should be all you need
@@ -20,7 +21,3 @@ To do that:
- commit + push (without adding the webkit-changes.md file)
- create PR titled "Upgrade Webkit to the <commit-sha>", paste your webkit-changes.md into the PR description
- delete the webkit-changes.md file
Things to check for a successful upgrade:
- Did JSType in vendor/WebKit/Source/JavaScriptCore have any recent changes? Does the enum values align with whats present in src/bun.js/bindings/JSType.zig?
- Were there any changes to the webcore code generator? If there are C++ compilation errors, check for differences in some of the generated code in like vendor/WebKit/source/WebCore/bindings/scripts/test/JS/

View File

@@ -19,8 +19,8 @@ No public constructor? Only Prototype and class needed.
Classes with C++ fields need subspaces in:
- `src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h`
- `src/bun.js/bindings/webcore/DOMIsoSubspaces.h`
- `src/buntime/bindings/webcore/DOMClientIsoSubspaces.h`
- `src/buntime/bindings/webcore/DOMIsoSubspaces.h`
```cpp
template<typename MyClassT, JSC::SubspaceAccess mode>

View File

@@ -89,7 +89,7 @@ pub const TextDecoder = struct {
- Use `bun.JSError!JSValue` return type for error handling
- Use `globalObject` not `ctx`
- `deinit()` for cleanup, `finalize()` called by GC
- Update `src/bun.js/bindings/generated_classes_list.zig`
- Update `src/buntime/bindings/generated_classes_list.zig`
## CallFrame Access
@@ -196,7 +196,7 @@ pub const MyClass = struct {
};
```
3. Add to `src/bun.js/bindings/generated_classes_list.zig`
3. Add to `src/buntime/bindings/generated_classes_list.zig`
## Generated Components

View File

@@ -88,7 +88,7 @@ jobs:
commit-message: "deps: update c-ares to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update c-ares to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-cares
branch: deps/update-cares-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -91,7 +91,7 @@ jobs:
commit-message: "deps: update hdrhistogram to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update hdrhistogram to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-hdrhistogram
branch: deps/update-hdrhistogram-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -107,7 +107,7 @@ jobs:
commit-message: "deps: update highway to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update highway to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-highway
branch: deps/update-highway-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -88,7 +88,7 @@ jobs:
commit-message: "deps: update libarchive to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update libarchive to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-libarchive
branch: deps/update-libarchive-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -88,7 +88,7 @@ jobs:
commit-message: "deps: update libdeflate to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update libdeflate to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-libdeflate
branch: deps/update-libdeflate-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -100,7 +100,7 @@ jobs:
commit-message: "deps: update lolhtml to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update lolhtml to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-lolhtml
branch: deps/update-lolhtml-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -105,7 +105,7 @@ jobs:
commit-message: "deps: update lshpack to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update lshpack to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-lshpack
branch: deps/update-lshpack-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -74,7 +74,7 @@ jobs:
```
${{ env.changed_files }}
```
branch: certs/update-root-certs
branch: certs/update-root-certs-${{ github.run_number }}
base: main
delete-branch: true
labels:

View File

@@ -83,7 +83,7 @@ jobs:
commit-message: "deps: update sqlite to ${{ steps.check-version.outputs.latest }}"
title: "deps: update sqlite to ${{ steps.check-version.outputs.latest }}"
delete-branch: true
branch: deps/update-sqlite
branch: deps/update-sqlite-${{ steps.check-version.outputs.latest }}
body: |
## What does this PR do?

View File

@@ -68,7 +68,7 @@ jobs:
commit-message: "deps: update ${{ matrix.package }} to ${{ steps.check-version.outputs.latest }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update ${{ matrix.package }} to ${{ steps.check-version.outputs.latest }}"
delete-branch: true
branch: deps/update-${{ matrix.package }}
branch: deps/update-${{ matrix.package }}-${{ github.run_number }}
body: |
## What does this PR do?

View File

@@ -88,7 +88,7 @@ jobs:
commit-message: "deps: update zstd to ${{ steps.check-version.outputs.tag }} (${{ steps.check-version.outputs.latest }})"
title: "deps: update zstd to ${{ steps.check-version.outputs.tag }}"
delete-branch: true
branch: deps/update-zstd
branch: deps/update-zstd-${{ github.run_number }}
body: |
## What does this PR do?

1
.gitignore vendored
View File

@@ -1,5 +1,4 @@
.claude/settings.local.json
.direnv
.DS_Store
.env
.envrc

206
CLAUDE.md
View File

@@ -10,8 +10,6 @@ This is the Bun repository - an all-in-one JavaScript runtime & toolkit designed
- **Run tests with your debug build**: `bun bd test <test-file>`
- **CRITICAL**: Never use `bun test` directly - it won't include your changes
- **Run any command with debug build**: `bun bd <command>`
- **Run with JavaScript exception scope verification**: `BUN_JSC_validateExceptionChecks=1
BUN_JSC_dumpSimulatedThrows=1 bun bd <command>`
Tip: Bun is already installed and in $PATH. The `bd` subcommand is a package.json script.
@@ -104,84 +102,129 @@ test("(multi-file test) my feature", async () => {
## Code Architecture
### Directory Structure Overview
The codebase is organized so you can **guess where code lives**:
| Task | Location |
| --------------------- | ----------------------------------- |
| Fix the transpiler | `src/transpiler/` |
| Fix the test runner | `src/test_runner/` |
| Fix the bundler | `src/bundler/` |
| Fix bun install | `src/install/` |
| Fix CSS parsing | `src/css/` |
| Fix the shell | `src/shell/` |
| Fix Postgres | `src/sql/postgres/` |
| Fix MySQL | `src/sql/mysql/` |
| Fix Valkey/Redis | `src/valkey/` |
| Fix S3 | `src/s3/` or `src/buntime/api/s3/` |
| Fix Bake | `src/bake/` |
| Fix Bun.serve() | `src/buntime/api/server/` |
| Fix fetch() | `src/buntime/web/fetch/` |
| Fix WebSocket | `src/buntime/web/websocket/` |
| Fix node:fs | `src/buntime/node/fs/` |
| Fix node:crypto | `src/buntime/node/crypto/` |
| Fix crypto.subtle | `src/buntime/web/webcrypto/` |
| Fix N-API | `src/buntime/compat/napi/` |
| Fix V8 compat | `src/buntime/compat/v8/` |
### Language Structure
- **Zig code** (`src/*.zig`): Core runtime, JavaScript bindings, package manager
- **C++ code** (`src/bun.js/bindings/*.cpp`): JavaScriptCore bindings, Web APIs
- **TypeScript** (`src/js/`): Built-in JavaScript modules with special syntax (see JavaScript Modules section)
- **Generated code**: Many files are auto-generated from `.classes.ts` and other sources. Bun will automatically rebuild these files when you make changes to them.
- **C++ code** (`src/buntime/**/*.cpp`): JavaScriptCore bindings, Web APIs
- **TypeScript** (`src/js/`): Built-in JavaScript modules with special syntax
- **Generated code**: Auto-generated from `.classes.ts` files during build
### Core Source Organization
### Top-Level Source Organization
#### Runtime Core (`src/`)
- `bun.zig` - Main entry point
- `cli.zig` - CLI command orchestration
- `js_parser.zig`, `js_lexer.zig`, `js_printer.zig` - JavaScript parsing/printing
- `transpiler.zig` - Wrapper around js_parser with sourcemap support
- `resolver/` - Module resolution system
- `allocators/` - Custom memory allocators for performance
#### JavaScript Runtime (`src/bun.js/`)
- `bindings/` - C++ JavaScriptCore bindings
- Generated classes from `.classes.ts` files
- Manual bindings for complex APIs
- `api/` - Bun-specific APIs
- `server.zig` - HTTP server implementation
- `FFI.zig` - Foreign Function Interface
- `crypto.zig` - Cryptographic operations
- `glob.zig` - File pattern matching
- `node/` - Node.js compatibility layer
- Module implementations (fs, path, crypto, etc.)
- Process and Buffer APIs
- `webcore/` - Web API implementations
- `fetch.zig` - Fetch API
- `streams.zig` - Web Streams
- `Blob.zig`, `Response.zig`, `Request.zig`
- `event_loop/` - Event loop and task management
#### Build Tools & Package Manager
- `src/bundler/` - JavaScript bundler
- Advanced tree-shaking
- CSS processing
- HTML handling
- `src/install/` - Package manager
- `lockfile/` - Lockfile handling
- `npm.zig` - npm registry client
- `lifecycle_script_runner.zig` - Package scripts
#### Other Key Components
- `src/shell/` - Cross-platform shell implementation
- `src/css/` - CSS parser and processor
- `src/http/` - HTTP client implementation
- `websocket_client/` - WebSocket client (including deflate support)
- `src/sql/` - SQL database integrations
- `src/bake/` - Server-side rendering framework
### JavaScript Class Implementation (C++)
When implementing JavaScript classes in C++:
1. Create three classes if there's a public constructor:
- `class Foo : public JSC::JSDestructibleObject` (if has C++ fields)
- `class FooPrototype : public JSC::JSNonFinalObject`
- `class FooConstructor : public JSC::InternalFunction`
2. Define properties using HashTableValue arrays
3. Add iso subspaces for classes with C++ fields
4. Cache structures in ZigGlobalObject
```
src/
├── transpiler/ # JS/TS transpiler (js_parser, js_lexer, js_printer)
├── test_runner/ # bun:test implementation
├── bundler/ # bun build
├── resolver/ # Module resolution
├── install/ # Package manager (bun install)
├── css/ # CSS parser
├── shell/ # Bun.$ shell
├── bake/ # Bake framework
├── sql/ # SQL clients (postgres/, mysql/)
├── s3/ # S3 core
├── valkey/ # Valkey/Redis
├── http/ # HTTP client
├── string/ # String utilities
├── ast/ # AST types
├── js/ # TypeScript built-in modules
└── buntime/ # JavaScript runtime
├── api/ # Bun.* APIs
│ ├── server/ # Bun.serve()
│ ├── console/ # console.*
│ ├── inspector/ # Debugger, profiler
│ ├── error/ # Error handling, stack traces
│ ├── cookie/ # Cookie parsing
│ ├── s3/ # S3 JS bindings
│ ├── ffi/ # Bun.FFI
│ ├── sqlite/ # bun:sqlite
│ ├── sql/ # SQL bindings
│ ├── shell/ # Shell bindings
│ ├── ipc/ # IPC
│ ├── plugin/ # Bundler plugins
│ ├── secrets/ # Secrets API
│ └── test/ # Test helpers
├── web/ # Web Standards
│ ├── fetch/ # Fetch API
│ ├── url/ # URL, URLSearchParams
│ ├── blob/ # Blob, File, FormData
│ ├── encoding/ # TextEncoder/Decoder
│ ├── compression/ # CompressionStream
│ ├── events/ # EventTarget, CustomEvent
│ ├── streams/ # ReadableStream, WritableStream
│ ├── performance/ # Performance API
│ ├── websocket/ # WebSocket
│ └── webcrypto/ # crypto.subtle
├── node/ # Node.js Compatibility
│ ├── buffer/ # Buffer
│ ├── process/ # process.*
│ ├── vm/ # node:vm
│ ├── crypto/ # node:crypto
│ ├── http/ # node:http
│ ├── fs/ # node:fs helpers
│ ├── os/ # node:os
│ ├── path/ # node:path
│ ├── util/ # node:util
│ ├── timers/ # Timers
│ ├── async_hooks/ # AsyncLocalStorage
│ ├── perf_hooks/ # Performance hooks
│ └── constants/ # Constants
├── compat/ # Native Addon Compatibility
│ ├── napi/ # N-API
│ ├── v8/ # V8 C++ API
│ ├── libuv/ # libuv polyfills
│ └── windows/ # Windows-specific
├── jsc/ # JavaScriptCore Integration
│ ├── types/ # JSValue, JSString, JSArray, etc.
│ ├── global/ # ZigGlobalObject, BunGlobalScope
│ ├── gc/ # GC helpers, weak refs
│ ├── interop/ # C++/Zig bindings, IDL
│ └── generated/ # Generated bindings
├── module/ # Module system (CommonJS, ESM)
├── event_loop/ # Event loop, tasks, timers
└── core/ # VirtualMachine, config
```
### Code Generation
Code generation happens automatically as part of the build process. The main scripts are:
Code generation happens automatically during build. Main scripts:
- `src/codegen/generate-classes.ts` - Generates Zig & C++ bindings from `*.classes.ts` files
- `src/codegen/generate-jssink.ts` - Generates stream-related classes
- `src/codegen/bundle-modules.ts` - Bundles built-in modules like `node:fs`
- `src/codegen/bundle-functions.ts` - Bundles global functions like `ReadableStream`
- `src/codegen/generate-classes.ts` - Generates Zig & C++ from `*.classes.ts`
- `src/codegen/generate-jssink.ts` - Stream-related classes
- `src/codegen/bundle-modules.ts` - Built-in modules like `node:fs`
- `src/codegen/bundle-functions.ts` - Global functions like `ReadableStream`
In development, bundled modules can be reloaded without rebuilding Zig by running `bun run build`.
@@ -211,24 +254,3 @@ Built-in JavaScript modules use special syntax and are organized as:
12. **Branch names must start with `claude/`** - This is a requirement for the CI to work.
**ONLY** push up changes after running `bun bd test <file>` and ensuring your tests pass.
## Debugging CI Failures
Use `scripts/buildkite-failures.ts` to fetch and analyze CI build failures:
```bash
# View failures for current branch
bun run scripts/buildkite-failures.ts
# View failures for a specific build number
bun run scripts/buildkite-failures.ts 35051
# View failures for a GitHub PR
bun run scripts/buildkite-failures.ts #26173
bun run scripts/buildkite-failures.ts https://github.com/oven-sh/bun/pull/26173
# Wait for build to complete (polls every 10s until pass/fail)
bun run scripts/buildkite-failures.ts --wait
```
The script fetches logs from BuildKite's public API and saves complete logs to `/tmp/bun-build-{number}-{platform}-{step}.log`. It displays a summary of errors and the file path for each failed job. Use `--wait` to poll continuously until the build completes or fails.

View File

@@ -259,13 +259,18 @@ $ git clone https://github.com/oven-sh/WebKit vendor/WebKit
# Check out the commit hash specified in `set(WEBKIT_VERSION <commit_hash>)` in cmake/tools/SetupWebKit.cmake
$ git -C vendor/WebKit checkout <commit_hash>
# Build bun with the local JSC build — this automatically configures and builds JSC
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
# Optionally, you can use `bun run jsc:build` for a release build
$ bun run jsc:build:debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
# After an initial run of `make jsc-debug`, you can rebuild JSC with:
$ cmake --build vendor/WebKit/WebKitBuild/Debug --target jsc && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
# Build bun with the local JSC build
$ bun run build:local
```
`bun run build:local` handles everything: configuring JSC, building JSC, and building Bun. On subsequent runs, JSC will incrementally rebuild if any WebKit sources changed. `ninja -Cbuild/debug-local` also works after the first build, and will build Bun+JSC.
The build output goes to `./build/debug-local` (instead of `./build/debug`), so you'll need to update a couple of places:
Using `bun run build:local` will build Bun in the `./build/debug-local` directory (instead of `./build/debug`), you'll have to change a couple of places to use this new directory:
- The first line in [`src/js/builtins.d.ts`](/src/js/builtins.d.ts)
- The `CompilationDatabase` line in [`.clangd` config](/.clangd) should be `CompilationDatabase: build/debug-local`
@@ -276,7 +281,7 @@ Note that the WebKit folder, including build artifacts, is 8GB+ in size.
If you are using a JSC debug build and using VScode, make sure to run the `C/C++: Select a Configuration` command to configure intellisense to find the debug headers.
Note that if you make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change [`SetupWebKit.cmake`](/cmake/tools/SetupWebKit.cmake) to point to the commit hash.
Note that if you change make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change [`SetupWebKit.cmake`](/cmake/tools/SetupWebKit.cmake) to point to the commit hash.
## Troubleshooting

2
LATEST
View File

@@ -1 +1 @@
1.3.8
1.3.5

View File

@@ -36,7 +36,6 @@ Bun statically links these libraries:
| [`libbase64`](https://github.com/aklomp/base64/blob/master/LICENSE) | BSD 2-Clause |
| [`libuv`](https://github.com/libuv/libuv) (on Windows) | MIT |
| [`libdeflate`](https://github.com/ebiggers/libdeflate) | MIT |
| [`uucode`](https://github.com/jacobsandlund/uucode) | MIT |
| A fork of [`uWebsockets`](https://github.com/jarred-sumner/uwebsockets) | Apache 2.0 licensed |
| Parts of [Tigerbeetle's IO code](https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1) | Apache 2.0 licensed |

1112
PLAN.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -18,18 +18,12 @@
"fast-glob": "3.3.1",
"fastify": "^5.0.0",
"fdir": "^6.1.0",
"marked": "^17.0.1",
"mitata": "1.0.20",
"react": "^19",
"react-dom": "^19",
"react-markdown": "^9.0.3",
"remark": "^15.0.1",
"remark-html": "^16.0.1",
"mitata": "^1.0.25",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"string-width": "7.1.0",
"strip-ansi": "^7.1.0",
"tar": "^7.4.3",
"tinycolor2": "^1.6.0",
"wrap-ansi": "^9.0.0",
"zx": "^7.2.3",
},
"devDependencies": {
@@ -114,8 +108,6 @@
"@fastify/proxy-addr": ["@fastify/proxy-addr@5.0.0", "", { "dependencies": { "@fastify/forwarded": "^3.0.0", "ipaddr.js": "^2.1.0" } }, "sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA=="],
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.1.1", "", { "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.0", "", {}, "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="],
@@ -154,36 +146,18 @@
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.3.35", "", { "os": "win32", "cpu": "x64" }, "sha512-/RvphT4WfuGfIK84Ha0dovdPrKB1bW/mc+dtdmhv2E3EGkNc5FoueNwYmXWRimxnU7X0X7IkcRhyKB4G5DeAmg=="],
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
"@types/fs-extra": ["@types/fs-extra@11.0.4", "", { "dependencies": { "@types/jsonfile": "*", "@types/node": "*" } }, "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ=="],
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
"@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
"@types/minimist": ["@types/minimist@1.2.5", "", {}, "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag=="],
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
"@types/node": ["@types/node@18.19.8", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-g1pZtPhsvGVTwmeVoexWZLTQaOvXwoSq//pTL0DHeNzUDrFnir4fgETdhjhIxjVnN+hKOuh98+E1eMLnUXstFg=="],
"@types/ps-tree": ["@types/ps-tree@1.1.6", "", {}, "sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ=="],
"@types/react": ["@types/react@19.2.10", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw=="],
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
"@types/which": ["@types/which@3.0.3", "", {}, "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"abstract-logging": ["abstract-logging@2.0.1", "", {}, "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA=="],
"ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
@@ -192,14 +166,12 @@
"ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
"ansi-styles": ["ansi-styles@6.2.3", "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/ansi-styles/-/ansi-styles-6.2.3.tgz", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
"atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
"avvio": ["avvio@9.1.0", "", { "dependencies": { "@fastify/error": "^4.0.0", "fastq": "^1.17.1" } }, "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw=="],
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
"benchmark": ["benchmark@2.1.4", "", { "dependencies": { "lodash": "^4.17.4", "platform": "^1.3.3" } }, "sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ=="],
"braces": ["braces@3.0.2", "", { "dependencies": { "fill-range": "^7.0.1" } }, "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="],
@@ -208,20 +180,8 @@
"caniuse-lite": ["caniuse-lite@1.0.30001456", "", {}, "sha512-XFHJY5dUgmpMV25UqaD4kVq2LsiaU5rS8fb0f17pCoXQiQslzmFgnfOxfvo1bTpTqf7dwG/N/05CnLCnOEKmzA=="],
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
"chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="],
"character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="],
"character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
"character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="],
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
"color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
@@ -230,26 +190,18 @@
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
"convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="],
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
"cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="],
"debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="],
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
"dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="],
"duplexer": ["duplexer@0.1.2", "", {}, "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="],
@@ -304,16 +256,12 @@
"escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
"estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="],
"event-stream": ["event-stream@3.3.4", "", { "dependencies": { "duplexer": "~0.1.1", "from": "~0", "map-stream": "~0.1.0", "pause-stream": "0.0.11", "split": "0.3", "stream-combiner": "~0.0.4", "through": "~2.3.1" } }, "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g=="],
"eventemitter3": ["eventemitter3@5.0.0", "", {}, "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg=="],
"execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="],
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
@@ -364,44 +312,20 @@
"has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
"hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="],
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
"hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
"html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="],
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
"human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="],
"ignore": ["ignore@5.3.0", "", {}, "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg=="],
"inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
"ipaddr.js": ["ipaddr.js@2.2.0", "", {}, "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA=="],
"is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
"is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
@@ -422,87 +346,23 @@
"lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
"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=="],
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
"map-stream": ["map-stream@0.1.0", "", {}, "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g=="],
"marked": ["marked@17.0.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg=="],
"mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="],
"mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="],
"mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="],
"mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="],
"mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="],
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
"mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="],
"mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="],
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="],
"micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
"micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="],
"micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="],
"micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="],
"micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="],
"micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="],
"micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
"micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="],
"micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="],
"micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="],
"micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="],
"micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="],
"micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
"micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="],
"micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="],
"micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="],
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
"micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="],
"micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
"micromatch": ["micromatch@4.0.5", "", { "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA=="],
"mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
"minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="],
"mitata": ["mitata@1.0.20", "", {}, "sha512-oHWYGX5bi4wGT/1zrhiZAEzqTV14Vq6/PUTW8WK0b3YHBBQcZz2QFm+InHhjnD0I7B6CMtwdGt2K0938r7YTdQ=="],
"mitata": ["mitata@1.0.25", "", {}, "sha512-0v5qZtVW5vwj9FDvYfraR31BMDcRLkhSFWPTLaxx/Z3/EvScfVtAAWtMI2ArIbBcwh7P86dXh0lQWKiXQPlwYA=="],
"ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
@@ -518,8 +378,6 @@
"onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="],
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
@@ -540,32 +398,18 @@
"process-warning": ["process-warning@5.0.0", "", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="],
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
"ps-tree": ["ps-tree@1.2.0", "", { "dependencies": { "event-stream": "=3.3.4" }, "bin": { "ps-tree": "./bin/ps-tree.js" } }, "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
"react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="],
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
"react-markdown": ["react-markdown@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw=="],
"react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="],
"real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="],
"remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="],
"remark-html": ["remark-html@16.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "hast-util-sanitize": "^5.0.0", "hast-util-to-html": "^9.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0" } }, "sha512-B9JqA5i0qZe0Nsf49q3OXyGvyXuZFDzAP2iOFLEumymuYJITVpiH1IgsTEwTpdptDmZlMDMWeDmSawdaJIGCXQ=="],
"remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
"remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
"remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="],
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
"ret": ["ret@0.5.0", "", {}, "sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw=="],
@@ -580,7 +424,7 @@
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
"secure-json-parse": ["secure-json-parse@4.0.0", "", {}, "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA=="],
@@ -600,8 +444,6 @@
"sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="],
"space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
"split": ["split@0.3.3", "", { "dependencies": { "through": "2" } }, "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA=="],
"split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
@@ -610,20 +452,12 @@
"string-width": ["string-width@7.1.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw=="],
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
"style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="],
"style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="],
"supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="],
"tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="],
"thread-stream": ["thread-stream@3.1.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A=="],
"through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="],
@@ -636,52 +470,30 @@
"toad-cache": ["toad-cache@3.7.0", "", {}, "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw=="],
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
"unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
"unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="],
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
"update-browserslist-db": ["update-browserslist-db@1.0.10", "", { "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "browserslist-lint": "cli.js" } }, "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ=="],
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
"vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
"web-streams-polyfill": ["web-streams-polyfill@3.3.2", "", {}, "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ=="],
"webpod": ["webpod@0.0.2", "", { "bin": { "webpod": "dist/index.js" } }, "sha512-cSwwQIeg8v4i3p4ajHhwgR7N6VyxAf+KYSSsY6Pd3aETE+xEU4vbitz7qQkB0I321xnhDdgtxuiSfk5r/FVtjg=="],
"which": ["which@3.0.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg=="],
"wrap-ansi": ["wrap-ansi@9.0.2", "https://artifactory.infra.ant.dev:443/artifactory/api/npm/npm-all/wrap-ansi/-/wrap-ansi-9.0.2.tgz", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"yaml": ["yaml@2.3.4", "", {}, "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"zx": ["zx@7.2.3", "", { "dependencies": { "@types/fs-extra": "^11.0.1", "@types/minimist": "^1.2.2", "@types/node": "^18.16.3", "@types/ps-tree": "^1.1.2", "@types/which": "^3.0.0", "chalk": "^5.2.0", "fs-extra": "^11.1.1", "fx": "*", "globby": "^13.1.4", "minimist": "^1.2.8", "node-fetch": "3.3.1", "ps-tree": "^1.2.0", "webpod": "^0", "which": "^3.0.0", "yaml": "^2.2.2" }, "bin": { "zx": "build/cli.js" } }, "sha512-QODu38nLlYXg/B/Gw7ZKiZrvPkEsjPN3LQ5JFXM7h0JvwhEdPNNl+4Ao1y4+o3CLNiDUNcwzQYZ4/Ko7kKzCMA=="],
"@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.2", "", { "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } }, "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A=="],
"@babel/highlight/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
"ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"avvio/fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
"cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
@@ -690,16 +502,8 @@
"light-my-request/process-warning": ["process-warning@4.0.1", "", {}, "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q=="],
"lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
"@babel/highlight/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
"@babel/highlight/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"@babel/highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
"ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
}
}

View File

@@ -1,15 +0,0 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "json5-benchmark",
"dependencies": {
"json5": "^2.2.3",
},
},
},
"packages": {
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
}
}

View File

@@ -1,88 +0,0 @@
import JSON5 from "json5";
import { bench, group, run } from "../runner.mjs";
const isBun = typeof Bun !== "undefined" && Bun.JSON5;
function sizeLabel(n) {
if (n >= 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)}MB`;
if (n >= 1024) return `${(n / 1024).toFixed(0)}KB`;
return `${n}B`;
}
// -- parse inputs --
const smallJson5 = `{
// User profile
name: "John Doe",
age: 30,
email: 'john@example.com',
active: true,
}`;
function generateLargeJson5(count) {
const lines = ["{\n // Auto-generated dataset\n items: [\n"];
for (let i = 0; i < count; i++) {
lines.push(` {
id: ${i},
name: 'item_${i}',
value: ${(Math.random() * 1000).toFixed(2)},
hex: 0x${i.toString(16).toUpperCase()},
active: ${i % 2 === 0},
tags: ['tag_${i % 10}', 'category_${i % 5}',],
// entry ${i}
},\n`);
}
lines.push(" ],\n total: " + count + ",\n status: 'complete',\n}\n");
return lines.join("");
}
const largeJson5 = generateLargeJson5(6500);
// -- stringify inputs --
const smallObject = {
name: "John Doe",
age: 30,
email: "john@example.com",
active: true,
};
const largeObject = {
items: Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `item_${i}`,
value: +(Math.random() * 1000).toFixed(2),
active: i % 2 === 0,
tags: [`tag_${i % 10}`, `category_${i % 5}`],
})),
total: 10000,
status: "complete",
};
const stringify = isBun ? Bun.JSON5.stringify : JSON5.stringify;
// -- parse benchmarks --
group(`parse small (${sizeLabel(smallJson5.length)})`, () => {
if (isBun) bench("Bun.JSON5.parse", () => Bun.JSON5.parse(smallJson5));
bench("json5.parse", () => JSON5.parse(smallJson5));
});
group(`parse large (${sizeLabel(largeJson5.length)})`, () => {
if (isBun) bench("Bun.JSON5.parse", () => Bun.JSON5.parse(largeJson5));
bench("json5.parse", () => JSON5.parse(largeJson5));
});
// -- stringify benchmarks --
group(`stringify small (${sizeLabel(stringify(smallObject).length)})`, () => {
if (isBun) bench("Bun.JSON5.stringify", () => Bun.JSON5.stringify(smallObject));
bench("json5.stringify", () => JSON5.stringify(smallObject));
});
group(`stringify large (${sizeLabel(stringify(largeObject).length)})`, () => {
if (isBun) bench("Bun.JSON5.stringify", () => Bun.JSON5.stringify(largeObject));
bench("json5.stringify", () => JSON5.stringify(largeObject));
});
await run();

View File

@@ -1,7 +0,0 @@
{
"name": "json5-benchmark",
"version": "1.0.0",
"dependencies": {
"json5": "^2.2.3"
}
}

View File

@@ -14,18 +14,12 @@
"fast-glob": "3.3.1",
"fastify": "^5.0.0",
"fdir": "^6.1.0",
"marked": "^17.0.1",
"mitata": "1.0.20",
"react": "^19",
"react-dom": "^19",
"react-markdown": "^9.0.3",
"remark": "^15.0.1",
"remark-html": "^16.0.1",
"mitata": "^1.0.25",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"string-width": "7.1.0",
"strip-ansi": "^7.1.0",
"tar": "^7.4.3",
"tinycolor2": "^1.6.0",
"wrap-ansi": "^9.0.0",
"zx": "^7.2.3"
},
"scripts": {

View File

@@ -14,4 +14,3 @@ export function run(opts = {}) {
export const bench = Mitata.bench;
export const group = Mitata.group;
export const summary = Mitata.summary;

View File

@@ -1,477 +0,0 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { Pack, Unpack } from "tar";
import { bench, group, run } from "../runner.mjs";
// Check if Bun.Archive is available
const hasBunArchive = typeof Bun !== "undefined" && typeof Bun.Archive !== "undefined";
// Test data sizes
const smallContent = "Hello, World!";
const mediumContent = Buffer.alloc(10 * 1024, "x").toString(); // 10KB
const largeContent = Buffer.alloc(100 * 1024, "x").toString(); // 100KB
// Create test files for node-tar (it reads from filesystem)
const setupDir = mkdtempSync(join(tmpdir(), "archive-bench-setup-"));
function setupNodeTarFiles(prefix, files) {
const dir = join(setupDir, prefix);
mkdirSync(dir, { recursive: true });
for (const [name, content] of Object.entries(files)) {
const filePath = join(dir, name);
const fileDir = join(filePath, "..");
mkdirSync(fileDir, { recursive: true });
writeFileSync(filePath, content);
}
return dir;
}
// Setup directories for different test cases
const smallFilesDir = setupNodeTarFiles("small", {
"file1.txt": smallContent,
"file2.txt": smallContent,
"file3.txt": smallContent,
});
const mediumFilesDir = setupNodeTarFiles("medium", {
"file1.txt": mediumContent,
"file2.txt": mediumContent,
"file3.txt": mediumContent,
});
const largeFilesDir = setupNodeTarFiles("large", {
"file1.txt": largeContent,
"file2.txt": largeContent,
"file3.txt": largeContent,
});
const manyFilesEntries = {};
for (let i = 0; i < 100; i++) {
manyFilesEntries[`file${i}.txt`] = smallContent;
}
const manyFilesDir = setupNodeTarFiles("many", manyFilesEntries);
// Pre-create archives for extraction benchmarks
let smallTarGzBuffer, mediumTarGzBuffer, largeTarGzBuffer, manyFilesTarGzBuffer;
let smallTarBuffer, mediumTarBuffer, largeTarBuffer, manyFilesTarBuffer;
let smallBunArchiveGz, mediumBunArchiveGz, largeBunArchiveGz, manyFilesBunArchiveGz;
let smallBunArchive, mediumBunArchive, largeBunArchive, manyFilesBunArchive;
// Create tar buffer using node-tar (with optional gzip)
async function createNodeTarBuffer(cwd, files, gzip = false) {
return new Promise(resolve => {
const pack = new Pack({ cwd, gzip });
const bufs = [];
pack.on("data", chunk => bufs.push(chunk));
pack.on("end", () => resolve(Buffer.concat(bufs)));
for (const file of files) {
pack.add(file);
}
pack.end();
});
}
// Extract tar buffer using node-tar
async function extractNodeTarBuffer(buffer, cwd) {
return new Promise((resolve, reject) => {
const unpack = new Unpack({ cwd });
unpack.on("end", resolve);
unpack.on("error", reject);
unpack.end(buffer);
});
}
// Initialize gzipped archives
smallTarGzBuffer = await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
mediumTarGzBuffer = await createNodeTarBuffer(mediumFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
largeTarGzBuffer = await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
manyFilesTarGzBuffer = await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), true);
// Initialize uncompressed archives
smallTarBuffer = await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
mediumTarBuffer = await createNodeTarBuffer(mediumFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
largeTarBuffer = await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
manyFilesTarBuffer = await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), false);
const smallFiles = { "file1.txt": smallContent, "file2.txt": smallContent, "file3.txt": smallContent };
const mediumFiles = { "file1.txt": mediumContent, "file2.txt": mediumContent, "file3.txt": mediumContent };
const largeFiles = { "file1.txt": largeContent, "file2.txt": largeContent, "file3.txt": largeContent };
if (hasBunArchive) {
smallBunArchiveGz = await Bun.Archive.from(smallFiles).bytes("gzip");
mediumBunArchiveGz = await Bun.Archive.from(mediumFiles).bytes("gzip");
largeBunArchiveGz = await Bun.Archive.from(largeFiles).bytes("gzip");
manyFilesBunArchiveGz = await Bun.Archive.from(manyFilesEntries).bytes("gzip");
smallBunArchive = await Bun.Archive.from(smallFiles).bytes();
mediumBunArchive = await Bun.Archive.from(mediumFiles).bytes();
largeBunArchive = await Bun.Archive.from(largeFiles).bytes();
manyFilesBunArchive = await Bun.Archive.from(manyFilesEntries).bytes();
}
// Create reusable extraction directories (overwriting is fine)
const extractDirNodeTar = mkdtempSync(join(tmpdir(), "archive-bench-extract-node-"));
const extractDirBun = mkdtempSync(join(tmpdir(), "archive-bench-extract-bun-"));
const writeDirNodeTar = mkdtempSync(join(tmpdir(), "archive-bench-write-node-"));
const writeDirBun = mkdtempSync(join(tmpdir(), "archive-bench-write-bun-"));
// ============================================================================
// Create .tar (uncompressed) benchmarks
// ============================================================================
group("create .tar (3 small files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(smallFiles).bytes();
});
}
});
group("create .tar (3 x 100KB files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(largeFiles).bytes();
});
}
});
group("create .tar (100 small files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), false);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(manyFilesEntries).bytes();
});
}
});
// ============================================================================
// Create .tar.gz (compressed) benchmarks
// ============================================================================
group("create .tar.gz (3 small files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(smallFiles).bytes("gzip");
});
}
});
group("create .tar.gz (3 x 100KB files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(largeFiles).bytes("gzip");
});
}
});
group("create .tar.gz (100 small files)", () => {
bench("node-tar", async () => {
await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), true);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(manyFilesEntries).bytes("gzip");
});
}
});
// ============================================================================
// Extract .tar (uncompressed) benchmarks
// ============================================================================
group("extract .tar (3 small files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(smallTarBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(smallBunArchive).extract(extractDirBun);
});
}
});
group("extract .tar (3 x 100KB files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(largeTarBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(largeBunArchive).extract(extractDirBun);
});
}
});
group("extract .tar (100 small files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(manyFilesTarBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(manyFilesBunArchive).extract(extractDirBun);
});
}
});
// ============================================================================
// Extract .tar.gz (compressed) benchmarks
// ============================================================================
group("extract .tar.gz (3 small files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(smallTarGzBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(smallBunArchiveGz).extract(extractDirBun);
});
}
});
group("extract .tar.gz (3 x 100KB files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(largeTarGzBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(largeBunArchiveGz).extract(extractDirBun);
});
}
});
group("extract .tar.gz (100 small files)", () => {
bench("node-tar", async () => {
await extractNodeTarBuffer(manyFilesTarGzBuffer, extractDirNodeTar);
});
if (hasBunArchive) {
bench("Bun.Archive", async () => {
await Bun.Archive.from(manyFilesBunArchiveGz).extract(extractDirBun);
});
}
});
// ============================================================================
// Write .tar to disk benchmarks
// ============================================================================
let writeCounter = 0;
group("write .tar to disk (3 small files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar`), smallFiles);
});
}
});
group("write .tar to disk (3 x 100KB files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], false);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar`), largeFiles);
});
}
});
group("write .tar to disk (100 small files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), false);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar`), manyFilesEntries);
});
}
});
// ============================================================================
// Write .tar.gz to disk benchmarks
// ============================================================================
group("write .tar.gz to disk (3 small files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(smallFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar.gz`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar.gz`), smallFiles, "gzip");
});
}
});
group("write .tar.gz to disk (3 x 100KB files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(largeFilesDir, ["file1.txt", "file2.txt", "file3.txt"], true);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar.gz`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar.gz`), largeFiles, "gzip");
});
}
});
group("write .tar.gz to disk (100 small files)", () => {
bench("node-tar + writeFileSync", async () => {
const buffer = await createNodeTarBuffer(manyFilesDir, Object.keys(manyFilesEntries), true);
writeFileSync(join(writeDirNodeTar, `archive-${writeCounter++}.tar.gz`), buffer);
});
if (hasBunArchive) {
bench("Bun.Archive.write", async () => {
await Bun.Archive.write(join(writeDirBun, `archive-${writeCounter++}.tar.gz`), manyFilesEntries, "gzip");
});
}
});
// ============================================================================
// Get files array from archive (files() method) benchmarks
// ============================================================================
// Helper to get files array from node-tar (reads all entries into memory)
async function getFilesArrayNodeTar(buffer) {
return new Promise((resolve, reject) => {
const files = new Map();
let pending = 0;
let closed = false;
const maybeResolve = () => {
if (closed && pending === 0) {
resolve(files);
}
};
const unpack = new Unpack({
onReadEntry: entry => {
if (entry.type === "File") {
pending++;
const chunks = [];
entry.on("data", chunk => chunks.push(chunk));
entry.on("end", () => {
const content = Buffer.concat(chunks);
// Create a File-like object similar to Bun.Archive.files()
files.set(entry.path, new Blob([content]));
pending--;
maybeResolve();
});
}
entry.resume(); // Drain the entry
},
});
unpack.on("close", () => {
closed = true;
maybeResolve();
});
unpack.on("error", reject);
unpack.end(buffer);
});
}
group("files() - get all files as Map (3 small files)", () => {
bench("node-tar", async () => {
await getFilesArrayNodeTar(smallTarBuffer);
});
if (hasBunArchive) {
bench("Bun.Archive.files()", async () => {
await Bun.Archive.from(smallBunArchive).files();
});
}
});
group("files() - get all files as Map (3 x 100KB files)", () => {
bench("node-tar", async () => {
await getFilesArrayNodeTar(largeTarBuffer);
});
if (hasBunArchive) {
bench("Bun.Archive.files()", async () => {
await Bun.Archive.from(largeBunArchive).files();
});
}
});
group("files() - get all files as Map (100 small files)", () => {
bench("node-tar", async () => {
await getFilesArrayNodeTar(manyFilesTarBuffer);
});
if (hasBunArchive) {
bench("Bun.Archive.files()", async () => {
await Bun.Archive.from(manyFilesBunArchive).files();
});
}
});
group("files() - get all files as Map from .tar.gz (3 small files)", () => {
bench("node-tar", async () => {
await getFilesArrayNodeTar(smallTarGzBuffer);
});
if (hasBunArchive) {
bench("Bun.Archive.files()", async () => {
await Bun.Archive.from(smallBunArchiveGz).files();
});
}
});
group("files() - get all files as Map from .tar.gz (100 small files)", () => {
bench("node-tar", async () => {
await getFilesArrayNodeTar(manyFilesTarGzBuffer);
});
if (hasBunArchive) {
bench("Bun.Archive.files()", async () => {
await Bun.Archive.from(manyFilesBunArchiveGz).files();
});
}
});
await run();
// Cleanup
rmSync(setupDir, { recursive: true, force: true });
rmSync(extractDirNodeTar, { recursive: true, force: true });
rmSync(extractDirBun, { recursive: true, force: true });
rmSync(writeDirNodeTar, { recursive: true, force: true });
rmSync(writeDirBun, { recursive: true, force: true });

View File

@@ -1,38 +0,0 @@
// @runtime bun,node
import { Buffer } from "node:buffer";
import { bench, group, run } from "../runner.mjs";
// Small arrays (common case)
const int32Array8 = [1, 2, 3, 4, 5, 6, 7, 8];
const doubleArray8 = [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5];
// Medium arrays
const int32Array64 = Array.from({ length: 64 }, (_, i) => i % 256);
const doubleArray64 = Array.from({ length: 64 }, (_, i) => i + 0.5);
// Large arrays
const int32Array1024 = Array.from({ length: 1024 }, (_, i) => i % 256);
// Array-like objects (fallback path)
const arrayLike8 = { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, length: 8 };
// Empty array
const emptyArray = [];
group("Buffer.from(array) - Int32 arrays", () => {
bench("Buffer.from(int32[8])", () => Buffer.from(int32Array8));
bench("Buffer.from(int32[64])", () => Buffer.from(int32Array64));
bench("Buffer.from(int32[1024])", () => Buffer.from(int32Array1024));
});
group("Buffer.from(array) - Double arrays", () => {
bench("Buffer.from(double[8])", () => Buffer.from(doubleArray8));
bench("Buffer.from(double[64])", () => Buffer.from(doubleArray64));
});
group("Buffer.from(array) - Edge cases", () => {
bench("Buffer.from([])", () => Buffer.from(emptyArray));
bench("Buffer.from(arrayLike[8])", () => Buffer.from(arrayLike8));
});
await run();

View File

@@ -1,92 +0,0 @@
import React from "react";
import { renderToString } from "react-dom/server";
import ReactMarkdown from "react-markdown";
const markdown = `# Project README
## Introduction
This is a medium-sized markdown document that includes **bold text**, *italic text*,
and \`inline code\`. It also has [links](https://example.com) and various formatting.
## Features
- Feature one with **bold**
- Feature two with *emphasis*
- Feature three with \`code\`
- Feature four with [a link](https://example.com)
## Code Example
\`\`\`javascript
function hello() {
console.log("Hello, world!");
return 42;
}
const result = hello();
\`\`\`
## Table
| Name | Value | Description |
|------|-------|-------------|
| foo | 1 | First item |
| bar | 2 | Second item |
| baz | 3 | Third item |
## Blockquote
> This is a blockquote with **bold** and *italic* text.
> It spans multiple lines and contains a [link](https://example.com).
---
### Nested Lists
1. First ordered item
- Nested unordered
- Another nested
2. Second ordered item
1. Nested ordered
2. Another nested
3. Third ordered item
Some final paragraph with ~~strikethrough~~ text and more **formatting**.
`;
// Verify outputs are roughly the same
const bunHtml = renderToString(Bun.markdown.react(markdown));
const reactMarkdownHtml = renderToString(React.createElement(ReactMarkdown, { children: markdown }));
console.log("=== Bun.markdown.react output ===");
console.log(bunHtml.slice(0, 500));
console.log(`... (${bunHtml.length} chars total)\n`);
console.log("=== react-markdown output ===");
console.log(reactMarkdownHtml.slice(0, 500));
console.log(`... (${reactMarkdownHtml.length} chars total)\n`);
const server = Bun.serve({
port: 0,
routes: {
"/bun-markdown": () => {
return new Response(renderToString(Bun.markdown.react(markdown)), {
headers: { "Content-Type": "text/html" },
});
},
"/react-markdown": () => {
return new Response(renderToString(React.createElement(ReactMarkdown, { children: markdown })), {
headers: { "Content-Type": "text/html" },
});
},
},
});
console.log(`Server listening on ${server.url}`);
console.log(` ${server.url}bun-markdown`);
console.log(` ${server.url}react-markdown`);
console.log();
console.log("Run:");
console.log(` oha -c 20 -z 5s ${server.url}bun-markdown`);
console.log(` oha -c 20 -z 5s ${server.url}react-markdown`);

View File

@@ -1,159 +0,0 @@
import { marked } from "marked";
import { remark } from "remark";
import remarkHtml from "remark-html";
import { bench, run, summary } from "../runner.mjs";
const remarkProcessor = remark().use(remarkHtml);
const small = `# Hello World
This is a **bold** and *italic* paragraph with a [link](https://example.com).
- Item 1
- Item 2
- Item 3
`;
const medium = `# Project README
## Introduction
This is a medium-sized markdown document that includes **bold text**, *italic text*,
and \`inline code\`. It also has [links](https://example.com) and various formatting.
## Features
- Feature one with **bold**
- Feature two with *emphasis*
- Feature three with \`code\`
- Feature four with [a link](https://example.com)
## Code Example
\`\`\`javascript
function hello() {
console.log("Hello, world!");
return 42;
}
const result = hello();
\`\`\`
## Table
| Name | Value | Description |
|------|-------|-------------|
| foo | 1 | First item |
| bar | 2 | Second item |
| baz | 3 | Third item |
## Blockquote
> This is a blockquote with **bold** and *italic* text.
> It spans multiple lines and contains a [link](https://example.com).
---
### Nested Lists
1. First ordered item
- Nested unordered
- Another nested
2. Second ordered item
1. Nested ordered
2. Another nested
3. Third ordered item
Some final paragraph with ~~strikethrough~~ text and more **formatting**.
`;
const large = medium.repeat(20);
const renderCallbacks = {
heading: (children, { level }) => `<h${level}>${children}</h${level}>`,
paragraph: children => `<p>${children}</p>`,
strong: children => `<strong>${children}</strong>`,
emphasis: children => `<em>${children}</em>`,
codespan: children => `<code>${children}</code>`,
code: (children, { language }) =>
language
? `<pre><code class="language-${language}">${children}</code></pre>`
: `<pre><code>${children}</code></pre>`,
link: (children, { href, title }) =>
title ? `<a href="${href}" title="${title}">${children}</a>` : `<a href="${href}">${children}</a>`,
image: (children, { src, title }) =>
title ? `<img src="${src}" alt="${children}" title="${title}" />` : `<img src="${src}" alt="${children}" />`,
list: (children, { ordered, start }) => (ordered ? `<ol start="${start}">${children}</ol>` : `<ul>${children}</ul>`),
listItem: children => `<li>${children}</li>`,
blockquote: children => `<blockquote>${children}</blockquote>`,
hr: () => `<hr />`,
strikethrough: children => `<del>${children}</del>`,
table: children => `<table>${children}</table>`,
thead: children => `<thead>${children}</thead>`,
tbody: children => `<tbody>${children}</tbody>`,
tr: children => `<tr>${children}</tr>`,
th: children => `<th>${children}</th>`,
td: children => `<td>${children}</td>`,
};
summary(() => {
if (typeof Bun !== "undefined" && Bun.markdown) {
bench(`small (${small.length} chars) - Bun.markdown.html`, () => {
return Bun.markdown.html(small);
});
bench(`small (${small.length} chars) - Bun.markdown.render`, () => {
return Bun.markdown.render(small, renderCallbacks);
});
}
bench(`small (${small.length} chars) - marked`, () => {
return marked(small);
});
bench(`small (${small.length} chars) - remark`, () => {
return remarkProcessor.processSync(small).toString();
});
});
summary(() => {
if (typeof Bun !== "undefined" && Bun.markdown) {
bench(`medium (${medium.length} chars) - Bun.markdown.html`, () => {
return Bun.markdown.html(medium);
});
bench(`medium (${medium.length} chars) - Bun.markdown.render`, () => {
return Bun.markdown.render(medium, renderCallbacks);
});
}
bench(`medium (${medium.length} chars) - marked`, () => {
return marked(medium);
});
bench(`medium (${medium.length} chars) - remark`, () => {
return remarkProcessor.processSync(medium).toString();
});
});
summary(() => {
if (typeof Bun !== "undefined" && Bun.markdown) {
bench(`large (${large.length} chars) - Bun.markdown.html`, () => {
return Bun.markdown.html(large);
});
bench(`large (${large.length} chars) - Bun.markdown.render`, () => {
return Bun.markdown.render(large, renderCallbacks);
});
}
bench(`large (${large.length} chars) - marked`, () => {
return marked(large);
});
bench(`large (${large.length} chars) - remark`, () => {
return remarkProcessor.processSync(large).toString();
});
});
await run();

View File

@@ -1,20 +0,0 @@
// Benchmark for [...set] optimization (WebKit#56539)
// https://github.com/WebKit/WebKit/pull/56539
import { bench, run } from "../runner.mjs";
const intSet10 = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const intSet100 = new Set(Array.from({ length: 100 }, (_, i) => i));
const strSet10 = new Set(Array.from({ length: 10 }, (_, i) => `key-${i}`));
const strSet100 = new Set(Array.from({ length: 100 }, (_, i) => `key-${i}`));
const objSet10 = new Set(Array.from({ length: 10 }, (_, i) => ({ id: i })));
const objSet100 = new Set(Array.from({ length: 100 }, (_, i) => ({ id: i })));
bench("[...set] - integers (10)", () => [...intSet10]);
bench("[...set] - integers (100)", () => [...intSet100]);
bench("[...set] - strings (10)", () => [...strSet10]);
bench("[...set] - strings (100)", () => [...strSet100]);
bench("[...set] - objects (10)", () => [...objSet10]);
bench("[...set] - objects (100)", () => [...objSet100]);
await run();

View File

@@ -1,103 +0,0 @@
import wrapAnsi from "wrap-ansi";
import { bench, run, summary } from "../runner.mjs";
// Test fixtures
const shortText = "The quick brown fox jumped over the lazy dog.";
const mediumText = "The quick brown fox jumped over the lazy dog and then ran away with the unicorn. ".repeat(10);
const longText = "The quick brown fox jumped over the lazy dog and then ran away with the unicorn. ".repeat(100);
// ANSI colored text
const red = s => `\u001B[31m${s}\u001B[39m`;
const green = s => `\u001B[32m${s}\u001B[39m`;
const blue = s => `\u001B[34m${s}\u001B[39m`;
const coloredShort = `The quick ${red("brown fox")} jumped over the ${green("lazy dog")}.`;
const coloredMedium =
`The quick ${red("brown fox jumped over")} the ${green("lazy dog and then ran away")} with the ${blue("unicorn")}. `.repeat(
10,
);
const coloredLong =
`The quick ${red("brown fox jumped over")} the ${green("lazy dog and then ran away")} with the ${blue("unicorn")}. `.repeat(
100,
);
// Full-width characters (Japanese)
const japaneseText = "日本語のテキストを折り返すテストです。全角文字は幅2としてカウントされます。".repeat(5);
// Emoji text
const emojiText = "Hello 👋 World 🌍! Let's test 🧪 some emoji 😀 wrapping 📦!".repeat(5);
// Hyperlink text
const hyperlinkText = "Check out \u001B]8;;https://bun.sh\u0007Bun\u001B]8;;\u0007, it's fast! ".repeat(10);
// Options
const hardOpts = { hard: true };
const noTrimOpts = { trim: false };
// Basic text benchmarks
summary(() => {
bench("Short text (45 chars) - npm", () => wrapAnsi(shortText, 20));
bench("Short text (45 chars) - Bun", () => Bun.wrapAnsi(shortText, 20));
});
summary(() => {
bench("Medium text (810 chars) - npm", () => wrapAnsi(mediumText, 40));
bench("Medium text (810 chars) - Bun", () => Bun.wrapAnsi(mediumText, 40));
});
summary(() => {
bench("Long text (8100 chars) - npm", () => wrapAnsi(longText, 80));
bench("Long text (8100 chars) - Bun", () => Bun.wrapAnsi(longText, 80));
});
// ANSI colored text benchmarks
summary(() => {
bench("Colored short - npm", () => wrapAnsi(coloredShort, 20));
bench("Colored short - Bun", () => Bun.wrapAnsi(coloredShort, 20));
});
summary(() => {
bench("Colored medium - npm", () => wrapAnsi(coloredMedium, 40));
bench("Colored medium - Bun", () => Bun.wrapAnsi(coloredMedium, 40));
});
summary(() => {
bench("Colored long - npm", () => wrapAnsi(coloredLong, 80));
bench("Colored long - Bun", () => Bun.wrapAnsi(coloredLong, 80));
});
// Hard wrap benchmarks
summary(() => {
bench("Hard wrap long - npm", () => wrapAnsi(longText, 80, hardOpts));
bench("Hard wrap long - Bun", () => Bun.wrapAnsi(longText, 80, hardOpts));
});
summary(() => {
bench("Hard wrap colored - npm", () => wrapAnsi(coloredLong, 80, hardOpts));
bench("Hard wrap colored - Bun", () => Bun.wrapAnsi(coloredLong, 80, hardOpts));
});
// Unicode benchmarks
summary(() => {
bench("Japanese (full-width) - npm", () => wrapAnsi(japaneseText, 40));
bench("Japanese (full-width) - Bun", () => Bun.wrapAnsi(japaneseText, 40));
});
summary(() => {
bench("Emoji text - npm", () => wrapAnsi(emojiText, 30));
bench("Emoji text - Bun", () => Bun.wrapAnsi(emojiText, 30));
});
// Hyperlink benchmarks
summary(() => {
bench("Hyperlink (OSC 8) - npm", () => wrapAnsi(hyperlinkText, 40));
bench("Hyperlink (OSC 8) - Bun", () => Bun.wrapAnsi(hyperlinkText, 40));
});
// No trim option
summary(() => {
bench("No trim long - npm", () => wrapAnsi(longText, 80, noTrimOpts));
bench("No trim long - Bun", () => Bun.wrapAnsi(longText, 80, noTrimOpts));
});
await run();

152
build.zig
View File

@@ -34,7 +34,6 @@ const BunBuildOptions = struct {
enable_asan: bool,
enable_fuzzilli: bool,
enable_valgrind: bool,
enable_tinycc: bool,
use_mimalloc: bool,
tracy_callstack_depth: u16,
reported_nodejs_version: Version,
@@ -43,7 +42,7 @@ const BunBuildOptions = struct {
/// is set (to allow CI to build a portable executable). Affected files:
///
/// - src/bake/runtime.ts (bundled)
/// - src/bun.js/api/FFI.h
/// - src/buntime/api/FFI.h
///
/// A similar technique is used in C++ code for JavaScript builtins
codegen_embed: bool = false,
@@ -85,7 +84,6 @@ const BunBuildOptions = struct {
opts.addOption(bool, "enable_asan", this.enable_asan);
opts.addOption(bool, "enable_fuzzilli", this.enable_fuzzilli);
opts.addOption(bool, "enable_valgrind", this.enable_valgrind);
opts.addOption(bool, "enable_tinycc", this.enable_tinycc);
opts.addOption(bool, "use_mimalloc", this.use_mimalloc);
opts.addOption([]const u8, "reported_nodejs_version", b.fmt("{f}", .{this.reported_nodejs_version}));
opts.addOption(bool, "zig_self_hosted_backend", this.no_llvm);
@@ -261,7 +259,6 @@ pub fn build(b: *Build) !void {
.enable_asan = b.option(bool, "enable_asan", "Enable asan") orelse false,
.enable_fuzzilli = b.option(bool, "enable_fuzzilli", "Enable fuzzilli instrumentation") orelse false,
.enable_valgrind = b.option(bool, "enable_valgrind", "Enable valgrind") orelse false,
.enable_tinycc = b.option(bool, "enable_tinycc", "Enable TinyCC for FFI JIT compilation") orelse true,
.use_mimalloc = b.option(bool, "use_mimalloc", "Use mimalloc as default allocator") orelse false,
.llvm_codegen_threads = b.option(u32, "llvm_codegen_threads", "Number of threads to use for LLVM codegen") orelse 1,
};
@@ -345,7 +342,6 @@ pub fn build(b: *Build) !void {
const step = b.step("check-debug", "Check for semantic analysis errors on some platforms");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
.{ .os = .mac, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64 },
}, &.{.Debug});
@@ -356,7 +352,6 @@ pub fn build(b: *Build) !void {
const step = b.step("check-all", "Check for semantic analysis errors on all supported platforms");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64 },
@@ -371,7 +366,6 @@ pub fn build(b: *Build) !void {
const step = b.step("check-all-debug", "Check for semantic analysis errors on all supported platforms in debug mode");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64 },
@@ -386,14 +380,12 @@ pub fn build(b: *Build) !void {
const step = b.step("check-windows", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
}, &.{ .Debug, .ReleaseFast });
}
{
const step = b.step("check-windows-debug", "Check for semantic analysis errors on Windows");
addMultiCheck(b, step, build_options, &.{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
}, &.{.Debug});
}
{
@@ -430,7 +422,6 @@ pub fn build(b: *Build) !void {
const step = b.step("translate-c", "Copy generated translated-c-headers.zig to zig-out");
for ([_]TargetDescription{
.{ .os = .windows, .arch = .x86_64 },
.{ .os = .windows, .arch = .aarch64 },
.{ .os = .mac, .arch = .x86_64 },
.{ .os = .mac, .arch = .aarch64 },
.{ .os = .linux, .arch = .x86_64 },
@@ -459,146 +450,6 @@ pub fn build(b: *Build) !void {
// const run = b.addRunArtifact(exe);
// step.dependOn(&run.step);
}
// zig build generate-grapheme-tables
// Regenerates src/string/immutable/grapheme_tables.zig from the vendored uucode.
// Run this when updating src/deps/uucode. Normal builds use the committed file.
{
const step = b.step("generate-grapheme-tables", "Regenerate grapheme property tables from vendored uucode");
// --- Phase 1: Build uucode tables (separate module graph, no tables dependency) ---
const bt_config_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/config.zig"),
.target = b.graph.host,
});
const bt_types_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/types.zig"),
.target = b.graph.host,
});
bt_types_mod.addImport("config.zig", bt_config_mod);
bt_config_mod.addImport("types.zig", bt_types_mod);
const bt_config_x_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/x/config.x.zig"),
.target = b.graph.host,
});
const bt_types_x_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/x/types.x.zig"),
.target = b.graph.host,
});
bt_types_x_mod.addImport("config.x.zig", bt_config_x_mod);
bt_config_x_mod.addImport("types.x.zig", bt_types_x_mod);
bt_config_x_mod.addImport("types.zig", bt_types_mod);
bt_config_x_mod.addImport("config.zig", bt_config_mod);
const bt_build_config_mod = b.createModule(.{
.root_source_file = b.path("src/unicode/uucode/uucode_config.zig"),
.target = b.graph.host,
});
bt_build_config_mod.addImport("types.zig", bt_types_mod);
bt_build_config_mod.addImport("config.zig", bt_config_mod);
bt_build_config_mod.addImport("types.x.zig", bt_types_x_mod);
bt_build_config_mod.addImport("config.x.zig", bt_config_x_mod);
const build_tables_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/build/tables.zig"),
.target = b.graph.host,
.optimize = .Debug,
});
build_tables_mod.addImport("config.zig", bt_config_mod);
build_tables_mod.addImport("build_config", bt_build_config_mod);
build_tables_mod.addImport("types.zig", bt_types_mod);
const build_tables_exe = b.addExecutable(.{
.name = "uucode_build_tables",
.root_module = build_tables_mod,
.use_llvm = true,
});
const run_build_tables = b.addRunArtifact(build_tables_exe);
run_build_tables.setCwd(b.path("src/deps/uucode"));
const tables_path = run_build_tables.addOutputFileArg("tables.zig");
// --- Phase 2: Build grapheme-gen with full uucode (separate module graph) ---
const rt_config_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/config.zig"),
.target = b.graph.host,
});
const rt_types_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/types.zig"),
.target = b.graph.host,
});
rt_types_mod.addImport("config.zig", rt_config_mod);
rt_config_mod.addImport("types.zig", rt_types_mod);
const rt_config_x_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/x/config.x.zig"),
.target = b.graph.host,
});
const rt_types_x_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/x/types.x.zig"),
.target = b.graph.host,
});
rt_types_x_mod.addImport("config.x.zig", rt_config_x_mod);
rt_config_x_mod.addImport("types.x.zig", rt_types_x_mod);
rt_config_x_mod.addImport("types.zig", rt_types_mod);
rt_config_x_mod.addImport("config.zig", rt_config_mod);
const rt_build_config_mod = b.createModule(.{
.root_source_file = b.path("src/unicode/uucode/uucode_config.zig"),
.target = b.graph.host,
});
rt_build_config_mod.addImport("types.zig", rt_types_mod);
rt_build_config_mod.addImport("config.zig", rt_config_mod);
rt_build_config_mod.addImport("types.x.zig", rt_types_x_mod);
rt_build_config_mod.addImport("config.x.zig", rt_config_x_mod);
const rt_tables_mod = b.createModule(.{
.root_source_file = tables_path,
.target = b.graph.host,
});
rt_tables_mod.addImport("types.zig", rt_types_mod);
rt_tables_mod.addImport("types.x.zig", rt_types_x_mod);
rt_tables_mod.addImport("config.zig", rt_config_mod);
rt_tables_mod.addImport("build_config", rt_build_config_mod);
const rt_get_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/get.zig"),
.target = b.graph.host,
});
rt_get_mod.addImport("types.zig", rt_types_mod);
rt_get_mod.addImport("tables", rt_tables_mod);
rt_types_mod.addImport("get.zig", rt_get_mod);
const uucode_mod = b.createModule(.{
.root_source_file = b.path("src/deps/uucode/src/root.zig"),
.target = b.graph.host,
});
uucode_mod.addImport("types.zig", rt_types_mod);
uucode_mod.addImport("config.zig", rt_config_mod);
uucode_mod.addImport("types.x.zig", rt_types_x_mod);
uucode_mod.addImport("tables", rt_tables_mod);
uucode_mod.addImport("get.zig", rt_get_mod);
// grapheme_gen executable
const gen_exe = b.addExecutable(.{
.name = "grapheme-gen",
.root_module = b.createModule(.{
.root_source_file = b.path("src/unicode/uucode/grapheme_gen.zig"),
.target = b.graph.host,
.optimize = .Debug,
.imports = &.{
.{ .name = "uucode", .module = uucode_mod },
},
}),
.use_llvm = true,
});
const run_gen = b.addRunArtifact(gen_exe);
const gen_output = run_gen.captureStdOut();
const install = b.addInstallFile(gen_output, "../src/string/immutable/grapheme_tables.zig");
step.dependOn(&install.step);
}
}
const TargetDescription = struct {
@@ -642,7 +493,6 @@ fn addMultiCheck(
.no_llvm = root_build_options.no_llvm,
.enable_asan = root_build_options.enable_asan,
.enable_valgrind = root_build_options.enable_valgrind,
.enable_tinycc = root_build_options.enable_tinycc,
.enable_fuzzilli = root_build_options.enable_fuzzilli,
.use_mimalloc = root_build_options.use_mimalloc,
.override_no_export_cpp_apis = root_build_options.override_no_export_cpp_apis,

View File

@@ -21,10 +21,6 @@ endforeach()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64")
if(APPLE)
register_compiler_flags(-mcpu=apple-m1)
elseif(WIN32)
# Windows ARM64: use /clang: prefix for clang-cl, skip for MSVC cl.exe subprojects
# These flags are only understood by clang-cl, not MSVC cl.exe
register_compiler_flags(/clang:-march=armv8-a+crc /clang:-mtune=ampere1)
else()
register_compiler_flags(-march=armv8-a+crc -mtune=ampere1)
endif()
@@ -246,17 +242,10 @@ if(UNIX)
)
endif()
if(WIN32)
register_compiler_flags(
DESCRIPTION "Set C/C++ error limit"
/clang:-ferror-limit=${ERROR_LIMIT}
)
else()
register_compiler_flags(
DESCRIPTION "Set C/C++ error limit"
-ferror-limit=${ERROR_LIMIT}
)
endif()
register_compiler_flags(
DESCRIPTION "Set C/C++ error limit"
-ferror-limit=${ERROR_LIMIT}
)
# --- LTO ---
if(ENABLE_LTO)

View File

@@ -106,9 +106,9 @@ else()
endif()
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
set(HOST_ARCH "aarch64")
set(HOST_OS "aarch64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64")
set(HOST_ARCH "x64")
set(HOST_OS "x64")
else()
unsupported(CMAKE_HOST_SYSTEM_PROCESSOR)
endif()
@@ -433,33 +433,6 @@ function(register_command)
list(APPEND CMD_EFFECTIVE_DEPENDS ${CMD_EXECUTABLE})
endif()
# SKIP_CODEGEN: Skip commands that use BUN_EXECUTABLE if all outputs exist
# This is used for Windows ARM64 builds where x64 bun crashes under emulation
if(SKIP_CODEGEN AND CMD_EXECUTABLE STREQUAL "${BUN_EXECUTABLE}")
set(ALL_OUTPUTS_EXIST TRUE)
foreach(output ${CMD_OUTPUTS})
if(NOT EXISTS ${output})
set(ALL_OUTPUTS_EXIST FALSE)
break()
endif()
endforeach()
if(ALL_OUTPUTS_EXIST AND CMD_OUTPUTS)
message(STATUS "SKIP_CODEGEN: Skipping ${CMD_TARGET} (outputs exist)")
if(CMD_TARGET)
add_custom_target(${CMD_TARGET})
endif()
return()
elseif(NOT CMD_OUTPUTS)
message(STATUS "SKIP_CODEGEN: Skipping ${CMD_TARGET} (no outputs)")
if(CMD_TARGET)
add_custom_target(${CMD_TARGET})
endif()
return()
else()
message(FATAL_ERROR "SKIP_CODEGEN: Cannot skip ${CMD_TARGET} - missing outputs. Run codegen on x64 first.")
endif()
endif()
foreach(target ${CMD_TARGETS})
if(target MATCHES "/|\\\\")
message(FATAL_ERROR "register_command: TARGETS contains \"${target}\", if it's a path add it to SOURCES instead")
@@ -677,7 +650,6 @@ function(register_bun_install)
${NPM_CWD}
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
install
--frozen-lockfile
SOURCES
@@ -785,7 +757,7 @@ function(register_cmake_command)
set(MAKE_EFFECTIVE_ARGS -B${MAKE_BUILD_PATH} ${CMAKE_ARGS})
set(setFlags GENERATOR BUILD_TYPE)
set(appendFlags C_FLAGS CXX_FLAGS LINKER_FLAGS STATIC_LINKER_FLAGS EXE_LINKER_FLAGS SHARED_LINKER_FLAGS MODULE_LINKER_FLAGS)
set(appendFlags C_FLAGS CXX_FLAGS LINKER_FLAGS)
set(specialFlags POSITION_INDEPENDENT_CODE)
set(flags ${setFlags} ${appendFlags} ${specialFlags})
@@ -831,14 +803,6 @@ function(register_cmake_command)
list(APPEND MAKE_EFFECTIVE_ARGS "-DCMAKE_${flag}=${MAKE_${flag}}")
endforeach()
# Workaround for CMake 4.1.0 bug: Force correct machine type for Windows ARM64
# Use toolchain file and set CMP0197 policy to prevent duplicate /machine: flags
if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64|AARCH64")
list(APPEND MAKE_EFFECTIVE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CWD}/cmake/toolchains/windows-aarch64.cmake")
list(APPEND MAKE_EFFECTIVE_ARGS "-DCMAKE_POLICY_DEFAULT_CMP0197=NEW")
list(APPEND MAKE_EFFECTIVE_ARGS "-DCMAKE_PROJECT_INCLUDE=${CWD}/cmake/arm64-static-lib-fix.cmake")
endif()
if(DEFINED FRESH)
list(APPEND MAKE_EFFECTIVE_ARGS --fresh)
endif()

View File

@@ -4,7 +4,6 @@ endif()
optionx(BUN_LINK_ONLY BOOL "If only the linking step should be built" DEFAULT OFF)
optionx(BUN_CPP_ONLY BOOL "If only the C++ part of Bun should be built" DEFAULT OFF)
optionx(SKIP_CODEGEN BOOL "Skip JavaScript codegen (for Windows ARM64 debug)" DEFAULT OFF)
optionx(BUILDKITE BOOL "If Buildkite is enabled" DEFAULT OFF)
optionx(GITHUB_ACTIONS BOOL "If GitHub Actions is enabled" DEFAULT OFF)
@@ -50,7 +49,7 @@ else()
message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}")
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm")
setx(ARCH "aarch64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64")
setx(ARCH "x64")
@@ -58,18 +57,6 @@ else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif()
# CMake 4.0+ policy CMP0197 controls how MSVC machine type flags are handled
# Setting to NEW prevents duplicate /machine: flags being added to linker commands
if(WIN32 AND ARCH STREQUAL "aarch64")
set(CMAKE_POLICY_DEFAULT_CMP0197 NEW)
set(CMAKE_MSVC_CMP0197 NEW)
# Set linker flags for exe/shared linking
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /machine:ARM64")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /machine:ARM64")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /machine:ARM64")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /machine:ARM64")
endif()
# Windows Code Signing Option
if(WIN32)
optionx(ENABLE_WINDOWS_CODESIGNING BOOL "Enable Windows code signing with DigiCert KeyLocker" DEFAULT OFF)
@@ -212,16 +199,6 @@ optionx(USE_WEBKIT_ICU BOOL "Use the ICU libraries from WebKit" DEFAULT ${DEFAUL
optionx(ERROR_LIMIT STRING "Maximum number of errors to show when compiling C++ code" DEFAULT "100")
# TinyCC is used for FFI JIT compilation
# Disable on Windows ARM64 where it's not yet supported
if(WIN32 AND ARCH STREQUAL "aarch64")
set(DEFAULT_ENABLE_TINYCC OFF)
else()
set(DEFAULT_ENABLE_TINYCC ON)
endif()
optionx(ENABLE_TINYCC BOOL "Enable TinyCC for FFI JIT compilation" DEFAULT ${DEFAULT_ENABLE_TINYCC})
# This is not an `option` because setting this variable to OFF is experimental
# and unsupported. This replaces the `use_mimalloc` variable previously in
# bun.zig, and enables C++ code to also be aware of the option.

View File

@@ -9,7 +9,13 @@
},
{
"output": "ZigGeneratedClassesSources.txt",
"paths": ["src/bun.js/*.classes.ts", "src/bun.js/{api,node,test,webcore}/*.classes.ts"]
"paths": [
"src/buntime/*.classes.ts",
"src/buntime/{api,node,web}/*.classes.ts",
"src/buntime/web/*/*.classes.ts",
"src/buntime/api/*/*.classes.ts",
"src/test_runner/*.classes.ts"
]
},
{
"output": "JavaScriptSources.txt",
@@ -44,17 +50,63 @@
"output": "CxxSources.txt",
"paths": [
"src/io/*.cpp",
"src/bun.js/modules/*.cpp",
"src/bun.js/bindings/*.cpp",
"src/bun.js/bindings/webcore/*.cpp",
"src/bun.js/bindings/sqlite/*.cpp",
"src/bun.js/bindings/webcrypto/*.cpp",
"src/bun.js/bindings/webcrypto/*/*.cpp",
"src/bun.js/bindings/node/*.cpp",
"src/bun.js/bindings/node/crypto/*.cpp",
"src/bun.js/bindings/node/http/*.cpp",
"src/bun.js/bindings/v8/*.cpp",
"src/bun.js/bindings/v8/shim/*.cpp",
"src/buntime/modules/*.cpp",
"src/buntime/jsc/types/*.cpp",
"src/buntime/jsc/global/*.cpp",
"src/buntime/jsc/gc/*.cpp",
"src/buntime/jsc/interop/*.cpp",
"src/buntime/jsc/generated/*.cpp",
"src/buntime/api/sqlite/*.cpp",
"src/buntime/web/webcrypto/*.cpp",
"src/buntime/web/webcrypto/*/*.cpp",
"src/buntime/node/buffer/*.cpp",
"src/buntime/node/process/*.cpp",
"src/buntime/node/vm/*.cpp",
"src/buntime/node/crypto/*.cpp",
"src/buntime/node/http/*.cpp",
"src/buntime/node/fs/*.cpp",
"src/buntime/node/os/*.cpp",
"src/buntime/node/path/*.cpp",
"src/buntime/node/util/*.cpp",
"src/buntime/node/timers/*.cpp",
"src/buntime/node/async_hooks/*.cpp",
"src/buntime/node/perf_hooks/*.cpp",
"src/buntime/compat/v8/*.cpp",
"src/buntime/compat/v8/shim/*.cpp",
"src/buntime/compat/napi/*.cpp",
"src/buntime/module/*.cpp",
"src/buntime/api/console/*.cpp",
"src/buntime/api/inspector/*.cpp",
"src/buntime/api/error/*.cpp",
"src/buntime/api/cookie/*.cpp",
"src/buntime/api/s3/*.cpp",
"src/buntime/api/secrets/*.cpp",
"src/buntime/api/ffi/*.cpp",
"src/buntime/api/sql/*.cpp",
"src/buntime/api/shell/*.cpp",
"src/buntime/api/ipc/*.cpp",
"src/buntime/api/test/*.cpp",
"src/buntime/api/server/*.cpp",
"src/buntime/api/plugin/*.cpp",
"src/buntime/api/process/*.cpp",
"src/buntime/api/bun/*.cpp",
"src/buntime/core/*.cpp",
"src/buntime/event_loop/*.cpp",
"src/string/*.cpp",
"src/buntime/web/fetch/*.cpp",
"src/buntime/web/url/*.cpp",
"src/buntime/web/blob/*.cpp",
"src/buntime/web/http/*.cpp",
"src/buntime/web/encoding/*.cpp",
"src/buntime/web/compression/*.cpp",
"src/buntime/web/events/*.cpp",
"src/buntime/web/streams/*.cpp",
"src/buntime/web/performance/*.cpp",
"src/buntime/web/websocket/*.cpp",
"src/buntime/web/workers/*.cpp",
"src/buntime/web/messaging/*.cpp",
"src/buntime/web/mime/*.cpp",
"src/buntime/web/serialization/*.cpp",
"src/bake/*.cpp",
"src/deps/*.cpp",
"src/vm/*.cpp",
@@ -68,10 +120,10 @@
"packages/bun-usockets/src/eventing/*.c",
"packages/bun-usockets/src/internal/*.c",
"packages/bun-usockets/src/crypto/*.c",
"src/bun.js/bindings/uv-posix-polyfills.c",
"src/bun.js/bindings/uv-posix-stubs.c",
"src/buntime/compat/libuv/uv-posix-polyfills.c",
"src/buntime/compat/libuv/uv-posix-stubs.c",
"src/*.c",
"src/bun.js/bindings/node/http/llhttp/*.c"
"src/buntime/node/http/llhttp/*.c"
]
}
]

View File

@@ -1,8 +1,8 @@
# https://clang.llvm.org/docs/ClangFormat.html
file(GLOB BUN_H_SOURCES LIST_DIRECTORIES false ${CONFIGURE_DEPENDS}
${CWD}/src/bun.js/bindings/*.h
${CWD}/src/bun.js/modules/*.h
${CWD}/src/buntime/bindings/*.h
${CWD}/src/buntime/modules/*.h
)
set(CLANG_FORMAT_SOURCES ${BUN_C_SOURCES} ${BUN_CXX_SOURCES} ${BUN_H_SOURCES})

View File

@@ -1,8 +0,0 @@
# This file is included after project() via CMAKE_PROJECT_INCLUDE
# It fixes the static library creation command to use ARM64 machine type
if(WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL \"aarch64\")
# Override the static library creation commands to avoid spurious /machine:x64 flags
set(CMAKE_C_CREATE_STATIC_LIBRARY \"<CMAKE_AR> /nologo /machine:ARM64 /out:<TARGET> <OBJECTS>\" CACHE STRING \"\" FORCE)
set(CMAKE_CXX_CREATE_STATIC_LIBRARY \"<CMAKE_AR> /nologo /machine:ARM64 /out:<TARGET> <OBJECTS>\" CACHE STRING \"\" FORCE)
endif()

View File

@@ -21,12 +21,7 @@ if(NOT DEFINED CMAKE_HOST_SYSTEM_PROCESSOR)
endif()
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
# Windows ARM64 can run x86_64 via emulation, and no native ARM64 Zig build exists yet
if(CMAKE_HOST_WIN32)
set(ZIG_ARCH "x86_64")
else()
set(ZIG_ARCH "aarch64")
endif()
set(ZIG_ARCH "aarch64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|AMD64|x86_64|X86_64|x64|X64")
set(ZIG_ARCH "x86_64")
else()

View File

@@ -1,34 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Wrapper for llvm-lib that strips conflicting /machine:x64 flag for ARM64 builds
REM This is a workaround for CMake 4.1.0 bug
REM Find llvm-lib.exe - check LLVM_LIB env var, then PATH, then known locations
if defined LLVM_LIB (
set "LLVM_LIB_EXE=!LLVM_LIB!"
) else (
where llvm-lib.exe >nul 2>&1
if !ERRORLEVEL! equ 0 (
for /f "delims=" %%i in ('where llvm-lib.exe') do set "LLVM_LIB_EXE=%%i"
) else if exist "C:\Program Files\LLVM\bin\llvm-lib.exe" (
set "LLVM_LIB_EXE=C:\Program Files\LLVM\bin\llvm-lib.exe"
) else (
echo Error: Cannot find llvm-lib.exe. Set LLVM_LIB environment variable or add LLVM to PATH.
exit /b 1
)
)
set "ARGS="
for %%a in (%*) do (
set "ARG=%%a"
if /i "!ARG!"=="/machine:x64" (
REM Skip this argument
) else (
set "ARGS=!ARGS! %%a"
)
)
"!LLVM_LIB_EXE!" %ARGS%
exit /b %ERRORLEVEL%

View File

@@ -1,18 +0,0 @@
# Wrapper for llvm-lib that strips conflicting /machine:x64 flag for ARM64 builds
# This is a workaround for CMake 4.1.0 bug where both /machine:ARM64 and /machine:x64 are added
# Find llvm-lib.exe - check LLVM_LIB env var, then PATH, then known locations
if ($env:LLVM_LIB) {
$llvmLib = $env:LLVM_LIB
} elseif (Get-Command llvm-lib.exe -ErrorAction SilentlyContinue) {
$llvmLib = (Get-Command llvm-lib.exe).Source
} elseif (Test-Path "C:\Program Files\LLVM\bin\llvm-lib.exe") {
$llvmLib = "C:\Program Files\LLVM\bin\llvm-lib.exe"
} else {
Write-Error "Cannot find llvm-lib.exe. Set LLVM_LIB environment variable or add LLVM to PATH."
exit 1
}
$filteredArgs = $args | Where-Object { $_ -ne "/machine:x64" }
& $llvmLib @filteredArgs
exit $LASTEXITCODE

View File

@@ -1,34 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Wrapper for llvm-lib that strips conflicting /machine:x64 flag for ARM64 builds
REM This is a workaround for CMake 4.1.0 bug
REM Find llvm-lib.exe - check LLVM_LIB env var, then PATH, then known locations
if defined LLVM_LIB (
set "LLVM_LIB_EXE=!LLVM_LIB!"
) else (
where llvm-lib.exe >nul 2>&1
if !ERRORLEVEL! equ 0 (
for /f "delims=" %%i in ('where llvm-lib.exe') do set "LLVM_LIB_EXE=%%i"
) else if exist "C:\Program Files\LLVM\bin\llvm-lib.exe" (
set "LLVM_LIB_EXE=C:\Program Files\LLVM\bin\llvm-lib.exe"
) else (
echo Error: Cannot find llvm-lib.exe. Set LLVM_LIB environment variable or add LLVM to PATH.
exit /b 1
)
)
set NEWARGS=
for %%a in (%*) do (
set "ARG=%%a"
if /i "!ARG!"=="/machine:x64" (
REM Skip /machine:x64 argument
) else (
set "NEWARGS=!NEWARGS! %%a"
)
)
"!LLVM_LIB_EXE!" %NEWARGS%
exit /b %ERRORLEVEL%

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/boringssl
COMMIT
4f4f5ef8ebc6e23cbf393428f0ab1b526773f7ac
f1ffd9e83d4f5c28a9c70d73f9a4e6fcf310062f
)
register_cmake_command(

View File

@@ -57,17 +57,13 @@ set(BUN_DEPENDENCIES
LolHtml
Lshpack
Mimalloc
TinyCC
Zlib
LibArchive # must be loaded after zlib
HdrHistogram # must be loaded after zlib
Zstd
)
# TinyCC is optional - disabled on Windows ARM64 where it's not supported
if(ENABLE_TINYCC)
list(APPEND BUN_DEPENDENCIES TinyCC)
endif()
include(CloneZstd)
# --- Codegen ---
@@ -189,7 +185,7 @@ register_command(
CWD
${BUN_NODE_FALLBACKS_SOURCE}
COMMAND
${BUN_EXECUTABLE} ${BUN_FLAGS} run build-fallbacks
${BUN_EXECUTABLE} run build-fallbacks
${BUN_NODE_FALLBACKS_OUTPUT}
${BUN_NODE_FALLBACKS_SOURCES}
SOURCES
@@ -210,7 +206,7 @@ register_command(
CWD
${BUN_NODE_FALLBACKS_SOURCE}
COMMAND
${BUN_EXECUTABLE} ${BUN_FLAGS} build
${BUN_EXECUTABLE} build
${BUN_NODE_FALLBACKS_SOURCE}/node_modules/react-refresh/cjs/react-refresh-runtime.development.js
--outfile=${BUN_REACT_REFRESH_OUTPUT}
--target=browser
@@ -229,9 +225,9 @@ set(BUN_ERROR_CODE_SCRIPT ${CWD}/src/codegen/generate-node-errors.ts)
set(BUN_ERROR_CODE_SOURCES
${BUN_ERROR_CODE_SCRIPT}
${CWD}/src/bun.js/bindings/ErrorCode.ts
${CWD}/src/bun.js/bindings/ErrorCode.cpp
${CWD}/src/bun.js/bindings/ErrorCode.h
${CWD}/src/buntime/api/error/ErrorCode.ts
${CWD}/src/buntime/api/error/ErrorCode.cpp
${CWD}/src/buntime/api/error/ErrorCode.h
)
set(BUN_ERROR_CODE_OUTPUTS
@@ -247,7 +243,6 @@ register_command(
"Generating ErrorCode.{zig,h}"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_ERROR_CODE_SCRIPT}
${CODEGEN_PATH}
@@ -283,7 +278,6 @@ register_command(
"Generating ZigGeneratedClasses.{zig,cpp,h}"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_ZIG_GENERATED_CLASSES_SCRIPT}
${BUN_ZIG_GENERATED_CLASSES_SOURCES}
@@ -301,7 +295,7 @@ absolute_sources(BUN_JAVASCRIPT_SOURCES ${CWD}/cmake/sources/JavaScriptSources.t
absolute_sources(BUN_JAVASCRIPT_CODEGEN_SOURCES ${CWD}/cmake/sources/JavaScriptCodegenSources.txt)
list(APPEND BUN_JAVASCRIPT_CODEGEN_SOURCES
${CWD}/src/bun.js/bindings/InternalModuleRegistry.cpp
${CWD}/src/buntime/module/InternalModuleRegistry.cpp
)
set(BUN_JAVASCRIPT_OUTPUTS
@@ -316,7 +310,7 @@ set(BUN_JAVASCRIPT_OUTPUTS
${CODEGEN_PATH}/SyntheticModuleType.h
${CODEGEN_PATH}/GeneratedJS2Native.h
# Zig will complain if files are outside of the source directory
${CWD}/src/bun.js/bindings/GeneratedJS2Native.zig
${CWD}/src/buntime/jsc/generated/GeneratedJS2Native.zig
)
set(BUN_CPP_OUTPUTS
@@ -334,7 +328,6 @@ register_command(
"Generating C++ --> Zig bindings"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
${CWD}/src/codegen/cppbind.ts
${CWD}/src
${CODEGEN_PATH}
@@ -352,7 +345,6 @@ register_command(
"Generating CI info"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
${CWD}/src/codegen/ci_info.ts
${CODEGEN_PATH}/ci_info.zig
SOURCES
@@ -361,42 +353,31 @@ register_command(
${BUN_CI_INFO_OUTPUTS}
)
if(SKIP_CODEGEN)
# Skip JavaScript codegen - useful for Windows ARM64 debug builds where bun crashes
message(STATUS "SKIP_CODEGEN is ON - skipping bun-js-modules codegen")
foreach(output ${BUN_JAVASCRIPT_OUTPUTS})
if(NOT EXISTS ${output})
message(FATAL_ERROR "SKIP_CODEGEN is ON but ${output} does not exist. Run codegen manually first.")
endif()
endforeach()
else()
register_command(
TARGET
bun-js-modules
COMMENT
"Generating JavaScript modules"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_JAVASCRIPT_CODEGEN_SCRIPT}
--debug=${DEBUG}
${BUILD_PATH}
SOURCES
${BUN_JAVASCRIPT_SOURCES}
${BUN_JAVASCRIPT_CODEGEN_SOURCES}
register_command(
TARGET
bun-js-modules
COMMENT
"Generating JavaScript modules"
COMMAND
${BUN_EXECUTABLE}
run
${BUN_JAVASCRIPT_CODEGEN_SCRIPT}
OUTPUTS
${BUN_JAVASCRIPT_OUTPUTS}
)
endif()
--debug=${DEBUG}
${BUILD_PATH}
SOURCES
${BUN_JAVASCRIPT_SOURCES}
${BUN_JAVASCRIPT_CODEGEN_SOURCES}
${BUN_JAVASCRIPT_CODEGEN_SCRIPT}
OUTPUTS
${BUN_JAVASCRIPT_OUTPUTS}
)
set(BUN_BAKE_RUNTIME_CODEGEN_SCRIPT ${CWD}/src/codegen/bake-codegen.ts)
absolute_sources(BUN_BAKE_RUNTIME_SOURCES ${CWD}/cmake/sources/BakeRuntimeSources.txt)
list(APPEND BUN_BAKE_RUNTIME_CODEGEN_SOURCES
${CWD}/src/bun.js/bindings/InternalModuleRegistry.cpp
${CWD}/src/buntime/module/InternalModuleRegistry.cpp
)
set(BUN_BAKE_RUNTIME_OUTPUTS
@@ -411,7 +392,6 @@ register_command(
"Bundling Bake Runtime"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_BAKE_RUNTIME_CODEGEN_SCRIPT}
--debug=${DEBUG}
@@ -435,13 +415,16 @@ string(REPLACE ";" "," BUN_BINDGENV2_SOURCES_COMMA_SEPARATED
"${BUN_BINDGENV2_SOURCES}")
execute_process(
COMMAND ${BUN_EXECUTABLE} ${BUN_FLAGS} run ${BUN_BINDGENV2_SCRIPT}
COMMAND ${BUN_EXECUTABLE} run ${BUN_BINDGENV2_SCRIPT}
--command=list-outputs
--sources=${BUN_BINDGENV2_SOURCES_COMMA_SEPARATED}
--codegen-path=${CODEGEN_PATH}
RESULT_VARIABLE bindgen_result
OUTPUT_VARIABLE bindgen_outputs
COMMAND_ERROR_IS_FATAL ANY
)
if(${bindgen_result})
message(FATAL_ERROR "bindgenv2/script.ts exited with non-zero status")
endif()
foreach(output IN LISTS bindgen_outputs)
if(output MATCHES "\.cpp$")
list(APPEND BUN_BINDGENV2_CPP_OUTPUTS ${output})
@@ -458,7 +441,7 @@ register_command(
COMMENT
"Generating bindings (v2)"
COMMAND
${BUN_EXECUTABLE} ${BUN_FLAGS} run ${BUN_BINDGENV2_SCRIPT}
${BUN_EXECUTABLE} run ${BUN_BINDGENV2_SCRIPT}
--command=generate
--codegen-path=${CODEGEN_PATH}
--sources=${BUN_BINDGENV2_SOURCES_COMMA_SEPARATED}
@@ -479,7 +462,7 @@ set(BUN_BINDGEN_CPP_OUTPUTS
)
set(BUN_BINDGEN_ZIG_OUTPUTS
${CWD}/src/bun.js/bindings/GeneratedBindings.zig
${CWD}/src/buntime/jsc/generated/GeneratedBindings.zig
)
register_command(
@@ -489,7 +472,6 @@ register_command(
"Processing \".bind.ts\" files"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_BINDGEN_SCRIPT}
--debug=${DEBUG}
@@ -522,7 +504,6 @@ register_command(
"Generating JSSink.{cpp,h}"
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_JS_SINK_SCRIPT}
${CODEGEN_PATH}
@@ -535,16 +516,16 @@ register_command(
set(BUN_OBJECT_LUT_SCRIPT ${CWD}/src/codegen/create-hash-table.ts)
set(BUN_OBJECT_LUT_SOURCES
${CWD}/src/bun.js/bindings/BunObject.cpp
${CWD}/src/bun.js/bindings/ZigGlobalObject.lut.txt
${CWD}/src/bun.js/bindings/JSBuffer.cpp
${CWD}/src/bun.js/bindings/BunProcess.cpp
${CWD}/src/bun.js/bindings/ProcessBindingBuffer.cpp
${CWD}/src/bun.js/bindings/ProcessBindingConstants.cpp
${CWD}/src/bun.js/bindings/ProcessBindingFs.cpp
${CWD}/src/bun.js/bindings/ProcessBindingNatives.cpp
${CWD}/src/bun.js/bindings/ProcessBindingHTTPParser.cpp
${CWD}/src/bun.js/modules/NodeModuleModule.cpp
${CWD}/src/buntime/jsc/global/BunObject.cpp
${CWD}/src/buntime/jsc/global/ZigGlobalObject.lut.txt
${CWD}/src/buntime/node/buffer/JSBuffer.cpp
${CWD}/src/buntime/api/process/BunProcess.cpp
${CWD}/src/buntime/api/process/ProcessBindingBuffer.cpp
${CWD}/src/buntime/api/process/ProcessBindingConstants.cpp
${CWD}/src/buntime/api/process/ProcessBindingFs.cpp
${CWD}/src/buntime/api/process/ProcessBindingNatives.cpp
${CWD}/src/buntime/api/process/ProcessBindingHTTPParser.cpp
${CWD}/src/buntime/modules/NodeModuleModule.cpp
${CODEGEN_PATH}/ZigGeneratedClasses.lut.txt
)
@@ -595,7 +576,6 @@ foreach(i RANGE 0 ${BUN_OBJECT_LUT_SOURCES_MAX_INDEX})
${BUN_OBJECT_LUT_SOURCE}
COMMAND
${BUN_EXECUTABLE}
${BUN_FLAGS}
run
${BUN_OBJECT_LUT_SCRIPT}
${BUN_OBJECT_LUT_SOURCE}
@@ -611,24 +591,24 @@ foreach(i RANGE 0 ${BUN_OBJECT_LUT_SOURCES_MAX_INDEX})
endforeach()
WEBKIT_ADD_SOURCE_DEPENDENCIES(
${CWD}/src/bun.js/bindings/ErrorCode.cpp
${CWD}/src/buntime/api/error/ErrorCode.cpp
${CODEGEN_PATH}/ErrorCode+List.h
)
WEBKIT_ADD_SOURCE_DEPENDENCIES(
${CWD}/src/bun.js/bindings/ErrorCode.h
${CWD}/src/buntime/api/error/ErrorCode.h
${CODEGEN_PATH}/ErrorCode+Data.h
)
WEBKIT_ADD_SOURCE_DEPENDENCIES(
${CWD}/src/bun.js/bindings/ZigGlobalObject.cpp
${CWD}/src/buntime/jsc/global/ZigGlobalObject.cpp
${CODEGEN_PATH}/ZigGlobalObject.lut.h
)
WEBKIT_ADD_SOURCE_DEPENDENCIES(
${CWD}/src/bun.js/bindings/InternalModuleRegistry.cpp
${CWD}/src/buntime/module/InternalModuleRegistry.cpp
${CODEGEN_PATH}/InternalModuleRegistryConstants.h
)
@@ -679,10 +659,6 @@ endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64")
if(APPLE)
set(ZIG_CPU "apple_m1")
elseif(WIN32)
# Windows ARM64: use a specific CPU with NEON support
# Zig running under x64 emulation would detect wrong CPU with "native"
set(ZIG_CPU "cortex_a76")
else()
set(ZIG_CPU "native")
endif()
@@ -721,7 +697,6 @@ register_command(
-Denable_asan=$<IF:$<BOOL:${ENABLE_ZIG_ASAN}>,true,false>
-Denable_fuzzilli=$<IF:$<BOOL:${ENABLE_FUZZILLI}>,true,false>
-Denable_valgrind=$<IF:$<BOOL:${ENABLE_VALGRIND}>,true,false>
-Denable_tinycc=$<IF:$<BOOL:${ENABLE_TINYCC}>,true,false>
-Duse_mimalloc=$<IF:$<BOOL:${USE_MIMALLOC_AS_DEFAULT_ALLOCATOR}>,true,false>
-Dllvm_codegen_threads=${LLVM_ZIG_CODEGEN_THREADS}
-Dversion=${VERSION}
@@ -752,8 +727,8 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "build.zig")
set(BUN_USOCKETS_SOURCE ${CWD}/packages/bun-usockets)
if(WIN32)
list(APPEND BUN_CXX_SOURCES ${CWD}/src/bun.js/bindings/windows/rescle.cpp)
list(APPEND BUN_CXX_SOURCES ${CWD}/src/bun.js/bindings/windows/rescle-binding.cpp)
list(APPEND BUN_CXX_SOURCES ${CWD}/src/buntime/compat/windows/rescle.cpp)
list(APPEND BUN_CXX_SOURCES ${CWD}/src/buntime/compat/windows/rescle-binding.cpp)
endif()
register_repository(
@@ -868,7 +843,7 @@ if (NOT WIN32)
# 2. In CI AND BUN_CPP_ONLY is enabled
if(NOT CI OR (CI AND BUN_CPP_ONLY))
target_precompile_headers(${bun} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CWD}/src/bun.js/bindings/root.h>"
"$<$<COMPILE_LANGUAGE:CXX>:${CWD}/src/buntime/jsc/interop/root.h>"
)
endif()
endif()
@@ -876,21 +851,72 @@ endif()
# --- C/C++ Includes ---
if(WIN32)
target_include_directories(${bun} PRIVATE ${CWD}/src/bun.js/bindings/windows)
target_include_directories(${bun} PRIVATE ${CWD}/src/buntime/compat/windows)
endif()
target_include_directories(${bun} PRIVATE
${CWD}/packages
${CWD}/packages/bun-usockets
${CWD}/packages/bun-usockets/src
${CWD}/src/bun.js/bindings
${CWD}/src/bun.js/bindings/webcore
${CWD}/src/bun.js/bindings/webcrypto
${CWD}/src/bun.js/bindings/node/crypto
${CWD}/src/bun.js/bindings/node/http
${CWD}/src/bun.js/bindings/sqlite
${CWD}/src/bun.js/bindings/v8
${CWD}/src/bun.js/modules
${CWD}/src/buntime/jsc/interop
${CWD}/src/buntime/jsc/global
${CWD}/src/buntime/jsc/gc
${CWD}/src/buntime/jsc/types
${CWD}/src/buntime/jsc/generated
${CWD}/src/bake
${CWD}/src/string
${CWD}/src/buntime/web
${CWD}/src/buntime/web/webcrypto
${CWD}/src/buntime/node
${CWD}/src/buntime/node/buffer
${CWD}/src/buntime/node/process
${CWD}/src/buntime/node/vm
${CWD}/src/buntime/node/crypto
${CWD}/src/buntime/node/http
${CWD}/src/buntime/node/fs
${CWD}/src/buntime/node/os
${CWD}/src/buntime/node/path
${CWD}/src/buntime/node/util
${CWD}/src/buntime/node/timers
${CWD}/src/buntime/node/async_hooks
${CWD}/src/buntime/node/perf_hooks
${CWD}/src/buntime/node/constants
${CWD}/src/buntime/api/sqlite
${CWD}/src/buntime/compat/v8
${CWD}/src/buntime/compat/napi
${CWD}/src/buntime/compat
${CWD}/src/buntime/module
${CWD}/src/buntime/api/console
${CWD}/src/buntime/api/inspector
${CWD}/src/buntime/api/error
${CWD}/src/buntime/api/cookie
${CWD}/src/buntime/api/s3
${CWD}/src/buntime/api/secrets
${CWD}/src/buntime/api/ffi
${CWD}/src/buntime/api/sql
${CWD}/src/buntime/api/shell
${CWD}/src/buntime/api/ipc
${CWD}/src/buntime/api/test
${CWD}/src/buntime/api/server
${CWD}/src/buntime/api/plugin
${CWD}/src/buntime/api/process
${CWD}/src/buntime/core
${CWD}/src/buntime/event_loop
${CWD}/src/buntime/web/fetch
${CWD}/src/buntime/web/url
${CWD}/src/buntime/web/blob
${CWD}/src/buntime/web/http
${CWD}/src/buntime/web/encoding
${CWD}/src/buntime/web/compression
${CWD}/src/buntime/web/events
${CWD}/src/buntime/web/streams
${CWD}/src/buntime/web/performance
${CWD}/src/buntime/web/websocket
${CWD}/src/buntime/web/workers
${CWD}/src/buntime/web/messaging
${CWD}/src/buntime/web/mime
${CWD}/src/buntime/web/serialization
${CWD}/src/buntime/modules
${CWD}/src/js/builtins
${CWD}/src/napi
${CWD}/src/deps
@@ -902,21 +928,8 @@ target_include_directories(${bun} PRIVATE
${NODEJS_HEADERS_PATH}/include/node
)
# --- Python ---
set(PYTHON_ROOT /Users/dylan/code/bun/vendor/cpython/install)
set(PYTHON_VERSION_MAJOR 3)
set(PYTHON_VERSION_MINOR 13)
set(PYTHON_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
target_include_directories(${bun} PRIVATE
${PYTHON_ROOT}/include/python${PYTHON_VERSION}
)
# Pass PYTHON_ROOT to C++ so BunPython.cpp can use it for runtime paths
target_compile_definitions(${bun} PRIVATE
PYTHON_ROOT="${PYTHON_ROOT}"
)
if(NOT WIN32)
target_include_directories(${bun} PRIVATE ${CWD}/src/bun.js/bindings/libuv)
target_include_directories(${bun} PRIVATE ${CWD}/src/buntime/compat/libuv)
endif()
if(LINUX)
@@ -952,7 +965,7 @@ if(WIN32)
endif()
if(USE_MIMALLOC_AS_DEFAULT_ALLOCATOR)
target_compile_definitions(${bun} PRIVATE USE_BUN_MIMALLOC=1)
target_compile_definitions(${bun} PRIVATE USE_MIMALLOC=1)
endif()
target_compile_definitions(${bun} PRIVATE
@@ -1252,7 +1265,7 @@ if(BUN_LINK_ONLY)
WEBKIT_DOWNLOAD_URL=${WEBKIT_DOWNLOAD_URL}
WEBKIT_VERSION=${WEBKIT_VERSION}
ZIG_COMMIT=${ZIG_COMMIT}
${BUN_EXECUTABLE} ${BUN_FLAGS} ${CWD}/scripts/create-link-metadata.mjs ${BUILD_PATH} ${bun}
${BUN_EXECUTABLE} ${CWD}/scripts/create-link-metadata.mjs ${BUILD_PATH} ${bun}
SOURCES
${BUN_ZIG_OUTPUT}
${BUN_CPP_OUTPUT}
@@ -1266,7 +1279,6 @@ if(WIN32)
target_link_libraries(${bun} PRIVATE
${WEBKIT_LIB_PATH}/WTF.lib
${WEBKIT_LIB_PATH}/JavaScriptCore.lib
${WEBKIT_LIB_PATH}/bmalloc.lib
${WEBKIT_LIB_PATH}/sicudtd.lib
${WEBKIT_LIB_PATH}/sicuind.lib
${WEBKIT_LIB_PATH}/sicuucd.lib
@@ -1275,7 +1287,6 @@ if(WIN32)
target_link_libraries(${bun} PRIVATE
${WEBKIT_LIB_PATH}/WTF.lib
${WEBKIT_LIB_PATH}/JavaScriptCore.lib
${WEBKIT_LIB_PATH}/bmalloc.lib
${WEBKIT_LIB_PATH}/sicudt.lib
${WEBKIT_LIB_PATH}/sicuin.lib
${WEBKIT_LIB_PATH}/sicuuc.lib
@@ -1286,18 +1297,13 @@ else()
${WEBKIT_LIB_PATH}/libWTF.a
${WEBKIT_LIB_PATH}/libJavaScriptCore.a
)
if(WEBKIT_LOCAL OR NOT APPLE OR EXISTS ${WEBKIT_LIB_PATH}/libbmalloc.a)
if(NOT APPLE OR EXISTS ${WEBKIT_LIB_PATH}/libbmalloc.a)
target_link_libraries(${bun} PRIVATE ${WEBKIT_LIB_PATH}/libbmalloc.a)
endif()
endif()
include_directories(${WEBKIT_INCLUDE_PATH})
# When building with a local WebKit, ensure JSC is built before compiling Bun's C++ sources.
if(WEBKIT_LOCAL AND TARGET jsc)
add_dependencies(${bun} jsc)
endif()
# Include the generated dependency versions header
include_directories(${CMAKE_BINARY_DIR})
@@ -1327,19 +1333,6 @@ if(APPLE)
target_compile_definitions(${bun} PRIVATE U_DISABLE_RENAMING=1)
endif()
# --- Python ---
# Link against shared Python library so extension modules can find symbols
if(APPLE)
target_link_libraries(${bun} PRIVATE
"${PYTHON_ROOT}/lib/libpython${PYTHON_VERSION}.dylib"
"-framework CoreFoundation"
)
else()
target_link_libraries(${bun} PRIVATE
"${PYTHON_ROOT}/lib/libpython${PYTHON_VERSION}.so"
)
endif()
if(USE_STATIC_SQLITE)
target_compile_definitions(${bun} PRIVATE LAZY_LOAD_SQLITE=0)
else()
@@ -1355,14 +1348,9 @@ if(LINUX)
target_link_libraries(${bun} PUBLIC libatomic.so)
endif()
if(WEBKIT_LOCAL)
find_package(ICU REQUIRED COMPONENTS data i18n uc)
target_link_libraries(${bun} PRIVATE ICU::data ICU::i18n ICU::uc)
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)
@@ -1376,9 +1364,6 @@ if(WIN32)
wsock32 # ws2_32 required by TransmitFile aka sendfile on windows
delayimp.lib
)
# Required for static ICU linkage - without this, ICU headers expect DLL linkage
# which causes ABI mismatch and crashes (STATUS_STACK_BUFFER_OVERRUN)
target_compile_definitions(${bun} PRIVATE U_STATIC_IMPLEMENTATION)
endif()
# --- Packaging ---

View File

@@ -20,15 +20,6 @@ set(HIGHWAY_CMAKE_ARGS
-DHWY_ENABLE_INSTALL=OFF
)
# On Windows ARM64 with clang-cl, the __ARM_NEON macro isn't defined by default
# but NEON intrinsics are supported. Define it so Highway can detect NEON support.
if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64|AARCH64")
list(APPEND HIGHWAY_CMAKE_ARGS
-DCMAKE_C_FLAGS=-D__ARM_NEON=1
-DCMAKE_CXX_FLAGS=-D__ARM_NEON=1
)
endif()
register_cmake_command(
TARGET
highway

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
cloudflare/lol-html
COMMIT
e9e16dca48dd4a8ffbc77642bc4be60407585f11
d64457d9ff0143deef025d5df7e8586092b9afb7
)
set(LOLHTML_CWD ${VENDOR_PATH}/lolhtml/c-api)
@@ -33,37 +33,6 @@ if (NOT WIN32)
set(RUSTFLAGS "-Cpanic=abort-Cdebuginfo=0-Cforce-unwind-tables=no-Copt-level=s")
endif()
# On Windows, ensure MSVC link.exe is used instead of Git's link.exe
set(LOLHTML_ENV
CARGO_TERM_COLOR=always
CARGO_TERM_VERBOSE=true
CARGO_TERM_DIAGNOSTIC=true
CARGO_ENCODED_RUSTFLAGS=${RUSTFLAGS}
CARGO_HOME=${CARGO_HOME}
RUSTUP_HOME=${RUSTUP_HOME}
)
if(WIN32)
# On Windows, tell Rust to use MSVC link.exe directly via the target-specific linker env var.
# This avoids Git's /usr/bin/link being found first in PATH.
# Find the MSVC link.exe from Visual Studio installation
file(GLOB MSVC_VERSIONS "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*")
if(MSVC_VERSIONS)
list(GET MSVC_VERSIONS -1 MSVC_LATEST) # Get the latest version
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
set(MSVC_LINK_PATH "${MSVC_LATEST}/bin/HostARM64/arm64/link.exe")
set(CARGO_LINKER_VAR "CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER")
else()
set(MSVC_LINK_PATH "${MSVC_LATEST}/bin/Hostx64/x64/link.exe")
set(CARGO_LINKER_VAR "CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER")
endif()
if(EXISTS "${MSVC_LINK_PATH}")
list(APPEND LOLHTML_ENV "${CARGO_LINKER_VAR}=${MSVC_LINK_PATH}")
message(STATUS "lolhtml: Using MSVC link.exe: ${MSVC_LINK_PATH}")
endif()
endif()
endif()
register_command(
TARGET
lolhtml
@@ -76,7 +45,12 @@ register_command(
ARTIFACTS
${LOLHTML_LIBRARY}
ENVIRONMENT
${LOLHTML_ENV}
CARGO_TERM_COLOR=always
CARGO_TERM_VERBOSE=true
CARGO_TERM_DIAGNOSTIC=true
CARGO_ENCODED_RUSTFLAGS=${RUSTFLAGS}
CARGO_HOME=${CARGO_HOME}
RUSTUP_HOME=${RUSTUP_HOME}
)
target_link_libraries(${bun} PRIVATE ${LOLHTML_LIBRARY})

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/mimalloc
COMMIT
ffa38ab8ac914f9eb7af75c1f8ad457643dc14f2
1beadf9651a7bfdec6b5367c380ecc3fe1c40d1a
)
set(MIMALLOC_CMAKE_ARGS
@@ -14,7 +14,7 @@ set(MIMALLOC_CMAKE_ARGS
-DMI_BUILD_TESTS=OFF
-DMI_USE_CXX=ON
-DMI_SKIP_COLLECT_ON_EXIT=ON
# ```
# mimalloc_allow_large_os_pages=0 BUN_PORT=3004 mem bun http-hello.js
# Started development server: http://localhost:3004
@@ -51,7 +51,7 @@ if(ENABLE_ASAN)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_DEBUG_UBSAN=ON)
elseif(APPLE OR LINUX)
if(APPLE)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OVERRIDE=OFF)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OVERRIDE=OFF)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OSX_ZONE=OFF)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OSX_INTERPOSE=OFF)
else()
@@ -69,27 +69,17 @@ if(ENABLE_VALGRIND)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_VALGRIND=ON)
endif()
# Enable architecture-specific optimizations when not building for baseline.
# On Linux aarch64, upstream mimalloc force-enables MI_OPT_ARCH which adds
# -march=armv8.1-a (LSE atomics). This crashes on ARMv8.0 CPUs
# (Cortex-A53, Raspberry Pi 4, AWS a1 instances). Use MI_NO_OPT_ARCH
# to prevent that, but keep SIMD enabled. -moutline-atomics for runtime
# dispatch to LSE/LL-SC. macOS arm64 always has LSE (Apple Silicon) so
# MI_OPT_ARCH is safe there.
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64|AARCH64" AND NOT APPLE)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_NO_OPT_ARCH=ON)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OPT_SIMD=ON)
list(APPEND MIMALLOC_CMAKE_ARGS "-DCMAKE_C_FLAGS=-moutline-atomics")
elseif(NOT ENABLE_BASELINE)
# Enable SIMD optimizations when not building for baseline (older CPUs)
if(NOT ENABLE_BASELINE)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OPT_ARCH=ON)
list(APPEND MIMALLOC_CMAKE_ARGS -DMI_OPT_SIMD=ON)
endif()
if(WIN32)
if(DEBUG)
set(MIMALLOC_LIBRARY mimalloc-debug)
set(MIMALLOC_LIBRARY mimalloc-static-debug)
else()
set(MIMALLOC_LIBRARY mimalloc)
set(MIMALLOC_LIBRARY mimalloc-static)
endif()
elseif(DEBUG)
if (ENABLE_ASAN)

View File

@@ -2,7 +2,7 @@ register_cmake_command(
TARGET
sqlite
CWD
${CWD}/src/bun.js/bindings/sqlite
${CWD}/src/buntime/bindings/sqlite
LIBRARIES
sqlite3
INCLUDES

View File

@@ -4,7 +4,7 @@ register_repository(
REPOSITORY
oven-sh/tinycc
COMMIT
12882eee073cfe5c7621bcfadf679e1372d4537b
29985a3b59898861442fa3b43f663fc1af2591d7
)
register_cmake_command(

View File

@@ -1,20 +0,0 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)
# Force ARM64 architecture ID - this is what CMake uses to determine /machine: flag
set(MSVC_C_ARCHITECTURE_ID ARM64 CACHE INTERNAL "")
set(MSVC_CXX_ARCHITECTURE_ID ARM64 CACHE INTERNAL "")
# CMake 4.0+ policy CMP0197 controls how MSVC machine type flags are handled
set(CMAKE_POLICY_DEFAULT_CMP0197 NEW CACHE INTERNAL "")
# Clear any inherited static linker flags that might have wrong machine types
set(CMAKE_STATIC_LINKER_FLAGS "" CACHE STRING "" FORCE)
# Use wrapper script for llvm-lib that strips /machine:x64 flags
# This works around CMake 4.1.0 bug where both ARM64 and x64 machine flags are added
get_filename_component(_TOOLCHAIN_DIR "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY)
set(CMAKE_AR "${_TOOLCHAIN_DIR}/scripts/llvm-lib-wrapper.bat" CACHE FILEPATH "" FORCE)

View File

@@ -6,8 +6,7 @@ endif()
optionx(BUILDKITE_ORGANIZATION_SLUG STRING "The organization slug to use on Buildkite" DEFAULT "bun")
optionx(BUILDKITE_PIPELINE_SLUG STRING "The pipeline slug to use on Buildkite" DEFAULT "bun")
optionx(BUILDKITE_BUILD_ID STRING "The build ID (UUID) to use on Buildkite")
optionx(BUILDKITE_BUILD_NUMBER STRING "The build number to use on Buildkite")
optionx(BUILDKITE_BUILD_ID STRING "The build ID to use on Buildkite")
optionx(BUILDKITE_GROUP_ID STRING "The group ID to use on Buildkite")
if(ENABLE_BASELINE)
@@ -33,13 +32,7 @@ if(NOT BUILDKITE_BUILD_ID)
return()
endif()
# Use BUILDKITE_BUILD_NUMBER for the URL if available, as the UUID format causes a 302 redirect
# that CMake's file(DOWNLOAD) doesn't follow, resulting in empty response.
if(BUILDKITE_BUILD_NUMBER)
setx(BUILDKITE_BUILD_URL https://buildkite.com/${BUILDKITE_ORGANIZATION_SLUG}/${BUILDKITE_PIPELINE_SLUG}/builds/${BUILDKITE_BUILD_NUMBER})
else()
setx(BUILDKITE_BUILD_URL https://buildkite.com/${BUILDKITE_ORGANIZATION_SLUG}/${BUILDKITE_PIPELINE_SLUG}/builds/${BUILDKITE_BUILD_ID})
endif()
setx(BUILDKITE_BUILD_URL https://buildkite.com/${BUILDKITE_ORGANIZATION_SLUG}/${BUILDKITE_PIPELINE_SLUG}/builds/${BUILDKITE_BUILD_ID})
setx(BUILDKITE_BUILD_PATH ${BUILDKITE_BUILDS_PATH}/builds/${BUILDKITE_BUILD_ID})
file(
@@ -55,16 +48,8 @@ if(NOT BUILDKITE_BUILD_STATUS EQUAL 0)
endif()
file(READ ${BUILDKITE_BUILD_PATH}/build.json BUILDKITE_BUILD)
# CMake's string(JSON ...) interprets escape sequences like \n, \r, \t.
# We need to escape these specific sequences while preserving valid JSON escapes like \" and \\.
# Strategy: Use a unique placeholder to protect \\ sequences, escape \n/\r/\t, then restore \\.
# This prevents \\n (literal backslash + n) from being corrupted to \\\n.
set(BKSLASH_PLACEHOLDER "___BKSLASH_PLACEHOLDER_7f3a9b2c___")
string(REPLACE "\\\\" "${BKSLASH_PLACEHOLDER}" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
string(REPLACE "\\n" "\\\\n" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
string(REPLACE "\\r" "\\\\r" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
string(REPLACE "\\t" "\\\\t" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
string(REPLACE "${BKSLASH_PLACEHOLDER}" "\\\\" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
# Escape backslashes so CMake doesn't interpret JSON escape sequences (e.g., \n in commit messages)
string(REPLACE "\\" "\\\\" BUILDKITE_BUILD "${BUILDKITE_BUILD}")
string(JSON BUILDKITE_BUILD_UUID GET ${BUILDKITE_BUILD} id)
string(JSON BUILDKITE_JOBS GET ${BUILDKITE_BUILD} jobs)

View File

@@ -17,16 +17,8 @@ if (NOT CI)
set(BUN_EXECUTABLE ${BUN_EXECUTABLE} CACHE FILEPATH "Bun executable" FORCE)
endif()
# On Windows ARM64, we need to add --smol flag to avoid crashes when running
# x64 bun under WoW64 emulation
if(WIN32 AND ARCH STREQUAL "aarch64")
set(BUN_FLAGS "--smol" CACHE STRING "Extra flags for bun executable")
else()
set(BUN_FLAGS "" CACHE STRING "Extra flags for bun executable")
endif()
# If this is not set, some advanced features are not checked.
# https://github.com/oven-sh/bun/blob/cd7f6a1589db7f1e39dc4e3f4a17234afbe7826c/src/bun.js/javascript.zig#L1069-L1072
# https://github.com/oven-sh/bun/blob/cd7f6a1589db7f1e39dc4e3f4a17234afbe7826c/src/buntime/javascript.zig#L1069-L1072
setenv(BUN_GARBAGE_COLLECTOR_LEVEL 1)
setenv(BUN_FEATURE_FLAG_INTERNAL_FOR_TESTING 1)
setenv(BUN_DEBUG_QUIET_LOGS 1)

View File

@@ -12,13 +12,7 @@ if(NOT ENABLE_LLVM)
return()
endif()
# LLVM 21 is required for Windows ARM64 (first version with ARM64 Windows builds)
# Other platforms use LLVM 19.1.7
if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64|AARCH64")
set(DEFAULT_LLVM_VERSION "21.1.8")
else()
set(DEFAULT_LLVM_VERSION "19.1.7")
endif()
set(DEFAULT_LLVM_VERSION "19.1.7")
optionx(LLVM_VERSION STRING "The version of LLVM to use" DEFAULT ${DEFAULT_LLVM_VERSION})

View File

@@ -31,6 +31,13 @@ execute_process(
ERROR_QUIET
)
if(MACOS_VERSION VERSION_LESS ${CMAKE_OSX_DEPLOYMENT_TARGET})
message(FATAL_ERROR "Your computer is running macOS ${MACOS_VERSION}, which is older than the target macOS SDK ${CMAKE_OSX_DEPLOYMENT_TARGET}. To fix this, either:\n"
" - Upgrade your computer to macOS ${CMAKE_OSX_DEPLOYMENT_TARGET} or newer\n"
" - Download a newer version of the macOS SDK from Apple: https://developer.apple.com/download/all/?q=xcode\n"
" - Set -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOS_VERSION}\n")
endif()
execute_process(
COMMAND xcrun --sdk macosx --show-sdk-path
OUTPUT_VARIABLE DEFAULT_CMAKE_OSX_SYSROOT

View File

@@ -1,25 +1,14 @@
# NOTE: Changes to this file trigger QEMU JIT stress tests in CI.
# See scripts/verify-jit-stress-qemu.sh for details.
option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
option(WEBKIT_BUILD_TYPE "The build type for local WebKit (defaults to CMAKE_BUILD_TYPE)")
if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION 515344bc5d65aa2d4f9ff277b5fb944f0e051dcd)
set(WEBKIT_VERSION 863778130931e0081a688f48e8479b8ee61b9507)
endif()
# Use preview build URL for Windows ARM64 until the fix is merged to main
set(WEBKIT_PREVIEW_PR 140)
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
string(SUBSTRING ${WEBKIT_VERSION} 0 8 WEBKIT_VERSION_SHORT)
if(WEBKIT_LOCAL)
if(NOT WEBKIT_BUILD_TYPE)
set(WEBKIT_BUILD_TYPE ${CMAKE_BUILD_TYPE})
endif()
set(DEFAULT_WEBKIT_PATH ${VENDOR_PATH}/WebKit/WebKitBuild/${WEBKIT_BUILD_TYPE})
set(DEFAULT_WEBKIT_PATH ${VENDOR_PATH}/WebKit/WebKitBuild/${CMAKE_BUILD_TYPE})
else()
set(DEFAULT_WEBKIT_PATH ${CACHE_PATH}/webkit-${WEBKIT_VERSION_PREFIX})
endif()
@@ -34,153 +23,18 @@ set(WEBKIT_INCLUDE_PATH ${WEBKIT_PATH}/include)
set(WEBKIT_LIB_PATH ${WEBKIT_PATH}/lib)
if(WEBKIT_LOCAL)
set(WEBKIT_SOURCE_DIR ${VENDOR_PATH}/WebKit)
if(WIN32)
# --- Build ICU from source (Windows only) ---
# On macOS, ICU is found automatically (Homebrew icu4c for headers, system for libs).
# On Linux, ICU is found automatically from system packages (e.g. libicu-dev).
# On Windows, there is no system ICU, so we build it from source.
set(ICU_LOCAL_ROOT ${VENDOR_PATH}/WebKit/WebKitBuild/icu)
if(NOT EXISTS ${ICU_LOCAL_ROOT}/lib/sicudt.lib)
message(STATUS "Building ICU from source...")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
set(ICU_PLATFORM "ARM64")
else()
set(ICU_PLATFORM "x64")
endif()
execute_process(
COMMAND powershell -ExecutionPolicy Bypass -File
${WEBKIT_SOURCE_DIR}/build-icu.ps1
-Platform ${ICU_PLATFORM}
-BuildType ${WEBKIT_BUILD_TYPE}
-OutputDir ${ICU_LOCAL_ROOT}
RESULT_VARIABLE ICU_BUILD_RESULT
)
if(NOT ICU_BUILD_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to build ICU (exit code: ${ICU_BUILD_RESULT}).")
endif()
endif()
# Copy ICU libs to WEBKIT_LIB_PATH with the names BuildBun.cmake expects.
# Prebuilt WebKit uses 's' prefix (static) and 'd' suffix (debug).
file(MAKE_DIRECTORY ${WEBKIT_LIB_PATH})
if(WEBKIT_BUILD_TYPE STREQUAL "Debug")
set(ICU_SUFFIX "d")
else()
set(ICU_SUFFIX "")
endif()
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/sicudt.lib ${WEBKIT_LIB_PATH}/sicudt${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/icuin.lib ${WEBKIT_LIB_PATH}/sicuin${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/icuuc.lib ${WEBKIT_LIB_PATH}/sicuuc${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
endif()
# --- Configure JSC ---
message(STATUS "Configuring JSC from local WebKit source at ${WEBKIT_SOURCE_DIR}...")
set(JSC_CMAKE_ARGS
-S ${WEBKIT_SOURCE_DIR}
-B ${WEBKIT_PATH}
-G ${CMAKE_GENERATOR}
-DPORT=JSCOnly
-DENABLE_STATIC_JSC=ON
-DUSE_THIN_ARCHIVES=OFF
-DENABLE_FTL_JIT=ON
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DUSE_BUN_JSC_ADDITIONS=ON
-DUSE_BUN_EVENT_LOOP=ON
-DENABLE_BUN_SKIP_FAILING_ASSERTIONS=ON
-DALLOW_LINE_AND_COLUMN_NUMBER_IN_BUILTINS=ON
-DCMAKE_BUILD_TYPE=${WEBKIT_BUILD_TYPE}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DENABLE_REMOTE_INSPECTOR=ON
)
if(WIN32)
# ICU paths and Windows-specific compiler/linker settings
list(APPEND JSC_CMAKE_ARGS
-DICU_ROOT=${ICU_LOCAL_ROOT}
-DICU_LIBRARY=${ICU_LOCAL_ROOT}/lib
-DICU_INCLUDE_DIR=${ICU_LOCAL_ROOT}/include
-DCMAKE_LINKER=lld-link
if(EXISTS ${WEBKIT_PATH}/cmakeconfig.h)
# You may need to run:
# make jsc-compile-debug jsc-copy-headers
include_directories(
${WEBKIT_PATH}
${WEBKIT_PATH}/JavaScriptCore/Headers/JavaScriptCore
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders
${WEBKIT_PATH}/bmalloc/Headers
${WEBKIT_PATH}/WTF/Headers
${WEBKIT_PATH}/JavaScriptCore/DerivedSources/inspector
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders/JavaScriptCore
)
# Static CRT and U_STATIC_IMPLEMENTATION
if(WEBKIT_BUILD_TYPE STREQUAL "Debug")
set(JSC_MSVC_RUNTIME "MultiThreadedDebug")
else()
set(JSC_MSVC_RUNTIME "MultiThreaded")
endif()
list(APPEND JSC_CMAKE_ARGS
-DCMAKE_MSVC_RUNTIME_LIBRARY=${JSC_MSVC_RUNTIME}
"-DCMAKE_C_FLAGS=/DU_STATIC_IMPLEMENTATION"
"-DCMAKE_CXX_FLAGS=/DU_STATIC_IMPLEMENTATION /clang:-fno-c++-static-destructors"
)
endif()
if(ENABLE_ASAN)
list(APPEND JSC_CMAKE_ARGS -DENABLE_SANITIZERS=address)
endif()
# Pass through ccache if available
if(CMAKE_C_COMPILER_LAUNCHER)
list(APPEND JSC_CMAKE_ARGS -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER})
endif()
if(CMAKE_CXX_COMPILER_LAUNCHER)
list(APPEND JSC_CMAKE_ARGS -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER})
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} ${JSC_CMAKE_ARGS}
RESULT_VARIABLE JSC_CONFIGURE_RESULT
)
if(NOT JSC_CONFIGURE_RESULT EQUAL 0)
message(FATAL_ERROR "Failed to configure JSC (exit code: ${JSC_CONFIGURE_RESULT}). "
"Check the output above for errors.")
endif()
if(WIN32)
set(JSC_BYPRODUCTS
${WEBKIT_LIB_PATH}/JavaScriptCore.lib
${WEBKIT_LIB_PATH}/WTF.lib
${WEBKIT_LIB_PATH}/bmalloc.lib
)
else()
set(JSC_BYPRODUCTS
${WEBKIT_LIB_PATH}/libJavaScriptCore.a
${WEBKIT_LIB_PATH}/libWTF.a
${WEBKIT_LIB_PATH}/libbmalloc.a
)
endif()
if(WIN32)
add_custom_target(jsc ALL
COMMAND ${CMAKE_COMMAND} --build ${WEBKIT_PATH} --config ${WEBKIT_BUILD_TYPE} --target jsc
BYPRODUCTS ${JSC_BYPRODUCTS}
COMMENT "Building JSC (${WEBKIT_PATH})"
)
else()
add_custom_target(jsc ALL
COMMAND ${CMAKE_COMMAND} --build ${WEBKIT_PATH} --config ${WEBKIT_BUILD_TYPE} --target jsc
BYPRODUCTS ${JSC_BYPRODUCTS}
COMMENT "Building JSC (${WEBKIT_PATH})"
USES_TERMINAL
)
endif()
include_directories(
${WEBKIT_PATH}
${WEBKIT_PATH}/JavaScriptCore/Headers
${WEBKIT_PATH}/JavaScriptCore/Headers/JavaScriptCore
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders
${WEBKIT_PATH}/bmalloc/Headers
${WEBKIT_PATH}/WTF/Headers
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders/JavaScriptCore
)
# On Windows, add ICU headers from the local ICU build
if(WIN32)
include_directories(${ICU_LOCAL_ROOT}/include)
endif()
# After this point, only prebuilt WebKit is supported
@@ -197,7 +51,7 @@ else()
message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}")
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
set(WEBKIT_ARCH "arm64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64")
set(WEBKIT_ARCH "amd64")
@@ -226,14 +80,7 @@ endif()
setx(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX})
set(WEBKIT_FILENAME ${WEBKIT_NAME}.tar.gz)
if(WEBKIT_VERSION MATCHES "^autobuild-")
set(WEBKIT_TAG ${WEBKIT_VERSION})
else()
set(WEBKIT_TAG autobuild-${WEBKIT_VERSION})
endif()
setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/${WEBKIT_TAG}/${WEBKIT_FILENAME})
setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/autobuild-${WEBKIT_VERSION}/${WEBKIT_FILENAME})
if(EXISTS ${WEBKIT_PATH}/package.json)
file(READ ${WEBKIT_PATH}/package.json WEBKIT_PACKAGE_JSON)
@@ -243,14 +90,7 @@ if(EXISTS ${WEBKIT_PATH}/package.json)
endif()
endif()
file(
DOWNLOAD ${WEBKIT_DOWNLOAD_URL} ${CACHE_PATH}/${WEBKIT_FILENAME} SHOW_PROGRESS
STATUS WEBKIT_DOWNLOAD_STATUS
)
if(NOT "${WEBKIT_DOWNLOAD_STATUS}" MATCHES "^0;")
message(FATAL_ERROR "Failed to download WebKit: ${WEBKIT_DOWNLOAD_STATUS}")
endif()
file(DOWNLOAD ${WEBKIT_DOWNLOAD_URL} ${CACHE_PATH}/${WEBKIT_FILENAME} SHOW_PROGRESS)
file(ARCHIVE_EXTRACT INPUT ${CACHE_PATH}/${WEBKIT_FILENAME} DESTINATION ${CACHE_PATH} TOUCH)
file(REMOVE ${CACHE_PATH}/${WEBKIT_FILENAME})
file(REMOVE_RECURSE ${WEBKIT_PATH})

View File

@@ -1,4 +1,4 @@
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
set(DEFAULT_ZIG_ARCH "aarch64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64")
set(DEFAULT_ZIG_ARCH "x86_64")

View File

@@ -35,8 +35,8 @@ end
set -l bun_install_boolean_flags yarn production optional development no-save dry-run force no-cache silent verbose global
set -l bun_install_boolean_flags_descriptions "Write a yarn.lock file (yarn v1)" "Don't install devDependencies" "Add dependency to optionalDependencies" "Add dependency to devDependencies" "Don't update package.json or save a lockfile" "Don't install anything" "Always request the latest versions from the registry & reinstall all dependencies" "Ignore manifest cache entirely" "Don't output anything" "Excessively verbose logging" "Use global folder"
set -l bun_builtin_cmds_without_run dev create help bun upgrade discord install remove add update init pm x
set -l bun_builtin_cmds_accepting_flags create help bun upgrade discord run init link unlink pm x update
set -l bun_builtin_cmds_without_run dev create help bun upgrade discord install remove add init pm x
set -l bun_builtin_cmds_accepting_flags create help bun upgrade discord run init link unlink pm x
function __bun_complete_bins_scripts --inherit-variable bun_builtin_cmds_without_run -d "Emit bun completions for bins and scripts"
# Do nothing if we already have a builtin subcommand,
@@ -148,14 +148,14 @@ complete -c bun \
for i in (seq (count $bun_install_boolean_flags))
complete -c bun \
-n "__fish_seen_subcommand_from install add remove update" -l "$bun_install_boolean_flags[$i]" -d "$bun_install_boolean_flags_descriptions[$i]"
-n "__fish_seen_subcommand_from install add remove" -l "$bun_install_boolean_flags[$i]" -d "$bun_install_boolean_flags_descriptions[$i]"
end
complete -c bun \
-n "__fish_seen_subcommand_from install add remove update" -l 'cwd' -d 'Change working directory'
-n "__fish_seen_subcommand_from install add remove" -l 'cwd' -d 'Change working directory'
complete -c bun \
-n "__fish_seen_subcommand_from install add remove update" -l 'cache-dir' -d 'Choose a cache directory (default: $HOME/.bun/install/cache)'
-n "__fish_seen_subcommand_from install add remove" -l 'cache-dir' -d 'Choose a cache directory (default: $HOME/.bun/install/cache)'
complete -c bun \
-n "__fish_seen_subcommand_from add" -d 'Popular' -a '(__fish__get_bun_packages)'
@@ -183,5 +183,4 @@ complete -c bun -n "__fish_use_subcommand" -a "unlink" -d "Unregister a local np
complete -c bun -n "__fish_use_subcommand" -a "pm" -d "Additional package management utilities" -f
complete -c bun -n "__fish_use_subcommand" -a "x" -d "Execute a package binary, installing if needed" -f
complete -c bun -n "__fish_use_subcommand" -a "outdated" -d "Display the latest versions of outdated dependencies" -f
complete -c bun -n "__fish_use_subcommand" -a "update" -d "Update dependencies to their latest versions" -f
complete -c bun -n "__fish_use_subcommand" -a "publish" -d "Publish your package from local to npm" -f

View File

@@ -7,9 +7,9 @@ Bytecode caching is a build-time optimization that dramatically improves applica
## Usage
### Basic usage (CommonJS)
### Basic usage
Enable bytecode caching with the `--bytecode` flag. Without `--format`, this defaults to CommonJS:
Enable bytecode caching with the `--bytecode` flag:
```bash terminal icon="terminal"
bun build ./index.ts --target=bun --bytecode --outdir=./dist
@@ -17,7 +17,7 @@ bun build ./index.ts --target=bun --bytecode --outdir=./dist
This generates two files:
- `dist/index.js` - Your bundled JavaScript (CommonJS)
- `dist/index.js` - Your bundled JavaScript
- `dist/index.jsc` - The bytecode cache file
At runtime, Bun automatically detects and uses the `.jsc` file:
@@ -28,24 +28,14 @@ bun ./dist/index.js # Automatically uses index.jsc
### With standalone executables
When creating executables with `--compile`, bytecode is embedded into the binary. Both ESM and CommonJS formats are supported:
When creating executables with `--compile`, bytecode is embedded into the binary:
```bash terminal icon="terminal"
# ESM (requires --compile)
bun build ./cli.ts --compile --bytecode --format=esm --outfile=mycli
# CommonJS (works with or without --compile)
bun build ./cli.ts --compile --bytecode --outfile=mycli
```
The resulting executable contains both the code and bytecode, giving you maximum performance in a single file.
### ESM bytecode
ESM bytecode requires `--compile` because Bun embeds module metadata (import/export information) in the compiled binary. This metadata allows the JavaScript engine to skip parsing entirely at runtime.
Without `--compile`, ESM bytecode would still require parsing the source to analyze module dependencies—defeating the purpose of bytecode caching.
### Combining with other optimizations
Bytecode works great with minification and source maps:
@@ -100,9 +90,35 @@ Larger applications benefit more because they have more code to parse.
- ❌ **Code that runs once**
- ❌ **Development builds**
- ❌ **Size-constrained environments**
- ❌ **Code with top-level await** (not supported)
## Limitations
### CommonJS only
Bytecode caching currently works with CommonJS output format. Bun's bundler automatically converts most ESM code to CommonJS, but **top-level await** is the exception:
```js
// This prevents bytecode caching
const data = await fetch("https://api.example.com");
export default data;
```
**Why**: Top-level await requires async module evaluation, which can't be represented in CommonJS. The module graph becomes asynchronous, and the CommonJS wrapper function model breaks down.
**Workaround**: Move async initialization into a function:
```js
async function init() {
const data = await fetch("https://api.example.com");
return data;
}
export default init;
```
Now the module exports a function that the consumer can await when needed.
### Version compatibility
Bytecode is **not portable across Bun versions**. The bytecode format is tied to JavaScriptCore's internal representation, which changes between versions.
@@ -220,6 +236,8 @@ It's normal for it it to log a cache miss multiple times since Bun doesn't curre
- Compressing `.jsc` files for network transfer (gzip/brotli)
- Evaluating if the startup performance gain is worth the size increase
**Top-level await**: Not supported. Refactor to use async initialization functions.
## What is bytecode?
When you run JavaScript, the JavaScript engine doesn't execute your source code directly. Instead, it goes through several steps:

View File

@@ -322,7 +322,10 @@ Using bytecode compilation, `tsc` starts 2x faster:
Bytecode compilation moves parsing overhead for large input files from runtime to bundle time. Your app starts faster, in exchange for making the `bun build` command a little slower. It doesn't obscure source code.
<Note>Bytecode compilation supports both `cjs` and `esm` formats when used with `--compile`.</Note>
<Warning>
**Experimental:** Bytecode compilation is an experimental feature. Only `cjs` format is supported (which means no
top-level-await). Let us know if you run into any issues!
</Warning>
### What do these flags do?
@@ -362,23 +365,6 @@ The `--bytecode` argument enables bytecode compilation. Every time you run JavaS
console.log(process.execArgv); // ["--smol", "--user-agent=MyBot"]
```
### Runtime arguments via `BUN_OPTIONS`
The `BUN_OPTIONS` environment variable is applied to standalone executables, allowing you to pass runtime flags without recompiling:
```bash terminal icon="terminal"
# Enable CPU profiling on a compiled executable
BUN_OPTIONS="--cpu-prof" ./myapp
# Enable heap profiling with markdown output
BUN_OPTIONS="--heap-prof-md" ./myapp
# Combine multiple flags
BUN_OPTIONS="--smol --cpu-prof-md" ./myapp
```
This is useful for debugging or profiling production executables without rebuilding them.
---
## Automatic config loading

View File

@@ -220,78 +220,6 @@ An array of paths corresponding to the entrypoints of our application. One bundl
</Tab>
</Tabs>
### files
A map of file paths to their contents for in-memory bundling. This allows you to bundle virtual files that don't exist on disk, or override the contents of files that do exist. This option is only available in the JavaScript API.
File contents can be provided as a `string`, `Blob`, `TypedArray`, or `ArrayBuffer`.
#### Bundle entirely from memory
You can bundle code without any files on disk by providing all sources via `files`:
```ts title="build.ts" icon="/icons/typescript.svg"
const result = await Bun.build({
entrypoints: ["/app/index.ts"],
files: {
"/app/index.ts": `
import { greet } from "./greet.ts";
console.log(greet("World"));
`,
"/app/greet.ts": `
export function greet(name: string) {
return "Hello, " + name + "!";
}
`,
},
});
const output = await result.outputs[0].text();
console.log(output);
```
When all entrypoints are in the `files` map, the current working directory is used as the root.
#### Override files on disk
In-memory files take priority over files on disk. This lets you override specific files while keeping the rest of your codebase unchanged:
```ts title="build.ts" icon="/icons/typescript.svg"
// Assume ./src/config.ts exists on disk with development settings
await Bun.build({
entrypoints: ["./src/index.ts"],
files: {
// Override config.ts with production values
"./src/config.ts": `
export const API_URL = "https://api.production.com";
export const DEBUG = false;
`,
},
outdir: "./dist",
});
```
#### Mix disk and virtual files
Real files on disk can import virtual files, and virtual files can import real files:
```ts title="build.ts" icon="/icons/typescript.svg"
// ./src/index.ts exists on disk and imports "./generated.ts"
await Bun.build({
entrypoints: ["./src/index.ts"],
files: {
// Provide a virtual file that index.ts imports
"./src/generated.ts": `
export const BUILD_ID = "${crypto.randomUUID()}";
export const BUILD_TIME = ${Date.now()};
`,
},
outdir: "./dist",
});
```
This is useful for code generation, injecting build-time constants, or testing with mock modules.
### outdir
The directory where output files will be written.
@@ -1291,123 +1219,6 @@ declare module "bun:bundle" {
Ensure the file is included in your `tsconfig.json` (e.g., `"include": ["src", "env.d.ts"]`). Now `feature()` only accepts those flags, and invalid strings like `feature("TYPO")` become type errors.
### metafile
Generate metadata about the build in a structured format. The metafile contains information about all input files, output files, their sizes, imports, and exports. This is useful for:
- **Bundle analysis**: Understand what's contributing to bundle size
- **Visualization**: Feed into tools like [esbuild's bundle analyzer](https://esbuild.github.io/analyze/) or other visualization tools
- **Dependency tracking**: See the full import graph of your application
- **CI integration**: Track bundle size changes over time
<Tabs>
<Tab title="JavaScript">
```ts title="build.ts" icon="/icons/typescript.svg"
const result = await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
metafile: true,
});
if (result.metafile) {
// Analyze inputs
for (const [path, meta] of Object.entries(result.metafile.inputs)) {
console.log(`${path}: ${meta.bytes} bytes`);
}
// Analyze outputs
for (const [path, meta] of Object.entries(result.metafile.outputs)) {
console.log(`${path}: ${meta.bytes} bytes`);
}
// Save for external analysis tools
await Bun.write('./dist/meta.json', JSON.stringify(result.metafile));
}
```
</Tab>
<Tab title="CLI">
```bash terminal icon="terminal"
bun build ./src/index.ts --outdir ./dist --metafile ./dist/meta.json
```
</Tab>
</Tabs>
#### Markdown metafile
Use `--metafile-md` to generate a markdown metafile, which is LLM-friendly and easy to read in the terminal:
```bash terminal icon="terminal"
bun build ./src/index.ts --outdir ./dist --metafile-md ./dist/meta.md
```
Both `--metafile` and `--metafile-md` can be used together:
```bash terminal icon="terminal"
bun build ./src/index.ts --outdir ./dist --metafile ./dist/meta.json --metafile-md ./dist/meta.md
```
#### `metafile` option formats
In the JavaScript API, `metafile` accepts several forms:
```ts title="build.ts" icon="/icons/typescript.svg"
// Boolean — include metafile in the result object
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: true,
});
// String — write JSON metafile to a specific path
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: "./dist/meta.json",
});
// Object — specify separate paths for JSON and markdown output
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
metafile: {
json: "./dist/meta.json",
markdown: "./dist/meta.md",
},
});
```
The metafile structure contains:
```ts
interface BuildMetafile {
inputs: {
[path: string]: {
bytes: number;
imports: Array<{
path: string;
kind: ImportKind;
original?: string; // Original specifier before resolution
external?: boolean;
}>;
format?: "esm" | "cjs" | "json" | "css";
};
};
outputs: {
[path: string]: {
bytes: number;
inputs: {
[path: string]: { bytesInOutput: number };
};
imports: Array<{ path: string; kind: ImportKind }>;
exports: string[];
entryPoint?: string;
cssBundle?: string; // Associated CSS file for JS entry points
};
};
}
```
## Outputs
The `Bun.build` function returns a `Promise<BuildOutput>`, defined as:
@@ -1417,7 +1228,6 @@ interface BuildOutput {
outputs: BuildArtifact[];
success: boolean;
logs: Array<object>; // see docs for details
metafile?: BuildMetafile; // only when metafile: true
}
interface BuildArtifact extends Blob {
@@ -1508,43 +1318,22 @@ BuildArtifact (entry-point) {
## Bytecode
The `bytecode: boolean` option can be used to generate bytecode for any JavaScript/TypeScript entrypoints. This can greatly improve startup times for large applications. Requires `"target": "bun"` and is dependent on a matching version of Bun.
- **CommonJS**: Works with or without `compile: true`. Generates a `.jsc` file alongside each entrypoint.
- **ESM**: Requires `compile: true`. Bytecode and module metadata are embedded in the standalone executable.
Without an explicit `format`, bytecode defaults to CommonJS.
The `bytecode: boolean` option can be used to generate bytecode for any JavaScript/TypeScript entrypoints. This can greatly improve startup times for large applications. Only supported for `"cjs"` format, only supports `"target": "bun"` and dependent on a matching version of Bun. This adds a corresponding `.jsc` file for each entrypoint.
<Tabs>
<Tab title="JavaScript">
```ts title="build.ts" icon="/icons/typescript.svg"
// CommonJS bytecode (generates .jsc files)
await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
bytecode: true,
})
// ESM bytecode (requires compile)
await Bun.build({
entrypoints: ["./index.tsx"],
outfile: "./mycli",
bytecode: true,
format: "esm",
compile: true,
})
```
</Tab>
<Tab title="CLI">
```bash terminal icon="terminal"
# CommonJS bytecode
bun build ./index.tsx --outdir ./out --bytecode
# ESM bytecode (requires --compile)
bun build ./index.tsx --outfile ./mycli --bytecode --format=esm --compile
```
</Tab>
</Tabs>
@@ -1711,10 +1500,7 @@ interface BuildConfig {
* start times, but will make the final output larger and slightly increase
* memory usage.
*
* - CommonJS: works with or without `compile: true`
* - ESM: requires `compile: true`
*
* Without an explicit `format`, defaults to CommonJS.
* Bytecode is currently only supported for CommonJS (`format: "cjs"`).
*
* Must be `target: "bun"`
* @default false

View File

@@ -121,7 +121,6 @@
"/runtime/file-io",
"/runtime/streams",
"/runtime/binary-data",
"/runtime/archive",
"/runtime/sql",
"/runtime/sqlite",
"/runtime/s3",
@@ -150,9 +149,6 @@
"/runtime/secrets",
"/runtime/console",
"/runtime/yaml",
"/runtime/markdown",
"/runtime/json5",
"/runtime/jsonl",
"/runtime/html-rewriter",
"/runtime/hashing",
"/runtime/glob",
@@ -500,7 +496,6 @@
"/guides/runtime/import-json",
"/guides/runtime/import-toml",
"/guides/runtime/import-yaml",
"/guides/runtime/import-json5",
"/guides/runtime/import-html",
"/guides/util/import-meta-dir",
"/guides/util/import-meta-file",

View File

@@ -33,7 +33,7 @@ Alternatively, you can create a PM2 configuration file. Create a file named `pm2
```js pm2.config.js icon="file-code"
module.exports = {
name: "app", // Name of your application
title: "app", // Name of your application
script: "index.ts", // Entry point of your application
interpreter: "bun", // Bun interpreter
env: {

View File

@@ -1,74 +0,0 @@
---
title: Import a JSON5 file
sidebarTitle: Import JSON5
mode: center
---
Bun natively supports `.json5` imports.
```json5 config.json5 icon="file-code"
{
// Comments are allowed
database: {
host: "localhost",
port: 5432,
name: "myapp",
},
server: {
port: 3000,
timeout: 30,
},
features: {
auth: true,
rateLimit: true,
},
}
```
---
Import the file like any other source file.
```ts config.ts icon="/icons/typescript.svg"
import config from "./config.json5";
config.database.host; // => "localhost"
config.server.port; // => 3000
config.features.auth; // => true
```
---
You can also use named imports to destructure top-level properties:
```ts config.ts icon="/icons/typescript.svg"
import { database, server, features } from "./config.json5";
console.log(database.name); // => "myapp"
console.log(server.timeout); // => 30
console.log(features.rateLimit); // => true
```
---
For parsing JSON5 strings at runtime, use `Bun.JSON5.parse()`:
```ts config.ts icon="/icons/typescript.svg"
const data = JSON5.parse(`{
name: 'John Doe',
age: 30,
hobbies: [
'reading',
'coding',
],
}`);
console.log(data.name); // => "John Doe"
console.log(data.hobbies); // => ["reading", "coding"]
```
---
See [Docs > API > JSON5](/runtime/json5) for complete documentation on JSON5 support in Bun.

View File

@@ -26,6 +26,21 @@ The `bun` CLI contains a Node.js-compatible package manager designed to be a dra
</Note>
<Accordion title="For Linux users">
The recommended minimum Linux Kernel version is 5.6. If you're on Linux kernel 5.1 - 5.5, `bun install` will work, but HTTP requests will be slow due to a lack of support for io_uring's `connect()` operation.
If you're using Ubuntu 20.04, here's how to install a [newer kernel](https://wiki.ubuntu.com/Kernel/LTSEnablementStack):
```bash terminal icon="terminal"
# If this returns a version >= 5.6, you don't need to do anything
uname -r
# Install the official Ubuntu hardware enablement kernel
sudo apt install --install-recommends linux-generic-hwe-20.04
```
</Accordion>
To install all dependencies of a project:
```bash terminal icon="terminal"

View File

@@ -97,31 +97,6 @@ Filters respect your [workspace configuration](/pm/workspaces): If you have a `p
bun run --filter foo myscript
```
### Parallel and sequential mode
Combine `--filter` or `--workspaces` with `--parallel` or `--sequential` to run scripts across workspace packages with Foreman-style prefixed output:
```bash terminal icon="terminal"
# Run "build" in all matching packages concurrently
bun run --parallel --filter '*' build
# Run "build" in all workspace packages sequentially
bun run --sequential --workspaces build
# Run glob-matched scripts across all packages
bun run --parallel --filter '*' "build:*"
# Continue running even if one package's script fails
bun run --parallel --no-exit-on-error --filter '*' test
# Run multiple scripts across all packages
bun run --parallel --filter '*' build lint
```
Each line of output is prefixed with the package and script name (e.g. `pkg-a:build | ...`). Without `--filter`/`--workspaces`, the prefix is just the script name (e.g. `build | ...`). When a package's `package.json` has no `name` field, the relative path from the workspace root is used instead.
Use `--if-present` with `--workspaces` to skip packages that don't have the requested script instead of erroring.
### Dependency Order
Bun will respect package dependency order when running scripts. Say you have a package `foo` that depends on another package `bar` in your workspace, and both packages have a `build` script. When you run `bun --filter '*' build`, you will notice that `foo` will only start running once `bar` is done.

View File

@@ -189,7 +189,7 @@ Isolated installs are conceptually similar to pnpm, so migration should be strai
```bash terminal icon="terminal"
# Remove pnpm files
rm -rf node_modules pnpm-lock.yaml
$ rm -rf node_modules pnpm-lock.yaml
# Install with Bun's isolated linker
bun install --linker isolated

View File

@@ -72,7 +72,6 @@ The following options are supported:
- `username`
- `_password` (base64 encoded password)
- `_auth` (base64 encoded username:password, e.g. `btoa(username + ":" + password)`)
- `email`
The equivalent `bunfig.toml` option is to add a key in [`install.scopes`](/runtime/bunfig#install-registry):
@@ -110,136 +109,3 @@ The equivalent `bunfig.toml` option is [`install.exact`](/runtime/bunfig#install
[install]
exact = true
```
### `ignore-scripts`: Skip lifecycle scripts
Prevents running lifecycle scripts during installation:
```ini .npmrc icon="npm"
ignore-scripts=true
```
This is equivalent to using the `--ignore-scripts` flag with `bun install`.
### `dry-run`: Preview changes without installing
Shows what would be installed without actually installing:
```ini .npmrc icon="npm"
dry-run=true
```
The equivalent `bunfig.toml` option is [`install.dryRun`](/runtime/bunfig#install-dryrun):
```toml bunfig.toml icon="settings"
[install]
dryRun = true
```
### `cache`: Configure cache directory
Set the cache directory path, or disable caching:
```ini .npmrc icon="npm"
# set a custom cache directory
cache=/path/to/cache
# or disable caching
cache=false
```
The equivalent `bunfig.toml` option is [`install.cache`](/runtime/bunfig#install-cache):
```toml bunfig.toml icon="settings"
[install.cache]
# set a custom cache directory
dir = "/path/to/cache"
# or disable caching
disable = true
```
### `ca` and `cafile`: Configure CA certificates
Configure custom CA certificates for registry connections:
```ini .npmrc icon="npm"
# single CA certificate
ca="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
# multiple CA certificates
ca[]="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
ca[]="-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
# or specify a path to a CA file
cafile=/path/to/ca-bundle.crt
```
### `omit` and `include`: Control dependency types
Control which dependency types are installed:
```ini .npmrc icon="npm"
# omit dev dependencies
omit=dev
# omit multiple types
omit[]=dev
omit[]=optional
# include specific types (overrides omit)
include=dev
```
Valid values: `dev`, `peer`, `optional`
### `install-strategy` and `node-linker`: Installation strategy
Control how packages are installed in `node_modules`. Bun supports two different configuration options for compatibility with different package managers.
**npm's `install-strategy`:**
```ini .npmrc icon="npm"
# flat node_modules structure (default)
install-strategy=hoisted
# symlinked structure
install-strategy=linked
```
**pnpm/yarn's `node-linker`:**
The `node-linker` option controls the installation mode. Bun supports values from both pnpm and yarn:
| Value | Description | Accepted by |
| -------------- | ----------------------------------------------- | ----------- |
| `isolated` | Symlinked structure with isolated dependencies | pnpm |
| `hoisted` | Flat node_modules structure | pnpm |
| `pnpm` | Symlinked structure (same as `isolated`) | yarn |
| `node-modules` | Flat node_modules structure (same as `hoisted`) | yarn |
```ini .npmrc icon="npm"
# symlinked/isolated mode
node-linker=isolated
node-linker=pnpm
# flat/hoisted mode
node-linker=hoisted
node-linker=node-modules
```
### `public-hoist-pattern` and `hoist-pattern`: Control hoisting
Control which packages are hoisted to the root `node_modules`:
```ini .npmrc icon="npm"
# packages matching this pattern will be hoisted to the root
public-hoist-pattern=*eslint*
# multiple patterns
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
# control general hoisting behavior
hoist-pattern=*
```

View File

@@ -227,26 +227,6 @@ bun --cpu-prof script.js
This generates a `.cpuprofile` file you can open in Chrome DevTools (Performance tab → Load profile) or VS Code's CPU profiler.
### Markdown output
Use `--cpu-prof-md` to generate a markdown CPU profile, which is grep-friendly and designed for LLM analysis:
```sh terminal icon="terminal"
bun --cpu-prof-md script.js
```
Both `--cpu-prof` and `--cpu-prof-md` can be used together to generate both formats at once:
```sh terminal icon="terminal"
bun --cpu-prof --cpu-prof-md script.js
```
You can also trigger profiling via the `BUN_OPTIONS` environment variable:
```sh terminal icon="terminal"
BUN_OPTIONS="--cpu-prof-md" bun script.js
```
### Options
```sh terminal icon="terminal"
@@ -254,43 +234,8 @@ bun --cpu-prof --cpu-prof-name my-profile.cpuprofile script.js
bun --cpu-prof --cpu-prof-dir ./profiles script.js
```
| Flag | Description |
| ---------------------------- | ----------------------------------------------------------- |
| `--cpu-prof` | Generate a `.cpuprofile` JSON file (Chrome DevTools format) |
| `--cpu-prof-md` | Generate a markdown CPU profile (grep/LLM-friendly) |
| `--cpu-prof-name <filename>` | Set output filename |
| `--cpu-prof-dir <dir>` | Set output directory |
## Heap profiling
Generate heap snapshots on exit to analyze memory usage and find memory leaks.
```sh terminal icon="terminal"
bun --heap-prof script.js
```
This generates a V8 `.heapsnapshot` file that can be loaded in Chrome DevTools (Memory tab → Load).
### Markdown output
Use `--heap-prof-md` to generate a markdown heap profile for CLI analysis:
```sh terminal icon="terminal"
bun --heap-prof-md script.js
```
<Note>If both `--heap-prof` and `--heap-prof-md` are specified, the markdown format is used.</Note>
### Options
```sh terminal icon="terminal"
bun --heap-prof --heap-prof-name my-snapshot.heapsnapshot script.js
bun --heap-prof --heap-prof-dir ./profiles script.js
```
| Flag | Description |
| ----------------------------- | ------------------------------------------ |
| `--heap-prof` | Generate a V8 `.heapsnapshot` file on exit |
| `--heap-prof-md` | Generate a markdown heap profile on exit |
| `--heap-prof-name <filename>` | Set output filename |
| `--heap-prof-dir <dir>` | Set output directory |
| Flag | Description |
| ---------------------------- | -------------------- |
| `--cpu-prof` | Enable profiling |
| `--cpu-prof-name <filename>` | Set output filename |
| `--cpu-prof-dir <dir>` | Set output directory |

View File

@@ -14,7 +14,7 @@ It is strongly recommended to use [PowerShell 7 (`pwsh.exe`)](https://learn.micr
By default, running unverified scripts are blocked.
```ps1
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
```
### System Dependencies
@@ -22,7 +22,7 @@ Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
Bun v1.1 or later. We use Bun to run it's own code generators.
```ps1
irm bun.sh/install.ps1 | iex
> irm bun.sh/install.ps1 | iex
```
[Visual Studio](https://visualstudio.microsoft.com) with the "Desktop Development with C++" workload. While installing, make sure to install Git as well, if Git for Windows is not already installed.
@@ -30,12 +30,12 @@ irm bun.sh/install.ps1 | iex
Visual Studio can be installed graphically using the wizard or through WinGet:
```ps1
winget install "Visual Studio Community 2022" --override "--add Microsoft.VisualStudio.Workload.NativeDesktop Microsoft.VisualStudio.Component.Git " -s msstore
> winget install "Visual Studio Community 2022" --override "--add Microsoft.VisualStudio.Workload.NativeDesktop Microsoft.VisualStudio.Component.Git " -s msstore
```
After Visual Studio, you need the following:
- LLVM (19.1.7 for x64, 21.1.8 for ARM64)
- LLVM 19.1.7
- Go
- Rust
- NASM
@@ -47,19 +47,11 @@ After Visual Studio, you need the following:
[Scoop](https://scoop.sh) can be used to install these remaining tools easily.
```ps1 Scoop (x64)
irm https://get.scoop.sh | iex
scoop install nodejs-lts go rust nasm ruby perl ccache
```ps1 Scoop
> irm https://get.scoop.sh | iex
> scoop install nodejs-lts go rust nasm ruby perl ccache
# scoop seems to be buggy if you install llvm and the rest at the same time
scoop install llvm@19.1.7
```
For Windows ARM64, download LLVM 21.1.8 directly from GitHub releases (first version with ARM64 Windows builds):
```ps1 ARM64
# Download and install LLVM for ARM64
Invoke-WebRequest -Uri "https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.8/LLVM-21.1.8-woa64.exe" -OutFile "$env:TEMP\LLVM-21.1.8-woa64.exe"
Start-Process -FilePath "$env:TEMP\LLVM-21.1.8-woa64.exe" -ArgumentList "/S" -Wait
> scoop install llvm@19.1.7
```
<Note>
@@ -68,24 +60,22 @@ Start-Process -FilePath "$env:TEMP\LLVM-21.1.8-woa64.exe" -ArgumentList "/S" -Wa
will conflict with MSVC and break the build.
</Note>
If you intend on building WebKit locally (optional, x64 only), you should install these packages:
If you intend on building WebKit locally (optional), you should install these packages:
```ps1 Scoop
scoop install make cygwin python
> scoop install make cygwin python
```
<Note>Cygwin is not required for ARM64 builds as WebKit is provided as a pre-built binary.</Note>
From here on out, it is **expected you use a PowerShell Terminal with `.\scripts\vs-shell.ps1` sourced**. This script is available in the Bun repository and can be loaded by executing it:
```ps1
.\scripts\vs-shell.ps1
> .\scripts\vs-shell.ps1
```
To verify, you can check for an MSVC-only command line such as `mt.exe`
```ps1
Get-Command mt
> Get-Command mt
```
<Note>
@@ -96,16 +86,16 @@ Get-Command mt
## Building
```ps1
bun run build
> bun run build
# after the initial `bun run build` you can use the following to build
ninja -Cbuild/debug
> ninja -Cbuild/debug
```
If this was successful, you should have a `bun-debug.exe` in the `build/debug` folder.
```ps1
.\build\debug\bun-debug.exe --revision
> .\build\debug\bun-debug.exe --revision
```
You should add this to `$Env:PATH`. The simplest way to do so is to open the start menu, type "Path", and then navigate the environment variables menu to add `C:\.....\bun\build\debug` to the user environment variable `PATH`. You should then restart your editor (if it does not update still, log out and log back in).
@@ -121,15 +111,15 @@ You can run the test suite either using `bun test <path>` or by using the wrappe
```ps1
# Setup
bun i --cwd packages\bun-internal-test
> bun i --cwd packages\bun-internal-test
# Run the entire test suite with reporter
# the package.json script "test" uses "build/debug/bun-debug.exe" by default
bun run test
> bun run test
# Run an individual test file:
bun-debug test node\fs
bun-debug test "C:\bun\test\js\bun\resolve\import-meta.test.js"
> bun-debug test node\fs
> bun-debug test "C:\bun\test\js\bun\resolve\import-meta.test.js"
```
## Troubleshooting

View File

@@ -28,23 +28,23 @@ Using your system's package manager, install Bun's dependencies:
<CodeGroup>
```bash macOS (Homebrew)
brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby
$ brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby
```
```bash Ubuntu/Debian
sudo apt install curl wget lsb-release software-properties-common cargo cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
$ sudo apt install curl wget lsb-release software-properties-common cargo cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
```
```bash Arch
sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
$ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
```
```bash Fedora
sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
$ sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
```
```bash openSUSE Tumbleweed
sudo zypper install go cmake ninja automake git icu rustup && rustup toolchain install stable
$ sudo zypper install go cmake ninja automake git icu rustup && rustup toolchain install stable
```
</CodeGroup>
@@ -56,16 +56,16 @@ Before starting, you will need to already have a release build of Bun installed,
<CodeGroup>
```bash Native
curl -fsSL https://bun.com/install | bash
$ curl -fsSL https://bun.com/install | bash
```
```bash npm
npm install -g bun
$ npm install -g bun
```
```bash Homebrew
brew tap oven-sh/bun
brew install bun
$ brew tap oven-sh/bun
$ brew install bun
```
</CodeGroup>
@@ -76,19 +76,19 @@ ccache is used to cache compilation artifacts, significantly speeding up builds:
```bash
# For macOS
brew install ccache
$ brew install ccache
# For Ubuntu/Debian
sudo apt install ccache
$ sudo apt install ccache
# For Arch
sudo pacman -S ccache
$ sudo pacman -S ccache
# For Fedora
sudo dnf install ccache
$ sudo dnf install ccache
# For openSUSE
sudo zypper install ccache
$ sudo zypper install ccache
```
Our build scripts will automatically detect and use `ccache` if available. You can check cache statistics with `ccache --show-stats`.
@@ -100,24 +100,24 @@ Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to m
<CodeGroup>
```bash macOS (Homebrew)
brew install llvm@19
$ brew install llvm@19
```
```bash Ubuntu/Debian
# LLVM has an automatic installation script that is compatible with all versions of Ubuntu
wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 19 all
$ # LLVM has an automatic installation script that is compatible with all versions of Ubuntu
$ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 19 all
```
```bash Arch
sudo pacman -S llvm clang lld
$ sudo pacman -S llvm clang lld
```
```bash Fedora
sudo dnf install llvm clang lld-devel
$ sudo dnf install llvm clang lld-devel
```
```bash openSUSE Tumbleweed
sudo zypper install clang19 lld19 llvm19
$ sudo zypper install clang19 lld19 llvm19
```
</CodeGroup>
@@ -127,7 +127,7 @@ If none of the above solutions apply, you will have to install it [manually](htt
Make sure Clang/LLVM 19 is in your path:
```bash
which clang-19
$ which clang-19
```
If not, run this to manually add it:
@@ -137,12 +137,12 @@ If not, run this to manually add it:
```bash macOS (Homebrew)
# use fish_add_path if you're using fish
# use path+="$(brew --prefix llvm@19)/bin" if you are using zsh
export PATH="$(brew --prefix llvm@19)/bin:$PATH"
$ export PATH="$(brew --prefix llvm@19)/bin:$PATH"
```
```bash Arch
# use fish_add_path if you're using fish
export PATH="$PATH:/usr/lib/llvm19/bin"
$ export PATH="$PATH:/usr/lib/llvm19/bin"
```
</CodeGroup>
@@ -162,7 +162,7 @@ bun run build
The binary will be located at `./build/debug/bun-debug`. It is recommended to add this to your `$PATH`. To verify the build worked, let's print the version number on the development build of Bun.
```bash
build/debug/bun-debug --version
$ build/debug/bun-debug --version
x.y.z_debug
```
@@ -261,18 +261,23 @@ WebKit is not cloned by default (to save time and disk space). To clone and buil
```bash
# Clone WebKit into ./vendor/WebKit
git clone https://github.com/oven-sh/WebKit vendor/WebKit
$ git clone https://github.com/oven-sh/WebKit vendor/WebKit
# Check out the commit hash specified in `set(WEBKIT_VERSION <commit_hash>)` in cmake/tools/SetupWebKit.cmake
git -C vendor/WebKit checkout <commit_hash>
$ git -C vendor/WebKit checkout <commit_hash>
# Build bun with the local JSC build — this automatically configures and builds JSC
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
# Optionally, you can use `bun run jsc:build` for a release build
bun run jsc:build:debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
# After an initial run of `make jsc-debug`, you can rebuild JSC with:
$ cmake --build vendor/WebKit/WebKitBuild/Debug --target jsc && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
# Build bun with the local JSC build
bun run build:local
```
`bun run build:local` handles everything: configuring JSC, building JSC, and building Bun. On subsequent runs, JSC will incrementally rebuild if any WebKit sources changed. `ninja -Cbuild/debug-local` also works after the first build, and will build Bun+JSC.
The build output goes to `./build/debug-local` (instead of `./build/debug`), so you'll need to update a couple of places:
Using `bun run build:local` will build Bun in the `./build/debug-local` directory (instead of `./build/debug`), you'll have to change a couple of places to use this new directory:
- The first line in `src/js/builtins.d.ts`
- The `CompilationDatabase` line in `.clangd` config should be `CompilationDatabase: build/debug-local`
@@ -283,7 +288,7 @@ Note that the WebKit folder, including build artifacts, is 8GB+ in size.
If you are using a JSC debug build and using VScode, make sure to run the `C/C++: Select a Configuration` command to configure intellisense to find the debug headers.
Note that if you make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change `SetupWebKit.cmake` to point to the commit hash.
Note that if you change make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change `SetupWebKit.cmake` to point to the commit hash.
## Troubleshooting
@@ -317,20 +322,20 @@ is not able to compile a simple test program.
To fix the error, we need to update the GCC version to 11. To do this, we'll need to check if the latest version is available in the distribution's official repositories or use a third-party repository that provides GCC 11 packages. Here are general steps:
```bash
sudo apt update
sudo apt install gcc-11 g++-11
$ sudo apt update
$ sudo apt install gcc-11 g++-11
# If the above command fails with `Unable to locate package gcc-11` we need
# to add the APT repository
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
$ sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# Now run `apt install` again
sudo apt install gcc-11 g++-11
$ sudo apt install gcc-11 g++-11
```
Now, we need to set GCC 11 as the default compiler:
```bash
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100
```
### libarchive
@@ -338,7 +343,7 @@ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 100
If you see an error on macOS when compiling `libarchive`, run:
```bash
brew install pkg-config
$ brew install pkg-config
```
### macOS `library not found for -lSystem`
@@ -346,7 +351,7 @@ brew install pkg-config
If you see this error when compiling, run:
```bash
xcode-select --install
$ xcode-select --install
```
### Cannot find `libatomic.a`

View File

@@ -1,452 +0,0 @@
---
title: Archive
description: Create and extract tar archives with Bun's fast native implementation
---
Bun provides a fast, native implementation for working with tar archives through `Bun.Archive`. It supports creating archives from in-memory data, extracting archives to disk, and reading archive contents without extraction.
## Quickstart
**Create an archive from files:**
```ts
const archive = new Bun.Archive({
"hello.txt": "Hello, World!",
"data.json": JSON.stringify({ foo: "bar" }),
"nested/file.txt": "Nested content",
});
// Write to disk
await Bun.write("bundle.tar", archive);
```
**Extract an archive:**
```ts
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
const entryCount = await archive.extract("./output");
console.log(`Extracted ${entryCount} entries`);
```
**Read archive contents without extracting:**
```ts
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
const files = await archive.files();
for (const [path, file] of files) {
console.log(`${path}: ${await file.text()}`);
}
```
## Creating Archives
Use `new Bun.Archive()` to create an archive from an object where keys are file paths and values are file contents. By default, archives are uncompressed:
```ts
// Creates an uncompressed tar archive (default)
const archive = new Bun.Archive({
"README.md": "# My Project",
"src/index.ts": "console.log('Hello');",
"package.json": JSON.stringify({ name: "my-project" }),
});
```
File contents can be:
- **Strings** - Text content
- **Blobs** - Binary data
- **ArrayBufferViews** (e.g., `Uint8Array`) - Raw bytes
- **ArrayBuffers** - Raw binary data
```ts
const data = "binary data";
const arrayBuffer = new ArrayBuffer(8);
const archive = new Bun.Archive({
"text.txt": "Plain text",
"blob.bin": new Blob([data]),
"bytes.bin": new Uint8Array([1, 2, 3, 4]),
"buffer.bin": arrayBuffer,
});
```
### Writing Archives to Disk
Use `Bun.write()` to write an archive to disk:
```ts
// Write uncompressed tar (default)
const archive = new Bun.Archive({
"file1.txt": "content1",
"file2.txt": "content2",
});
await Bun.write("output.tar", archive);
// Write gzipped tar
const compressed = new Bun.Archive({ "src/index.ts": "console.log('Hello');" }, { compress: "gzip" });
await Bun.write("output.tar.gz", compressed);
```
### Getting Archive Bytes
Get the archive data as bytes or a Blob:
```ts
const archive = new Bun.Archive({ "hello.txt": "Hello, World!" });
// As Uint8Array
const bytes = await archive.bytes();
// As Blob
const blob = await archive.blob();
// With gzip compression (set at construction)
const gzipped = new Bun.Archive({ "hello.txt": "Hello, World!" }, { compress: "gzip" });
const gzippedBytes = await gzipped.bytes();
const gzippedBlob = await gzipped.blob();
```
## Extracting Archives
### From Existing Archive Data
Create an archive from existing tar/tar.gz data:
```ts
// From a file
const tarball = await Bun.file("package.tar.gz").bytes();
const archiveFromFile = new Bun.Archive(tarball);
```
```ts
// From a fetch response
const response = await fetch("https://example.com/archive.tar.gz");
const archiveFromFetch = new Bun.Archive(await response.blob());
```
### Extracting to Disk
Use `.extract()` to write all files to a directory:
```ts
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
const count = await archive.extract("./extracted");
console.log(`Extracted ${count} entries`);
```
The target directory is created automatically if it doesn't exist. Existing files are overwritten. The returned count includes files, directories, and symlinks (on POSIX systems).
**Note**: On Windows, symbolic links in archives are always skipped during extraction. Bun does not attempt to create them regardless of privilege level. On Linux and macOS, symlinks are extracted normally.
**Security note**: Bun.Archive validates paths during extraction, rejecting absolute paths (POSIX `/`, Windows drive letters like `C:\` or `C:/`, and UNC paths like `\\server\share`). Path traversal components (`..`) are normalized away (e.g., `dir/sub/../file` becomes `dir/file`) to prevent directory escape attacks.
### Filtering Extracted Files
Use glob patterns to extract only specific files. Patterns are matched against archive entry paths normalized to use forward slashes (`/`). Positive patterns specify what to include, and negative patterns (prefixed with `!`) specify what to exclude. Negative patterns are applied after positive patterns, so **using only negative patterns will match nothing** (you must include a positive pattern like `**` first):
```ts
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
// Extract only TypeScript files
const tsCount = await archive.extract("./extracted", { glob: "**/*.ts" });
// Extract files from multiple directories
const multiCount = await archive.extract("./extracted", {
glob: ["src/**", "lib/**"],
});
```
Use negative patterns (prefixed with `!`) to exclude files. When mixing positive and negative patterns, entries must match at least one positive pattern and not match any negative pattern:
```ts
// Extract everything except node_modules
const distCount = await archive.extract("./extracted", {
glob: ["**", "!node_modules/**"],
});
// Extract source files but exclude tests
const srcCount = await archive.extract("./extracted", {
glob: ["src/**", "!**/*.test.ts", "!**/__tests__/**"],
});
```
## Reading Archive Contents
### Get All Files
Use `.files()` to get archive contents as a `Map` of `File` objects without extracting to disk. Unlike `extract()` which processes all entry types, `files()` returns only regular files (no directories):
```ts
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
const files = await archive.files();
for (const [path, file] of files) {
console.log(`${path}: ${file.size} bytes`);
console.log(await file.text());
}
```
Each `File` object includes:
- `name` - The file path within the archive (always uses forward slashes `/` as separators)
- `size` - File size in bytes
- `lastModified` - Modification timestamp
- Standard `Blob` methods: `text()`, `arrayBuffer()`, `stream()`, etc.
**Note**: `files()` loads file contents into memory. For large archives, consider using `extract()` to write directly to disk instead.
### Error Handling
Archive operations can fail due to corrupted data, I/O errors, or invalid paths. Use try/catch to handle these cases:
```ts
try {
const tarball = await Bun.file("package.tar.gz").bytes();
const archive = new Bun.Archive(tarball);
const count = await archive.extract("./output");
console.log(`Extracted ${count} entries`);
} catch (e: unknown) {
if (e instanceof Error) {
const error = e as Error & { code?: string };
if (error.code === "EACCES") {
console.error("Permission denied");
} else if (error.code === "ENOSPC") {
console.error("Disk full");
} else {
console.error("Archive error:", error.message);
}
} else {
console.error("Archive error:", String(e));
}
}
```
Common error scenarios:
- **Corrupted/truncated archives** - `new Archive()` loads the archive data; errors may be deferred until read/extract operations
- **Permission denied** - `extract()` throws if the target directory is not writable
- **Disk full** - `extract()` throws if there's insufficient space
- **Invalid paths** - Operations throw for malformed file paths
The count returned by `extract()` includes all successfully written entries (files, directories, and symlinks on POSIX systems).
**Security note**: Bun.Archive automatically validates paths during extraction. Absolute paths (POSIX `/`, Windows drive letters, UNC paths) and unsafe symlink targets are rejected. Path traversal components (`..`) are normalized away to prevent directory escape.
For additional security with untrusted archives, you can enumerate and validate paths before extraction:
```ts
const archive = new Bun.Archive(untrustedData);
const files = await archive.files();
// Optional: Custom validation for additional checks
for (const [path] of files) {
// Example: Reject hidden files
if (path.startsWith(".") || path.includes("/.")) {
throw new Error(`Hidden file rejected: ${path}`);
}
// Example: Whitelist specific directories
if (!path.startsWith("src/") && !path.startsWith("lib/")) {
throw new Error(`Unexpected path: ${path}`);
}
}
// Extract to a controlled destination
await archive.extract("./safe-output");
```
When using `files()` with a glob pattern, an empty `Map` is returned if no files match:
```ts
const matches = await archive.files("*.nonexistent");
if (matches.size === 0) {
console.log("No matching files found");
}
```
### Filtering with Glob Patterns
Pass a glob pattern to filter which files are returned:
```ts
// Get only TypeScript files
const tsFiles = await archive.files("**/*.ts");
// Get files in src directory
const srcFiles = await archive.files("src/*");
// Get all JSON files (recursive)
const jsonFiles = await archive.files("**/*.json");
// Get multiple file types with array of patterns
const codeFiles = await archive.files(["**/*.ts", "**/*.js"]);
```
Supported glob patterns (subset of [Bun.Glob](/docs/api/glob) syntax):
- `*` - Match any characters except `/`
- `**` - Match any characters including `/`
- `?` - Match single character
- `[abc]` - Match character set
- `{a,b}` - Match alternatives
- `!pattern` - Exclude files matching pattern (negation). Must be combined with positive patterns; using only negative patterns matches nothing.
See [Bun.Glob](/docs/api/glob) for the full glob syntax including escaping and advanced patterns.
## Compression
Bun.Archive creates uncompressed tar archives by default. Use `{ compress: "gzip" }` to enable gzip compression:
```ts
// Default: uncompressed tar
const archive = new Bun.Archive({ "hello.txt": "Hello, World!" });
// Reading: automatically detects gzip
const gzippedTarball = await Bun.file("archive.tar.gz").bytes();
const readArchive = new Bun.Archive(gzippedTarball);
// Enable gzip compression
const compressed = new Bun.Archive({ "hello.txt": "Hello, World!" }, { compress: "gzip" });
// Gzip with custom level (1-12)
const maxCompression = new Bun.Archive({ "hello.txt": "Hello, World!" }, { compress: "gzip", level: 12 });
```
The options accept:
- No options or `undefined` - Uncompressed tar (default)
- `{ compress: "gzip" }` - Enable gzip compression at level 6
- `{ compress: "gzip", level: number }` - Gzip with custom level 1-12 (1 = fastest, 12 = smallest)
## Examples
### Bundle Project Files
```ts
import { Glob } from "bun";
// Collect source files
const files: Record<string, string> = {};
const glob = new Glob("src/**/*.ts");
for await (const path of glob.scan(".")) {
// Normalize path separators to forward slashes for cross-platform compatibility
const archivePath = path.replaceAll("\\", "/");
files[archivePath] = await Bun.file(path).text();
}
// Add package.json
files["package.json"] = await Bun.file("package.json").text();
// Create compressed archive and write to disk
const archive = new Bun.Archive(files, { compress: "gzip" });
await Bun.write("bundle.tar.gz", archive);
```
### Extract and Process npm Package
```ts
const response = await fetch("https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz");
const archive = new Bun.Archive(await response.blob());
// Get package.json
const files = await archive.files("package/package.json");
const packageJson = files.get("package/package.json");
if (packageJson) {
const pkg = JSON.parse(await packageJson.text());
console.log(`Package: ${pkg.name}@${pkg.version}`);
}
```
### Create Archive from Directory
```ts
import { readdir } from "node:fs/promises";
import { join } from "node:path";
async function archiveDirectory(dir: string, compress = false): Promise<Bun.Archive> {
const files: Record<string, Blob> = {};
async function walk(currentDir: string, prefix: string = "") {
const entries = await readdir(currentDir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = join(currentDir, entry.name);
const archivePath = prefix ? `${prefix}/${entry.name}` : entry.name;
if (entry.isDirectory()) {
await walk(fullPath, archivePath);
} else {
files[archivePath] = Bun.file(fullPath);
}
}
}
await walk(dir);
return new Bun.Archive(files, compress ? { compress: "gzip" } : undefined);
}
const archive = await archiveDirectory("./my-project", true);
await Bun.write("my-project.tar.gz", archive);
```
## Reference
> **Note**: The following type signatures are simplified for documentation purposes. See [`packages/bun-types/bun.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts) for the full type definitions.
```ts
type ArchiveInput =
| Record<string, string | Blob | Bun.ArrayBufferView | ArrayBufferLike>
| Blob
| Bun.ArrayBufferView
| ArrayBufferLike;
type ArchiveOptions = {
/** Compression algorithm. Currently only "gzip" is supported. */
compress?: "gzip";
/** Compression level 1-12 (default 6 when gzip is enabled). */
level?: number;
};
interface ArchiveExtractOptions {
/** Glob pattern(s) to filter extraction. Supports negative patterns with "!" prefix. */
glob?: string | readonly string[];
}
class Archive {
/**
* Create an Archive from input data
* @param data - Files to archive (as object) or existing archive data (as bytes/blob)
* @param options - Compression options. Uncompressed by default.
* Pass { compress: "gzip" } to enable compression.
*/
constructor(data: ArchiveInput, options?: ArchiveOptions);
/**
* Extract archive to a directory
* @returns Number of entries extracted (files, directories, and symlinks)
*/
extract(path: string, options?: ArchiveExtractOptions): Promise<number>;
/**
* Get archive as a Blob (uses compression setting from constructor)
*/
blob(): Promise<Blob>;
/**
* Get archive as a Uint8Array (uses compression setting from constructor)
*/
bytes(): Promise<Uint8Array<ArrayBuffer>>;
/**
* Get archive contents as File objects (regular files only, no directories)
*/
files(glob?: string | readonly string[]): Promise<Map<string, File>>;
}
```

View File

@@ -55,5 +55,5 @@ Click the link in the right column to jump to the associated documentation.
| Stream Processing | [`Bun.readableStreamTo*()`](/runtime/utils#bun-readablestreamto), `Bun.readableStreamToBytes()`, `Bun.readableStreamToBlob()`, `Bun.readableStreamToFormData()`, `Bun.readableStreamToJSON()`, `Bun.readableStreamToArray()` |
| Memory & Buffer Management | `Bun.ArrayBufferSink`, `Bun.allocUnsafe`, `Bun.concatArrayBuffers` |
| Module Resolution | [`Bun.resolveSync()`](/runtime/utils#bun-resolvesync) |
| Parsing & Formatting | [`Bun.semver`](/runtime/semver), `Bun.TOML.parse`, [`Bun.markdown`](/runtime/markdown), [`Bun.color`](/runtime/color) |
| Parsing & Formatting | [`Bun.semver`](/runtime/semver), `Bun.TOML.parse`, [`Bun.color`](/runtime/color) |
| Low-level / Internals | `Bun.mmap`, `Bun.gc`, `Bun.generateHeapSnapshot`, [`bun:jsc`](https://bun.com/reference/bun/jsc) |

View File

@@ -358,8 +358,6 @@ Bun represents [pointers](<https://en.wikipedia.org/wiki/Pointer_(computer_progr
**Why not `BigInt`?** `BigInt` is slower. JavaScript engines allocate a separate `BigInt` which means they can't fit into a regular JavaScript value. If you pass a `BigInt` to a function, it will be converted to a `number`
**Windows Note**: The Windows API type HANDLE does not represent a virtual address, and using `ptr` for it will _not_ work as expected. Use `u64` to safely represent HANDLE values.
</Accordion>
To convert from a `TypedArray` to a pointer:

View File

@@ -5,7 +5,7 @@ description: "File types and loaders supported by Bun's bundler and runtime"
The Bun bundler implements a set of default loaders out of the box. As a rule of thumb, the bundler and the runtime both support the same set of file types out of the box.
`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.css` `.json` `.jsonc` `.json5` `.toml` `.yaml` `.yml` `.txt` `.wasm` `.node` `.html` `.sh`
`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.css` `.json` `.jsonc` `.toml` `.yaml` `.yml` `.txt` `.wasm` `.node` `.html` `.sh`
Bun uses the file extension to determine which built-in _loader_ should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](/bundler/plugins) that extend Bun with custom loaders.
@@ -197,53 +197,6 @@ export default {
</CodeGroup>
### `json5`
**JSON5 loader**. Default for `.json5`.
JSON5 files can be directly imported. Bun will parse them with its fast native JSON5 parser. JSON5 is a superset of JSON that supports comments, trailing commas, unquoted keys, single-quoted strings, and more.
```ts
import config from "./config.json5";
console.log(config);
// via import attribute:
import data from "./data.txt" with { type: "json5" };
```
During bundling, the parsed JSON5 is inlined into the bundle as a JavaScript object.
```ts
var config = {
name: "my-app",
version: "1.0.0",
// ...other fields
};
```
If a `.json5` file is passed as an entrypoint, it will be converted to a `.js` module that `export default`s the parsed object.
<CodeGroup>
```json5 Input
{
// Configuration
name: "John Doe",
age: 35,
email: "johndoe@example.com",
}
```
```ts Output
export default {
name: "John Doe",
age: 35,
email: "johndoe@example.com",
};
```
</CodeGroup>
### `text`
**Text loader**. Default for `.txt`.

View File

@@ -1,271 +0,0 @@
---
title: JSON5
description: Use Bun's built-in support for JSON5 files through both runtime APIs and bundler integration
---
In Bun, JSON5 is a first-class citizen alongside JSON, TOML, and YAML. You can:
- Parse and stringify JSON5 with `Bun.JSON5.parse` and `Bun.JSON5.stringify`
- `import` & `require` JSON5 files as modules at runtime (including hot reloading & watch mode support)
- `import` & `require` JSON5 files in frontend apps via Bun's bundler
---
## Conformance
Bun's JSON5 parser passes 100% of the [official JSON5 test suite](https://github.com/json5/json5-tests). The parser is written in Zig for optimal performance. You can view our [translated test suite](https://github.com/oven-sh/bun/blob/main/test/js/bun/json5/json5-test-suite.test.ts) to see every test case.
---
## Runtime API
### `Bun.JSON5.parse()`
Parse a JSON5 string into a JavaScript value.
```ts
import { JSON5 } from "bun";
const data = JSON5.parse(`{
// JSON5 supports comments
name: 'my-app',
version: '1.0.0',
debug: true,
// trailing commas are allowed
tags: ['web', 'api',],
}`);
console.log(data);
// {
// name: "my-app",
// version: "1.0.0",
// debug: true,
// tags: ["web", "api"]
// }
```
#### Supported JSON5 Features
JSON5 is a superset of JSON based on ECMAScript 5.1 syntax. It supports:
- **Comments**: single-line (`//`) and multi-line (`/* */`)
- **Trailing commas**: in objects and arrays
- **Unquoted keys**: valid ECMAScript 5.1 identifiers can be used as keys
- **Single-quoted strings**: in addition to double-quoted strings
- **Multi-line strings**: using backslash line continuations
- **Hex numbers**: `0xFF`
- **Leading & trailing decimal points**: `.5` and `5.`
- **Infinity and NaN**: positive and negative
- **Explicit plus sign**: `+42`
```ts
const data = JSON5.parse(`{
// Unquoted keys
unquoted: 'keys work',
// Single and double quotes
single: 'single-quoted',
double: "double-quoted",
// Trailing commas
trailing: 'comma',
// Special numbers
hex: 0xDEADbeef,
half: .5,
to: Infinity,
nan: NaN,
// Multi-line strings
multiline: 'line 1 \
line 2',
}`);
```
#### Error Handling
`Bun.JSON5.parse()` throws a `SyntaxError` if the input is invalid JSON5:
```ts
try {
JSON5.parse("{invalid}");
} catch (error) {
console.error("Failed to parse JSON5:", error.message);
}
```
### `Bun.JSON5.stringify()`
Stringify a JavaScript value to a JSON5 string.
```ts
import { JSON5 } from "bun";
const str = JSON5.stringify({ name: "my-app", version: "1.0.0" });
console.log(str);
// {name:'my-app',version:'1.0.0'}
```
#### Pretty Printing
Pass a `space` argument to format the output with indentation:
```ts
const pretty = JSON5.stringify(
{
name: "my-app",
debug: true,
tags: ["web", "api"],
},
null,
2,
);
console.log(pretty);
// {
// name: 'my-app',
// debug: true,
// tags: [
// 'web',
// 'api',
// ],
// }
```
The `space` argument can be a number (number of spaces) or a string (used as the indent character):
```ts
// Tab indentation
JSON5.stringify(data, null, "\t");
```
#### Special Values
Unlike `JSON.stringify`, `JSON5.stringify` preserves special numeric values:
```ts
JSON5.stringify({ inf: Infinity, ninf: -Infinity, nan: NaN });
// {inf:Infinity,ninf:-Infinity,nan:NaN}
```
---
## Module Import
### ES Modules
You can import JSON5 files directly as ES modules:
```json5 config.json5
{
// Database configuration
database: {
host: "localhost",
port: 5432,
name: "myapp",
},
features: {
auth: true,
rateLimit: true,
analytics: false,
},
}
```
#### Default Import
```ts app.ts icon="/icons/typescript.svg"
import config from "./config.json5";
console.log(config.database.host); // "localhost"
console.log(config.features.auth); // true
```
#### Named Imports
You can destructure top-level properties as named imports:
```ts app.ts icon="/icons/typescript.svg"
import { database, features } from "./config.json5";
console.log(database.host); // "localhost"
console.log(features.rateLimit); // true
```
### CommonJS
JSON5 files can also be required in CommonJS:
```ts app.ts icon="/icons/typescript.svg"
const config = require("./config.json5");
console.log(config.database.name); // "myapp"
// Destructuring also works
const { database, features } = require("./config.json5");
```
---
## Hot Reloading with JSON5
When you run your application with `bun --hot`, changes to JSON5 files are automatically detected and reloaded:
```json5 config.json5
{
server: {
port: 3000,
host: "localhost",
},
features: {
debug: true,
verbose: false,
},
}
```
```ts server.ts icon="/icons/typescript.svg"
import { server, features } from "./config.json5";
Bun.serve({
port: server.port,
hostname: server.host,
fetch(req) {
if (features.verbose) {
console.log(`${req.method} ${req.url}`);
}
return new Response("Hello World");
},
});
```
Run with hot reloading:
```bash terminal icon="terminal"
bun --hot server.ts
```
---
## Bundler Integration
When you import JSON5 files and bundle with Bun, the JSON5 is parsed at build time and included as a JavaScript module:
```bash terminal icon="terminal"
bun build app.ts --outdir=dist
```
This means:
- Zero runtime JSON5 parsing overhead in production
- Smaller bundle sizes
- Tree-shaking support for unused properties (named imports)
### Dynamic Imports
JSON5 files can be dynamically imported:
```ts
const config = await import("./config.json5");
```

View File

@@ -1,188 +0,0 @@
---
title: JSONL
description: Parse newline-delimited JSON (JSONL) with Bun's built-in streaming parser
---
Bun has built-in support for parsing [JSONL](https://jsonlines.org/) (newline-delimited JSON), where each line is a separate JSON value. The parser is implemented in C++ using JavaScriptCore's optimized JSON parser and supports streaming use cases.
```ts
const results = Bun.JSONL.parse('{"name":"Alice"}\n{"name":"Bob"}\n');
// [{ name: "Alice" }, { name: "Bob" }]
```
---
## `Bun.JSONL.parse()`
Parse a complete JSONL input and return an array of all parsed values.
```ts
import { JSONL } from "bun";
const input = '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n{"id":3,"name":"Charlie"}\n';
const records = JSONL.parse(input);
console.log(records);
// [
// { id: 1, name: "Alice" },
// { id: 2, name: "Bob" },
// { id: 3, name: "Charlie" }
// ]
```
Input can be a string or a `Uint8Array`:
```ts
const buffer = new TextEncoder().encode('{"a":1}\n{"b":2}\n');
const results = Bun.JSONL.parse(buffer);
// [{ a: 1 }, { b: 2 }]
```
When passed a `Uint8Array`, a UTF-8 BOM at the start of the buffer is automatically skipped.
### Error handling
If the input contains invalid JSON, `Bun.JSONL.parse()` throws a `SyntaxError`:
```ts
try {
Bun.JSONL.parse('{"valid":true}\n{invalid}\n');
} catch (error) {
console.error(error); // SyntaxError: Failed to parse JSONL
}
```
---
## `Bun.JSONL.parseChunk()`
For streaming scenarios, `parseChunk` parses as many complete values as possible from the input and reports how far it got. This is useful when receiving data incrementally (e.g., from a network stream) and you need to know where to resume parsing.
```ts
const chunk = '{"id":1}\n{"id":2}\n{"id":3';
const result = Bun.JSONL.parseChunk(chunk);
console.log(result.values); // [{ id: 1 }, { id: 2 }]
console.log(result.read); // 17 — characters consumed
console.log(result.done); // false — incomplete value remains
console.log(result.error); // null — no parse error
```
### Return value
`parseChunk` returns an object with four properties:
| Property | Type | Description |
| -------- | --------------------- | ----------------------------------------------------------------------- |
| `values` | `any[]` | Array of successfully parsed JSON values |
| `read` | `number` | Number of bytes (for `Uint8Array`) or characters (for strings) consumed |
| `done` | `boolean` | `true` if the entire input was consumed with no remaining data |
| `error` | `SyntaxError \| null` | Parse error, or `null` if no error occurred |
### Streaming example
Use `read` to slice off consumed input and carry forward the remainder:
```ts
let buffer = "";
async function processStream(stream: ReadableStream<string>) {
for await (const chunk of stream) {
buffer += chunk;
const result = Bun.JSONL.parseChunk(buffer);
for (const value of result.values) {
handleRecord(value);
}
// Keep only the unconsumed portion
buffer = buffer.slice(result.read);
}
// Handle any remaining data
if (buffer.length > 0) {
const final = Bun.JSONL.parseChunk(buffer);
for (const value of final.values) {
handleRecord(value);
}
if (final.error) {
console.error("Parse error in final chunk:", final.error.message);
}
}
}
```
### Byte offsets with `Uint8Array`
When the input is a `Uint8Array`, you can pass optional `start` and `end` byte offsets:
```ts
const buf = new TextEncoder().encode('{"a":1}\n{"b":2}\n{"c":3}\n');
// Parse starting from byte 8
const result = Bun.JSONL.parseChunk(buf, 8);
console.log(result.values); // [{ b: 2 }, { c: 3 }]
console.log(result.read); // 24
// Parse a specific range
const partial = Bun.JSONL.parseChunk(buf, 0, 8);
console.log(partial.values); // [{ a: 1 }]
```
The `read` value is always a byte offset into the original buffer, making it easy to use with `TypedArray.subarray()` for zero-copy streaming:
```ts
let buf = new Uint8Array(0);
async function processBinaryStream(stream: ReadableStream<Uint8Array>) {
for await (const chunk of stream) {
// Append chunk to buffer
const newBuf = new Uint8Array(buf.length + chunk.length);
newBuf.set(buf);
newBuf.set(chunk, buf.length);
buf = newBuf;
const result = Bun.JSONL.parseChunk(buf);
for (const value of result.values) {
handleRecord(value);
}
// Keep unconsumed bytes
buf = buf.slice(result.read);
}
}
```
### Error recovery
Unlike `parse()`, `parseChunk()` does not throw on invalid JSON. Instead, it returns the error in the `error` property, along with any values that were successfully parsed before the error:
```ts
const input = '{"a":1}\n{invalid}\n{"b":2}\n';
const result = Bun.JSONL.parseChunk(input);
console.log(result.values); // [{ a: 1 }] — values parsed before the error
console.log(result.error); // SyntaxError
console.log(result.read); // 7 — position up to last successful parse
```
---
## Supported value types
Each line can be any valid JSON value, not just objects:
```ts
const input = '42\n"hello"\ntrue\nnull\n[1,2,3]\n{"key":"value"}\n';
const values = Bun.JSONL.parse(input);
// [42, "hello", true, null, [1, 2, 3], { key: "value" }]
```
---
## Performance notes
- **ASCII fast path**: Pure ASCII input is parsed directly without copying, using a zero-allocation `StringView`.
- **UTF-8 support**: Non-ASCII `Uint8Array` input is decoded to UTF-16 using SIMD-accelerated conversion.
- **BOM handling**: UTF-8 BOM (`0xEF 0xBB 0xBF`) at the start of a `Uint8Array` is automatically skipped.
- **Pre-built object shape**: The result object from `parseChunk` uses a cached structure for fast property access.

View File

@@ -1,344 +0,0 @@
---
title: Markdown
description: Parse and render Markdown with Bun's built-in Markdown API, supporting GFM extensions and custom rendering callbacks
---
{% callout type="note" %}
**Unstable API** — This API is under active development and may change in future versions of Bun.
{% /callout %}
Bun includes a fast, built-in Markdown parser written in Zig. It supports GitHub Flavored Markdown (GFM) extensions and provides three APIs:
- `Bun.markdown.html()` — render Markdown to an HTML string
- `Bun.markdown.render()` — render Markdown with custom callbacks for each element
- `Bun.markdown.react()` — render Markdown to React JSX elements
---
## `Bun.markdown.html()`
Convert a Markdown string to HTML.
```ts
const html = Bun.markdown.html("# Hello **world**");
// "<h1>Hello <strong>world</strong></h1>\n"
```
GFM extensions like tables, strikethrough, and task lists are enabled by default:
```ts
const html = Bun.markdown.html(`
| Feature | Status |
|-------------|--------|
| Tables | ~~done~~ |
| Strikethrough| ~~done~~ |
| Task lists | done |
`);
```
### Options
Pass an options object as the second argument to configure the parser:
```ts
const html = Bun.markdown.html("some markdown", {
tables: true, // GFM tables (default: true)
strikethrough: true, // GFM strikethrough (default: true)
tasklists: true, // GFM task lists (default: true)
tagFilter: true, // GFM tag filter for disallowed HTML tags
autolinks: true, // Autolink URLs, emails, and www. links
});
```
All available options:
| Option | Default | Description |
| ---------------------- | ------- | ----------------------------------------------------------- |
| `tables` | `false` | GFM tables |
| `strikethrough` | `false` | GFM strikethrough (`~~text~~`) |
| `tasklists` | `false` | GFM task lists (`- [x] item`) |
| `autolinks` | `false` | Enable autolinks — see [Autolinks](#autolinks) |
| `headings` | `false` | Heading IDs and autolinks — see [Heading IDs](#heading-ids) |
| `hardSoftBreaks` | `false` | Treat soft line breaks as hard breaks |
| `wikiLinks` | `false` | Enable `[[wiki links]]` |
| `underline` | `false` | `__text__` renders as `<u>` instead of `<strong>` |
| `latexMath` | `false` | Enable `$inline$` and `$$display$$` math |
| `collapseWhitespace` | `false` | Collapse whitespace in text |
| `permissiveAtxHeaders` | `false` | ATX headers without space after `#` |
| `noIndentedCodeBlocks` | `false` | Disable indented code blocks |
| `noHtmlBlocks` | `false` | Disable HTML blocks |
| `noHtmlSpans` | `false` | Disable inline HTML |
| `tagFilter` | `false` | GFM tag filter for disallowed HTML tags |
#### Autolinks
Pass `true` to enable all autolink types, or an object for granular control:
```ts
// Enable all autolinks (URL, WWW, email)
Bun.markdown.html("Visit www.example.com", { autolinks: true });
// Enable only specific types
Bun.markdown.html("Visit www.example.com", {
autolinks: { url: true, www: true },
});
```
#### Heading IDs
Pass `true` to enable both heading IDs and autolink headings, or an object for granular control:
```ts
// Enable heading IDs and autolink headings
Bun.markdown.html("## Hello World", { headings: true });
// '<h2 id="hello-world"><a href="#hello-world">Hello World</a></h2>\n'
// Enable only heading IDs (no autolink)
Bun.markdown.html("## Hello World", { headings: { ids: true } });
// '<h2 id="hello-world">Hello World</h2>\n'
```
---
## `Bun.markdown.render()`
Parse Markdown and render it using custom JavaScript callbacks. This gives you full control over the output format — you can generate HTML with custom classes, React elements, ANSI terminal output, or any other string format.
```ts
const result = Bun.markdown.render("# Hello **world**", {
heading: (children, { level }) => `<h${level} class="title">${children}</h${level}>`,
strong: children => `<b>${children}</b>`,
paragraph: children => `<p>${children}</p>`,
});
// '<h1 class="title">Hello <b>world</b></h1>'
```
### Callback signature
Each callback receives:
1. **`children`** — the accumulated content of the element as a string
2. **`meta`** (optional) — an object with element-specific metadata
Return a string to replace the element's rendering. Return `null` or `undefined` to omit the element from the output entirely. If no callback is registered for an element, its children pass through unchanged.
### Block callbacks
| Callback | Meta | Description |
| ------------ | ------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `heading` | `{ level: number, id?: string }` | Heading level 16. `id` is set when `headings: { ids: true }` is enabled |
| `paragraph` | — | Paragraph block |
| `blockquote` | — | Blockquote block |
| `code` | `{ language?: string }` | Fenced or indented code block. `language` is the info-string when specified on the fence |
| `list` | `{ ordered: boolean, start?: number }` | Ordered or unordered list. `start` is the start number for ordered lists |
| `listItem` | `{ checked?: boolean }` | List item. `checked` is set for task list items (`- [x]` / `- [ ]`) |
| `hr` | — | Horizontal rule |
| `table` | — | Table block |
| `thead` | — | Table head |
| `tbody` | — | Table body |
| `tr` | — | Table row |
| `th` | `{ align?: "left" \| "center" \| "right" }` | Table header cell. `align` is set when alignment is specified |
| `td` | `{ align?: "left" \| "center" \| "right" }` | Table data cell. `align` is set when alignment is specified |
| `html` | — | Raw HTML content |
### Inline callbacks
| Callback | Meta | Description |
| --------------- | ---------------------------------- | ---------------------------- |
| `strong` | — | Strong emphasis (`**text**`) |
| `emphasis` | — | Emphasis (`*text*`) |
| `link` | `{ href: string, title?: string }` | Link |
| `image` | `{ src: string, title?: string }` | Image |
| `codespan` | — | Inline code (`` `code` ``) |
| `strikethrough` | — | Strikethrough (`~~text~~`) |
| `text` | — | Plain text content |
### Examples
#### Custom HTML with classes
```ts
const html = Bun.markdown.render("# Title\n\nHello **world**", {
heading: (children, { level }) => `<h${level} class="heading heading-${level}">${children}</h${level}>`,
paragraph: children => `<p class="body">${children}</p>`,
strong: children => `<strong class="bold">${children}</strong>`,
});
```
#### Stripping all formatting
```ts
const plaintext = Bun.markdown.render("# Hello **world**", {
heading: children => children,
paragraph: children => children,
strong: children => children,
emphasis: children => children,
link: children => children,
image: () => "",
code: children => children,
codespan: children => children,
});
// "Hello world"
```
#### Omitting elements
Return `null` or `undefined` to remove an element from the output:
```ts
const result = Bun.markdown.render("# Title\n\n![logo](img.png)\n\nHello", {
image: () => null, // Remove all images
heading: children => children,
paragraph: children => children + "\n",
});
// "Title\nHello\n"
```
#### ANSI terminal output
```ts
const ansi = Bun.markdown.render("# Hello\n\nThis is **bold** and *italic*", {
heading: (children, { level }) => `\x1b[1;4m${children}\x1b[0m\n`,
paragraph: children => children + "\n",
strong: children => `\x1b[1m${children}\x1b[22m`,
emphasis: children => `\x1b[3m${children}\x1b[23m`,
});
```
#### Code block syntax highlighting
````ts
const result = Bun.markdown.render("```js\nconsole.log('hi')\n```", {
code: (children, meta) => {
const lang = meta?.language ?? "";
return `<pre><code class="language-${lang}">${children}</code></pre>`;
},
});
````
### Parser options
Parser options are passed as a separate third argument:
```ts
const result = Bun.markdown.render(
"Visit www.example.com",
{
link: (children, { href }) => `[${children}](${href})`,
paragraph: children => children,
},
{ autolinks: true },
);
```
---
## `Bun.markdown.react()`
Render Markdown directly to React elements. Returns a `<Fragment>` that you can use as a component return value.
```tsx
function Markdown({ text }: { text: string }) {
return Bun.markdown.react(text);
}
```
### Server-side rendering
Works with `renderToString()` and React Server Components:
```tsx
import { renderToString } from "react-dom/server";
const html = renderToString(Bun.markdown.react("# Hello **world**"));
// "<h1>Hello <strong>world</strong></h1>"
```
### Component overrides
Replace any HTML element with a custom React component by passing it in the second argument, keyed by tag name:
```tsx
function Code({ language, children }) {
return (
<pre data-language={language}>
<code>{children}</code>
</pre>
);
}
function Link({ href, title, children }) {
return (
<a href={href} title={title} target="_blank" rel="noopener noreferrer">
{children}
</a>
);
}
function Heading({ id, children }) {
return (
<h2 id={id}>
<a href={`#${id}`}>{children}</a>
</h2>
);
}
const el = Bun.markdown.react(
content,
{
pre: Code,
a: Link,
h2: Heading,
},
{ headings: { ids: true } },
);
```
#### Available overrides
Every HTML tag produced by the parser can be overridden:
| Option | Props | Description |
| ------------ | ---------------------------- | --------------------------------------------------------------- |
| `h1``h6` | `{ id?, children }` | Headings. `id` is set when `headings: { ids: true }` is enabled |
| `p` | `{ children }` | Paragraph |
| `blockquote` | `{ children }` | Blockquote |
| `pre` | `{ language?, children }` | Code block. `language` is the info string (e.g. `"js"`) |
| `hr` | `{}` | Horizontal rule (no children) |
| `ul` | `{ children }` | Unordered list |
| `ol` | `{ start, children }` | Ordered list. `start` is the first item number |
| `li` | `{ checked?, children }` | List item. `checked` is set for task list items |
| `table` | `{ children }` | Table |
| `thead` | `{ children }` | Table head |
| `tbody` | `{ children }` | Table body |
| `tr` | `{ children }` | Table row |
| `th` | `{ align?, children }` | Table header cell |
| `td` | `{ align?, children }` | Table data cell |
| `em` | `{ children }` | Emphasis (`*text*`) |
| `strong` | `{ children }` | Strong (`**text**`) |
| `a` | `{ href, title?, children }` | Link |
| `img` | `{ src, alt?, title? }` | Image (no children) |
| `code` | `{ children }` | Inline code |
| `del` | `{ children }` | Strikethrough (`~~text~~`) |
| `br` | `{}` | Hard line break (no children) |
### React 18 and older
By default, elements use `Symbol.for('react.transitional.element')` as the `$$typeof` symbol. For React 18 and older, pass `reactVersion: 18` in the options (third argument):
```tsx
function Markdown({ text }: { text: string }) {
return Bun.markdown.react(text, undefined, { reactVersion: 18 });
}
```
### Parser options
All [parser options](#options) are passed as the third argument:
```tsx
const el = Bun.markdown.react("## Hello World", undefined, {
headings: { ids: true },
autolinks: true,
});
```

View File

@@ -127,54 +127,3 @@ const socket = await Bun.udpSocket({
},
});
```
### Socket options
UDP sockets support setting various socket options:
```ts
const socket = await Bun.udpSocket({});
// Enable broadcasting to send packets to a broadcast address
socket.setBroadcast(true);
// Set the IP TTL (time to live) for outgoing packets
socket.setTTL(64);
```
### Multicast
Bun supports multicast operations for UDP sockets. Use `addMembership` and `dropMembership` to join and leave multicast groups:
```ts
const socket = await Bun.udpSocket({});
// Join a multicast group
socket.addMembership("224.0.0.1");
// Join with a specific interface
socket.addMembership("224.0.0.1", "192.168.1.100");
// Leave a multicast group
socket.dropMembership("224.0.0.1");
```
Additional multicast options:
```ts
// Set TTL for multicast packets (number of network hops)
socket.setMulticastTTL(2);
// Control whether multicast packets loop back to the local socket
socket.setMulticastLoopback(true);
// Specify which interface to use for outgoing multicast packets
socket.setMulticastInterface("192.168.1.100");
```
For source-specific multicast (SSM), use `addSourceSpecificMembership` and `dropSourceSpecificMembership`:
```ts
socket.addSourceSpecificMembership("10.0.0.1", "232.0.0.1");
socket.dropSourceSpecificMembership("10.0.0.1", "232.0.0.1");
```

View File

@@ -165,7 +165,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:inspector`](https://nodejs.org/api/inspector.html)
🟡 Partially implemented. `Profiler` API is supported (`Profiler.enable`, `Profiler.disable`, `Profiler.start`, `Profiler.stop`, `Profiler.setSamplingInterval`). Other inspector APIs are not yet implemented.
🔴 Not implemented.
### [`node:repl`](https://nodejs.org/api/repl.html)

View File

@@ -135,18 +135,6 @@ await s3file.write(JSON.stringify({ name: "John", age: 30 }), {
type: "application/json",
});
// Write with content encoding (e.g. for pre-compressed data)
await s3file.write(compressedData, {
type: "application/json",
contentEncoding: "gzip",
});
// Write with content disposition
await s3file.write(pdfData, {
type: "application/pdf",
contentDisposition: 'attachment; filename="report.pdf"',
});
// Write using a writer (streaming)
const writer = s3file.writer({ type: "application/json" });
writer.write("Hello");
@@ -200,13 +188,7 @@ const download = s3.presign("my-file.txt"); // GET, text/plain, expires in 24 ho
const upload = s3.presign("my-file", {
expiresIn: 3600, // 1 hour
method: "PUT",
type: "application/json", // Sets response-content-type in the presigned URL
});
// Presign with content disposition (e.g. force download with a specific filename)
const downloadUrl = s3.presign("report.pdf", {
expiresIn: 3600,
contentDisposition: 'attachment; filename="quarterly-report.pdf"',
type: "application/json", // No extension for inferring, so we can specify the content type to be JSON
});
// You can call .presign() if on a file reference, but avoid doing so

View File

@@ -460,7 +460,7 @@ console.log(result); // Blob(13) { size: 13, type: "text/plain" }
For cross-platform compatibility, Bun Shell implements a set of builtin commands, in addition to reading commands from the PATH environment variable.
- `cd`: change the working directory
- `ls`: list files in a directory (supports `-l` for long listing format)
- `ls`: list files in a directory
- `rm`: remove files and directories
- `echo`: print text
- `pwd`: print the working directory

View File

@@ -19,7 +19,7 @@ If you're looking to create a brand new empty project, use [`bun init`](/runtime
`bun create ./MyComponent.tsx` turns an existing React component into a complete dev environment with hot reload and production builds in one command.
```bash
bun create ./MyComponent.jsx # .tsx also supported
$ bun create ./MyComponent.jsx # .tsx also supported
```
<Frame>

View File

@@ -880,94 +880,6 @@ npm/strip-ansi 212,992 chars long-ansi 1.36 ms/iter 1.38 ms
---
## `Bun.wrapAnsi()`
<Note>Drop-in replacement for `wrap-ansi` npm package</Note>
`Bun.wrapAnsi(input: string, columns: number, options?: WrapAnsiOptions): string`
Wrap text to a specified column width while preserving ANSI escape codes, hyperlinks, and handling Unicode/emoji width correctly. This is a native, high-performance alternative to the popular [`wrap-ansi`](https://www.npmjs.com/package/wrap-ansi) npm package.
```ts
// Basic wrapping at 20 columns
Bun.wrapAnsi("The quick brown fox jumps over the lazy dog", 20);
// => "The quick brown fox\njumps over the lazy\ndog"
// Preserves ANSI escape codes
Bun.wrapAnsi("\u001b[31mThe quick brown fox jumps over the lazy dog\u001b[0m", 20);
// => "\u001b[31mThe quick brown fox\njumps over the lazy\ndog\u001b[0m"
```
### Options
```ts
Bun.wrapAnsi("Hello World", 5, {
hard: true, // Break words that exceed column width (default: false)
wordWrap: true, // Wrap at word boundaries (default: true)
trim: true, // Trim leading/trailing whitespace per line (default: true)
ambiguousIsNarrow: true, // Treat ambiguous-width characters as narrow (default: true)
});
```
| Option | Default | Description |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `hard` | `false` | If `true`, break words in the middle if they exceed the column width. |
| `wordWrap` | `true` | If `true`, wrap at word boundaries. If `false`, only break at explicit newlines. |
| `trim` | `true` | If `true`, trim leading and trailing whitespace from each line. |
| `ambiguousIsNarrow` | `true` | If `true`, treat ambiguous-width Unicode characters as 1 column wide. If `false`, treat them as 2 columns wide. |
TypeScript definition:
```ts expandable
namespace Bun {
export function wrapAnsi(
/**
* The string to wrap
*/
input: string,
/**
* The maximum column width
*/
columns: number,
/**
* Wrapping options
*/
options?: {
/**
* If `true`, break words in the middle if they don't fit on a line.
* If `false`, only break at word boundaries.
*
* @default false
*/
hard?: boolean;
/**
* If `true`, wrap at word boundaries when possible.
* If `false`, don't perform word wrapping (only wrap at explicit newlines).
*
* @default true
*/
wordWrap?: boolean;
/**
* If `true`, trim leading and trailing whitespace from each line.
* If `false`, preserve whitespace.
*
* @default true
*/
trim?: boolean;
/**
* When it's ambiguous and `true`, count ambiguous width characters as 1 character wide.
* If `false`, count them as 2 characters wide.
*
* @default true
*/
ambiguousIsNarrow?: boolean;
},
): string;
}
```
---
## `serialize` & `deserialize` in `bun:jsc`
To save a JavaScript value into an ArrayBuffer & back, use `serialize` and `deserialize` from the `"bun:jsc"` module.

View File

@@ -50,8 +50,7 @@ bun build <entry points>
</ParamField>
<ParamField path="--format" type="string" default="esm">
Module format of the output bundle. One of <code>esm</code>, <code>cjs</code>, or <code>iife</code>. Defaults to{" "}
<code>cjs</code> when <code>--bytecode</code> is used.
Module format of the output bundle. One of <code>esm</code>, <code>cjs</code>, or <code>iife</code>
</ParamField>
### File Naming

View File

@@ -40,18 +40,6 @@ bun run <file or script>
Run a script in all workspace packages (from the <code>workspaces</code> field in <code>package.json</code>)
</ParamField>
<ParamField path="--parallel" type="boolean">
Run multiple scripts or workspace scripts concurrently with prefixed output
</ParamField>
<ParamField path="--sequential" type="boolean">
Run multiple scripts or workspace scripts one after another with prefixed output
</ParamField>
<ParamField path="--no-exit-on-error" type="boolean">
When using <code>--parallel</code> or <code>--sequential</code>, continue running other scripts when one fails
</ParamField>
### Runtime &amp; Process Control
<ParamField path="--bun" type="boolean">

View File

@@ -149,25 +149,25 @@ div.callout .code-block {
margin-bottom: 0px;
}
[language="shellscript"] code span.line:not(:empty):has(span)::before {
.code-block[language="shellscript"] code span.line:not(:empty):has(span)::before {
content: "$ ";
color: #6272a4;
user-select: none;
}
[language="shellscript"] code span.line:has(> span:first-child[style*="color: rgb(98, 114, 164)"])::before,
[language="shellscript"] code span.line:has(> span:first-child[style*="#6272A4"])::before {
.code-block[language="shellscript"] code span.line:has(> span:first-child[style*="color: rgb(98, 114, 164)"])::before,
.code-block[language="shellscript"] code span.line:has(> span:first-child[style*="#6272A4"])::before {
content: "";
}
[language="powershell"] code span.line:not(:empty):has(span)::before {
.code-block[language="powershell"] code span.line:not(:empty):has(span)::before {
content: "> ";
color: #6272a4;
user-select: none;
}
[language="powershell"] code span.line:has(> span:first-child[style*="color: rgb(98, 114, 164)"])::before,
[language="powershell"] code span.line:has(> span:first-child[style*="#6272A4"])::before {
.code-block[language="powershell"] code span.line:has(> span:first-child[style*="color: rgb(98, 114, 164)"])::before,
.code-block[language="powershell"] code span.line:has(> span:first-child[style*="#6272A4"])::before {
content: "";
}

View File

@@ -131,7 +131,6 @@
stdenv = pkgs.clangStdenv;
}) {
inherit packages;
hardeningDisable = [ "fortify" ];
shellHook = ''
# Set up build environment

View File

@@ -1,24 +0,0 @@
{
"inputs": {
"../../tmp/test-entry.js": {
"bytes": 21,
"imports": [
],
"format": "esm"
}
},
"outputs": {
"./test-entry.js": {
"bytes": 49,
"inputs": {
"../../tmp/test-entry.js": {
"bytesInOutput": 22
}
},
"imports": [
],
"exports": [],
"entryPoint": "../../tmp/test-entry.js"
}
}
}

View File

@@ -35,7 +35,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionWrite, (JSC::JSGlobalObject * globalObject,
JSValue arg1 = callframe->argument(0);
JSValue toWriteArg = callframe->argument(1);
auto &vm = globalObject->vm();
auto scope = DECLARE_TOP_EXCEPTION_SCOPE(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
int32_t fd = STDOUT_FILENO;
if (callframe->argumentCount() > 1) {

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "bun",
"version": "1.3.9",
"version": "1.3.6",
"workspaces": [
"./packages/bun-types",
"./packages/@types/bun"
@@ -49,7 +49,7 @@
"build:debug-zig-release": "cmake . -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=Debug -GNinja -Bbuild-debug-zig-release && ninja -Cbuild-debug-zig-release",
"run:linux": "docker run --rm -v \"$PWD:/root/bun/\" -w /root/bun ghcr.io/oven-sh/bun-development-docker-image",
"css-properties": "bun run src/css/properties/generate_properties.ts",
"uv-posix-stubs": "bun run src/bun.js/bindings/libuv/generate_uv_posix_stubs.ts",
"uv-posix-stubs": "bun run src/buntime/compat/libuv/generate_uv_posix_stubs.ts",
"bump": "bun ./scripts/bump.ts",
"jsc:build": "bun ./scripts/build-jsc.ts release",
"jsc:build:debug": "bun ./scripts/build-jsc.ts debug",

View File

@@ -71,25 +71,8 @@ async function buildRootModule(dryRun?: boolean) {
js: "// Source code: https://github.com/oven-sh/bun/blob/main/packages/bun-release/scripts/npm-postinstall.ts",
},
});
// Create placeholder scripts that print an error message if postinstall hasn't run.
// On Unix, these are executed as shell scripts despite the .exe extension.
// Do NOT add a shebang (#!/bin/sh) here — npm's cmd-shim reads shebangs to generate
// .ps1/.cmd wrappers BEFORE postinstall runs, and bakes the interpreter path in.
// A #!/bin/sh shebang breaks Windows because the wrappers reference /bin/sh which
// doesn't exist, even after postinstall replaces the placeholder with the real binary.
const placeholderScript = `echo "Error: Bun's postinstall script was not run." >&2
echo "" >&2
echo "This occurs when using --ignore-scripts during installation, or when using a" >&2
echo "package manager like pnpm that does not run postinstall scripts by default." >&2
echo "" >&2
echo "To fix this, run the postinstall script manually:" >&2
echo " cd node_modules/bun && node install.js" >&2
echo "" >&2
echo "Or reinstall bun without the --ignore-scripts flag." >&2
exit 1
`;
write(join(cwd, "bin", "bun.exe"), placeholderScript);
write(join(cwd, "bin", "bunx.exe"), placeholderScript);
write(join(cwd, "bin", "bun.exe"), "");
write(join(cwd, "bin", "bunx.exe"), "");
write(
join(cwd, "bin", "README.txt"),
`The 'bun.exe' file is a placeholder for the binary file, which

File diff suppressed because it is too large Load Diff

View File

@@ -23,11 +23,6 @@ declare module "*.jsonc" {
export = contents;
}
declare module "*.json5" {
var contents: any;
export = contents;
}
declare module "*/bun.lock" {
var contents: import("bun").BunLockFile;
export = contents;

View File

@@ -1,11 +0,0 @@
export {};
type ReactElement = typeof globalThis extends { React: infer React }
? React extends { createElement(...args: any): infer R }
? R
: never
: unknown;
export namespace JSX {
export type Element = ReactElement;
}

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