javascript / intermediate
Snippet
Bridging Class-Based State Machines with Vue Reactivity for Real-Time Sockets
Encapsulating networking lifecycles and private WebSocket instances inside an ES6 class keeps connection logic decoupled from UI concerns. By passing a callback that updates a Vue `ref`, the class instance safely drives the reactive state while `onScopeDispose` guarantees teardown when the calling component unmounts.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { ref, onScopeDispose } from 'vue';class SocketSessionController {#socket = null;#onStateChange;constructor(url, onStateChange) {this.url = url;this.#onStateChange = onStateChange;}connect() {this.#socket = new WebSocket(this.url);this.#socket.onopen = () => this.#onStateChange('CONNECTED');this.#socket.onclose = () => this.#onStateChange('DISCONNECTED');this.#socket.onerror = () => this.#onStateChange('ERROR');}disconnect() {if (this.#socket) {this.#socket.close();this.#socket = null;}}}export function useRealtimeConnection(endpoint) {const connectionState = ref('DISCONNECTED');const controller = new SocketSessionController(endpoint, (newState) => {connectionState.value = newState;});controller.connect();onScopeDispose(() => controller.disconnect());return { connectionState };}
vue
Breakdown
1
class SocketSessionController { #socket = null;
Defines an ES6 class with a private field to securely hold the underlying WebSocket instance.
2
this.#socket.onopen = () => this.#onStateChange('CONNECTED');
Invokes the state-change callback to broadcast connection transitions to listeners.
3
const controller = new SocketSessionController(endpoint, (newState) => {
Instantiates the controller class within a Vue composable, connecting class events to a reactive ref.
4
onScopeDispose(() => controller.disconnect());
Hooks into Vue's effect scope disposal to clean up socket resources and prevent memory leaks.