From 304c87d3c025717c8c16fc779a431264e26d98c4 Mon Sep 17 00:00:00 2001 From: Joe Freeman Date: Sat, 24 Jan 2026 19:19:19 +0000 Subject: [PATCH 1/3] Support providing a custom WebSocket creation function --- client_js/src/index.ts | 8 +++++++- client_js/src/socket.ts | 11 +++++++++-- client_react/src/index.ts | 1 + client_react/src/provider.ts | 13 +++++++++---- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/client_js/src/index.ts b/client_js/src/index.ts index ba98b6a..fbb53ff 100644 --- a/client_js/src/index.ts +++ b/client_js/src/index.ts @@ -1 +1,7 @@ -export { default as Socket, Params, ParamsInput, SocketState } from "./socket"; +export { + default as Socket, + Params, + ParamsInput, + SocketState, + WebSocketFactory, +} from "./socket"; diff --git a/client_js/src/socket.ts b/client_js/src/socket.ts index 1794729..6b81766 100644 --- a/client_js/src/socket.ts +++ b/client_js/src/socket.ts @@ -50,6 +50,8 @@ function topicKey(topic: string[], params: Params): string { return `${topic.map(encodeURIComponent).join("/")}?${sortedParams}`; } +export type WebSocketFactory = (url: string) => WebSocket; + export default class Socket { private socket: WebSocket; private closed = false; @@ -61,15 +63,20 @@ export default class Socket { // Maps aliased channel IDs to their target channel IDs private aliases: Record = {}; private listeners: ((state: SocketState) => void)[] = []; + private createWebSocket: WebSocketFactory; - constructor(private readonly url: string) { + constructor( + private readonly url: string, + createWebSocket?: WebSocketFactory, + ) { + this.createWebSocket = createWebSocket ?? ((url) => new WebSocket(url)); this.socket = this.open(); } private open() { this.closed = false; this.setState("connecting"); - const socket = new WebSocket(this.url); + const socket = this.createWebSocket(this.url); socket.addEventListener("open", this.handleSocketOpen); socket.addEventListener("error", this.handleSocketError); socket.addEventListener("message", this.handleSocketMessage); diff --git a/client_react/src/index.ts b/client_react/src/index.ts index b9233d0..b20183a 100644 --- a/client_react/src/index.ts +++ b/client_react/src/index.ts @@ -1,3 +1,4 @@ export { default as SocketProvider } from "./provider"; export { default as useSocket } from "./useSocket"; export { default as useTopic } from "./useTopic"; +export type { WebSocketFactory } from "@topical/core"; diff --git a/client_react/src/provider.ts b/client_react/src/provider.ts index 0901504..13eec7d 100644 --- a/client_react/src/provider.ts +++ b/client_react/src/provider.ts @@ -1,4 +1,4 @@ -import { Socket } from "@topical/core"; +import { Socket, type WebSocketFactory } from "@topical/core"; import { createContext, createElement, @@ -11,17 +11,22 @@ export const Context = createContext(undefined); type ProviderProps = { url: string; + createWebSocket?: WebSocketFactory; children: ReactNode; }; -export default function Provider({ url, children }: ProviderProps) { +export default function Provider({ + url, + createWebSocket, + children, +}: ProviderProps) { const [socket, setSocket] = useState(); useEffect(() => { - const socket = new Socket(url); + const socket = new Socket(url, createWebSocket); setSocket(socket); return () => { socket.close(); }; - }, [url]); + }, [url, createWebSocket]); return createElement(Context.Provider, { value: socket }, children); } From 823a7917b637250f392a5d0aa868ab39217e85e7 Mon Sep 17 00:00:00 2001 From: Joe Freeman Date: Sat, 24 Jan 2026 19:23:08 +0000 Subject: [PATCH 2/3] Revert changes to React client --- client_react/src/index.ts | 1 - client_react/src/provider.ts | 13 ++++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/client_react/src/index.ts b/client_react/src/index.ts index b20183a..b9233d0 100644 --- a/client_react/src/index.ts +++ b/client_react/src/index.ts @@ -1,4 +1,3 @@ export { default as SocketProvider } from "./provider"; export { default as useSocket } from "./useSocket"; export { default as useTopic } from "./useTopic"; -export type { WebSocketFactory } from "@topical/core"; diff --git a/client_react/src/provider.ts b/client_react/src/provider.ts index 13eec7d..0901504 100644 --- a/client_react/src/provider.ts +++ b/client_react/src/provider.ts @@ -1,4 +1,4 @@ -import { Socket, type WebSocketFactory } from "@topical/core"; +import { Socket } from "@topical/core"; import { createContext, createElement, @@ -11,22 +11,17 @@ export const Context = createContext(undefined); type ProviderProps = { url: string; - createWebSocket?: WebSocketFactory; children: ReactNode; }; -export default function Provider({ - url, - createWebSocket, - children, -}: ProviderProps) { +export default function Provider({ url, children }: ProviderProps) { const [socket, setSocket] = useState(); useEffect(() => { - const socket = new Socket(url, createWebSocket); + const socket = new Socket(url); setSocket(socket); return () => { socket.close(); }; - }, [url, createWebSocket]); + }, [url]); return createElement(Context.Provider, { value: socket }, children); } From 5abdd93f92b0256d99aa8ec70cb4f56cd8154bf5 Mon Sep 17 00:00:00 2001 From: Joe Freeman Date: Sat, 24 Jan 2026 19:32:33 +0000 Subject: [PATCH 3/3] Update changelog --- client_js/CHANGELOG.md | 6 ++++++ client_js/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client_js/CHANGELOG.md b/client_js/CHANGELOG.md index ef656f0..fa5493c 100644 --- a/client_js/CHANGELOG.md +++ b/client_js/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 0.3.1 + +### Features + +- Adds optional `createWebSocket` factory function for customizing WebSocket creation. + ## 0.3.0 ### Features diff --git a/client_js/package.json b/client_js/package.json index 4e5009a..c746869 100644 --- a/client_js/package.json +++ b/client_js/package.json @@ -1,6 +1,6 @@ { "name": "@topical/core", - "version": "0.3.0", + "version": "0.3.1", "description": "Vanilla Topical client.", "main": "dist/index.js", "typings": "dist/index.d.ts",