Add initial WASM support for Browser Support#2002
Conversation
…e module On wasm32-unknown-unknown, std::time::SystemTime::now() panics at runtime. This commit introduces a centralized module that re-exports on WASM targets and on native targets. All internal call sites are updated to use , and helper functions / bridge chrono conversions since chrono's trait impls only cover std::time::SystemTime. - Adds web-time = 1 to workspace and bashkit Cargo.toml - Creates crates/bashkit/src/time.rs with cfg-gated re-exports - Updates 20+ source files to use crate::time instead of std::time - All 2442 lib tests pass on native - cargo check passes for wasm32-unknown-unknown
Adds crates/bashkit-wasm-tests as a standalone workspace crate that exercises the platform-compatible time module on wasm32-unknown-unknown. Tests verify: - SystemTime::now() does not panic - UNIX_EPOCH < now - chrono roundtrip (SystemTime -> DateTime<Utc> -> SystemTime) - Duration arithmetic Run with: wasm-pack test --node (or --headless --chrome) All 4 tests pass.
SystemTime::now() was not the only time API that panics on wasm32-unknown-unknown — Instant::now() does too. This commit extends the centralized time module to also export Instant, and updates all call sites to use crate::time::Instant. - time.rs now exports Instant alongside SystemTime/Duration/UNIX_EPOCH - interpreter, parser, sqlite engine, sleep, tool modules updated - Verified: Bash::new() and bash.exec() now work in the browser
Implement IndexedDbFs using rexie + serde-wasm-bindgen behind the indexeddb feature flag. Includes invisible root node (/) auto-creation and AssertSend wrapper for wasm32 async_trait compatibility.
Add wasm_bindgen_test coverage for IndexedDbFs including write/read, append, mkdir, read_dir, remove, stat, rename, copy, symlink, chmod, and PosixFs wrapper smoke test. Configure run_in_browser for headless Chrome execution.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds WASM compatibility and browser persistence by introducing platform-compatible time re-exports and a new IndexedDB-backed filesystem backend.
Changes:
- Introduce
crate::timemodule (std on native,web_timeon WASM) and migrateInstant/SystemTime/Durationusages to it. - Add
IndexedDbFs(feature-gated) for browser persistence via IndexedDB (Rexie). - Add a new
bashkit-wasm-testscrate covering WASM time helpers and IndexedDB FS operations.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/bashkit/src/tool.rs | Switches timing to crate::time::Instant for WASM-safe Instant::now(). |
| crates/bashkit/src/time.rs | Adds platform-compatible time exports and chrono conversion helpers. |
| crates/bashkit/src/scripted_tool/execute.rs | Switches timing to crate::time::Instant in tool execution + tests. |
| crates/bashkit/src/parser/mod.rs | Uses crate::time::{Duration, Instant} to avoid WASM Instant::now() panics. |
| crates/bashkit/src/network/bot_auth.rs | Uses crate::time::{SystemTime, UNIX_EPOCH} for WASM-safe time. |
| crates/bashkit/src/lib.rs | Exposes new time module and conditionally re-exports IndexedDbFs. |
| crates/bashkit/src/interpreter/mod.rs | Switches timing to crate::time::Instant and updates test imports. |
| crates/bashkit/src/interop/fs.rs | Uses crate::time types for ABI timestamp handling. |
| crates/bashkit/src/fs/traits.rs | Switches to crate::time::SystemTime in FS trait types. |
| crates/bashkit/src/fs/realfs.rs | Switches to crate::time::SystemTime for metadata timestamps. |
| crates/bashkit/src/fs/readonly.rs | Switches to crate::time::SystemTime for metadata timestamps. |
| crates/bashkit/src/fs/posix.rs | Switches to crate::time::SystemTime for metadata timestamps. |
| crates/bashkit/src/fs/overlay.rs | Switches to crate::time::SystemTime for metadata timestamps. |
| crates/bashkit/src/fs/mountable.rs | Switches to crate::time::SystemTime for metadata and new mount entries. |
| crates/bashkit/src/fs/mod.rs | Adds indexeddb module + re-export behind feature flag. |
| crates/bashkit/src/fs/memory.rs | Switches to crate::time::SystemTime for metadata timestamps. |
| crates/bashkit/src/fs/indexeddb.rs | Adds new IndexedDB-based FsBackend implementation for WASM. |
| crates/bashkit/src/fs/backend.rs | Switches FsBackend timestamps to crate::time::SystemTime. |
| crates/bashkit/src/builtins/sqlite/engine.rs | Switches timing to crate::time::Instant for WASM-safe Instant::now(). |
| crates/bashkit/src/builtins/sleep.rs | Switches timing to crate::time::Instant in tests. |
| crates/bashkit/src/builtins/shuf.rs | Switches RNG seeding source to crate::time::{SystemTime, UNIX_EPOCH}. |
| crates/bashkit/src/builtins/rg/mod.rs | Switches test mtimes to crate::time::{UNIX_EPOCH, Duration}. |
| crates/bashkit/src/builtins/python.rs | Switches to crate::time::Duration and uses crate::time::UNIX_EPOCH. |
| crates/bashkit/src/builtins/mod.rs | Switches execution deadline anchor to crate::time::Instant. |
| crates/bashkit/src/builtins/ls/list.rs | Uses crate::time::UNIX_EPOCH for mtime formatting. |
| crates/bashkit/src/builtins/ls/find.rs | Uses crate::time::UNIX_EPOCH for mtime formatting. |
| crates/bashkit/src/builtins/inspect.rs | Uses crate::time::UNIX_EPOCH for stat formatting. |
| crates/bashkit/src/builtins/fileops.rs | Bridges chrono <-> platform SystemTime via new helpers. |
| crates/bashkit/src/builtins/date.rs | Uses crate::time::to_chrono_utc for mtime -> chrono conversion. |
| crates/bashkit/src/builtins/curl.rs | Uses crate::time for multipart boundary entropy + test trait signature. |
| crates/bashkit/src/builtins/archive.rs | Uses crate::time::UNIX_EPOCH for tar mtime output. |
| crates/bashkit/Cargo.toml | Adds web-time and introduces optional IndexedDB deps + feature. |
| crates/bashkit-wasm-tests/src/lib.rs | Adds WASM smoke tests for time helpers and IndexedDB FS. |
| crates/bashkit-wasm-tests/Cargo.toml | Adds new WASM test crate configuration and deps. |
| Cargo.toml | Adds workspace dependency on web-time. |
Comments suppressed due to low confidence (2)
crates/bashkit/src/time.rs:1
from_chronomis-handles datetimes beforeUNIX_EPOCH:secsis ani64, but it’s cast tou64, which will wrap negative timestamps into a huge positive duration (producing far-futureSystemTime). Consider handlingsecs < 0explicitly (computeUNIX_EPOCH - Duration::...), and be careful to combine seconds/nanos without underflow for negative timestamps.
crates/bashkit/src/time.rs:1to_chrono_utcsilently clamps anySystemTimebeforeUNIX_EPOCHto the Unix epoch viaunwrap_or_default(), losing information. If this function is used for file mtimes (e.g.,touch -t), pre-1970 timestamps will round to 1970-01-01. Consider handling theErr(e)case fromduration_since()by converting to a negative chrono timestamp usinge.duration().
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let all = store | ||
| .get_all(None, None) | ||
| .await | ||
| .map_err(|e| IoError::other(format!("indexeddb get_all: {e}")))?; |
There was a problem hiding this comment.
I feel like this is the correct behavior?
| //! WASM-specific smoke tests for bashkit platform-compatible time types. | ||
| //! | ||
| //! Run with: wasm-pack test --node | ||
| //! or: wasm-pack test --headless --chrome | ||
|
|
||
| use wasm_bindgen_test::*; | ||
| wasm_bindgen_test_configure!(run_in_browser); |
|
Wow :). Let me look at this later today. Definely sounds like a fun. |
Make http_client a marker feature (empty) and use target-specific dependencies so reqwest/rustls are only compiled on native, while js-sys/wasm-bindgen/web-sys are available on WASM. This fixes the getrandom 0.2 / ring compilation failure on wasm32-unknown-unknown.
|
I tried to keep a healthy abstraction of native vs WASM so WASM wouldn't cause issues with the existing code. |
|
Returning to draft to work out more kinks in the design patterns. Browser-based |
|
Hey @siennathesane , I checked you demo! It is nice. I however have troubles to proceed with this PR. In this PR it is would be a third implementation of WASM for this repo.
What I think could be a good steps moving forward:
|
|
Ah I'm sorry, I missed it. I'll check your WASM code and let you know. |

This PR introduces initial support for the WASM platform so Bashkit can be run in a sandboxed browser environment. For the most part, despite the amount of files changed, this is a simple PR.
The first change was to standardize
timeinto an internal package where it could switched betweenweb-timeandstd::time. Unfortunately I had to update a large amount of files for this change, but the scope is limited exclusively to updating time components.The second change was introducing an IndexedDb
FsBackendimplementation. This allows for a semi-persistent, browser-backed storage engine for the environment.The final change is adding network support. The HTTP client was abstracted and then WASM was implemented separately.
If you'd like to see it working, you can test it at sunbeam.pt