@fullstackcraftllc/floe 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,411 @@
1
+ import { NormalizedOption, NormalizedTicker } from "../types";
2
+ /**
3
+ * Supported broker integrations for the FloeClient.
4
+ * @enum {string}
5
+ */
6
+ export declare enum Broker {
7
+ /** Tradier brokerage API */
8
+ TRADIER = "tradier"
9
+ }
10
+ /**
11
+ * Event types emitted by the FloeClient.
12
+ * @remarks
13
+ * Used with the {@link FloeClient.on} and {@link FloeClient.off} methods for event-driven updates.
14
+ */
15
+ type FloeEventType = 'tickerUpdate' | 'optionUpdate' | 'error' | 'connected' | 'disconnected';
16
+ /**
17
+ * Event payload map for type-safe event handling.
18
+ */
19
+ interface FloeEventMap {
20
+ tickerUpdate: NormalizedTicker;
21
+ optionUpdate: NormalizedOption;
22
+ error: Error;
23
+ connected: {
24
+ broker: Broker;
25
+ };
26
+ disconnected: {
27
+ broker: Broker;
28
+ reason?: string;
29
+ };
30
+ }
31
+ /**
32
+ * Listener function type for FloeClient events.
33
+ * @template T - The event type from FloeEventType
34
+ */
35
+ type FloeEventListener<T extends FloeEventType> = (data: FloeEventMap[T]) => void;
36
+ /**
37
+ * FloeClient provides a unified, broker-agnostic interface for subscribing to
38
+ * real-time market data including stock tickers and options.
39
+ *
40
+ * @remarks
41
+ * The client normalizes data from various brokers into a consistent format,
42
+ * allowing consumers to switch brokers without changing their application code.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const client = new FloeClient();
47
+ *
48
+ * // Connect to a broker
49
+ * client.connect(Broker.TRADIER, 'your-api-key');
50
+ *
51
+ * // Subscribe to updates using the event emitter pattern
52
+ * client.on('tickerUpdate', (ticker) => {
53
+ * console.log(`${ticker.symbol}: ${ticker.price}`);
54
+ * });
55
+ *
56
+ * // Or use the callback pattern
57
+ * client.onTickerDataChange((ticker) => {
58
+ * console.log(`${ticker.symbol}: ${ticker.price}`);
59
+ * });
60
+ *
61
+ * // Subscribe to specific tickers
62
+ * client.subscribeToTickers(['AAPL', 'GOOGL', 'MSFT']);
63
+ * ```
64
+ */
65
+ export declare class FloeClient {
66
+ /** Currently connected broker, or null if not connected */
67
+ private currentBroker;
68
+ /** List of ticker symbols currently subscribed to */
69
+ private currentSubscribedTickers;
70
+ /** List of option symbols (OCC format) currently subscribed to */
71
+ private currentSubscribedOptions;
72
+ /** Cache of the latest normalized ticker data */
73
+ private normalizedTickers;
74
+ /** Cache of the latest normalized option data */
75
+ private normalizedOptions;
76
+ /** Tradier broker client instance */
77
+ private tradierClient;
78
+ /** Event listeners registry for the EventEmitter pattern */
79
+ private eventListeners;
80
+ /** Callback for ticker data changes (legacy callback pattern) */
81
+ private tickerDataCallback;
82
+ /** Callback for option data changes (legacy callback pattern) */
83
+ private optionDataCallback;
84
+ /**
85
+ * Creates a new FloeClient instance.
86
+ *
87
+ * @remarks
88
+ * The client is created in a disconnected state. Call {@link connect} to
89
+ * establish a connection to a broker before subscribing to data.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const client = new FloeClient();
94
+ * ```
95
+ */
96
+ constructor();
97
+ /**
98
+ * Establishes a connection to a broker's API.
99
+ *
100
+ * @param broker - The broker to connect to (e.g., Broker.TRADIER)
101
+ * @param authKey - The API authentication key or token for the broker
102
+ *
103
+ * @throws {Error} Throws if the specified broker is not supported
104
+ *
105
+ * @remarks
106
+ * Must be called before subscribing to any market data. Only one broker
107
+ * connection is active at a time; calling connect again will switch brokers.
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * await client.connect(Broker.TRADIER, 'your-tradier-api-key');
112
+ * ```
113
+ */
114
+ connect(broker: Broker, authKey: string): Promise<void>;
115
+ /**
116
+ * Disconnects from the current broker.
117
+ *
118
+ * @remarks
119
+ * Closes the WebSocket connection and clears all subscriptions.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * client.disconnect();
124
+ * ```
125
+ */
126
+ disconnect(): void;
127
+ /**
128
+ * Subscribes to real-time updates for the specified stock ticker symbols.
129
+ *
130
+ * @param tickers - Array of ticker symbols to subscribe to (e.g., ['AAPL', 'GOOGL'])
131
+ *
132
+ * @throws {Error} Throws if no broker connection has been established
133
+ *
134
+ * @remarks
135
+ * Ticker updates will be delivered via the 'tickerUpdate' event or through
136
+ * the callback registered with {@link onTickerDataChange}.
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * client.subscribeToTickers(['AAPL', 'GOOGL', 'MSFT']);
141
+ * ```
142
+ */
143
+ subscribeToTickers(tickers: Array<string>): void;
144
+ /**
145
+ * Subscribes to real-time updates for the specified option contracts.
146
+ *
147
+ * @param symbols - Array of option symbols in OCC format
148
+ * (e.g., ['AAPL230120C00150000'] for AAPL $150 Call expiring Jan 20, 2023)
149
+ *
150
+ * @throws {Error} Throws if no broker connection has been established
151
+ *
152
+ * @remarks
153
+ * Option symbols must be in the standard OCC (Options Clearing Corporation) format:
154
+ * - Root symbol (up to 6 characters, left-padded)
155
+ * - Expiration date (YYMMDD)
156
+ * - Option type (C for call, P for put)
157
+ * - Strike price (8 digits, price × 1000, left-padded with zeros)
158
+ *
159
+ * Option updates will be delivered via the 'optionUpdate' event or through
160
+ * the callback registered with {@link onOptionDataChange}.
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * // Subscribe to AAPL $150 Call expiring Jan 20, 2023
165
+ * client.subscribeToOptions(['AAPL230120C00150000']);
166
+ * ```
167
+ */
168
+ subscribeToOptions(symbols: Array<string>): void;
169
+ /**
170
+ * Unsubscribes from real-time updates for the specified stock ticker symbols.
171
+ *
172
+ * @param tickers - Array of ticker symbols to unsubscribe from
173
+ *
174
+ * @throws {Error} Throws if no broker connection has been established
175
+ *
176
+ * @remarks
177
+ * After unsubscribing, no further updates will be received for these tickers.
178
+ * Has no effect if the specified tickers were not previously subscribed.
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * client.unsubscribeFromTickers(['AAPL', 'GOOGL']);
183
+ * ```
184
+ */
185
+ unsubscribeFromTickers(tickers: Array<string>): void;
186
+ /**
187
+ * Unsubscribes from real-time updates for the specified option contracts.
188
+ *
189
+ * @param symbols - Array of option symbols in OCC format to unsubscribe from
190
+ *
191
+ * @throws {Error} Throws if no broker connection has been established
192
+ *
193
+ * @remarks
194
+ * After unsubscribing, no further updates will be received for these options.
195
+ * Has no effect if the specified options were not previously subscribed.
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * client.unsubscribeFromOptions(['AAPL230120C00150000']);
200
+ * ```
201
+ */
202
+ unsubscribeFromOptions(symbols: Array<string>): void;
203
+ /**
204
+ * Fetches open interest and initial option data via REST API.
205
+ *
206
+ * @param symbols - Array of option symbols in OCC format to fetch data for.
207
+ * If not provided, fetches data for all currently subscribed options.
208
+ * @returns Promise that resolves when all data has been fetched
209
+ *
210
+ * @throws {Error} Throws if no broker connection has been established
211
+ *
212
+ * @remarks
213
+ * Open interest is not available via streaming and must be fetched via REST API.
214
+ * This method should be called after subscribing to options to populate
215
+ * open interest, volume, and initial bid/ask values.
216
+ *
217
+ * The fetched data is automatically merged into the option cache and
218
+ * emitted via 'optionUpdate' events.
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * // Subscribe to options
223
+ * client.subscribeToOptions(optionSymbols);
224
+ *
225
+ * // Fetch open interest data
226
+ * await client.fetchOpenInterest();
227
+ *
228
+ * // Options now have open interest populated
229
+ * client.on('optionUpdate', (option) => {
230
+ * console.log(`${option.occSymbol}: OI=${option.openInterest}`);
231
+ * });
232
+ * ```
233
+ */
234
+ fetchOpenInterest(symbols?: string[]): Promise<void>;
235
+ /**
236
+ * Returns cached option data for a specific symbol.
237
+ *
238
+ * @param occSymbol - OCC option symbol
239
+ * @returns Cached option data, or undefined if not found
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * const option = client.getOption('QQQ250117C00530000');
244
+ * console.log(`Open Interest: ${option?.openInterest}`);
245
+ * ```
246
+ */
247
+ getOption(occSymbol: string): NormalizedOption | undefined;
248
+ /**
249
+ * Returns all cached options.
250
+ *
251
+ * @returns Map of OCC symbols to option data
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * const allOptions = client.getAllOptions();
256
+ * for (const [symbol, option] of allOptions) {
257
+ * console.log(`${symbol}: OI=${option.openInterest}`);
258
+ * }
259
+ * ```
260
+ */
261
+ getAllOptions(): Map<string, NormalizedOption>;
262
+ /**
263
+ * Registers an event listener for the specified event type.
264
+ *
265
+ * @template T - The event type
266
+ * @param event - The event type to listen for
267
+ * @param listener - The callback function to invoke when the event occurs
268
+ * @returns The FloeClient instance for method chaining
269
+ *
270
+ * @remarks
271
+ * Multiple listeners can be registered for the same event type.
272
+ * Use {@link off} to remove a listener when it's no longer needed.
273
+ *
274
+ * @example
275
+ * ```typescript
276
+ * client
277
+ * .on('tickerUpdate', (ticker) => console.log(ticker))
278
+ * .on('error', (error) => console.error(error));
279
+ * ```
280
+ */
281
+ on<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
282
+ /**
283
+ * Removes an event listener for the specified event type.
284
+ *
285
+ * @template T - The event type
286
+ * @param event - The event type to stop listening for
287
+ * @param listener - The callback function to remove
288
+ * @returns The FloeClient instance for method chaining
289
+ *
290
+ * @remarks
291
+ * The listener must be the exact same function reference that was passed to {@link on}.
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * const handler = (ticker) => console.log(ticker);
296
+ * client.on('tickerUpdate', handler);
297
+ * // Later...
298
+ * client.off('tickerUpdate', handler);
299
+ * ```
300
+ */
301
+ off<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
302
+ /**
303
+ * Registers a one-time event listener that automatically removes itself after firing.
304
+ *
305
+ * @template T - The event type
306
+ * @param event - The event type to listen for
307
+ * @param listener - The callback function to invoke once when the event occurs
308
+ * @returns The FloeClient instance for method chaining
309
+ *
310
+ * @example
311
+ * ```typescript
312
+ * client.once('connected', ({ broker }) => {
313
+ * console.log(`Connected to ${broker}`);
314
+ * });
315
+ * ```
316
+ */
317
+ once<T extends FloeEventType>(event: T, listener: FloeEventListener<T>): this;
318
+ /**
319
+ * Emits an event to all registered listeners.
320
+ *
321
+ * @template T - The event type
322
+ * @param event - The event type to emit
323
+ * @param data - The event payload
324
+ *
325
+ * @internal
326
+ * @remarks
327
+ * This method is used internally to dispatch events. It also triggers
328
+ * legacy callback handlers for backwards compatibility.
329
+ */
330
+ private emit;
331
+ /**
332
+ * Registers a callback to be invoked whenever ticker data is updated.
333
+ *
334
+ * @param callback - Function to call with the updated ticker data
335
+ *
336
+ * @deprecated Prefer using {@link on}('tickerUpdate', callback) for new code.
337
+ * The event emitter pattern supports multiple listeners and provides
338
+ * better lifecycle management.
339
+ *
340
+ * @remarks
341
+ * Only one callback can be registered at a time. Calling this method again
342
+ * will replace the previous callback. For multiple listeners, use {@link on}.
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * client.onTickerDataChange((ticker) => {
347
+ * console.log(`${ticker.symbol} updated: ${ticker.price}`);
348
+ * });
349
+ * ```
350
+ */
351
+ onTickerDataChange(callback: (data: NormalizedTicker) => void): void;
352
+ /**
353
+ * Registers a callback to be invoked whenever option data is updated.
354
+ *
355
+ * @param callback - Function to call with the updated option data
356
+ *
357
+ * @deprecated Prefer using {@link on}('optionUpdate', callback) for new code.
358
+ * The event emitter pattern supports multiple listeners and provides
359
+ * better lifecycle management.
360
+ *
361
+ * @remarks
362
+ * Only one callback can be registered at a time. Calling this method again
363
+ * will replace the previous callback. For multiple listeners, use {@link on}.
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * client.onOptionDataChange((option) => {
368
+ * console.log(`${option.symbol} bid: ${option.bid}, ask: ${option.ask}`);
369
+ * });
370
+ * ```
371
+ */
372
+ onOptionDataChange(callback: (data: NormalizedOption) => void): void;
373
+ /**
374
+ * Returns the list of currently subscribed ticker symbols.
375
+ *
376
+ * @returns Array of ticker symbols currently subscribed to
377
+ *
378
+ * @example
379
+ * ```typescript
380
+ * const tickers = client.getSubscribedTickers();
381
+ * console.log(`Subscribed to: ${tickers.join(', ')}`);
382
+ * ```
383
+ */
384
+ getSubscribedTickers(): ReadonlyArray<string>;
385
+ /**
386
+ * Returns the list of currently subscribed option symbols.
387
+ *
388
+ * @returns Array of option symbols (OCC format) currently subscribed to
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * const options = client.getSubscribedOptions();
393
+ * console.log(`Subscribed to ${options.length} options`);
394
+ * ```
395
+ */
396
+ getSubscribedOptions(): ReadonlyArray<string>;
397
+ /**
398
+ * Returns whether the client is currently connected to a broker.
399
+ *
400
+ * @returns True if connected to a broker, false otherwise
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * if (client.isConnected()) {
405
+ * client.subscribeToTickers(['AAPL']);
406
+ * }
407
+ * ```
408
+ */
409
+ isConnected(): boolean;
410
+ }
411
+ export {};