fix(ws): resolve a function `url` lazily — don't invoke the getter at construction

createWsClient eagerly invoked a function-form `config.url` to print a dev-time
URL-validation warning. For a module-scope singleton built with
`createVueWsClient({ url: () => useRuntimeConfig().public... })`, that called
useRuntimeConfig() at import time — outside any Nuxt context — and threw
"A composable that requires access to the Nuxt instance was called outside of a
plugin, Nuxt hook, Nuxt middleware, or Vue setup function" (regression vs 0.2.x).

Now only STRING urls are validated eagerly; a function url stays lazy and is
resolved in _getUrl() at connect time (as in 0.2.x). Bump 0.3.1.
This commit is contained in:
Fabian @ Blax Software 2026-06-30 11:53:40 +02:00
parent 1d8f43148f
commit c21553536f
2 changed files with 23 additions and 15 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@blax-software/networking", "name": "@blax-software/networking",
"version": "0.3.0", "version": "0.3.1",
"description": "Plug-and-play API + WebSocket client. Framework-agnostic core with optional Vue, Nuxt, and React bindings.", "description": "Plug-and-play API + WebSocket client. Framework-agnostic core with optional Vue, Nuxt, and React bindings.",
"type": "module", "type": "module",
"main": "./dist/index.cjs", "main": "./dist/index.cjs",

View File

@ -642,8 +642,15 @@ export function createWsClient(
: (config.isServer ?? false) : (config.isServer ?? false)
if (isServer) return createSsrStub(createRef) if (isServer) return createSsrStub(createRef)
// Validate configuration and warn developers about common issues // Validate configuration and warn developers about common issues.
const url = typeof config.url === 'function' ? config.url() : config.url // IMPORTANT: only resolve a STRING url here. A function url is lazy by design —
// it may depend on a runtime context that does not exist yet at construction
// time (e.g. Nuxt's `useRuntimeConfig()`, which throws when called outside a
// plugin/setup/lifecycle). Calling it eagerly here crashed module-scope
// singletons built with `createVueWsClient({ url: () => useRuntimeConfig()... })`.
// Function urls are resolved lazily at connect time instead.
if (typeof config.url === 'string') {
const url = config.url
if (!url || url === 'wss:///app/' || url === 'ws:///app/') { if (!url || url === 'wss:///app/' || url === 'ws:///app/') {
console.error( console.error(
'[blax-networking] WebSocket URL is empty or malformed: ' + JSON.stringify(url) + '\n' + '[blax-networking] WebSocket URL is empty or malformed: ' + JSON.stringify(url) + '\n' +
@ -657,6 +664,7 @@ export function createWsClient(
'where {appKey} matches the PUSHER_APP_KEY on the backend.', 'where {appKey} matches the PUSHER_APP_KEY on the backend.',
) )
} }
}
return new WsClientImpl(config, createRef) return new WsClientImpl(config, createRef)
} }