/** * WioEX Stream SDK - jQuery Plugin * * Provides jQuery-friendly wrapper around WioexStreamClient * * Usage: * ```javascript * $('#app').wioexStream({ * tokenEndpoint: '/api/stream/token', * stocks: ['AAPL', 'TSLA'], * debug: true * }); * ``` */ /// import { WioexStreamClient } from './WioexStreamClient'; import type { WioexStreamConfig, TickerData } from './types'; import { Logger } from './utils/Logger'; interface JQueryWioexStreamConfig extends Omit { /** Stocks to subscribe to on initialization */ stocks?: string | string[]; /** Auto-connect on initialization (default: true) */ autoConnect?: boolean; } declare global { interface JQuery { wioexStream(config: JQueryWioexStreamConfig): JQuery; wioexStream(method: 'subscribe', stocks: string | string[]): JQuery; wioexStream(method: 'unsubscribe', stocks: string | string[]): JQuery; wioexStream(method: 'disconnect'): JQuery; wioexStream(method: 'getStats'): unknown; wioexStream(method: 'getClient'): WioexStreamClient | undefined; data(key: 'wioexStream'): WioexStreamClient | undefined; } } declare const jQuery: ((selector: string | Element | Document) => JQuery) & { fn: { wioexStream: ( configOrMethod: JQueryWioexStreamConfig | string, ...args: unknown[] ) => JQuery | WioexStreamClient | undefined | unknown; }; }; /** * jQuery Plugin Definition */ (function ($) { $.fn.wioexStream = function ( this: JQuery, configOrMethod: JQueryWioexStreamConfig | string, ...args: unknown[] ): JQuery | WioexStreamClient | undefined | unknown { // Method call if (typeof configOrMethod === 'string') { const method = configOrMethod as string; const $element = this.first(); const client = $element.data('wioexStream') as WioexStreamClient | undefined; if (!client) { // Always show error messages (not controlled by debug mode) const logger = new Logger(true, 'WioEX:jQuery'); logger.error('Client not initialized. Call .wioexStream(config) first.'); return this; } switch (method) { case 'subscribe': { const stocks = args[0] as string | string[]; client.subscribe(stocks); return this; } case 'unsubscribe': { const stocks = args[0] as string | string[]; client.unsubscribe(stocks); return this; } case 'disconnect': { client.disconnect(); return this; } case 'getStats': { return client.getStats(); } case 'getClient': { return client; } default: { // Always show error messages (not controlled by debug mode) const logger = new Logger(true, 'WioEX:jQuery'); logger.error(`Unknown method: ${method}`); return this; } } } // Initialization const config = configOrMethod as JQueryWioexStreamConfig; return this.each(function (this: Element) { const $element = $(this); // Check if already initialized if ($element.data('wioexStream')) { // Check if debug mode is enabled in config const logger = new Logger(config.debug ?? false, 'WioEX:jQuery'); logger.warn('Client already initialized on this element.'); return; } // Extract stocks config const stocks = config.stocks; const autoConnect = config.autoConnect ?? true; // Prepare client config const clientConfig: WioexStreamConfig = { ...config, lazyConnect: !autoConnect, }; // Remove plugin-specific options delete (clientConfig as JQueryWioexStreamConfig).stocks; delete (clientConfig as JQueryWioexStreamConfig).autoConnect; // Create client const client = new WioexStreamClient(clientConfig); // Store client on element $element.data('wioexStream', client); // Forward all events to jQuery events with 'wioex:' prefix client.on('connected', () => { $element.trigger('wioex:connected'); }); client.on('disconnected', (code, reason) => { $element.trigger('wioex:disconnected', [code, reason]); }); client.on('registered', (data) => { $element.trigger('wioex:registered', [data]); }); client.on('subscribed', (stocks) => { $element.trigger('wioex:subscribed', [stocks]); }); client.on('unsubscribed', (stocks) => { $element.trigger('wioex:unsubscribed', [stocks]); }); client.on('ticker', (data: TickerData) => { $element.trigger('wioex:ticker', [data]); }); client.on('error', (error) => { $element.trigger('wioex:error', [error]); }); client.on('stateChange', (state) => { $element.trigger('wioex:stateChange', [state]); }); client.on('reconnecting', (attempt) => { $element.trigger('wioex:reconnecting', [attempt]); }); client.on('tokenExpiring', (data) => { $element.trigger('wioex:tokenExpiring', [data]); }); client.on('tokenRefreshed', (data) => { $element.trigger('wioex:tokenRefreshed', [data]); }); client.on('tokenRefreshFailed', (error) => { $element.trigger('wioex:tokenRefreshFailed', [error]); }); client.on('tokenFetchStarted', (source) => { $element.trigger('wioex:tokenFetchStarted', [source]); }); client.on('tokenFetchSucceeded', (data) => { $element.trigger('wioex:tokenFetchSucceeded', [data]); }); client.on('tokenFetchFailed', (error, attempt, willRetry) => { $element.trigger('wioex:tokenFetchFailed', [error, attempt, willRetry]); }); // Subscribe to initial stocks if provided if (stocks) { // Subscribe after a small delay to allow event listeners to be attached setTimeout(() => { client.subscribe(stocks); }, 0); } else if (autoConnect) { // Connect immediately if no stocks provided but autoConnect is true client.connect(); } // Cleanup on element removal $element.on('remove', () => { client.disconnect(); $element.removeData('wioexStream'); }); }); }; })( // eslint-disable-next-line @typescript-eslint/no-explicit-any typeof jQuery !== 'undefined' ? jQuery : typeof window !== 'undefined' ? (window as any).jQuery : undefined ); // Export for module systems export default WioexStreamClient; // Attach to window for script tag usage if (typeof window !== 'undefined') { // eslint-disable-next-line @typescript-eslint/no-explicit-any (window as any).WioexStream = WioexStreamClient; }