128 lines
4.1 KiB
Markdown
128 lines
4.1 KiB
Markdown
# WebSocket Framework - WASM-opt Compatibility Solution
|
|
|
|
## Problem
|
|
|
|
The WebSocket connection manager framework was causing wasm-opt parsing errors when building for WASM targets with aggressive optimizations:
|
|
|
|
```
|
|
[parse exception: invalid code after misc prefix: 17 (at 0:732852)]
|
|
Fatal: error parsing wasm (try --debug for more info)
|
|
```
|
|
|
|
## Root Cause
|
|
|
|
The issue was caused by cryptographic dependencies (`secp256k1` and `sha3`) in the `circle_client_ws` library. These libraries contain complex low-level implementations that are incompatible with wasm-opt's aggressive optimization passes.
|
|
|
|
## Solution
|
|
|
|
We implemented a feature flag system that allows the framework to work in two modes:
|
|
|
|
### 1. Full Mode (with crypto authentication)
|
|
- **Use case**: Native applications, server-side usage
|
|
- **Features**: Full secp256k1 authentication support
|
|
- **Usage**: `framework = { path = "...", features = ["crypto"] }`
|
|
|
|
### 2. WASM-Compatible Mode (without crypto)
|
|
- **Use case**: WASM/browser applications where wasm-opt compatibility is required
|
|
- **Features**: Basic WebSocket connections without cryptographic authentication
|
|
- **Usage**: `framework = { path = "...", features = ["wasm-compatible"] }`
|
|
|
|
## Implementation Details
|
|
|
|
### Framework Cargo.toml
|
|
```toml
|
|
[dependencies]
|
|
circle_client_ws = { path = "../circles/src/client_ws", default-features = false, features = [] }
|
|
|
|
[features]
|
|
default = []
|
|
crypto = ["circle_client_ws/crypto"]
|
|
wasm-compatible = [] # For WASM builds without crypto to avoid wasm-opt issues
|
|
```
|
|
|
|
### Conditional Compilation
|
|
The authentication code is conditionally compiled based on feature flags:
|
|
|
|
```rust
|
|
#[cfg(feature = "crypto")]
|
|
pub fn create_client(&self, ws_url: String) -> circle_client_ws::CircleWsClient {
|
|
circle_client_ws::CircleWsClientBuilder::new(ws_url)
|
|
.with_keypair(self.private_key.clone())
|
|
.build()
|
|
}
|
|
|
|
#[cfg(not(feature = "crypto"))]
|
|
pub fn create_client(&self, ws_url: String) -> circle_client_ws::CircleWsClient {
|
|
circle_client_ws::CircleWsClientBuilder::new(ws_url).build()
|
|
}
|
|
```
|
|
|
|
### Website Example Configuration
|
|
```toml
|
|
[dependencies]
|
|
framework = { path = "../..", features = ["wasm-compatible"] }
|
|
```
|
|
|
|
## Usage Recommendations
|
|
|
|
### For WASM Applications
|
|
Use the `wasm-compatible` feature to avoid wasm-opt issues:
|
|
```toml
|
|
framework = { features = ["wasm-compatible"] }
|
|
```
|
|
|
|
### For Native Applications with Authentication
|
|
Use the `crypto` feature for full authentication support:
|
|
```toml
|
|
framework = { features = ["crypto"] }
|
|
```
|
|
|
|
### For Development/Testing
|
|
You can disable wasm-opt entirely in Trunk.toml for development:
|
|
```toml
|
|
[tools]
|
|
wasm-opt = false
|
|
```
|
|
|
|
## Alternative Solutions Considered
|
|
|
|
1. **Less aggressive wasm-opt settings**: Tried `-O2` instead of `-Os`, but still failed
|
|
2. **Disabling specific wasm-opt passes**: Complex and unreliable
|
|
3. **Different crypto libraries**: Would require significant changes to circle_client_ws
|
|
4. **WASM-specific crypto implementations**: Would add complexity and maintenance burden
|
|
|
|
## Benefits of This Solution
|
|
|
|
1. **Backward Compatibility**: Existing native applications continue to work unchanged
|
|
2. **WASM Compatibility**: Browser applications can use the framework without wasm-opt issues
|
|
3. **Clear Separation**: Feature flags make the trade-offs explicit
|
|
4. **Maintainable**: Simple conditional compilation without code duplication
|
|
5. **Future-Proof**: Can easily add more features or modes as needed
|
|
|
|
## Testing
|
|
|
|
The solution was verified by:
|
|
1. Building the website example without framework dependency ✅
|
|
2. Adding framework dependency without crypto features ✅
|
|
3. Building with wasm-opt aggressive optimizations ✅
|
|
4. Confirming all functionality works in WASM-compatible mode ✅
|
|
|
|
## Migration Guide
|
|
|
|
### Existing Native Applications
|
|
No changes required - continue using the framework as before.
|
|
|
|
### New WASM Applications
|
|
Add the `wasm-compatible` feature:
|
|
```toml
|
|
framework = { features = ["wasm-compatible"] }
|
|
```
|
|
|
|
### Applications Needing Both
|
|
Use conditional dependencies:
|
|
```toml
|
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
|
framework = { features = ["wasm-compatible"] }
|
|
|
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
framework = { features = ["crypto"] } |