/**
* 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;
}