Multiple PriceFeed subscriptions

This commit is contained in:
Aleksandr Kraiz
2022-05-22 23:15:30 +04:00
parent 5ffc5ed00c
commit 9c3455e1b2
4 changed files with 66 additions and 52 deletions

View File

@@ -347,33 +347,30 @@ orionUnit.orionAggregator.ws.unsubscribe("btasabu");
## Price Feed Websocket Stream
> :warning: **Currently supported only one subscription per subscription type**
```ts
orionUnit.priceFeed.ws.subscribe(
"allTickers",
(tickers) => {
const allTickersSubscription = orionUnit.priceFeed.ws.subscribe("allTickers", {
callback: (tickers) => {
console.log(tickers);
},
undefined
);
orionUnit.priceFeed.ws.unsubscribe("allTickers");
});
allTickersSubscription.unsubscribe();
orionUnit.priceFeed.ws.unsubscribe("allTickers", allTickersSubscription.id); // Also you can unsubscribe like this
orionUnit.priceFeed.ws.subscribe(
"ticker",
(ticker) => {
const tickerSubscription = orionUnit.priceFeed.ws.subscribe("ticker", {
callback: (ticker) => {
console.log(tricker);
},
"ORN-USDT"
);
orionUnit.priceFeed.ws.unsubscribe("ticker");
payload: "ORN-USDT",
});
tickerSubscription.subscription();
orionUnit.priceFeed.ws.unsubscribe("ticker", tickerSubscription.id);
orionUnit.priceFeed.ws.subscribe(
"lastPrice",
({ pair, price }) => {
const lastPriceSubscription = orionUnit.priceFeed.ws.subscribe("lastPrice", {
callback: ({ pair, price }) => {
console.log(`Price: ${price}`);
},
"ORN-USDT"
);
orionUnit.priceFeed.ws.unsubscribe("lastPrice");
payload: "ORN-USDT",
});
lastPriceSubscription.unsubscribe();
orionUnit.priceFeed.ws.unsubscribe("lastPrice", lastPriceSubscription.id);
```

View File

@@ -1,6 +1,6 @@
{
"name": "@orionprotocol/sdk",
"version": "0.9.0",
"version": "0.10.0",
"description": "Orion Protocol SDK",
"main": "./lib/esm/index.js",
"module": "./lib/esm/index.js",

View File

@@ -38,7 +38,7 @@ export const subscriptions = {
payload: false as const,
},
[priceFeedSubscriptions.TICKER]: {
schema: z.tuple([z.number(), tickerInfoSchema]),
schema: z.tuple([z.number(), tickerInfoSchema]).transform(([, tickerInfo]) => tickerInfo),
payload: true as const,
},
[priceFeedSubscriptions.LAST_PRICE]: {
@@ -47,18 +47,24 @@ export const subscriptions = {
},
};
export type SubscriptionType = keyof typeof subscriptions
export type SubscriptionType = keyof typeof subscriptions;
export type Subscription<
T extends SubscriptionType,
Schema = z.infer<typeof subscriptions[T]['schema']>
> = typeof subscriptions[T] extends { payload: true }
? {
callback: (data: Schema) => void,
payload: string,
} : {
callback: (data: Schema) => void,
}
export type Payload<T extends SubscriptionType> = typeof subscriptions[T] extends { payload: true } ? string : undefined;
export type ResponseSchemaType<T extends SubscriptionType> = typeof subscriptions[T]['schema'];
export default class PriceFeedSubscription<S extends SubscriptionType> {
export default class PriceFeedSubscription<T extends SubscriptionType = SubscriptionType> {
public readonly id: string;
private readonly callback: (data: z.infer<ResponseSchemaType<S>>) => void;
private readonly callback: Subscription<T>['callback'];
private readonly payload: Payload<S>;
private readonly payload?: string;
private ws?: WebSocket;
@@ -66,19 +72,20 @@ export default class PriceFeedSubscription<S extends SubscriptionType> {
private heartbeatInterval?: ReturnType<typeof setInterval>;
private readonly type: S;
readonly type: T;
constructor(
type: S,
type: T,
url: string,
callback: (data: z.infer<ResponseSchemaType<S>>) => void,
payload: Payload<S>,
params: Subscription<T>,
) {
this.id = uuidv4();
this.url = url;
this.type = type;
this.payload = payload;
this.callback = callback;
if ('payload' in params) {
this.payload = params.payload;
}
this.callback = params.callback;
this.init();
}

View File

@@ -1,11 +1,15 @@
import { z } from 'zod';
import PriceFeedSubscription, { Payload, ResponseSchemaType, SubscriptionType } from './PriceFeedSubscription';
import PriceFeedSubscription, { SubscriptionType, Subscription } from './PriceFeedSubscription';
export * as schemas from './schemas';
export class PriceFeedWS {
private subscriptions: Partial<{
[S in SubscriptionType]: PriceFeedSubscription<S>
}> = { };
[K in SubscriptionType]: Partial<
Record<
string,
PriceFeedSubscription<K>
>
>;
}> = {};
private url: string;
@@ -15,23 +19,29 @@ export class PriceFeedWS {
subscribe<S extends SubscriptionType>(
type: S,
callback: (data: z.infer<ResponseSchemaType<S>>) => void,
payload: Payload<S>,
params: Subscription<S>,
) {
if (this.subscriptions[type]) throw new Error(`Subscription already exists for '${type}'. Please unsubscribe first.`);
const sub = new PriceFeedSubscription(
type,
this.url,
params,
);
this.subscriptions = {
...this.subscriptions,
[type]: new PriceFeedSubscription(
type,
this.url,
callback,
payload,
),
[type]: {
...this.subscriptions[type],
[sub.id]: sub,
},
};
return {
type: sub.type,
id: sub.id,
unsubscribe: () => this.unsubscribe(sub.type, sub.id),
};
}
unsubscribe<S extends SubscriptionType>(type: S) {
this.subscriptions[type]?.kill();
delete this.subscriptions[type];
unsubscribe(subType: SubscriptionType, subId: string) {
this.subscriptions[subType]?.[subId]?.kill();
delete this.subscriptions[subType]?.[subId];
}
}