From e80b3d09b1da0adefb95c53661d74adb3535afc3 Mon Sep 17 00:00:00 2001 From: "Fabian @ Blax Software" Date: Tue, 7 Apr 2026 09:12:38 +0200 Subject: [PATCH] I listenwhilemounted, U 0.2.0 --- package.json | 2 +- src/vue.ts | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 57b030a..e8b74aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@blax-software/networking", - "version": "0.1.0", + "version": "0.2.0", "description": "Plug-and-play API + WebSocket client. Framework-agnostic core with optional Vue, Nuxt, and React bindings.", "type": "module", "main": "./dist/index.cjs", diff --git a/src/vue.ts b/src/vue.ts index 2ba576f..0cdec61 100644 --- a/src/vue.ts +++ b/src/vue.ts @@ -14,6 +14,68 @@ import type { const vueRef: CreateRefFn = (initial: T): ReactiveRef => ref(initial) as ReactiveRef +// --------------------------------------------------------------------------- +// VueWsClient — WsClient with Vue lifecycle-aware listener methods +// --------------------------------------------------------------------------- + +/** + * Extended WsClient whose listener methods auto-cleanup on Vue `onUnmounted`. + * + * - `listenWhileMounted(event, channel, cb)` — subscribe for the component's lifetime + * - `listenOnceWhileMounted(event, channel)` — resolve once, auto-cleanup on unmount + * + * The underlying `listen()` / `listenOnce()` remain available for manual control. + */ +export interface VueWsClient extends WsClient { + /** Subscribe to `event` on `channel`. Auto-unsubscribes when the calling component unmounts. */ + listenWhileMounted(event: string, channel: string | null | undefined, callback: (data: T) => void): () => void + /** Resolve once when `event` fires. Auto-cleans up if the component unmounts first. */ + listenOnceWhileMounted(event: string, channel?: string | null): Promise +} + +/** + * Create a WsClient with Vue `ref()` for reactive state and + * `listenWhileMounted` / `listenOnceWhileMounted` convenience methods. + * + * ```ts + * const ws = createVueWsClient({ url: 'wss://…', … }) + * + * // In any component's setup(): + * ws.listenWhileMounted('chat.message', null, (msg) => { … }) + * ``` + */ +export function createVueWsClient(config: WsClientConfig): VueWsClient { + const ws = createWsClient(config, vueRef) + + return Object.assign(ws, { + listenWhileMounted( + event: string, + channel: string | null | undefined, + callback: (data: T) => void, + ): () => void { + const off = ws.listen(event, channel, callback) + onUnmounted(off) + return off + }, + + listenOnceWhileMounted( + event: string, + channel?: string | null, + ): Promise { + let off: (() => void) | null = null + const promise = new Promise((resolve) => { + off = ws.listen(event, channel, (data) => { + off?.() + off = null + resolve(data) + }) + }) + onUnmounted(() => { off?.() }) + return promise + }, + }) as VueWsClient +} + // --------------------------------------------------------------------------- // Composables // --------------------------------------------------------------------------- @@ -29,6 +91,8 @@ export function useApiClient(config: ApiClientConfig): ApiClient { /** * Create a WsClient with Vue `ref()` for reactive state. * `ws.is_setup`, `ws.is_opened`, etc. are Vue refs. + * + * @deprecated Prefer `createVueWsClient()` which also provides `listenWhileMounted`. */ export function useWsClient(config: WsClientConfig): WsClient { return createWsClient(config, vueRef) @@ -36,6 +100,7 @@ export function useWsClient(config: WsClientConfig): WsClient { /** * Listen for a WS event with automatic cleanup on component unmount. + * Standalone composable — use this if you prefer functions over instance methods. * * ```ts * useWsListener(ws, 'chat.message', null, (data) => { ... }) @@ -54,6 +119,7 @@ export function useWsListener( /** * Resolve once when a WS event fires. Cleans up automatically if the component unmounts first. + * Standalone composable — use this if you prefer functions over instance methods. */ export function useWsListenOnce( ws: WsClient,