growwapi
Version:
NodeJS SDK for Groww trading APIs
73 lines (72 loc) • 2.8 kB
JavaScript
import { connectToLiveFeed, generateSubscriptionTopic, liveFeedDecoder, retryStrategy } from '../utils/LiveFeed';
export class LiveFeed {
constructor() {
this.connection = null;
this.subscriptions = new Map();
this.subscriptionCallbacks = new Map();
this.retryCount = 0;
}
async connect() {
this.connection = await connectToLiveFeed();
}
async disconnect() {
if (this.connection) {
await this.connection.stream?.close();
this.connection = null;
}
}
async subscribe(type, exchangeToken) {
const subscriptionId = this.connection?.credentials.subscriptionId;
if (!subscriptionId) {
console.error('Subscription ID is not available. Please connect first.');
return undefined;
}
const topic = await generateSubscriptionTopic(type, subscriptionId, exchangeToken);
const natsSubscription = this.connection?.stream?.subscribe(topic);
if (!natsSubscription) {
console.error(`Failed to subscribe to topic: ${topic}`);
return undefined;
}
const subscription = {
natsSubscription, type, exchangeToken,
consume: (callback) => {
this.subscriptionCallbacks.set(topic, callback);
this.consume(natsSubscription, callback);
},
unsubscribe: () => {
this.subscriptionCallbacks.delete(topic);
this.unsubscribe(natsSubscription, topic);
}
};
this.subscriptions.set(topic, subscription);
return subscription;
}
unsubscribe(subscription, topic) {
if (this.connection) {
subscription.unsubscribe();
this.subscriptions.delete(topic);
}
}
async consume(subscription, callback) {
retryStrategy(this.connection, this.retryCount, () => this.disconnect(), () => this.reconnect(), async () => {
for await (const m of subscription) {
const feedType = this.subscriptions.get(m.subject)?.type;
const liveFeedData = liveFeedDecoder(feedType, m.data);
callback(liveFeedData);
}
});
}
async reconnect() {
await this.connect();
this.retryCount = 0;
for (const subscription of this.subscriptions.values()) {
const newSubscription = await this.subscribe(subscription.type, subscription.exchangeToken);
if (newSubscription) {
const callback = this.subscriptionCallbacks.get(subscription.natsSubscription.getSubject());
if (callback) {
newSubscription.consume(callback);
}
}
}
}
}