diff --git a/src/api.ts b/src/api.ts index ca9a539..497cf08 100644 --- a/src/api.ts +++ b/src/api.ts @@ -53,24 +53,24 @@ const REFLUX_HEADER = "reflux-middleware"; const REFLUX_VERSION = "1.0.0"; export class RefluxAPI { - private pluginStorage = localforage.createInstance({ + #pluginStorage = localforage.createInstance({ name: 'Reflux', storeName: 'plugins' }); - private statusStorage = localforage.createInstance({ + #statusStorage = localforage.createInstance({ name: 'Reflux', storeName: 'status' }); - private metadataStorageInstance?: LocalForage; + #metadataStorageInstance?: LocalForage; constructor() { try { - this.pluginStorage = localforage.createInstance({ + this.#pluginStorage = localforage.createInstance({ name: 'Reflux', storeName: 'plugins' }); - this.statusStorage = localforage.createInstance({ + this.#statusStorage = localforage.createInstance({ name: 'Reflux', storeName: 'status' }); @@ -79,26 +79,26 @@ export class RefluxAPI { } } - private ensureStorages(): void { - if (!this.pluginStorage) { - this.pluginStorage = localforage.createInstance({ name: 'Reflux', storeName: 'plugins' }); + #ensureStorages(): void { + if (!this.#pluginStorage) { + this.#pluginStorage = localforage.createInstance({ name: 'Reflux', storeName: 'plugins' }); } - if (!this.statusStorage) { - this.statusStorage = localforage.createInstance({ name: 'Reflux', storeName: 'status' }); + if (!this.#statusStorage) { + this.#statusStorage = localforage.createInstance({ name: 'Reflux', storeName: 'status' }); } } async addPlugin(plugin: RefluxPlugin): Promise { try { - this.ensureStorages(); - if (!this.pluginStorage) throw new Error('pluginStorage unavailable'); - await this.pluginStorage.setItem(plugin.name, plugin.function); + this.#ensureStorages(); + if (!this.#pluginStorage) throw new Error('pluginStorage unavailable'); + await this.#pluginStorage.setItem(plugin.name, plugin.function); const metadataStorage = localforage.createInstance({ name: 'Reflux', storeName: 'pluginMetadata' }); - + # await metadataStorage.setItem(plugin.name, { sites: plugin.sites, name: plugin.name @@ -113,9 +113,9 @@ export class RefluxAPI { async removePlugin(name: string): Promise { try { - this.ensureStorages(); - if (!this.pluginStorage) throw new Error('pluginStorage unavailable'); - await this.pluginStorage.removeItem(name); + this.#ensureStorages(); + if (!this.#pluginStorage) throw new Error('pluginStorage unavailable'); + await this.#pluginStorage.removeItem(name); const metadataStorage = localforage.createInstance({ name: 'Reflux', @@ -123,9 +123,9 @@ export class RefluxAPI { }); await metadataStorage.removeItem(name); - const enabledPlugins = await this.statusStorage.getItem('enabled') || []; + const enabledPlugins = await this.#statusStorage.getItem('enabled') || []; const updatedEnabled = enabledPlugins.filter(id => id !== name); - await this.statusStorage.setItem('enabled', updatedEnabled); + await this.#statusStorage.setItem('enabled', updatedEnabled); console.log(`Plugin ${name} removed successfully`); } catch (error) { @@ -136,13 +136,13 @@ export class RefluxAPI { async enablePlugin(name: string): Promise { try { - this.ensureStorages(); - if (!this.statusStorage) throw new Error('statusStorage unavailable'); - const enabledPlugins = await this.statusStorage.getItem('enabled') || []; + this.#ensureStorages(); + if (!this.#statusStorage) throw new Error('statusStorage unavailable'); + const enabledPlugins = await this.#statusStorage.getItem('enabled') || []; if (!enabledPlugins.includes(name)) { enabledPlugins.push(name); - await this.statusStorage.setItem('enabled', enabledPlugins); + await this.#statusStorage.setItem('enabled', enabledPlugins); } console.log(`Plugin ${name} enabled successfully`); @@ -154,11 +154,11 @@ export class RefluxAPI { async disablePlugin(name: string): Promise { try { - this.ensureStorages(); - if (!this.statusStorage) throw new Error('statusStorage unavailable'); - const enabledPlugins = await this.statusStorage.getItem('enabled') || []; + this.#ensureStorages(); + if (!this.#statusStorage) throw new Error('statusStorage unavailable'); + const enabledPlugins = await this.#statusStorage.getItem('enabled') || []; const updatedEnabled = enabledPlugins.filter(id => id !== name); - await this.statusStorage.setItem('enabled', updatedEnabled); + await this.#statusStorage.setItem('enabled', updatedEnabled); console.log(`Plugin ${name} disabled successfully`); } catch (error) { @@ -169,10 +169,10 @@ export class RefluxAPI { async listPlugins(): Promise> { try { - this.ensureStorages(); - if (!this.pluginStorage || !this.statusStorage) throw new Error('storages unavailable'); - const pluginKeys = await this.pluginStorage.keys(); - const enabledPlugins = await this.statusStorage.getItem('enabled') || []; + this.#ensureStorages(); + if (!this.#pluginStorage || !this.#statusStorage) throw new Error('storages unavailable'); + const pluginKeys = await this.#pluginStorage.keys(); + const enabledPlugins = await this.#statusStorage.getItem('enabled') || []; const metadataStorage = localforage.createInstance({ name: 'Reflux', storeName: 'pluginMetadata' @@ -181,7 +181,7 @@ export class RefluxAPI { const plugins: Array<{ name: string; sites: string[]; enabled: boolean; function: string }> = []; for (const key of pluginKeys) { - const pluginCode = await this.pluginStorage.getItem(key); + const pluginCode = await this.#pluginStorage.getItem(key); const metadata = await metadataStorage.getItem<{sites: string[], name: string}>(key); if (pluginCode) { @@ -203,9 +203,9 @@ export class RefluxAPI { async getEnabledPlugins(): Promise { try { - this.ensureStorages(); - if (!this.statusStorage) return []; - return await this.statusStorage.getItem('enabled') || []; + this.#ensureStorages(); + if (!this.#statusStorage) return []; + return await this.#statusStorage.getItem('enabled') || []; } catch (error) { console.error('Error getting enabled plugins:', error); return []; diff --git a/src/index.ts b/src/index.ts index b99f638..8adc5a6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,13 +15,16 @@ export type RefluxOptions = { export default class RefluxTransport implements BareTransport { ready = false; - private inner!: BareTransport; - private wrapped!: MiddlewareTransport; + #inner!: BareTransport; + #wrapped!: MiddlewareTransport; + #opts: RefluxOptions; - constructor(private opts: RefluxOptions) {} + constructor(opts: RefluxOptions) { + this.#opts = opts; + } get middleware(): MiddlewareTransport { - return this.wrapped; + return this.#wrapped; } async init() { @@ -30,7 +33,7 @@ export default class RefluxTransport implements BareTransport { middleware = [], controlPort, ...innerOptions - } = this.opts; + } = this.#opts; console.debug('%cRF%c Initializing transport wrapper', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -38,14 +41,14 @@ export default class RefluxTransport implements BareTransport { const mod = await import(transportPath); const TransportClass = mod.default; - this.inner = new TransportClass(innerOptions); + this.#inner = new TransportClass(innerOptions); - if (typeof this.inner.init === 'function') { - await this.inner.init(); + if (typeof this.#inner.init === 'function') { + await this.#inner.init(); } - this.wrapped = new MiddlewareTransport(this.inner); - await this.wrapped.init(); + this.#wrapped = new MiddlewareTransport(this.#inner); + await this.#wrapped.init(); this.ready = true; console.debug('%cRF%c Transport ready', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -56,7 +59,7 @@ export default class RefluxTransport implements BareTransport { } async meta() { - return this.wrapped.meta?.(); + return this.#wrapped.meta?.(); } async request( @@ -66,7 +69,7 @@ export default class RefluxTransport implements BareTransport { headers: BareHeaders, signal?: AbortSignal ): Promise { - return this.wrapped.request(remote, method, body, headers, signal); + return this.#wrapped.request(remote, method, body, headers, signal); } connect( @@ -78,7 +81,7 @@ export default class RefluxTransport implements BareTransport { onclose: (code: number, reason: string) => void, onerror: (error: string) => void ): [(data: Blob | ArrayBuffer | string) => void, (code: number, reason: string) => void] { - return this.wrapped.connect( + return this.#wrapped.connect( url, protocols, requestHeaders, diff --git a/src/middleware.ts b/src/middleware.ts index 19ef778..9cbcfa4 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -10,20 +10,20 @@ import localforage from "localforage"; export class MiddlewareTransport implements BareTransport { ready = false; - private middleware: Map = new Map(); - private plugins: Map = new Map(); - private pluginStorage = localforage.createInstance({ + #middleware: Map = new Map(); + #plugins: Map = new Map(); + #pluginStorage = localforage.createInstance({ name: 'Reflux', storeName: 'plugins' }); - private statusStorage = localforage.createInstance({ + #statusStorage = localforage.createInstance({ name: 'Reflux', storeName: 'status' }); - - constructor(private readonly inner: BareTransport) { +readonly #inner: BareTransport; + constructor(inner: BareTransport) { try { - const innerAny = this.inner as any; + const innerAny = (this.#inner = inner) as any; console.debug('%cRF%c Constructed with inner transport:', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', '', { name: innerAny?.constructor?.name || '', ready: innerAny?.ready @@ -36,20 +36,20 @@ export class MiddlewareTransport implements BareTransport { public async reloadPlugins(): Promise { console.log('%cRF%c Reloading plugins...', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - this.plugins.clear(); - this.middleware.clear(); + this.#plugins.clear(); + this.#middleware.clear(); - await this.loadPluginsFromStorage(); + await this.#loadPluginsFromStorage(); console.log('%cRF%c Plugin reload complete', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); } - private async loadPluginsFromStorage(): Promise { + async #loadPluginsFromStorage(): Promise { console.debug('%cRF%c loadPluginsFromStorage() called', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); try { - const enabledPluginIds = await this.statusStorage.getItem('enabled') || []; + const enabledPluginIds = await this.#statusStorage.getItem('enabled') || []; - const pluginKeys = await this.pluginStorage.keys(); + const pluginKeys = await this.#pluginStorage.keys(); console.log('%cRF%c Debug Info:', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log('%cRF%c All plugin keys in storage:', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', '', pluginKeys); @@ -61,7 +61,7 @@ export class MiddlewareTransport implements BareTransport { }); for (const pluginId of pluginKeys) { - const pluginCode = await this.pluginStorage.getItem(pluginId); + const pluginCode = await this.#pluginStorage.getItem(pluginId); const metadata = await metadataStorage.getItem<{sites: string[], name: string}>(pluginId); console.log(`%cRF%c [Plugin: ${pluginId}]`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -82,7 +82,7 @@ export class MiddlewareTransport implements BareTransport { }; console.log(`%cRF%c Loading plugin: ${pluginId}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - await this.addPlugin(plugin); + await this.#addPlugin(plugin); console.log(`%cRF%c Plugin loaded successfully: ${pluginId}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); } else { console.log(`%cRF%c Plugin has no code: ${pluginId}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -95,35 +95,35 @@ export class MiddlewareTransport implements BareTransport { console.log(`%cRF%c Summary:`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c Total plugins in storage: ${pluginKeys.length}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c Enabled plugins: ${enabledPluginIds.length}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - console.log(`%cRF%c Loaded plugins: ${this.plugins.size}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - console.log(`%cRF%c Active middleware: ${this.middleware.size}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); + console.log(`%cRF%c Loaded plugins: ${this.#plugins.size}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); + console.log(`%cRF%c Active middleware: ${this.#middleware.size}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); } catch (error) { console.error('%cRF%c Error loading plugins from storage:', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', '', error); } } - private isMiddlewareEnabled(middleware: MiddlewareFunction): boolean { + #isMiddlewareEnabled(middleware: MiddlewareFunction): boolean { if (typeof middleware.enabled === 'function') { return middleware.enabled(); } return middleware.enabled !== false; } - private async addPlugin(plugin: RefluxPlugin): Promise { + async #addPlugin(plugin: RefluxPlugin): Promise { console.log(`%cRF%c Adding plugin: ${plugin.name}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c Sites: ${JSON.stringify(plugin.sites)}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c Function length: ${plugin.function.length} characters`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - this.plugins.set(plugin.name, plugin); + this.#plugins.set(plugin.name, plugin); const pluginMiddleware: MiddlewareFunction = { id: plugin.name, onResponse: async (ctx, next) => { const response = await next(); - const shouldRun = this.shouldPluginRunOnSite(plugin, ctx.request.remote); + const shouldRun = this.#shouldPluginRunOnSite(plugin, ctx.request.remote); - const contentType = this.normalizeHeaderValue(response.headers, 'content-type'); + const contentType = this.#normalizeHeaderValue(response.headers, 'content-type'); console.log(`%cRF%c [${plugin.name}] URL: ${ctx.request.remote.href}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c [${plugin.name}] Should run: ${shouldRun}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -136,12 +136,12 @@ export class MiddlewareTransport implements BareTransport { try { const [stream1, stream2] = response.body.tee(); - const body = await this.streamToString(stream1); + const body = await this.#streamToString(stream1); if (body && body.includes("")) { try { console.log(`%cRF%c [${plugin.name}] Processing HTML body (${body.length} chars)`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - const result = this.executePlugin(plugin, body, ctx.request.remote.href, this.normalizeHeaders(response.headers)); + const result = this.#executePlugin(plugin, body, ctx.request.remote.href, this.#normalizeHeaders(response.headers)); if (typeof result === 'string' && result !== body) { console.log(`%cRF%c [${plugin.name}] Plugin modified content (${result.length} chars)`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -173,12 +173,12 @@ export class MiddlewareTransport implements BareTransport { return response; } } else { - const body = await this.bodyToString(response.body); + const body = await this.#bodyToString(response.body); if (body && body.includes("")) { try { console.log(`%cRF%c [${plugin.name}] Processing HTML body (${body.length} chars)`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - const result = this.executePlugin(plugin, body, ctx.request.remote.href, this.normalizeHeaders(response.headers)); + const result = this.#executePlugin(plugin, body, ctx.request.remote.href, this.#normalizeHeaders(response.headers)); if (typeof result === 'string' && result !== body) { console.log(`%cRF%c [${plugin.name}] Plugin modified content (${result.length} chars)`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -210,11 +210,11 @@ export class MiddlewareTransport implements BareTransport { } }; - this.middleware.set(plugin.name, pluginMiddleware); + this.#middleware.set(plugin.name, pluginMiddleware); console.log(`%cRF%c Plugin middleware registered: ${plugin.name}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); } - private executePlugin(plugin: RefluxPlugin, body: string, url: string, headers: Record): string { + #executePlugin(plugin: RefluxPlugin, body: string, url: string, headers: Record): string { console.log(`%cRF%c Running plugin: ${plugin.name}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c URL: ${url}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); console.log(`%cRF%c Body length: ${body.length}`, 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); @@ -269,12 +269,12 @@ export class MiddlewareTransport implements BareTransport { return modifiedBody; } - private removePlugin(name: string): void { - this.plugins.delete(name); - this.middleware.delete(name); + #removePlugin(name: string): void { + this.#plugins.delete(name); + this.#middleware.delete(name); } - private shouldPluginRunOnSite(plugin: RefluxPlugin, url: URL): boolean { + #shouldPluginRunOnSite(plugin: RefluxPlugin, url: URL): boolean { if (plugin.sites.includes('*')) { return true; } @@ -289,7 +289,7 @@ export class MiddlewareTransport implements BareTransport { }); } - private normalizeHeaders(headers: Record): Record { + #normalizeHeaders(headers: Record): Record { const out: Record = {}; for (const key of Object.keys(headers || {})) { const val = headers[key]; @@ -306,24 +306,24 @@ export class MiddlewareTransport implements BareTransport { return out; } - private normalizeHeaderValue(headers: Record, name: string): string | null { + #normalizeHeaderValue(headers: Record, name: string): string | null { const n = name.toLowerCase(); - const normalized = this.normalizeHeaders(headers || {}); + const normalized = this.#normalizeHeaders(headers || {}); return normalized[n] || null; } - private async bodyToString(body: any): Promise { + async #bodyToString(body: any): Promise { if (!body) return null; if (typeof body === 'string') return body; if (body instanceof Blob) return await body.text(); if (body instanceof ArrayBuffer) return new TextDecoder().decode(body); if (body instanceof ReadableStream) { - return await this.streamToString(body); + return await this.#streamToString(body); } return String(body); } - private async streamToString(stream: ReadableStream): Promise { + async #streamToString(stream: ReadableStream): Promise { const reader = stream.getReader(); const chunks: Uint8Array[] = []; let totalLength = 0; @@ -352,20 +352,20 @@ export class MiddlewareTransport implements BareTransport { async init() { console.debug('%cRF%c init() - initializing inner transport', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); try { - await this.inner.init?.(); + await this.#inner.init?.(); } catch (err) { console.error('%cRF%c Error initializing inner transport:', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', '', err); throw err; } console.debug('%cRF%c inner transport initialized, loading plugins', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); - await this.loadPluginsFromStorage(); + await this.#loadPluginsFromStorage(); this.ready = true; console.debug('%cRF%c init() complete, middleware ready', 'background: #0066cc; color: white; padding: 2px 4px; border-radius: 2px; font-weight: bold', ''); } async meta() { - return this.inner.meta?.(); + return this.#inner.meta?.(); } async request( @@ -383,9 +383,9 @@ export class MiddlewareTransport implements BareTransport { signal }; - const processedRequest = await this.processRequestMiddleware(requestContext); + const processedRequest = await this.#processRequestMiddleware(requestContext); - const response = await this.inner.request( + const response = await this.#inner.request( processedRequest.remote, processedRequest.method, processedRequest.body, @@ -397,16 +397,16 @@ export class MiddlewareTransport implements BareTransport { request: processedRequest }; - const processedResponse = await this.processResponseMiddleware(responseContext, response); + const processedResponse = await this.#processResponseMiddleware(responseContext, response); return processedResponse; } - private async processRequestMiddleware(initialContext: RequestContext): Promise { + async #processRequestMiddleware(initialContext: RequestContext): Promise { let currentContext = { ...initialContext }; - const enabledMiddleware = Array.from(this.middleware.values()) - .filter(middleware => this.isMiddlewareEnabled(middleware) && middleware.onRequest); + const enabledMiddleware = Array.from(this.#middleware.values()) + .filter(middleware => this.#isMiddlewareEnabled(middleware) && middleware.onRequest); for (const middleware of enabledMiddleware) { if (middleware.onRequest) { @@ -431,14 +431,14 @@ export class MiddlewareTransport implements BareTransport { return currentContext; } - private async processResponseMiddleware( + async #processResponseMiddleware( context: ResponseContext, initialResponse: BareTransferrableResponse ): Promise { let currentResponse: BareTransferrableResponse = { ...initialResponse }; - const enabledMiddleware = Array.from(this.middleware.values()) - .filter(middleware => this.isMiddlewareEnabled(middleware) && middleware.onResponse); + const enabledMiddleware = Array.from(this.#middleware.values()) + .filter(middleware => this.#isMiddlewareEnabled(middleware) && middleware.onResponse); for (const middleware of enabledMiddleware) { if (middleware.onResponse) { @@ -488,13 +488,13 @@ export class MiddlewareTransport implements BareTransport { onclose: (code: number, reason: string) => void, onerror: (error: string) => void ): [(data: Blob | ArrayBuffer | string) => void, (code: number, reason: string) => void] { - const [send, close] = this.inner.connect( + const [send, close] = this.#inner.connect( url, protocols, requestHeaders, onopen, (data: Blob | ArrayBuffer | string) => { - this.processWebSocketMessage(data, "receive").then(processedData => { + this.#processWebSocketMessage(data, "receive").then(processedData => { onmessage(processedData); }); }, @@ -503,21 +503,21 @@ export class MiddlewareTransport implements BareTransport { ); const wrappedSend = async (data: Blob | ArrayBuffer | string) => { - const processedData = await this.processWebSocketMessage(data, "send"); + const processedData = await this.#processWebSocketMessage(data, "send"); send(processedData); }; return [wrappedSend, close]; } - private async processWebSocketMessage( + async #processWebSocketMessage( data: Blob | ArrayBuffer | string, direction: "send" | "receive" ): Promise { let processedData = data; - const enabledMiddleware = Array.from(this.middleware.values()) - .filter(middleware => this.isMiddlewareEnabled(middleware) && middleware.modifyWebSocketMessage); + const enabledMiddleware = Array.from(this.#middleware.values()) + .filter(middleware => this.#isMiddlewareEnabled(middleware) && middleware.modifyWebSocketMessage); for (const middleware of enabledMiddleware) { if (middleware.modifyWebSocketMessage) {