@0xmonaco/react 1.0.51 → 1.0.54
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/hooks/useInstruments/useInstruments.d.ts +12 -10
- package/dist/hooks/useInstruments/useInstruments.js +16 -11
- package/dist/hooks/useUserBalances/useUserBalances.d.ts +78 -1
- package/dist/hooks/useUserBalances/useUserBalances.js +399 -44
- package/dist/hooks/useUserOrders/useUserOrders.d.ts +112 -5
- package/dist/hooks/useUserOrders/useUserOrders.js +583 -20
- package/package.json +3 -3
|
@@ -8,17 +8,19 @@ import type { UseInstrumentsReturn } from "./types";
|
|
|
8
8
|
* configuration rather than a delta, so state is kept as a terminal-state
|
|
9
9
|
* entry per trading pair: each event replaces that market's entry outright.
|
|
10
10
|
*
|
|
11
|
-
* A
|
|
12
|
-
* disappearing, so a consumer can distinguish
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* A market DELISTED while the socket was up keeps its entry with
|
|
12
|
+
* `isActive: false` rather than disappearing, so a consumer can distinguish
|
|
13
|
+
* "no longer tradable" from "never seen"; read
|
|
14
|
+
* `instruments.filter((instrument) => instrument.isActive)` for the tradable
|
|
15
|
+
* set.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* Reconnect is the exception, and the snapshot boundary is what makes it
|
|
18
|
+
* expressible. Each snapshot is the authoritative active-market set at the
|
|
19
|
+
* moment it was taken, so it REPLACES the map wholesale rather than merging
|
|
20
|
+
* into it: a market delisted while the socket was down is absent from the
|
|
21
|
+
* post-reconnect snapshot and leaves this state with it. Merging would have
|
|
22
|
+
* stranded that market here forever carrying its pre-outage config, because a
|
|
23
|
+
* delisted market emits nothing further to correct it.
|
|
22
24
|
*
|
|
23
25
|
* @param tradingPairId - Optional trading pair UUID to filter on; omit to
|
|
24
26
|
* receive every market. An empty string is rejected by the core helper and is
|
|
@@ -18,17 +18,19 @@ const NO_INSTRUMENTS = {};
|
|
|
18
18
|
* configuration rather than a delta, so state is kept as a terminal-state
|
|
19
19
|
* entry per trading pair: each event replaces that market's entry outright.
|
|
20
20
|
*
|
|
21
|
-
* A
|
|
22
|
-
* disappearing, so a consumer can distinguish
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* A market DELISTED while the socket was up keeps its entry with
|
|
22
|
+
* `isActive: false` rather than disappearing, so a consumer can distinguish
|
|
23
|
+
* "no longer tradable" from "never seen"; read
|
|
24
|
+
* `instruments.filter((instrument) => instrument.isActive)` for the tradable
|
|
25
|
+
* set.
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* Reconnect is the exception, and the snapshot boundary is what makes it
|
|
28
|
+
* expressible. Each snapshot is the authoritative active-market set at the
|
|
29
|
+
* moment it was taken, so it REPLACES the map wholesale rather than merging
|
|
30
|
+
* into it: a market delisted while the socket was down is absent from the
|
|
31
|
+
* post-reconnect snapshot and leaves this state with it. Merging would have
|
|
32
|
+
* stranded that market here forever carrying its pre-outage config, because a
|
|
33
|
+
* delisted market emits nothing further to correct it.
|
|
32
34
|
*
|
|
33
35
|
* @param tradingPairId - Optional trading pair UUID to filter on; omit to
|
|
34
36
|
* receive every market. An empty string is rejected by the core helper and is
|
|
@@ -61,7 +63,10 @@ export function useInstruments(tradingPairId) {
|
|
|
61
63
|
try {
|
|
62
64
|
unsubscribe = ws.instruments((event) => {
|
|
63
65
|
setSubscription((prev) => (belongsToThisSubscription(prev) ? { ...prev, byPair: { ...prev.byPair, [event.tradingPairId]: event.data } } : prev));
|
|
64
|
-
}, tradingPairId)
|
|
66
|
+
}, tradingPairId, (items) => {
|
|
67
|
+
const byPair = Object.fromEntries(items.map((item) => [item.tradingPairId, item]));
|
|
68
|
+
setSubscription((prev) => (belongsToThisSubscription(prev) ? { ...prev, byPair } : prev));
|
|
69
|
+
});
|
|
65
70
|
setSubscription((prev) => (belongsToThisSubscription(prev) ? { ...prev, subscribed: true } : prev));
|
|
66
71
|
}
|
|
67
72
|
catch (err) {
|
|
@@ -1,9 +1,86 @@
|
|
|
1
|
-
import type { AccountBalance, UserBalanceEvent } from "@0xmonaco/types";
|
|
1
|
+
import type { AccountBalance, UserBalanceEvent, UserBalanceEventData } from "@0xmonaco/types";
|
|
2
2
|
import type { UseUserBalancesReturn } from "./types";
|
|
3
3
|
/**
|
|
4
4
|
* Update an AccountBalance with data from a WebSocket balance event
|
|
5
5
|
*/
|
|
6
6
|
export declare function updateBalanceFromEvent(balance: AccountBalance, event: UserBalanceEvent): AccountBalance;
|
|
7
|
+
/**
|
|
8
|
+
* Apply a subscribe-time balances snapshot to the current list.
|
|
9
|
+
*
|
|
10
|
+
* The snapshot is the user's COMPLETE balance set, which is what makes this a
|
|
11
|
+
* different operation from applying a live event rather than a loop over one:
|
|
12
|
+
*
|
|
13
|
+
* - A held asset the snapshot omits has no balance left, so it is zeroed rather
|
|
14
|
+
* than left showing a figure that is no longer true. The row itself stays —
|
|
15
|
+
* a portfolio needs to render "0 WSEI", not to lose the line.
|
|
16
|
+
* - The snapshot's totals are taken VERBATIM. A snapshot row is built from the
|
|
17
|
+
* same accounts-service read that produced the REST row, so its `total`
|
|
18
|
+
* already is the REST `totalBalance` with margin collateral included —
|
|
19
|
+
* unlike a live event, whose `total` can describe the spot balance alone and
|
|
20
|
+
* therefore needs {@link updateBalanceFromEvent}'s margin reconciliation.
|
|
21
|
+
* Running a snapshot row through that would add the derived margin component
|
|
22
|
+
* a second time.
|
|
23
|
+
* - A row for an asset the list does not hold cannot be completed here: the
|
|
24
|
+
* wire payload carries no `assetId`, `decimals` or wrapped-native flag. That
|
|
25
|
+
* case is reported by {@link snapshotHasUnknownAsset} rather than from here,
|
|
26
|
+
* so the caller can decide to re-read WITHOUT doing it inside a state
|
|
27
|
+
* updater — React invokes an updater during render, and may invoke it more
|
|
28
|
+
* than once, so a flag assigned inside one is not readable afterwards.
|
|
29
|
+
*
|
|
30
|
+
* Pure, so the caller can use it inside a state updater.
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyBalanceSnapshot(current: AccountBalance[], items: UserBalanceEventData[]): {
|
|
33
|
+
balances: AccountBalance[];
|
|
34
|
+
hasUnknownAsset: boolean;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Whether the snapshot names an asset the current list does not hold.
|
|
38
|
+
*
|
|
39
|
+
* Split out of {@link applyBalanceSnapshot} so a caller can ask the question
|
|
40
|
+
* before entering a state updater: the answer decides whether to fire a REST
|
|
41
|
+
* re-read, and a side effect must not depend on an updater having run.
|
|
42
|
+
*/
|
|
43
|
+
export declare function snapshotHasUnknownAsset(current: AccountBalance[], items: UserBalanceEventData[]): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Merge a background REST read into the current list without disturbing it.
|
|
46
|
+
*
|
|
47
|
+
* The repair this serves has one job: learn about an asset the list does not
|
|
48
|
+
* hold yet, because the WebSocket payload carries no `assetId`, `decimals` or
|
|
49
|
+
* wrapped-native flag and so cannot introduce one on its own.
|
|
50
|
+
*
|
|
51
|
+
* It must not do more than that. The subscription stays live while the request
|
|
52
|
+
* is in flight, so an event or snapshot can land in between — and replacing the
|
|
53
|
+
* list with the response would roll those newer values back, including the
|
|
54
|
+
* authoritative snapshot figures that triggered the read in the first place.
|
|
55
|
+
* Rows already held therefore keep their live values untouched, and only
|
|
56
|
+
* genuinely new assets are appended.
|
|
57
|
+
*
|
|
58
|
+
* The initial load and the public `refresh()` still replace: the first runs
|
|
59
|
+
* before the subscription opens, so nothing newer can exist to lose, and the
|
|
60
|
+
* second is a deliberate "give me the server's answer" action.
|
|
61
|
+
*/
|
|
62
|
+
export declare function reconcileBalances(current: AccountBalance[], fetched: AccountBalance[]): AccountBalance[];
|
|
63
|
+
/**
|
|
64
|
+
* Overlay buffered wire state onto rows a REST read has just supplied metadata
|
|
65
|
+
* for.
|
|
66
|
+
*
|
|
67
|
+
* A frame naming a token the list does not hold yet is dropped by the event
|
|
68
|
+
* handler — there is no row to apply it to — and the repair read that follows
|
|
69
|
+
* may have queried the server BEFORE that frame. Appending its result would
|
|
70
|
+
* then leave the token at a value the stream has already moved past, with no
|
|
71
|
+
* later frame to correct it because every subsequent frame finds a row and
|
|
72
|
+
* takes the update path. Buffering the newest wire state for an unheld token
|
|
73
|
+
* and laying it over the row once metadata arrives is what closes that.
|
|
74
|
+
*
|
|
75
|
+
* Only entries newer than the read are applied. One buffered BEFORE the read
|
|
76
|
+
* started is already reflected in its result, and re-applying it would roll the
|
|
77
|
+
* row back to that older value.
|
|
78
|
+
*/
|
|
79
|
+
export declare function applyBufferedBalances(rows: AccountBalance[], buffered: Map<string, {
|
|
80
|
+
data: UserBalanceEventData;
|
|
81
|
+
seq: number;
|
|
82
|
+
source: "event" | "snapshot";
|
|
83
|
+
}>, readSeq: number): AccountBalance[];
|
|
7
84
|
/**
|
|
8
85
|
* Hook for subscribing to real-time user balance updates via WebSocket (authenticated)
|
|
9
86
|
*
|