Use when: you need a persistent, server-pushed connection — a live chat feed,
real-time dashboard, presence indicators, or a collaborative document.
Don’t use when: you only need server-sent data occasionally and polling would
suffice; a persistent socket has reconnect overhead and connection limits.
Cubit<S> is a StateContainer<S> with emit / patch exposed as
public mutation surface. Today it adds nothing structurally beyond
StateContainer — both are inherited from the underlying
StructuralContainer<S>. Kept as a real class (not a type alias) because
downstream code does instance instanceof Cubit checks (see A2 audit).
The class body is intentionally empty: a no-op emit override would
still go through applyState, and patch is inherited from
StructuralContainer (path-diffed, microtask-flushed). If a caller
needs the old "skip if no real change" patch semantics, they can wrap
patch themselves or call emit after a manual equality check.
// Always close on disposal — avoid orphaned connections.
this.
ChatCubit.socket: ReconnectingWebSocket |null
socket?.
ReconnectingWebSocket.close(): void
close();
this.
ChatCubit.socket: ReconnectingWebSocket |null
socket=null;
});
}
protectedoverride
ChatCubit.init({ channelId }: {
channelId: string;
}): void
Called once after construction with the args passed at acquire time, before the first
state snapshot is read by any consumer. Override to seed args-derived state (via
this.emit(...)) or kick off loads.
Override of StructuralContainer.patch that routes through the
StateContainer concerns: disposed guard, dev-only emit-rate check,
_changedWhileHydrating flag, pending-change capture (so legacy
listeners and stateChanged system events see the merged prev/next),
and the registry-level stateChanged notification. We still call
super.patch so path-marking semantics (the whole point of patch) are
preserved.
Override of StructuralContainer.patch that routes through the
StateContainer concerns: disposed guard, dev-only emit-rate check,
_changedWhileHydrating flag, pending-change capture (so legacy
listeners and stateChanged system events see the merged prev/next),
and the registry-level stateChanged notification. We still call
super.patch so path-marking semantics (the whole point of patch) are
preserved.
Override of StructuralContainer.patch that routes through the
StateContainer concerns: disposed guard, dev-only emit-rate check,
_changedWhileHydrating flag, pending-change capture (so legacy
listeners and stateChanged system events see the merged prev/next),
and the registry-level stateChanged notification. We still call
super.patch so path-marking semantics (the whole point of patch) are
preserved.
patch({
connected?: boolean |undefined
connected: false,
error?: string |null|undefined
error: 'Connection error' });
};
const ws:ReconnectingWebSocket
ws.
ReconnectingWebSocket.onmessage: ((e: {
data:string;
})=>void) |null
onmessage=({
data: string
data })=> {
// Parse incoming data defensively — the server may send system frames.
let
let message:ChatMessage
message:
interface ChatMessage
ChatMessage;
try {
let message:ChatMessage
message=
var JSON:JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON.
JSON.parse(text: string, reviver?:(this:any, key:string, value:any)=> any): any
Converts a JavaScript Object Notation (JSON) string into an object.
@param ― text A valid JSON string.
@param ― reviver A function that transforms the results. This function is called for each member of the object.
If a member contains nested objects, the nested objects are transformed before the parent object is.
@throws ― {SyntaxError} If text is not valid JSON.
Override of StructuralContainer.patch that routes through the
StateContainer concerns: disposed guard, dev-only emit-rate check,
_changedWhileHydrating flag, pending-change capture (so legacy
listeners and stateChanged system events see the merged prev/next),
and the registry-level stateChanged notification. We still call
super.patch so path-marking semantics (the whole point of patch) are
preserved.
patch({
messages?: readonly {
id?: string |undefined;
author?: string |undefined;
text?: string |undefined;
timestamp?: number |undefined;
}[] |undefined
messages: [...this.
StructuralContainer<ChatState>.state: ChatState
state.
ChatState.messages: ChatMessage[]
messages,
let message:ChatMessage
message],
});
};
}
ChatCubit.sendMessage: (text:string)=>void
sendMessage=(
text: string
text:string)=> {
if (!this.
StructuralContainer<ChatState>.state: ChatState
state.
ChatState.connected: boolean
connected||!this.
ChatCubit.socket: ReconnectingWebSocket |null
socket) return;
this.
ChatCubit.socket: ReconnectingWebSocket
socket.
ReconnectingWebSocket.send(data: string): void
send(
var JSON:JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.