@lifi/perps-sdk 1.5.3 → 1.5.4
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.
- package/dist/cjs/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/cjs/services/resolveSubscribeQuote.js +33 -19
- package/dist/cjs/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/services/resolveSubscribeQuote.d.ts +9 -8
- package/dist/esm/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/esm/services/resolveSubscribeQuote.js +44 -27
- package/dist/esm/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/types/services/resolveSubscribeQuote.d.ts +9 -8
- package/dist/types/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/services/resolveSubscribeQuote.ts +56 -28
- package/src/version.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAUvD,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAqBpC,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
|
|
@@ -7,7 +7,7 @@ const resolveQuote_js_1 = require("./resolveQuote.js");
|
|
|
7
7
|
exports.QUOTE_THROTTLE_MS = 100;
|
|
8
8
|
async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQuote) {
|
|
9
9
|
const market = await (0, resolveQuote_js_1.resolveQuoteMarket)(client, provider, params);
|
|
10
|
-
|
|
10
|
+
let latestContext = await (0, resolveQuote_js_1.resolveQuotePrice)(client, provider, market.id);
|
|
11
11
|
let latestBook;
|
|
12
12
|
let lastEmitAt = Number.NEGATIVE_INFINITY;
|
|
13
13
|
let trailing;
|
|
@@ -23,32 +23,45 @@ async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQu
|
|
|
23
23
|
side: params.side,
|
|
24
24
|
sizeUsd: params.size,
|
|
25
25
|
market,
|
|
26
|
-
price,
|
|
26
|
+
price: latestContext,
|
|
27
27
|
bids: latestBook.bids,
|
|
28
28
|
asks: latestBook.asks,
|
|
29
29
|
feeTier,
|
|
30
30
|
timestamp: Date.now(),
|
|
31
31
|
}));
|
|
32
32
|
};
|
|
33
|
-
const
|
|
34
|
-
if (event.channel !== '
|
|
33
|
+
const unsubscribeContext = await ws.subscribe({ channel: 'marketContext', dex: provider, marketId: market.id }, (event) => {
|
|
34
|
+
if (event.channel !== 'marketContext') {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
if (trailing !== undefined) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const wait = exports.QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
|
|
42
|
-
if (wait <= 0) {
|
|
43
|
-
emit();
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
trailing = setTimeout(() => {
|
|
47
|
-
trailing = undefined;
|
|
48
|
-
emit();
|
|
49
|
-
}, wait);
|
|
50
|
-
}
|
|
37
|
+
latestContext = event.data;
|
|
51
38
|
});
|
|
39
|
+
let unsubscribeBook;
|
|
40
|
+
try {
|
|
41
|
+
unsubscribeBook = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
|
|
42
|
+
if (event.channel !== 'orderbook') {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
latestBook = event.data;
|
|
46
|
+
if (trailing !== undefined) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const wait = exports.QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
|
|
50
|
+
if (wait <= 0) {
|
|
51
|
+
emit();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
trailing = setTimeout(() => {
|
|
55
|
+
trailing = undefined;
|
|
56
|
+
emit();
|
|
57
|
+
}, wait);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
unsubscribeContext();
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
52
65
|
let released = false;
|
|
53
66
|
return () => {
|
|
54
67
|
if (released) {
|
|
@@ -59,7 +72,8 @@ async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQu
|
|
|
59
72
|
clearTimeout(trailing);
|
|
60
73
|
trailing = undefined;
|
|
61
74
|
}
|
|
62
|
-
|
|
75
|
+
unsubscribeContext();
|
|
76
|
+
unsubscribeBook();
|
|
63
77
|
};
|
|
64
78
|
}
|
|
65
79
|
//# sourceMappingURL=resolveSubscribeQuote.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/version.d.ts
CHANGED
package/dist/cjs/version.js
CHANGED
|
@@ -12,17 +12,18 @@ export declare const QUOTE_THROTTLE_MS = 100;
|
|
|
12
12
|
/**
|
|
13
13
|
* Shared provider-side `subscribeQuote` implementation: resolve
|
|
14
14
|
* `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
|
|
15
|
-
* subscribe to that market's orderbook
|
|
16
|
-
* update rebuild the {@link Quote}
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* subscribe to that market's orderbook and marketContext channels on `ws`,
|
|
16
|
+
* and on each book update rebuild the {@link Quote} against the latest
|
|
17
|
+
* {@link MarketContext} with the provider's public base `feeTier` — the same
|
|
18
|
+
* transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
|
|
19
|
+
* are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
|
|
20
|
+
* immediately, then at most one (trailing, latest-book) emission per
|
|
20
21
|
* interval. Both venue WS plugins delegate here; each only supplies its own
|
|
21
22
|
* base tier.
|
|
22
23
|
*
|
|
23
|
-
* The returned unsubscribe is idempotent — it releases
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* The returned unsubscribe is idempotent — it releases both underlying
|
|
25
|
+
* listeners once and cancels any pending trailing emission, so the wire
|
|
26
|
+
* subscriptions' ref counts cannot be double-decremented.
|
|
26
27
|
*
|
|
27
28
|
* @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
|
|
28
29
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
|
|
@@ -11,24 +11,27 @@ export const QUOTE_THROTTLE_MS = 100;
|
|
|
11
11
|
/**
|
|
12
12
|
* Shared provider-side `subscribeQuote` implementation: resolve
|
|
13
13
|
* `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
|
|
14
|
-
* subscribe to that market's orderbook
|
|
15
|
-
* update rebuild the {@link Quote}
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* subscribe to that market's orderbook and marketContext channels on `ws`,
|
|
15
|
+
* and on each book update rebuild the {@link Quote} against the latest
|
|
16
|
+
* {@link MarketContext} with the provider's public base `feeTier` — the same
|
|
17
|
+
* transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
|
|
18
|
+
* are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
|
|
19
|
+
* immediately, then at most one (trailing, latest-book) emission per
|
|
19
20
|
* interval. Both venue WS plugins delegate here; each only supplies its own
|
|
20
21
|
* base tier.
|
|
21
22
|
*
|
|
22
|
-
* The returned unsubscribe is idempotent — it releases
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* The returned unsubscribe is idempotent — it releases both underlying
|
|
24
|
+
* listeners once and cancels any pending trailing emission, so the wire
|
|
25
|
+
* subscriptions' ref counts cannot be double-decremented.
|
|
25
26
|
*
|
|
26
27
|
* @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
|
|
27
28
|
* @internal
|
|
28
29
|
*/
|
|
29
30
|
export async function resolveSubscribeQuote(client, provider, ws, params, feeTier, onQuote) {
|
|
30
31
|
const market = await resolveQuoteMarket(client, provider, params);
|
|
31
|
-
|
|
32
|
+
// REST snapshot seeds the context; the marketContext subscription below
|
|
33
|
+
// keeps it live so streamed impact/funding track the moving market.
|
|
34
|
+
let latestContext = await resolveQuotePrice(client, provider, market.id);
|
|
32
35
|
let latestBook;
|
|
33
36
|
let lastEmitAt = Number.NEGATIVE_INFINITY;
|
|
34
37
|
let trailing;
|
|
@@ -44,32 +47,45 @@ export async function resolveSubscribeQuote(client, provider, ws, params, feeTie
|
|
|
44
47
|
side: params.side,
|
|
45
48
|
sizeUsd: params.size,
|
|
46
49
|
market,
|
|
47
|
-
price,
|
|
50
|
+
price: latestContext,
|
|
48
51
|
bids: latestBook.bids,
|
|
49
52
|
asks: latestBook.asks,
|
|
50
53
|
feeTier,
|
|
51
54
|
timestamp: Date.now(),
|
|
52
55
|
}));
|
|
53
56
|
};
|
|
54
|
-
const
|
|
55
|
-
if (event.channel !== '
|
|
57
|
+
const unsubscribeContext = await ws.subscribe({ channel: 'marketContext', dex: provider, marketId: market.id }, (event) => {
|
|
58
|
+
if (event.channel !== 'marketContext') {
|
|
56
59
|
return;
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
if (trailing !== undefined) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
|
|
63
|
-
if (wait <= 0) {
|
|
64
|
-
emit();
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
trailing = setTimeout(() => {
|
|
68
|
-
trailing = undefined;
|
|
69
|
-
emit();
|
|
70
|
-
}, wait);
|
|
71
|
-
}
|
|
61
|
+
latestContext = event.data;
|
|
72
62
|
});
|
|
63
|
+
let unsubscribeBook;
|
|
64
|
+
try {
|
|
65
|
+
unsubscribeBook = await ws.subscribe({ channel: 'orderbook', dex: provider, marketId: market.id }, (event) => {
|
|
66
|
+
if (event.channel !== 'orderbook') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
latestBook = event.data;
|
|
70
|
+
if (trailing !== undefined) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt);
|
|
74
|
+
if (wait <= 0) {
|
|
75
|
+
emit();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
trailing = setTimeout(() => {
|
|
79
|
+
trailing = undefined;
|
|
80
|
+
emit();
|
|
81
|
+
}, wait);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
unsubscribeContext();
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
73
89
|
let released = false;
|
|
74
90
|
return () => {
|
|
75
91
|
if (released) {
|
|
@@ -80,7 +96,8 @@ export async function resolveSubscribeQuote(client, provider, ws, params, feeTie
|
|
|
80
96
|
clearTimeout(trailing);
|
|
81
97
|
trailing = undefined;
|
|
82
98
|
}
|
|
83
|
-
|
|
99
|
+
unsubscribeContext();
|
|
100
|
+
unsubscribeBook();
|
|
84
101
|
};
|
|
85
102
|
}
|
|
86
103
|
//# sourceMappingURL=resolveSubscribeQuote.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolveSubscribeQuote.js","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/version.d.ts
CHANGED
package/dist/esm/version.js
CHANGED
|
@@ -12,17 +12,18 @@ export declare const QUOTE_THROTTLE_MS = 100;
|
|
|
12
12
|
/**
|
|
13
13
|
* Shared provider-side `subscribeQuote` implementation: resolve
|
|
14
14
|
* `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
|
|
15
|
-
* subscribe to that market's orderbook
|
|
16
|
-
* update rebuild the {@link Quote}
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* subscribe to that market's orderbook and marketContext channels on `ws`,
|
|
16
|
+
* and on each book update rebuild the {@link Quote} against the latest
|
|
17
|
+
* {@link MarketContext} with the provider's public base `feeTier` — the same
|
|
18
|
+
* transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
|
|
19
|
+
* are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
|
|
20
|
+
* immediately, then at most one (trailing, latest-book) emission per
|
|
20
21
|
* interval. Both venue WS plugins delegate here; each only supplies its own
|
|
21
22
|
* base tier.
|
|
22
23
|
*
|
|
23
|
-
* The returned unsubscribe is idempotent — it releases
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* The returned unsubscribe is idempotent — it releases both underlying
|
|
25
|
+
* listeners once and cancels any pending trailing emission, so the wire
|
|
26
|
+
* subscriptions' ref counts cannot be double-decremented.
|
|
26
27
|
*
|
|
27
28
|
* @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
|
|
28
29
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolveSubscribeQuote.d.ts","sourceRoot":"","sources":["../../../src/services/resolveSubscribeQuote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EAGR,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,aAAa,EACd,MAAM,sBAAsB,CAAA;AAE7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGvD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAA;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EACjC,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,IAAI,CAAC,CAuFrB"}
|
package/dist/types/version.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
FeeTier,
|
|
3
|
+
MarketContext,
|
|
4
|
+
OrderbookResponse,
|
|
5
|
+
} from '@lifi/perps-types'
|
|
2
6
|
import type {
|
|
3
7
|
PerpsSDKClient,
|
|
4
8
|
ProviderGetQuoteParams,
|
|
@@ -20,17 +24,18 @@ export const QUOTE_THROTTLE_MS = 100
|
|
|
20
24
|
/**
|
|
21
25
|
* Shared provider-side `subscribeQuote` implementation: resolve
|
|
22
26
|
* `params.symbol` to a market on `provider` (via {@link resolveQuoteMarket}),
|
|
23
|
-
* subscribe to that market's orderbook
|
|
24
|
-
* update rebuild the {@link Quote}
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* subscribe to that market's orderbook and marketContext channels on `ws`,
|
|
28
|
+
* and on each book update rebuild the {@link Quote} against the latest
|
|
29
|
+
* {@link MarketContext} with the provider's public base `feeTier` — the same
|
|
30
|
+
* transform the one-shot `resolveQuote` applies to a REST snapshot. Emissions
|
|
31
|
+
* are throttled to {@link QUOTE_THROTTLE_MS}: the first book update emits
|
|
32
|
+
* immediately, then at most one (trailing, latest-book) emission per
|
|
28
33
|
* interval. Both venue WS plugins delegate here; each only supplies its own
|
|
29
34
|
* base tier.
|
|
30
35
|
*
|
|
31
|
-
* The returned unsubscribe is idempotent — it releases
|
|
32
|
-
*
|
|
33
|
-
*
|
|
36
|
+
* The returned unsubscribe is idempotent — it releases both underlying
|
|
37
|
+
* listeners once and cancels any pending trailing emission, so the wire
|
|
38
|
+
* subscriptions' ref counts cannot be double-decremented.
|
|
34
39
|
*
|
|
35
40
|
* @throws {PerpsError} `MarketNotFound` when no market matches symbol+type.
|
|
36
41
|
* @internal
|
|
@@ -44,7 +49,13 @@ export async function resolveSubscribeQuote(
|
|
|
44
49
|
onQuote: QuoteListener
|
|
45
50
|
): Promise<() => void> {
|
|
46
51
|
const market = await resolveQuoteMarket(client, provider, params)
|
|
47
|
-
|
|
52
|
+
// REST snapshot seeds the context; the marketContext subscription below
|
|
53
|
+
// keeps it live so streamed impact/funding track the moving market.
|
|
54
|
+
let latestContext: MarketContext = await resolveQuotePrice(
|
|
55
|
+
client,
|
|
56
|
+
provider,
|
|
57
|
+
market.id
|
|
58
|
+
)
|
|
48
59
|
|
|
49
60
|
let latestBook: OrderbookResponse | undefined
|
|
50
61
|
let lastEmitAt = Number.NEGATIVE_INFINITY
|
|
@@ -63,7 +74,7 @@ export async function resolveSubscribeQuote(
|
|
|
63
74
|
side: params.side,
|
|
64
75
|
sizeUsd: params.size,
|
|
65
76
|
market,
|
|
66
|
-
price,
|
|
77
|
+
price: latestContext,
|
|
67
78
|
bids: latestBook.bids,
|
|
68
79
|
asks: latestBook.asks,
|
|
69
80
|
feeTier,
|
|
@@ -72,28 +83,44 @@ export async function resolveSubscribeQuote(
|
|
|
72
83
|
)
|
|
73
84
|
}
|
|
74
85
|
|
|
75
|
-
const
|
|
76
|
-
{ channel: '
|
|
86
|
+
const unsubscribeContext = await ws.subscribe(
|
|
87
|
+
{ channel: 'marketContext', dex: provider, marketId: market.id },
|
|
77
88
|
(event) => {
|
|
78
|
-
if (event.channel !== '
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
latestBook = event.data
|
|
82
|
-
if (trailing !== undefined) {
|
|
89
|
+
if (event.channel !== 'marketContext') {
|
|
83
90
|
return
|
|
84
91
|
}
|
|
85
|
-
|
|
86
|
-
if (wait <= 0) {
|
|
87
|
-
emit()
|
|
88
|
-
} else {
|
|
89
|
-
trailing = setTimeout(() => {
|
|
90
|
-
trailing = undefined
|
|
91
|
-
emit()
|
|
92
|
-
}, wait)
|
|
93
|
-
}
|
|
92
|
+
latestContext = event.data
|
|
94
93
|
}
|
|
95
94
|
)
|
|
96
95
|
|
|
96
|
+
let unsubscribeBook: () => void
|
|
97
|
+
try {
|
|
98
|
+
unsubscribeBook = await ws.subscribe(
|
|
99
|
+
{ channel: 'orderbook', dex: provider, marketId: market.id },
|
|
100
|
+
(event) => {
|
|
101
|
+
if (event.channel !== 'orderbook') {
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
latestBook = event.data
|
|
105
|
+
if (trailing !== undefined) {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
const wait = QUOTE_THROTTLE_MS - (Date.now() - lastEmitAt)
|
|
109
|
+
if (wait <= 0) {
|
|
110
|
+
emit()
|
|
111
|
+
} else {
|
|
112
|
+
trailing = setTimeout(() => {
|
|
113
|
+
trailing = undefined
|
|
114
|
+
emit()
|
|
115
|
+
}, wait)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
} catch (error) {
|
|
120
|
+
unsubscribeContext()
|
|
121
|
+
throw error
|
|
122
|
+
}
|
|
123
|
+
|
|
97
124
|
let released = false
|
|
98
125
|
return () => {
|
|
99
126
|
if (released) {
|
|
@@ -104,6 +131,7 @@ export async function resolveSubscribeQuote(
|
|
|
104
131
|
clearTimeout(trailing)
|
|
105
132
|
trailing = undefined
|
|
106
133
|
}
|
|
107
|
-
|
|
134
|
+
unsubscribeContext()
|
|
135
|
+
unsubscribeBook()
|
|
108
136
|
}
|
|
109
137
|
}
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/perps-sdk'
|
|
2
|
-
export const version = '1.5.
|
|
2
|
+
export const version = '1.5.4'
|