New:Socket for Asana Is Now Available.Learn more
Get Started

@tanstack/devtools-event-bus

Package Overview
Dependencies
Maintainers
3
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/devtools-event-bus - npm Package Compare versions

Comparing version
0.4.2
to
0.4.3
+4
-4
dist/cjs/client/client.cjs

@@ -35,9 +35,9 @@ const require_json = require("../utils/json.cjs");

};
constructor({ port = 4206, host = "localhost", protocol = "http", debug = false, connectToServerBus = false } = {}) {
constructor({ port = getDefaultPort(4206), host = getDefaultHost("localhost"), protocol = getDefaultProtocol("http"), debug = false, connectToServerBus = false } = {}) {
this.#debug = debug;
this.#broadcastChannel = new BroadcastChannel("tanstack-devtools");
this.#eventSource = null;
this.#port = getDefaultPort(port);
this.#host = getDefaultHost(host);
this.#protocol = getDefaultProtocol(protocol);
this.#port = port;
this.#host = host;
this.#protocol = protocol;
this.#socket = null;

@@ -44,0 +44,0 @@ this.#connectToServerBus = connectToServerBus;

@@ -1,1 +0,1 @@

{"version":3,"file":"client.cjs","names":["#eventTarget","#debug","#broadcastChannel","#eventSource","#port","#host","#protocol","#socket","#connectToServerBus","#pendingServerEvents","#dispatcher","#connectFunction"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { parseWithBigInt, stringifyWithBigInt } from '../utils/json'\n\n// Declare the global placeholders that get replaced by the Vite plugin at transform time\n// Fall back to defaults when not using the Vite plugin or in non-transformed environments\ndeclare const __TANSTACK_DEVTOOLS_PORT__: number | undefined\ndeclare const __TANSTACK_DEVTOOLS_HOST__: string | undefined\ndeclare const __TANSTACK_DEVTOOLS_PROTOCOL__: 'http' | 'https' | undefined\n\nfunction getDefaultPort(configPort: number): number {\n if (typeof __TANSTACK_DEVTOOLS_PORT__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PORT__\n return configPort\n}\n\nfunction getDefaultHost(configHost: string): string {\n if (typeof __TANSTACK_DEVTOOLS_HOST__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_HOST__\n return configHost\n}\n\nfunction getDefaultProtocol(\n configProtocol: 'http' | 'https',\n): 'http' | 'https' {\n if (typeof __TANSTACK_DEVTOOLS_PROTOCOL__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PROTOCOL__\n return configProtocol\n}\n\ninterface TanStackDevtoolsEvent<TEventName extends string, TPayload = any> {\n type: TEventName\n payload: TPayload\n pluginId?: string // Optional pluginId to filter events by plugin\n}\n\nexport interface ClientEventBusConfig {\n /**\n * Optional flag to indicate if the devtools server event bus is available to connect to.\n * This is used to determine if the devtools can connect to the server for real-time event streams.\n */\n connectToServerBus?: boolean\n\n /**\n * Optional flag to enable debug mode for the event bus.\n */\n debug?: boolean\n\n /**\n * Optional port to connect to the devtools server event bus.\n * Defaults to 4206.\n */\n port?: number\n\n /**\n * Optional host to connect to the devtools server event bus.\n * Defaults to 'localhost'.\n */\n host?: string\n\n /**\n * Optional protocol to use for connecting to the devtools server event bus.\n * Defaults to 'http'. Set to 'https' when the dev server uses HTTPS.\n */\n protocol?: 'http' | 'https'\n}\n\nexport class ClientEventBus {\n #port: number\n #host: string\n #protocol: 'http' | 'https'\n #socket: WebSocket | null\n #eventSource: EventSource | null\n #eventTarget: EventTarget\n #debug: boolean\n #connectToServerBus: boolean\n #broadcastChannel: BroadcastChannel | null\n // Events emitted while the WebSocket is still establishing its connection.\n // They are buffered here and flushed once the socket opens so early events\n // (e.g. the marketplace's `mounted` request) are never silently dropped.\n #pendingServerEvents: Array<string> = []\n #dispatcher = (e: Event) => {\n const event = (e as CustomEvent).detail\n this.emitToServer(event)\n this.emitToClients(event)\n }\n #connectFunction = () => {\n this.debugLog(\n 'Connection request made to event-bus, replying back with success',\n )\n this.#eventTarget.dispatchEvent(new CustomEvent('tanstack-connect-success'))\n }\n constructor({\n port = 4206,\n host = 'localhost',\n protocol = 'http',\n debug = false,\n connectToServerBus = false,\n }: ClientEventBusConfig = {}) {\n this.#debug = debug\n this.#broadcastChannel = new BroadcastChannel('tanstack-devtools')\n this.#eventSource = null\n this.#port = getDefaultPort(port)\n this.#host = getDefaultHost(host)\n this.#protocol = getDefaultProtocol(protocol)\n this.#socket = null\n this.#connectToServerBus = connectToServerBus\n this.#eventTarget = this.getGlobalTarget()\n this.#broadcastChannel.onmessage = (e) => {\n this.emitToClients(parseWithBigInt(e.data), true)\n }\n this.debugLog('Initializing client event bus')\n }\n\n private emitToClients(\n event: TanStackDevtoolsEvent<string>,\n fromBroadcastChannel = false,\n ) {\n this.debugLog('Emitting event from client bus', event)\n const specificEvent = new CustomEvent(event.type, { detail: event })\n this.debugLog('Emitting event to specific client listeners', event)\n this.#eventTarget.dispatchEvent(specificEvent)\n const globalEvent = new CustomEvent('tanstack-devtools-global', {\n detail: event,\n })\n // We only emit the events if they didn't come from the broadcast channel\n // otherwise it would infinitely send events between\n if (!fromBroadcastChannel) {\n this.#broadcastChannel?.postMessage(stringifyWithBigInt(event))\n }\n this.debugLog('Emitting event to global client listeners', event)\n this.#eventTarget.dispatchEvent(globalEvent)\n }\n\n private flushPendingServerEvents() {\n if (!this.#socket || this.#socket.readyState !== WebSocket.OPEN) {\n return\n }\n const pending = this.#pendingServerEvents\n this.#pendingServerEvents = []\n for (const json of pending) {\n this.debugLog('Flushing queued event to server via WS')\n this.#socket.send(json)\n }\n }\n\n private emitToServer(event: TanStackDevtoolsEvent<string, any>) {\n const json = stringifyWithBigInt(event)\n // try to emit it to the event bus first\n if (this.#socket) {\n if (this.#socket.readyState === WebSocket.OPEN) {\n this.debugLog('Emitting event to server via WS', event)\n this.#socket.send(json)\n } else if (this.#socket.readyState === WebSocket.CONNECTING) {\n // The socket handshake is still in flight. Buffer the event instead of\n // dropping it; it will be sent once the connection opens.\n this.debugLog('WebSocket still connecting, queueing event', event)\n this.#pendingServerEvents.push(json)\n }\n // CLOSING/CLOSED sockets cannot deliver; the event is dropped.\n return\n }\n // try to emit to SSE if WebSocket is not available (this will only happen on the client side)\n if (this.#eventSource) {\n this.debugLog('Emitting event to server via SSE', event)\n\n fetch(`${this.#protocol}://${this.#host}:${this.#port}/__devtools/send`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: json,\n }).catch(() => {})\n }\n }\n start() {\n this.debugLog('Starting client event bus')\n if (typeof window === 'undefined') {\n return\n }\n if (this.#connectToServerBus) {\n this.connect()\n }\n this.#eventTarget = window\n this.#eventTarget.addEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.addEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n }\n stop() {\n this.debugLog('Stopping client event bus')\n if (typeof window === 'undefined') {\n return\n }\n this.#eventTarget.removeEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.removeEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n this.#eventSource?.close()\n this.#socket?.close()\n this.#socket = null\n this.#eventSource = null\n this.#pendingServerEvents = []\n }\n private getGlobalTarget() {\n if (typeof window !== 'undefined') {\n return window\n }\n\n return new EventTarget()\n }\n private debugLog(...messages: Array<any>) {\n if (this.#debug) {\n console.log('🌴 [tanstack-devtools:client-bus]', ...messages)\n }\n }\n private connectSSE() {\n this.debugLog('Connecting to SSE server')\n this.#eventSource = new EventSource(\n `${this.#protocol}://${this.#host}:${this.#port}/__devtools/sse`,\n )\n this.#eventSource.onmessage = (e) => {\n this.debugLog('Received message from SSE server', e.data)\n this.handleEventReceived(e.data)\n }\n }\n\n private connectWebSocket() {\n this.debugLog('Connecting to WebSocket server')\n\n const wsProtocol = this.#protocol === 'https' ? 'wss' : 'ws'\n this.#socket = new WebSocket(\n `${wsProtocol}://${this.#host}:${this.#port}/__devtools/ws`,\n )\n this.#socket.onopen = () => {\n this.debugLog('WebSocket connection opened')\n this.flushPendingServerEvents()\n }\n this.#socket.onmessage = (e) => {\n this.debugLog('Received message from server', e.data)\n this.handleEventReceived(e.data)\n }\n this.#socket.onclose = () => {\n this.debugLog('WebSocket connection closed')\n this.#socket = null\n // Drop any still-queued events — there is no open socket to deliver them.\n this.#pendingServerEvents = []\n }\n this.#socket.onerror = () => {\n this.debugLog('WebSocket connection error')\n }\n }\n\n private connect() {\n try {\n this.connectWebSocket()\n } catch {\n // Do not try to connect if we're on the server side\n if (typeof window === 'undefined') return\n this.connectSSE()\n }\n }\n\n private handleEventReceived(data: string) {\n try {\n const event = parseWithBigInt(data) as TanStackDevtoolsEvent<string, any>\n this.emitToClients(event)\n } catch {}\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"client.cjs","names":["#eventTarget","#debug","#broadcastChannel","#eventSource","#port","#host","#protocol","#socket","#connectToServerBus","#pendingServerEvents","#dispatcher","#connectFunction"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { parseWithBigInt, stringifyWithBigInt } from '../utils/json'\n\n// Declare the global placeholders that get replaced by the Vite plugin at transform time\n// Fall back to defaults when not using the Vite plugin or in non-transformed environments\ndeclare const __TANSTACK_DEVTOOLS_PORT__: number | undefined\ndeclare const __TANSTACK_DEVTOOLS_HOST__: string | undefined\ndeclare const __TANSTACK_DEVTOOLS_PROTOCOL__: 'http' | 'https' | undefined\n\nfunction getDefaultPort(configPort: number): number {\n if (typeof __TANSTACK_DEVTOOLS_PORT__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PORT__\n return configPort\n}\n\nfunction getDefaultHost(configHost: string): string {\n if (typeof __TANSTACK_DEVTOOLS_HOST__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_HOST__\n return configHost\n}\n\nfunction getDefaultProtocol(\n configProtocol: 'http' | 'https',\n): 'http' | 'https' {\n if (typeof __TANSTACK_DEVTOOLS_PROTOCOL__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PROTOCOL__\n return configProtocol\n}\n\ninterface TanStackDevtoolsEvent<TEventName extends string, TPayload = any> {\n type: TEventName\n payload: TPayload\n pluginId?: string // Optional pluginId to filter events by plugin\n}\n\nexport interface ClientEventBusConfig {\n /**\n * Optional flag to indicate if the devtools server event bus is available to connect to.\n * This is used to determine if the devtools can connect to the server for real-time event streams.\n */\n connectToServerBus?: boolean\n\n /**\n * Optional flag to enable debug mode for the event bus.\n */\n debug?: boolean\n\n /**\n * Optional port to connect to the devtools server event bus.\n * Defaults to 4206.\n */\n port?: number\n\n /**\n * Optional host to connect to the devtools server event bus.\n * Defaults to 'localhost'.\n */\n host?: string\n\n /**\n * Optional protocol to use for connecting to the devtools server event bus.\n * Defaults to 'http'. Set to 'https' when the dev server uses HTTPS.\n */\n protocol?: 'http' | 'https'\n}\n\nexport class ClientEventBus {\n #port: number\n #host: string\n #protocol: 'http' | 'https'\n #socket: WebSocket | null\n #eventSource: EventSource | null\n #eventTarget: EventTarget\n #debug: boolean\n #connectToServerBus: boolean\n #broadcastChannel: BroadcastChannel | null\n // Events emitted while the WebSocket is still establishing its connection.\n // They are buffered here and flushed once the socket opens so early events\n // (e.g. the marketplace's `mounted` request) are never silently dropped.\n #pendingServerEvents: Array<string> = []\n #dispatcher = (e: Event) => {\n const event = (e as CustomEvent).detail\n this.emitToServer(event)\n this.emitToClients(event)\n }\n #connectFunction = () => {\n this.debugLog(\n 'Connection request made to event-bus, replying back with success',\n )\n this.#eventTarget.dispatchEvent(new CustomEvent('tanstack-connect-success'))\n }\n constructor({\n port = getDefaultPort(4206),\n host = getDefaultHost('localhost'),\n protocol = getDefaultProtocol('http'),\n debug = false,\n connectToServerBus = false,\n }: ClientEventBusConfig = {}) {\n this.#debug = debug\n this.#broadcastChannel = new BroadcastChannel('tanstack-devtools')\n this.#eventSource = null\n this.#port = port\n this.#host = host\n this.#protocol = protocol\n this.#socket = null\n this.#connectToServerBus = connectToServerBus\n this.#eventTarget = this.getGlobalTarget()\n this.#broadcastChannel.onmessage = (e) => {\n this.emitToClients(parseWithBigInt(e.data), true)\n }\n this.debugLog('Initializing client event bus')\n }\n\n private emitToClients(\n event: TanStackDevtoolsEvent<string>,\n fromBroadcastChannel = false,\n ) {\n this.debugLog('Emitting event from client bus', event)\n const specificEvent = new CustomEvent(event.type, { detail: event })\n this.debugLog('Emitting event to specific client listeners', event)\n this.#eventTarget.dispatchEvent(specificEvent)\n const globalEvent = new CustomEvent('tanstack-devtools-global', {\n detail: event,\n })\n // We only emit the events if they didn't come from the broadcast channel\n // otherwise it would infinitely send events between\n if (!fromBroadcastChannel) {\n this.#broadcastChannel?.postMessage(stringifyWithBigInt(event))\n }\n this.debugLog('Emitting event to global client listeners', event)\n this.#eventTarget.dispatchEvent(globalEvent)\n }\n\n private flushPendingServerEvents() {\n if (!this.#socket || this.#socket.readyState !== WebSocket.OPEN) {\n return\n }\n const pending = this.#pendingServerEvents\n this.#pendingServerEvents = []\n for (const json of pending) {\n this.debugLog('Flushing queued event to server via WS')\n this.#socket.send(json)\n }\n }\n\n private emitToServer(event: TanStackDevtoolsEvent<string, any>) {\n const json = stringifyWithBigInt(event)\n // try to emit it to the event bus first\n if (this.#socket) {\n if (this.#socket.readyState === WebSocket.OPEN) {\n this.debugLog('Emitting event to server via WS', event)\n this.#socket.send(json)\n } else if (this.#socket.readyState === WebSocket.CONNECTING) {\n // The socket handshake is still in flight. Buffer the event instead of\n // dropping it; it will be sent once the connection opens.\n this.debugLog('WebSocket still connecting, queueing event', event)\n this.#pendingServerEvents.push(json)\n }\n // CLOSING/CLOSED sockets cannot deliver; the event is dropped.\n return\n }\n // try to emit to SSE if WebSocket is not available (this will only happen on the client side)\n if (this.#eventSource) {\n this.debugLog('Emitting event to server via SSE', event)\n\n fetch(`${this.#protocol}://${this.#host}:${this.#port}/__devtools/send`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: json,\n }).catch(() => {})\n }\n }\n start() {\n this.debugLog('Starting client event bus')\n if (typeof window === 'undefined') {\n return\n }\n if (this.#connectToServerBus) {\n this.connect()\n }\n this.#eventTarget = window\n this.#eventTarget.addEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.addEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n }\n stop() {\n this.debugLog('Stopping client event bus')\n if (typeof window === 'undefined') {\n return\n }\n this.#eventTarget.removeEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.removeEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n this.#eventSource?.close()\n this.#socket?.close()\n this.#socket = null\n this.#eventSource = null\n this.#pendingServerEvents = []\n }\n private getGlobalTarget() {\n if (typeof window !== 'undefined') {\n return window\n }\n\n return new EventTarget()\n }\n private debugLog(...messages: Array<any>) {\n if (this.#debug) {\n console.log('🌴 [tanstack-devtools:client-bus]', ...messages)\n }\n }\n private connectSSE() {\n this.debugLog('Connecting to SSE server')\n this.#eventSource = new EventSource(\n `${this.#protocol}://${this.#host}:${this.#port}/__devtools/sse`,\n )\n this.#eventSource.onmessage = (e) => {\n this.debugLog('Received message from SSE server', e.data)\n this.handleEventReceived(e.data)\n }\n }\n\n private connectWebSocket() {\n this.debugLog('Connecting to WebSocket server')\n\n const wsProtocol = this.#protocol === 'https' ? 'wss' : 'ws'\n this.#socket = new WebSocket(\n `${wsProtocol}://${this.#host}:${this.#port}/__devtools/ws`,\n )\n this.#socket.onopen = () => {\n this.debugLog('WebSocket connection opened')\n this.flushPendingServerEvents()\n }\n this.#socket.onmessage = (e) => {\n this.debugLog('Received message from server', e.data)\n this.handleEventReceived(e.data)\n }\n this.#socket.onclose = () => {\n this.debugLog('WebSocket connection closed')\n this.#socket = null\n // Drop any still-queued events — there is no open socket to deliver them.\n this.#pendingServerEvents = []\n }\n this.#socket.onerror = () => {\n this.debugLog('WebSocket connection error')\n }\n }\n\n private connect() {\n try {\n this.connectWebSocket()\n } catch {\n // Do not try to connect if we're on the server side\n if (typeof window === 'undefined') return\n this.connectSSE()\n }\n }\n\n private handleEventReceived(data: string) {\n try {\n const event = parseWithBigInt(data) as TanStackDevtoolsEvent<string, any>\n this.emitToClients(event)\n } catch {}\n }\n}\n"],"mappings":"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"}

@@ -35,9 +35,9 @@ import { parseWithBigInt, stringifyWithBigInt } from "../utils/json.js";

};
constructor({ port = 4206, host = "localhost", protocol = "http", debug = false, connectToServerBus = false } = {}) {
constructor({ port = getDefaultPort(4206), host = getDefaultHost("localhost"), protocol = getDefaultProtocol("http"), debug = false, connectToServerBus = false } = {}) {
this.#debug = debug;
this.#broadcastChannel = new BroadcastChannel("tanstack-devtools");
this.#eventSource = null;
this.#port = getDefaultPort(port);
this.#host = getDefaultHost(host);
this.#protocol = getDefaultProtocol(protocol);
this.#port = port;
this.#host = host;
this.#protocol = protocol;
this.#socket = null;

@@ -44,0 +44,0 @@ this.#connectToServerBus = connectToServerBus;

@@ -1,1 +0,1 @@

{"version":3,"file":"client.js","names":["#eventTarget","#debug","#broadcastChannel","#eventSource","#port","#host","#protocol","#socket","#connectToServerBus","#pendingServerEvents","#dispatcher","#connectFunction"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { parseWithBigInt, stringifyWithBigInt } from '../utils/json'\n\n// Declare the global placeholders that get replaced by the Vite plugin at transform time\n// Fall back to defaults when not using the Vite plugin or in non-transformed environments\ndeclare const __TANSTACK_DEVTOOLS_PORT__: number | undefined\ndeclare const __TANSTACK_DEVTOOLS_HOST__: string | undefined\ndeclare const __TANSTACK_DEVTOOLS_PROTOCOL__: 'http' | 'https' | undefined\n\nfunction getDefaultPort(configPort: number): number {\n if (typeof __TANSTACK_DEVTOOLS_PORT__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PORT__\n return configPort\n}\n\nfunction getDefaultHost(configHost: string): string {\n if (typeof __TANSTACK_DEVTOOLS_HOST__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_HOST__\n return configHost\n}\n\nfunction getDefaultProtocol(\n configProtocol: 'http' | 'https',\n): 'http' | 'https' {\n if (typeof __TANSTACK_DEVTOOLS_PROTOCOL__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PROTOCOL__\n return configProtocol\n}\n\ninterface TanStackDevtoolsEvent<TEventName extends string, TPayload = any> {\n type: TEventName\n payload: TPayload\n pluginId?: string // Optional pluginId to filter events by plugin\n}\n\nexport interface ClientEventBusConfig {\n /**\n * Optional flag to indicate if the devtools server event bus is available to connect to.\n * This is used to determine if the devtools can connect to the server for real-time event streams.\n */\n connectToServerBus?: boolean\n\n /**\n * Optional flag to enable debug mode for the event bus.\n */\n debug?: boolean\n\n /**\n * Optional port to connect to the devtools server event bus.\n * Defaults to 4206.\n */\n port?: number\n\n /**\n * Optional host to connect to the devtools server event bus.\n * Defaults to 'localhost'.\n */\n host?: string\n\n /**\n * Optional protocol to use for connecting to the devtools server event bus.\n * Defaults to 'http'. Set to 'https' when the dev server uses HTTPS.\n */\n protocol?: 'http' | 'https'\n}\n\nexport class ClientEventBus {\n #port: number\n #host: string\n #protocol: 'http' | 'https'\n #socket: WebSocket | null\n #eventSource: EventSource | null\n #eventTarget: EventTarget\n #debug: boolean\n #connectToServerBus: boolean\n #broadcastChannel: BroadcastChannel | null\n // Events emitted while the WebSocket is still establishing its connection.\n // They are buffered here and flushed once the socket opens so early events\n // (e.g. the marketplace's `mounted` request) are never silently dropped.\n #pendingServerEvents: Array<string> = []\n #dispatcher = (e: Event) => {\n const event = (e as CustomEvent).detail\n this.emitToServer(event)\n this.emitToClients(event)\n }\n #connectFunction = () => {\n this.debugLog(\n 'Connection request made to event-bus, replying back with success',\n )\n this.#eventTarget.dispatchEvent(new CustomEvent('tanstack-connect-success'))\n }\n constructor({\n port = 4206,\n host = 'localhost',\n protocol = 'http',\n debug = false,\n connectToServerBus = false,\n }: ClientEventBusConfig = {}) {\n this.#debug = debug\n this.#broadcastChannel = new BroadcastChannel('tanstack-devtools')\n this.#eventSource = null\n this.#port = getDefaultPort(port)\n this.#host = getDefaultHost(host)\n this.#protocol = getDefaultProtocol(protocol)\n this.#socket = null\n this.#connectToServerBus = connectToServerBus\n this.#eventTarget = this.getGlobalTarget()\n this.#broadcastChannel.onmessage = (e) => {\n this.emitToClients(parseWithBigInt(e.data), true)\n }\n this.debugLog('Initializing client event bus')\n }\n\n private emitToClients(\n event: TanStackDevtoolsEvent<string>,\n fromBroadcastChannel = false,\n ) {\n this.debugLog('Emitting event from client bus', event)\n const specificEvent = new CustomEvent(event.type, { detail: event })\n this.debugLog('Emitting event to specific client listeners', event)\n this.#eventTarget.dispatchEvent(specificEvent)\n const globalEvent = new CustomEvent('tanstack-devtools-global', {\n detail: event,\n })\n // We only emit the events if they didn't come from the broadcast channel\n // otherwise it would infinitely send events between\n if (!fromBroadcastChannel) {\n this.#broadcastChannel?.postMessage(stringifyWithBigInt(event))\n }\n this.debugLog('Emitting event to global client listeners', event)\n this.#eventTarget.dispatchEvent(globalEvent)\n }\n\n private flushPendingServerEvents() {\n if (!this.#socket || this.#socket.readyState !== WebSocket.OPEN) {\n return\n }\n const pending = this.#pendingServerEvents\n this.#pendingServerEvents = []\n for (const json of pending) {\n this.debugLog('Flushing queued event to server via WS')\n this.#socket.send(json)\n }\n }\n\n private emitToServer(event: TanStackDevtoolsEvent<string, any>) {\n const json = stringifyWithBigInt(event)\n // try to emit it to the event bus first\n if (this.#socket) {\n if (this.#socket.readyState === WebSocket.OPEN) {\n this.debugLog('Emitting event to server via WS', event)\n this.#socket.send(json)\n } else if (this.#socket.readyState === WebSocket.CONNECTING) {\n // The socket handshake is still in flight. Buffer the event instead of\n // dropping it; it will be sent once the connection opens.\n this.debugLog('WebSocket still connecting, queueing event', event)\n this.#pendingServerEvents.push(json)\n }\n // CLOSING/CLOSED sockets cannot deliver; the event is dropped.\n return\n }\n // try to emit to SSE if WebSocket is not available (this will only happen on the client side)\n if (this.#eventSource) {\n this.debugLog('Emitting event to server via SSE', event)\n\n fetch(`${this.#protocol}://${this.#host}:${this.#port}/__devtools/send`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: json,\n }).catch(() => {})\n }\n }\n start() {\n this.debugLog('Starting client event bus')\n if (typeof window === 'undefined') {\n return\n }\n if (this.#connectToServerBus) {\n this.connect()\n }\n this.#eventTarget = window\n this.#eventTarget.addEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.addEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n }\n stop() {\n this.debugLog('Stopping client event bus')\n if (typeof window === 'undefined') {\n return\n }\n this.#eventTarget.removeEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.removeEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n this.#eventSource?.close()\n this.#socket?.close()\n this.#socket = null\n this.#eventSource = null\n this.#pendingServerEvents = []\n }\n private getGlobalTarget() {\n if (typeof window !== 'undefined') {\n return window\n }\n\n return new EventTarget()\n }\n private debugLog(...messages: Array<any>) {\n if (this.#debug) {\n console.log('🌴 [tanstack-devtools:client-bus]', ...messages)\n }\n }\n private connectSSE() {\n this.debugLog('Connecting to SSE server')\n this.#eventSource = new EventSource(\n `${this.#protocol}://${this.#host}:${this.#port}/__devtools/sse`,\n )\n this.#eventSource.onmessage = (e) => {\n this.debugLog('Received message from SSE server', e.data)\n this.handleEventReceived(e.data)\n }\n }\n\n private connectWebSocket() {\n this.debugLog('Connecting to WebSocket server')\n\n const wsProtocol = this.#protocol === 'https' ? 'wss' : 'ws'\n this.#socket = new WebSocket(\n `${wsProtocol}://${this.#host}:${this.#port}/__devtools/ws`,\n )\n this.#socket.onopen = () => {\n this.debugLog('WebSocket connection opened')\n this.flushPendingServerEvents()\n }\n this.#socket.onmessage = (e) => {\n this.debugLog('Received message from server', e.data)\n this.handleEventReceived(e.data)\n }\n this.#socket.onclose = () => {\n this.debugLog('WebSocket connection closed')\n this.#socket = null\n // Drop any still-queued events — there is no open socket to deliver them.\n this.#pendingServerEvents = []\n }\n this.#socket.onerror = () => {\n this.debugLog('WebSocket connection error')\n }\n }\n\n private connect() {\n try {\n this.connectWebSocket()\n } catch {\n // Do not try to connect if we're on the server side\n if (typeof window === 'undefined') return\n this.connectSSE()\n }\n }\n\n private handleEventReceived(data: string) {\n try {\n const event = parseWithBigInt(data) as TanStackDevtoolsEvent<string, any>\n this.emitToClients(event)\n } catch {}\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"client.js","names":["#eventTarget","#debug","#broadcastChannel","#eventSource","#port","#host","#protocol","#socket","#connectToServerBus","#pendingServerEvents","#dispatcher","#connectFunction"],"sources":["../../../src/client/client.ts"],"sourcesContent":["import { parseWithBigInt, stringifyWithBigInt } from '../utils/json'\n\n// Declare the global placeholders that get replaced by the Vite plugin at transform time\n// Fall back to defaults when not using the Vite plugin or in non-transformed environments\ndeclare const __TANSTACK_DEVTOOLS_PORT__: number | undefined\ndeclare const __TANSTACK_DEVTOOLS_HOST__: string | undefined\ndeclare const __TANSTACK_DEVTOOLS_PROTOCOL__: 'http' | 'https' | undefined\n\nfunction getDefaultPort(configPort: number): number {\n if (typeof __TANSTACK_DEVTOOLS_PORT__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PORT__\n return configPort\n}\n\nfunction getDefaultHost(configHost: string): string {\n if (typeof __TANSTACK_DEVTOOLS_HOST__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_HOST__\n return configHost\n}\n\nfunction getDefaultProtocol(\n configProtocol: 'http' | 'https',\n): 'http' | 'https' {\n if (typeof __TANSTACK_DEVTOOLS_PROTOCOL__ !== 'undefined')\n return __TANSTACK_DEVTOOLS_PROTOCOL__\n return configProtocol\n}\n\ninterface TanStackDevtoolsEvent<TEventName extends string, TPayload = any> {\n type: TEventName\n payload: TPayload\n pluginId?: string // Optional pluginId to filter events by plugin\n}\n\nexport interface ClientEventBusConfig {\n /**\n * Optional flag to indicate if the devtools server event bus is available to connect to.\n * This is used to determine if the devtools can connect to the server for real-time event streams.\n */\n connectToServerBus?: boolean\n\n /**\n * Optional flag to enable debug mode for the event bus.\n */\n debug?: boolean\n\n /**\n * Optional port to connect to the devtools server event bus.\n * Defaults to 4206.\n */\n port?: number\n\n /**\n * Optional host to connect to the devtools server event bus.\n * Defaults to 'localhost'.\n */\n host?: string\n\n /**\n * Optional protocol to use for connecting to the devtools server event bus.\n * Defaults to 'http'. Set to 'https' when the dev server uses HTTPS.\n */\n protocol?: 'http' | 'https'\n}\n\nexport class ClientEventBus {\n #port: number\n #host: string\n #protocol: 'http' | 'https'\n #socket: WebSocket | null\n #eventSource: EventSource | null\n #eventTarget: EventTarget\n #debug: boolean\n #connectToServerBus: boolean\n #broadcastChannel: BroadcastChannel | null\n // Events emitted while the WebSocket is still establishing its connection.\n // They are buffered here and flushed once the socket opens so early events\n // (e.g. the marketplace's `mounted` request) are never silently dropped.\n #pendingServerEvents: Array<string> = []\n #dispatcher = (e: Event) => {\n const event = (e as CustomEvent).detail\n this.emitToServer(event)\n this.emitToClients(event)\n }\n #connectFunction = () => {\n this.debugLog(\n 'Connection request made to event-bus, replying back with success',\n )\n this.#eventTarget.dispatchEvent(new CustomEvent('tanstack-connect-success'))\n }\n constructor({\n port = getDefaultPort(4206),\n host = getDefaultHost('localhost'),\n protocol = getDefaultProtocol('http'),\n debug = false,\n connectToServerBus = false,\n }: ClientEventBusConfig = {}) {\n this.#debug = debug\n this.#broadcastChannel = new BroadcastChannel('tanstack-devtools')\n this.#eventSource = null\n this.#port = port\n this.#host = host\n this.#protocol = protocol\n this.#socket = null\n this.#connectToServerBus = connectToServerBus\n this.#eventTarget = this.getGlobalTarget()\n this.#broadcastChannel.onmessage = (e) => {\n this.emitToClients(parseWithBigInt(e.data), true)\n }\n this.debugLog('Initializing client event bus')\n }\n\n private emitToClients(\n event: TanStackDevtoolsEvent<string>,\n fromBroadcastChannel = false,\n ) {\n this.debugLog('Emitting event from client bus', event)\n const specificEvent = new CustomEvent(event.type, { detail: event })\n this.debugLog('Emitting event to specific client listeners', event)\n this.#eventTarget.dispatchEvent(specificEvent)\n const globalEvent = new CustomEvent('tanstack-devtools-global', {\n detail: event,\n })\n // We only emit the events if they didn't come from the broadcast channel\n // otherwise it would infinitely send events between\n if (!fromBroadcastChannel) {\n this.#broadcastChannel?.postMessage(stringifyWithBigInt(event))\n }\n this.debugLog('Emitting event to global client listeners', event)\n this.#eventTarget.dispatchEvent(globalEvent)\n }\n\n private flushPendingServerEvents() {\n if (!this.#socket || this.#socket.readyState !== WebSocket.OPEN) {\n return\n }\n const pending = this.#pendingServerEvents\n this.#pendingServerEvents = []\n for (const json of pending) {\n this.debugLog('Flushing queued event to server via WS')\n this.#socket.send(json)\n }\n }\n\n private emitToServer(event: TanStackDevtoolsEvent<string, any>) {\n const json = stringifyWithBigInt(event)\n // try to emit it to the event bus first\n if (this.#socket) {\n if (this.#socket.readyState === WebSocket.OPEN) {\n this.debugLog('Emitting event to server via WS', event)\n this.#socket.send(json)\n } else if (this.#socket.readyState === WebSocket.CONNECTING) {\n // The socket handshake is still in flight. Buffer the event instead of\n // dropping it; it will be sent once the connection opens.\n this.debugLog('WebSocket still connecting, queueing event', event)\n this.#pendingServerEvents.push(json)\n }\n // CLOSING/CLOSED sockets cannot deliver; the event is dropped.\n return\n }\n // try to emit to SSE if WebSocket is not available (this will only happen on the client side)\n if (this.#eventSource) {\n this.debugLog('Emitting event to server via SSE', event)\n\n fetch(`${this.#protocol}://${this.#host}:${this.#port}/__devtools/send`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: json,\n }).catch(() => {})\n }\n }\n start() {\n this.debugLog('Starting client event bus')\n if (typeof window === 'undefined') {\n return\n }\n if (this.#connectToServerBus) {\n this.connect()\n }\n this.#eventTarget = window\n this.#eventTarget.addEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.addEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n }\n stop() {\n this.debugLog('Stopping client event bus')\n if (typeof window === 'undefined') {\n return\n }\n this.#eventTarget.removeEventListener(\n 'tanstack-dispatch-event',\n this.#dispatcher,\n )\n this.#eventTarget.removeEventListener(\n 'tanstack-connect',\n this.#connectFunction,\n )\n this.#eventSource?.close()\n this.#socket?.close()\n this.#socket = null\n this.#eventSource = null\n this.#pendingServerEvents = []\n }\n private getGlobalTarget() {\n if (typeof window !== 'undefined') {\n return window\n }\n\n return new EventTarget()\n }\n private debugLog(...messages: Array<any>) {\n if (this.#debug) {\n console.log('🌴 [tanstack-devtools:client-bus]', ...messages)\n }\n }\n private connectSSE() {\n this.debugLog('Connecting to SSE server')\n this.#eventSource = new EventSource(\n `${this.#protocol}://${this.#host}:${this.#port}/__devtools/sse`,\n )\n this.#eventSource.onmessage = (e) => {\n this.debugLog('Received message from SSE server', e.data)\n this.handleEventReceived(e.data)\n }\n }\n\n private connectWebSocket() {\n this.debugLog('Connecting to WebSocket server')\n\n const wsProtocol = this.#protocol === 'https' ? 'wss' : 'ws'\n this.#socket = new WebSocket(\n `${wsProtocol}://${this.#host}:${this.#port}/__devtools/ws`,\n )\n this.#socket.onopen = () => {\n this.debugLog('WebSocket connection opened')\n this.flushPendingServerEvents()\n }\n this.#socket.onmessage = (e) => {\n this.debugLog('Received message from server', e.data)\n this.handleEventReceived(e.data)\n }\n this.#socket.onclose = () => {\n this.debugLog('WebSocket connection closed')\n this.#socket = null\n // Drop any still-queued events — there is no open socket to deliver them.\n this.#pendingServerEvents = []\n }\n this.#socket.onerror = () => {\n this.debugLog('WebSocket connection error')\n }\n }\n\n private connect() {\n try {\n this.connectWebSocket()\n } catch {\n // Do not try to connect if we're on the server side\n if (typeof window === 'undefined') return\n this.connectSSE()\n }\n }\n\n private handleEventReceived(data: string) {\n try {\n const event = parseWithBigInt(data) as TanStackDevtoolsEvent<string, any>\n this.emitToClients(event)\n } catch {}\n }\n}\n"],"mappings":";;AAQA,SAAS,eAAe,YAA4B;CAClD,IAAI,OAAO,+BAA+B,aACxC,OAAO;CACT,OAAO;;AAGT,SAAS,eAAe,YAA4B;CAClD,IAAI,OAAO,+BAA+B,aACxC,OAAO;CACT,OAAO;;AAGT,SAAS,mBACP,gBACkB;CAClB,IAAI,OAAO,mCAAmC,aAC5C,OAAO;CACT,OAAO;;AAwCT,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAIA,uBAAsC,EAAE;CACxC,eAAe,MAAa;EAC1B,MAAM,QAAS,EAAkB;EACjC,KAAK,aAAa,MAAM;EACxB,KAAK,cAAc,MAAM;;CAE3B,yBAAyB;EACvB,KAAK,SACH,mEACD;EACD,KAAKA,aAAa,cAAc,IAAI,YAAY,2BAA2B,CAAC;;CAE9E,YAAY,EACV,OAAO,eAAe,KAAK,EAC3B,OAAO,eAAe,YAAY,EAClC,WAAW,mBAAmB,OAAO,EACrC,QAAQ,OACR,qBAAqB,UACG,EAAE,EAAE;EAC5B,KAAKC,SAAS;EACd,KAAKC,oBAAoB,IAAI,iBAAiB,oBAAoB;EAClE,KAAKC,eAAe;EACpB,KAAKC,QAAQ;EACb,KAAKC,QAAQ;EACb,KAAKC,YAAY;EACjB,KAAKC,UAAU;EACf,KAAKC,sBAAsB;EAC3B,KAAKR,eAAe,KAAK,iBAAiB;EAC1C,KAAKE,kBAAkB,aAAa,MAAM;GACxC,KAAK,cAAc,gBAAgB,EAAE,KAAK,EAAE,KAAK;;EAEnD,KAAK,SAAS,gCAAgC;;CAGhD,cACE,OACA,uBAAuB,OACvB;EACA,KAAK,SAAS,kCAAkC,MAAM;EACtD,MAAM,gBAAgB,IAAI,YAAY,MAAM,MAAM,EAAE,QAAQ,OAAO,CAAC;EACpE,KAAK,SAAS,+CAA+C,MAAM;EACnE,KAAKF,aAAa,cAAc,cAAc;EAC9C,MAAM,cAAc,IAAI,YAAY,4BAA4B,EAC9D,QAAQ,OACT,CAAC;EAGF,IAAI,CAAC,sBACH,KAAKE,mBAAmB,YAAY,oBAAoB,MAAM,CAAC;EAEjE,KAAK,SAAS,6CAA6C,MAAM;EACjE,KAAKF,aAAa,cAAc,YAAY;;CAG9C,2BAAmC;EACjC,IAAI,CAAC,KAAKO,WAAW,KAAKA,QAAQ,eAAe,UAAU,MACzD;EAEF,MAAM,UAAU,KAAKE;EACrB,KAAKA,uBAAuB,EAAE;EAC9B,KAAK,MAAM,QAAQ,SAAS;GAC1B,KAAK,SAAS,yCAAyC;GACvD,KAAKF,QAAQ,KAAK,KAAK;;;CAI3B,aAAqB,OAA2C;EAC9D,MAAM,OAAO,oBAAoB,MAAM;EAEvC,IAAI,KAAKA,SAAS;GAChB,IAAI,KAAKA,QAAQ,eAAe,UAAU,MAAM;IAC9C,KAAK,SAAS,mCAAmC,MAAM;IACvD,KAAKA,QAAQ,KAAK,KAAK;UAClB,IAAI,KAAKA,QAAQ,eAAe,UAAU,YAAY;IAG3D,KAAK,SAAS,8CAA8C,MAAM;IAClE,KAAKE,qBAAqB,KAAK,KAAK;;GAGtC;;EAGF,IAAI,KAAKN,cAAc;GACrB,KAAK,SAAS,oCAAoC,MAAM;GAExD,MAAM,GAAG,KAAKG,UAAU,KAAK,KAAKD,MAAM,GAAG,KAAKD,MAAM,mBAAmB;IACvE,QAAQ;IACR,SAAS,EAAE,gBAAgB,oBAAoB;IAC/C,MAAM;IACP,CAAC,CAAC,YAAY,GAAG;;;CAGtB,QAAQ;EACN,KAAK,SAAS,4BAA4B;EAC1C,IAAI,OAAO,WAAW,aACpB;EAEF,IAAI,KAAKI,qBACP,KAAK,SAAS;EAEhB,KAAKR,eAAe;EACpB,KAAKA,aAAa,iBAChB,2BACA,KAAKU,YACN;EACD,KAAKV,aAAa,iBAChB,oBACA,KAAKW,iBACN;;CAEH,OAAO;EACL,KAAK,SAAS,4BAA4B;EAC1C,IAAI,OAAO,WAAW,aACpB;EAEF,KAAKX,aAAa,oBAChB,2BACA,KAAKU,YACN;EACD,KAAKV,aAAa,oBAChB,oBACA,KAAKW,iBACN;EACD,KAAKR,cAAc,OAAO;EAC1B,KAAKI,SAAS,OAAO;EACrB,KAAKA,UAAU;EACf,KAAKJ,eAAe;EACpB,KAAKM,uBAAuB,EAAE;;CAEhC,kBAA0B;EACxB,IAAI,OAAO,WAAW,aACpB,OAAO;EAGT,OAAO,IAAI,aAAa;;CAE1B,SAAiB,GAAG,UAAsB;EACxC,IAAI,KAAKR,QACP,QAAQ,IAAI,qCAAqC,GAAG,SAAS;;CAGjE,aAAqB;EACnB,KAAK,SAAS,2BAA2B;EACzC,KAAKE,eAAe,IAAI,YACtB,GAAG,KAAKG,UAAU,KAAK,KAAKD,MAAM,GAAG,KAAKD,MAAM,iBACjD;EACD,KAAKD,aAAa,aAAa,MAAM;GACnC,KAAK,SAAS,oCAAoC,EAAE,KAAK;GACzD,KAAK,oBAAoB,EAAE,KAAK;;;CAIpC,mBAA2B;EACzB,KAAK,SAAS,iCAAiC;EAE/C,MAAM,aAAa,KAAKG,cAAc,UAAU,QAAQ;EACxD,KAAKC,UAAU,IAAI,UACjB,GAAG,WAAW,KAAK,KAAKF,MAAM,GAAG,KAAKD,MAAM,gBAC7C;EACD,KAAKG,QAAQ,eAAe;GAC1B,KAAK,SAAS,8BAA8B;GAC5C,KAAK,0BAA0B;;EAEjC,KAAKA,QAAQ,aAAa,MAAM;GAC9B,KAAK,SAAS,gCAAgC,EAAE,KAAK;GACrD,KAAK,oBAAoB,EAAE,KAAK;;EAElC,KAAKA,QAAQ,gBAAgB;GAC3B,KAAK,SAAS,8BAA8B;GAC5C,KAAKA,UAAU;GAEf,KAAKE,uBAAuB,EAAE;;EAEhC,KAAKF,QAAQ,gBAAgB;GAC3B,KAAK,SAAS,6BAA6B;;;CAI/C,UAAkB;EAChB,IAAI;GACF,KAAK,kBAAkB;UACjB;GAEN,IAAI,OAAO,WAAW,aAAa;GACnC,KAAK,YAAY;;;CAIrB,oBAA4B,MAAc;EACxC,IAAI;GACF,MAAM,QAAQ,gBAAgB,KAAK;GACnC,KAAK,cAAc,MAAM;UACnB"}
{
"name": "@tanstack/devtools-event-bus",
"version": "0.4.2",
"version": "0.4.3",
"description": "TanStack Event Bus is a lightweight event bus for TanStack Devtools.",

@@ -13,2 +13,5 @@ "author": "Tanner Linsley",

"homepage": "https://tanstack.com/devtools",
"bugs": {
"url": "https://github.com/TanStack/devtools/issues"
},
"funding": {

@@ -15,0 +18,0 @@ "type": "github",

@@ -92,5 +92,5 @@ import { parseWithBigInt, stringifyWithBigInt } from '../utils/json'

constructor({
port = 4206,
host = 'localhost',
protocol = 'http',
port = getDefaultPort(4206),
host = getDefaultHost('localhost'),
protocol = getDefaultProtocol('http'),
debug = false,

@@ -102,5 +102,5 @@ connectToServerBus = false,

this.#eventSource = null
this.#port = getDefaultPort(port)
this.#host = getDefaultHost(host)
this.#protocol = getDefaultProtocol(protocol)
this.#port = port
this.#host = host
this.#protocol = protocol
this.#socket = null

@@ -107,0 +107,0 @@ this.#connectToServerBus = connectToServerBus