Files
Jason Lee 1614d3e144 web: Update to support web with WASM. (#2102)
Ref https://github.com/zed-industries/zed/pull/50228

## Summary
- Refactored to share Gallery component between native and web versions
- Fixed WASM compatibility issues with async/threading
- Added web version of the story gallery

## Show case

https://huacnlee.github.io/gpui-component-story-web/

## Key Changes

### 1. Shared Gallery Component
- Extracted Gallery to `crates/story/src/gallery.rs`
- Removed duplicate code (~570 lines) from `main.rs` and
`story-web/lib.rs`
- Both native and web versions now use the same Gallery implementation

### 2. WASM Async Architecture Improvements
**Problem:** WASM main thread cannot use blocking synchronization
primitives (`Mutex`, `RwLock`) that rely on `Atomics.wait`.

**Solution:** Redesigned the async architecture to avoid cross-thread
locks:
- Changed from `Arc<Mutex<ParsedContent>>` to direct storage in
`TextViewState`
- Backend tasks now use pure message-passing instead of shared locks
- All state updates happen on the main thread

**New workflow:**
1. User updates text → Send `UpdateOptions` to background task
2. Background task → Receives copy of current `ParsedContent`, parses
text, returns new `ParsedContent`
3. Main thread → Receives result, directly replaces `parsed_content`
4. Rendering → Reads `parsed_content`, no locks needed

### 3. Cross-platform Time APIs
- Replaced `std::time` with `instant` crate for cross-platform
compatibility
- Updated 11 files to use `instant::{Duration, Instant}`
- Fixed tracing-subscriber initialization for WASM (`.without_time()`)

## Technical Details

### Files Modified
- `crates/story/src/gallery.rs` - **New** shared Gallery module
- `crates/story/src/main.rs` - Simplified to use shared Gallery
- `crates/story-web/src/lib.rs` - Simplified to use shared Gallery (326
lines → 26 lines)
- `crates/ui/src/text/state.rs` - WASM async architecture improvements
- `crates/ui/src/async_util.rs` - Cross-platform async utilities
- `crates/ui/Cargo.toml` - Added `instant` and `parking_lot`
dependencies

### Key Architecture Changes
```rust
// Before: Shared mutable state with locks (blocked on WASM)
pub struct TextViewState {
    parsed_content: Arc<Mutex<ParsedContent>>,
}

// After: Direct storage with message-passing (WASM-compatible)
pub struct TextViewState {
    parsed_content: ParsedContent,
}
```

## Test Plan
-  Native version compiles and runs
-  WASM version builds successfully
-  All components render correctly in both versions
-  No "Atomics.wait cannot be called in this context" errors

## Benefits
- **Reduced code duplication**: Removed ~570 lines of duplicate code
- **Single source of truth**: Gallery updates only need to happen in one
place
- **WASM compatibility**: Proper async architecture that works on
single-threaded WASM
- **Cross-platform**: Native and Web use identical code paths

## TODO

- [ ] `gpui_web` not have implement the `set_menus`, app menu missing.
- [ ] `tree-sitter` can't compiled for wasm, disabled to without
highlight.
- [ ] Input can't handle any type events.
- [ ] Embed font for CJK.

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

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-02 13:12:24 +00:00
..
2024-10-14 11:20:16 +08:00