jala_websocket 0.7.0
jala_websocket: ^0.7.0 copied to clipboard
WebSocketChannel wrapper for Jala: connection lifecycle and frame timelines (direction, size, preview). Frames are not throttled.
jala_websocket #
package:web_socket_channel integration for Jala, the in-app Flutter network
inspector: captures a WebSocket connection's lifecycle (connect, open,
close, error) and every frame sent or received through it.
See the repo README for what Jala is and why (filter
grammar, redaction-by-default) and the jala package for the
facade that wires this up in an app.
Lockstep with jala / jala_core 0.7.x. Brownfield:
docs/ADOPTION.md. WebSocket frames are not
throttled (HTTP adapters only).
Install #
dependencies:
jala_websocket: ^0.7.0 # requires jala_core ^0.7.0
Wrap #
import 'package:jala_websocket/jala_websocket.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
final uri = Uri.parse('wss://echo.websocket.events');
final channel = JalaWebSocketChannel.wrap(
WebSocketChannel.connect(uri),
uri: uri,
);
channel.sink.add('hello');
channel.stream.listen((message) => print(message));
JalaWebSocketChannel.wrap reads JalaBinding.instance (wired up by
Jala.initialize() from the jala facade package), and returns a
WebSocketChannel that behaves exactly like the one you passed in — same
stream/sink semantics — while teeing every frame and lifecycle
transition into Jala's store.
Why the uri parameter? #
WebSocketChannel has no way to report the URL it was connected with
(WebSocketChannel.connect(uri) returns synchronously and doesn't retain
or expose uri anywhere on the interface). Pass the same Uri you connect
with so the inspector's connection list and detail screen have something
meaningful to show. If you omit it, Jala captures a placeholder
unknown://unknown URI instead — everything else (frames, status,
close code/reason) is still captured normally.
What gets captured #
A WsConnectionEntry (see jala_core) tracks, per connection:
- Lifecycle: a
WsConnectEventis emitted the instant you callwrap(statusconnecting); oncechannel.readyresolves, aWsOpenEventpromotes it toopen. AWsCloseEvent(statusclosed, with close code/reason) fires when either side closes the sink, or the underlying stream completes on its own. AWsErrorEvent(statuserror) fires if the stream errors — e.g. a dropped connection. - Frames: every
sink.add(...)(directionsent) and every value delivered onstream(directionreceived) is captured as aWsFrame— timestamp, direction, size, and (for text frames) a redacted preview capped at 4 KB. Binary frames are metadata-only: size is recorded, but the payload itself is never retained. - Ring buffer: each connection keeps its most recent
JalaConfig.maxWsFramesPerConnectionframes (default 200); older frames fall out silently, butWsConnectionEntry.frameCountkeeps counting the true total ever observed. Connections themselves are capped atJalaConfig.maxWsConnections(default 20), oldest-closed evicted first.
Throttling #
WebSocket frames are not throttled. JalaThrottleRegistry applies to
HTTP adapters (jala_dio, jala_http) only — frames still pass through
JalaWebSocketChannel at full speed regardless of the active profile.
(WS throttling is intentionally out of scope for v0.5.)
Production safety #
wrap()checksJalaBinding.instance.isEnabledonce, up front. When Jala is disabled (or never initialized),wrap()returns the exact samechannelyou passed in, untouched — no wrapper object, no capture code on the path at all. Safe to leaveJalaWebSocketChannel.wrap(...)in release builds.- Every capture call site (frame capture, connect/open/close/error
emission) is wrapped in
try/catch: a bug in Jala's own capture logic can never throw into your app'sstreamor blocksink.add/close. The original data, error, or done event is always forwarded to your app exactly once, regardless of whether capture succeeded. - Text frame previews are redacted at capture time via
JalaConfig.redactor's body patterns, before anything enters the in-memory store.
Limitations #
- Frame-level mocking (intercepting/replaying individual WS frames) is out of scope — a candidate for a future release.
- There is no HAR export for WebSocket connections — no standard format exists for representing a frame timeline.
- Network-condition simulation (latency / drop / bandwidth) does not apply to WebSocket frames — see Throttling above.