@flexemarkets/fm-sdk 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.
- package/dist/client.d.ts +47 -1
- package/dist/client.js +144 -7
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/market-view.d.ts +195 -0
- package/dist/market-view.js +440 -0
- package/dist/market-view.js.map +1 -0
- package/dist/orderbook.d.ts +9 -0
- package/dist/orderbook.js +16 -0
- package/dist/orderbook.js.map +1 -1
- package/dist/snapshot.d.ts +18 -0
- package/dist/snapshot.js +2 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/stomp.d.ts +18 -1
- package/dist/stomp.js +44 -3
- package/dist/stomp.js.map +1 -1
- package/dist/ticker.js +5 -5
- package/dist/ticker.js.map +1 -1
- package/dist/trades.d.ts +4 -0
- package/dist/trades.js +9 -0
- package/dist/trades.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarketView — always-current view of a single marketplace, hiding
|
|
3
|
+
* transport details (WebSocket subscribe, snapshot+delta
|
|
4
|
+
* reconciliation, sequence-gap recovery, reconnect) behind a small
|
|
5
|
+
* read-side surface. Mirrors the Java + Python SDKs; same staged
|
|
6
|
+
* roadmap. See project_fm_sdk_canonical_client.
|
|
7
|
+
*
|
|
8
|
+
* Phase 1 scope: API surface + skeleton that delegates to the
|
|
9
|
+
* existing listen() / callback pipe. No reconciliation, no
|
|
10
|
+
* snapshot seed, no sharing, no reconnect — those land in Phase 2.
|
|
11
|
+
*/
|
|
12
|
+
import { OrderBooks } from "./orderbook.js";
|
|
13
|
+
import { MarketplaceTrades } from "./trades.js";
|
|
14
|
+
import { NO_SEQ } from "./stomp.js";
|
|
15
|
+
export class DefaultMarketView {
|
|
16
|
+
marketplaceId;
|
|
17
|
+
markets;
|
|
18
|
+
_flexemarkets;
|
|
19
|
+
_orderBooks;
|
|
20
|
+
_trades;
|
|
21
|
+
_events = null;
|
|
22
|
+
_session = null;
|
|
23
|
+
_holding = null;
|
|
24
|
+
_sessionHandlers = [];
|
|
25
|
+
_holdingHandlers = [];
|
|
26
|
+
_bookHandlers = [];
|
|
27
|
+
_gapHandlers = [];
|
|
28
|
+
_reconnectHandlers = [];
|
|
29
|
+
_closed = false;
|
|
30
|
+
/**
|
|
31
|
+
* Highest ORDERS-UPDATE seq this view has applied so far. Deltas
|
|
32
|
+
* with `seq <= _lastAppliedSeq` are skipped — they've already been
|
|
33
|
+
* folded into the local state via the initial REST snapshot or a
|
|
34
|
+
* previously-applied delta. Initial value comes from the snapshot's
|
|
35
|
+
* `asOfSeq`; `NO_SEQ` disables filtering (older fm-server).
|
|
36
|
+
*/
|
|
37
|
+
_lastAppliedSeq = NO_SEQ;
|
|
38
|
+
static async open(flexemarkets, marketplaceId) {
|
|
39
|
+
const markets = await flexemarkets.markets(marketplaceId);
|
|
40
|
+
const view = new DefaultMarketView(flexemarkets, marketplaceId, markets);
|
|
41
|
+
// Subscribe WS first (so deltas start buffering on the callback
|
|
42
|
+
// path), then fetch + apply the snapshot, only THEN allow live
|
|
43
|
+
// dispatch. _seedFromSnapshot flips _seedComplete=true atomically
|
|
44
|
+
// with the buffer drain on its synchronous tail.
|
|
45
|
+
//
|
|
46
|
+
// Phase 2d: own the EventListener directly rather than calling
|
|
47
|
+
// flexemarkets.listen() — that would clobber the singleton
|
|
48
|
+
// _eventListener and prevent multiple shared views from
|
|
49
|
+
// coexisting in one Flexemarkets.
|
|
50
|
+
view._events = await flexemarkets._connectEvents(marketplaceId, (event) => view._dispatch(event));
|
|
51
|
+
await view._seedFromSnapshot();
|
|
52
|
+
return view;
|
|
53
|
+
}
|
|
54
|
+
_seedComplete = false;
|
|
55
|
+
_seedBuffer = [];
|
|
56
|
+
// 100 matches the default per-market Trades capacity. Plumb through to
|
|
57
|
+
// observe() later if a caller needs deeper trade scrollback.
|
|
58
|
+
constructor(flexemarkets, marketplaceId, markets) {
|
|
59
|
+
this._flexemarkets = flexemarkets;
|
|
60
|
+
this.marketplaceId = marketplaceId;
|
|
61
|
+
this.markets = markets;
|
|
62
|
+
this._orderBooks = new OrderBooks(markets);
|
|
63
|
+
this._trades = new MarketplaceTrades(markets, 100);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Phase 2a snapshot seeding. Fetches the V1 active-orders and
|
|
67
|
+
* recent-trades snapshots, applies them to the local aggregators,
|
|
68
|
+
* and records the `asOfSeq` so subsequent WS deltas can be
|
|
69
|
+
* filtered to avoid double-applying anything the snapshot already
|
|
70
|
+
* reflects.
|
|
71
|
+
*
|
|
72
|
+
* Known race window: a delta whose order persisted between the
|
|
73
|
+
* server's seq capture and its order read can appear both in the
|
|
74
|
+
* snapshot and in a delta with `seq > asOfSeq`, leading to a
|
|
75
|
+
* double-apply. Same caveat as the existing V0 WS snapshot path.
|
|
76
|
+
* Phase 2b (gap recovery + ID-based dedup) closes the window.
|
|
77
|
+
*/
|
|
78
|
+
async _seedFromSnapshot() {
|
|
79
|
+
const orders = await this._flexemarkets.activeOrdersV1(this.marketplaceId);
|
|
80
|
+
const trades = await this._flexemarkets.recentTradesV1(this.marketplaceId);
|
|
81
|
+
// Clear before reseeding so a resync (Phase 2b) doesn't double-add
|
|
82
|
+
// against existing price levels. Initial seed hits empty books so
|
|
83
|
+
// clear() is a no-op there.
|
|
84
|
+
this._orderBooks.clear();
|
|
85
|
+
this._trades.clear();
|
|
86
|
+
if (orders.body.length > 0)
|
|
87
|
+
this._orderBooks.update(orders.body);
|
|
88
|
+
if (trades.body.length > 0)
|
|
89
|
+
this._trades.update(trades.body);
|
|
90
|
+
this._lastAppliedSeq = orders.asOfSeq;
|
|
91
|
+
// Flip state and drain in a single synchronous block — no
|
|
92
|
+
// microtask boundary, so no concurrent dispatch can squeeze in
|
|
93
|
+
// between "buffer drained" and "_seedComplete=true" and leave its
|
|
94
|
+
// delta orphaned in the buffer.
|
|
95
|
+
const buffered = this._seedBuffer;
|
|
96
|
+
this._seedBuffer = [];
|
|
97
|
+
this._seedComplete = true;
|
|
98
|
+
this._resyncInFlight = false;
|
|
99
|
+
for (const update of buffered)
|
|
100
|
+
this._applyOrdersUpdate(update);
|
|
101
|
+
}
|
|
102
|
+
orderBook(marketId) {
|
|
103
|
+
this._ensureOpen();
|
|
104
|
+
return this._orderBooks.get(marketId) ?? null;
|
|
105
|
+
}
|
|
106
|
+
session() {
|
|
107
|
+
this._ensureOpen();
|
|
108
|
+
return this._session;
|
|
109
|
+
}
|
|
110
|
+
holding() {
|
|
111
|
+
this._ensureOpen();
|
|
112
|
+
return this._holding;
|
|
113
|
+
}
|
|
114
|
+
onSessionChange(handler) {
|
|
115
|
+
this._ensureOpen();
|
|
116
|
+
this._sessionHandlers.push(handler);
|
|
117
|
+
return () => {
|
|
118
|
+
const i = this._sessionHandlers.indexOf(handler);
|
|
119
|
+
if (i >= 0)
|
|
120
|
+
this._sessionHandlers.splice(i, 1);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
onOrderBookChange(marketId, handler) {
|
|
124
|
+
this._ensureOpen();
|
|
125
|
+
const entry = { marketId, handler };
|
|
126
|
+
this._bookHandlers.push(entry);
|
|
127
|
+
return () => {
|
|
128
|
+
const i = this._bookHandlers.indexOf(entry);
|
|
129
|
+
if (i >= 0)
|
|
130
|
+
this._bookHandlers.splice(i, 1);
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
onHoldingChange(handler) {
|
|
134
|
+
this._ensureOpen();
|
|
135
|
+
this._holdingHandlers.push(handler);
|
|
136
|
+
return () => {
|
|
137
|
+
const i = this._holdingHandlers.indexOf(handler);
|
|
138
|
+
if (i >= 0)
|
|
139
|
+
this._holdingHandlers.splice(i, 1);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
onGap(handler) {
|
|
143
|
+
this._ensureOpen();
|
|
144
|
+
this._gapHandlers.push(handler);
|
|
145
|
+
return () => {
|
|
146
|
+
const i = this._gapHandlers.indexOf(handler);
|
|
147
|
+
if (i >= 0)
|
|
148
|
+
this._gapHandlers.splice(i, 1);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
onReconnect(handler) {
|
|
152
|
+
this._ensureOpen();
|
|
153
|
+
this._reconnectHandlers.push(handler);
|
|
154
|
+
return () => {
|
|
155
|
+
const i = this._reconnectHandlers.indexOf(handler);
|
|
156
|
+
if (i >= 0)
|
|
157
|
+
this._reconnectHandlers.splice(i, 1);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
submitLimit(marketId, side, units, price) {
|
|
161
|
+
this._ensureOpen();
|
|
162
|
+
return this._flexemarkets.submitLimit(this.marketplaceId, marketId, side, units, price);
|
|
163
|
+
}
|
|
164
|
+
submitCancel(marketId, originalId) {
|
|
165
|
+
this._ensureOpen();
|
|
166
|
+
return this._flexemarkets.submitCancel(this.marketplaceId, marketId, originalId);
|
|
167
|
+
}
|
|
168
|
+
close() {
|
|
169
|
+
if (this._closed)
|
|
170
|
+
return;
|
|
171
|
+
this._closed = true;
|
|
172
|
+
if (this._events !== null) {
|
|
173
|
+
try {
|
|
174
|
+
this._events.close();
|
|
175
|
+
}
|
|
176
|
+
catch { /* best-effort */ }
|
|
177
|
+
this._events = null;
|
|
178
|
+
}
|
|
179
|
+
// Flexemarkets is owned by the caller; we don't close it. If
|
|
180
|
+
// observe() was the only consumer, the caller can close
|
|
181
|
+
// Flexemarkets themselves.
|
|
182
|
+
}
|
|
183
|
+
_resyncInFlight = false;
|
|
184
|
+
_dispatch(event) {
|
|
185
|
+
if (this._closed)
|
|
186
|
+
return;
|
|
187
|
+
// FmEvent is a discriminated union.
|
|
188
|
+
if (_isOrdersUpdate(event)) {
|
|
189
|
+
if (!this._seedComplete || this._resyncInFlight) {
|
|
190
|
+
// Buffer until the REST snapshot has landed so we don't
|
|
191
|
+
// apply deltas before the seq watermark is established.
|
|
192
|
+
this._seedBuffer.push(event);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// Phase 2b gap detection: a delta with seq > lastAppliedSeq+1
|
|
196
|
+
// means one or more frames were dropped. Refetch the snapshot
|
|
197
|
+
// and let the seq filter skip whatever the new asOfSeq covers.
|
|
198
|
+
if (event.seq !== NO_SEQ &&
|
|
199
|
+
this._lastAppliedSeq !== NO_SEQ &&
|
|
200
|
+
event.seq > this._lastAppliedSeq + 1) {
|
|
201
|
+
const expectedSeq = this._lastAppliedSeq + 1;
|
|
202
|
+
console.warn(`[MarketView] ORDERS-UPDATE seq gap on marketplace ${this.marketplaceId} ` +
|
|
203
|
+
`— expected ${expectedSeq}, got ${event.seq}; resyncing from snapshot`);
|
|
204
|
+
const gap = {
|
|
205
|
+
marketplaceId: this.marketplaceId,
|
|
206
|
+
expectedSeq,
|
|
207
|
+
receivedSeq: event.seq,
|
|
208
|
+
};
|
|
209
|
+
for (const h of this._gapHandlers) {
|
|
210
|
+
try {
|
|
211
|
+
h(gap);
|
|
212
|
+
}
|
|
213
|
+
catch { /* one bad handler can't stop recovery */ }
|
|
214
|
+
}
|
|
215
|
+
this._resyncInFlight = true;
|
|
216
|
+
this._seedComplete = false;
|
|
217
|
+
this._seedBuffer.push(event);
|
|
218
|
+
// _seedFromSnapshot flips both flags back atomically on its
|
|
219
|
+
// synchronous tail; nothing more to do in the .then().
|
|
220
|
+
void this._seedFromSnapshot();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this._applyOrdersUpdate(event);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (_isSession(event)) {
|
|
227
|
+
this._session = event;
|
|
228
|
+
for (const h of this._sessionHandlers)
|
|
229
|
+
h(event);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (_isHolding(event)) {
|
|
233
|
+
this._holding = event;
|
|
234
|
+
for (const h of this._holdingHandlers)
|
|
235
|
+
h(event);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (_isTransportError(event)) {
|
|
239
|
+
this._handleTransportError();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (_isWsException(event)) {
|
|
243
|
+
// STOMP ERROR / parse failure. Logged for visibility;
|
|
244
|
+
// reconnecting won't help with a malformed frame, so we leave
|
|
245
|
+
// the view as-is.
|
|
246
|
+
console.warn(`[MarketView] WS error on marketplace ${this.marketplaceId}: ${event.command} ${event.body}`);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// VERSION, SESSION-LIST — not reflected in the public surface yet.
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Phase 2c auto-reconnect. On a WsTransportError, reconnect the
|
|
253
|
+
* underlying WS and re-seed from the V1 snapshot — reconnect is
|
|
254
|
+
* just the largest possible gap, so 2b's _seedFromSnapshot()
|
|
255
|
+
* (clear + REST snapshot + reapply + seq watermark) handles state
|
|
256
|
+
* convergence. One reconnect attempt; if it fails the view is left
|
|
257
|
+
* stale until the caller close()s and observe()s again.
|
|
258
|
+
*/
|
|
259
|
+
_handleTransportError() {
|
|
260
|
+
if (this._resyncInFlight)
|
|
261
|
+
return; // already handling
|
|
262
|
+
console.warn(`[MarketView] WS transport error on marketplace ${this.marketplaceId}; reconnecting`);
|
|
263
|
+
this._resyncInFlight = true;
|
|
264
|
+
this._seedComplete = false;
|
|
265
|
+
void (async () => {
|
|
266
|
+
let outcome;
|
|
267
|
+
try {
|
|
268
|
+
if (this._events !== null)
|
|
269
|
+
await this._events.reconnect();
|
|
270
|
+
await this._seedFromSnapshot();
|
|
271
|
+
outcome = { marketplaceId: this.marketplaceId, success: true, reason: null };
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
275
|
+
console.error(`[MarketView] Reconnect failed on marketplace ${this.marketplaceId}; view is stale: ${reason}`);
|
|
276
|
+
outcome = { marketplaceId: this.marketplaceId, success: false, reason };
|
|
277
|
+
// Leave _resyncInFlight=true so subsequent dispatches keep
|
|
278
|
+
// buffering rather than corrupting state; caller can close()
|
|
279
|
+
// and observe() to recover.
|
|
280
|
+
}
|
|
281
|
+
for (const h of this._reconnectHandlers) {
|
|
282
|
+
try {
|
|
283
|
+
h(outcome);
|
|
284
|
+
}
|
|
285
|
+
catch { /* don't let one bad handler stop dispatch */ }
|
|
286
|
+
}
|
|
287
|
+
})();
|
|
288
|
+
}
|
|
289
|
+
_applyOrdersUpdate(update) {
|
|
290
|
+
// Phase 2a seq filter: drop deltas the snapshot already reflects.
|
|
291
|
+
// NO_SEQ disables filtering for older fm-server builds that don't
|
|
292
|
+
// stamp the header.
|
|
293
|
+
if (update.seq !== NO_SEQ &&
|
|
294
|
+
this._lastAppliedSeq !== NO_SEQ &&
|
|
295
|
+
update.seq <= this._lastAppliedSeq) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const orders = update.orders;
|
|
299
|
+
const touched = _marketIdsTouched(orders);
|
|
300
|
+
this._orderBooks.update(orders);
|
|
301
|
+
this._trades.update(orders);
|
|
302
|
+
for (const marketId of touched) {
|
|
303
|
+
const book = this._orderBooks.get(marketId);
|
|
304
|
+
if (!book)
|
|
305
|
+
continue;
|
|
306
|
+
for (const h of this._bookHandlers) {
|
|
307
|
+
if (h.marketId === marketId)
|
|
308
|
+
h.handler(book);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (update.seq !== NO_SEQ)
|
|
312
|
+
this._lastAppliedSeq = update.seq;
|
|
313
|
+
}
|
|
314
|
+
_ensureOpen() {
|
|
315
|
+
if (this._closed) {
|
|
316
|
+
throw new Error(`MarketView for marketplace ${this.marketplaceId} is closed`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function _marketIdsTouched(orders) {
|
|
321
|
+
const seen = new Set();
|
|
322
|
+
for (const o of orders)
|
|
323
|
+
seen.add(o.marketId);
|
|
324
|
+
return [...seen];
|
|
325
|
+
}
|
|
326
|
+
function _isOrdersUpdate(event) {
|
|
327
|
+
return typeof event === "object" && event !== null && event.kind === "orders-update";
|
|
328
|
+
}
|
|
329
|
+
function _isSession(event) {
|
|
330
|
+
return typeof event === "object" && event !== null && "status" in event && "marketplaceId" in event;
|
|
331
|
+
}
|
|
332
|
+
function _isHolding(event) {
|
|
333
|
+
return typeof event === "object" && event !== null && "securities" in event;
|
|
334
|
+
}
|
|
335
|
+
function _isTransportError(event) {
|
|
336
|
+
return typeof event === "object" && event !== null && event.kind === "transport-error";
|
|
337
|
+
}
|
|
338
|
+
function _isWsException(event) {
|
|
339
|
+
return typeof event === "object" && event !== null && event.kind === "ws-exception";
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Reader-side handle on a refcounted DefaultMarketView. Returned by
|
|
343
|
+
* Flexemarkets.observe(); multiple handles for the same marketplaceId
|
|
344
|
+
* share one underlying view + WS subscription + materialized state.
|
|
345
|
+
* Each handle's close() decrements the shared refcount and tears down
|
|
346
|
+
* the shared resources on the last close.
|
|
347
|
+
*
|
|
348
|
+
* Subscriptions registered via on*Change on this handle are tracked
|
|
349
|
+
* locally and closed when the handle closes — so a handler doesn't
|
|
350
|
+
* keep firing into stale state after the handle is gone.
|
|
351
|
+
*/
|
|
352
|
+
export class MarketViewHandle {
|
|
353
|
+
_shared;
|
|
354
|
+
_onClose;
|
|
355
|
+
_mySubscriptions = [];
|
|
356
|
+
_closed = false;
|
|
357
|
+
constructor(shared, onClose) {
|
|
358
|
+
this._shared = shared;
|
|
359
|
+
this._onClose = onClose;
|
|
360
|
+
}
|
|
361
|
+
get marketplaceId() {
|
|
362
|
+
return this._shared.marketplaceId;
|
|
363
|
+
}
|
|
364
|
+
get markets() {
|
|
365
|
+
this._check();
|
|
366
|
+
return this._shared.markets;
|
|
367
|
+
}
|
|
368
|
+
orderBook(marketId) {
|
|
369
|
+
this._check();
|
|
370
|
+
return this._shared.orderBook(marketId);
|
|
371
|
+
}
|
|
372
|
+
session() {
|
|
373
|
+
this._check();
|
|
374
|
+
return this._shared.session();
|
|
375
|
+
}
|
|
376
|
+
holding() {
|
|
377
|
+
this._check();
|
|
378
|
+
return this._shared.holding();
|
|
379
|
+
}
|
|
380
|
+
onSessionChange(handler) {
|
|
381
|
+
this._check();
|
|
382
|
+
const sub = this._shared.onSessionChange(handler);
|
|
383
|
+
this._mySubscriptions.push(sub);
|
|
384
|
+
return sub;
|
|
385
|
+
}
|
|
386
|
+
onOrderBookChange(marketId, handler) {
|
|
387
|
+
this._check();
|
|
388
|
+
const sub = this._shared.onOrderBookChange(marketId, handler);
|
|
389
|
+
this._mySubscriptions.push(sub);
|
|
390
|
+
return sub;
|
|
391
|
+
}
|
|
392
|
+
onHoldingChange(handler) {
|
|
393
|
+
this._check();
|
|
394
|
+
const sub = this._shared.onHoldingChange(handler);
|
|
395
|
+
this._mySubscriptions.push(sub);
|
|
396
|
+
return sub;
|
|
397
|
+
}
|
|
398
|
+
onGap(handler) {
|
|
399
|
+
this._check();
|
|
400
|
+
const sub = this._shared.onGap(handler);
|
|
401
|
+
this._mySubscriptions.push(sub);
|
|
402
|
+
return sub;
|
|
403
|
+
}
|
|
404
|
+
onReconnect(handler) {
|
|
405
|
+
this._check();
|
|
406
|
+
const sub = this._shared.onReconnect(handler);
|
|
407
|
+
this._mySubscriptions.push(sub);
|
|
408
|
+
return sub;
|
|
409
|
+
}
|
|
410
|
+
submitLimit(marketId, side, units, price) {
|
|
411
|
+
this._check();
|
|
412
|
+
return this._shared.submitLimit(marketId, side, units, price);
|
|
413
|
+
}
|
|
414
|
+
submitCancel(marketId, originalId) {
|
|
415
|
+
this._check();
|
|
416
|
+
return this._shared.submitCancel(marketId, originalId);
|
|
417
|
+
}
|
|
418
|
+
close() {
|
|
419
|
+
if (this._closed)
|
|
420
|
+
return;
|
|
421
|
+
this._closed = true;
|
|
422
|
+
// Close subscriptions this handle registered so handlers don't
|
|
423
|
+
// fire into a closed handle. Subscription is a () => void; calling
|
|
424
|
+
// twice is idempotent per the existing TS Subscription contract.
|
|
425
|
+
for (const sub of this._mySubscriptions) {
|
|
426
|
+
try {
|
|
427
|
+
sub();
|
|
428
|
+
}
|
|
429
|
+
catch { /* best-effort */ }
|
|
430
|
+
}
|
|
431
|
+
this._mySubscriptions.length = 0;
|
|
432
|
+
this._onClose();
|
|
433
|
+
}
|
|
434
|
+
_check() {
|
|
435
|
+
if (this._closed) {
|
|
436
|
+
throw new Error(`MarketView handle for marketplace ${this._shared.marketplaceId} is closed`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
//# sourceMappingURL=market-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"market-view.js","sourceRoot":"","sources":["../src/market-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAa,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,MAAM,EAAgG,MAAM,YAAY,CAAC;AAsGlI,MAAM,OAAO,iBAAiB;IACnB,aAAa,CAAS;IACtB,OAAO,CAAW;IAEV,aAAa,CAAe;IAC5B,WAAW,CAAa;IACxB,OAAO,CAAoB;IACpC,OAAO,GAAyB,IAAI,CAAC;IACrC,QAAQ,GAAmB,IAAI,CAAC;IAChC,QAAQ,GAAmB,IAAI,CAAC;IAEvB,gBAAgB,GAAgC,EAAE,CAAC;IACnD,gBAAgB,GAAgC,EAAE,CAAC;IACnD,aAAa,GAAiE,EAAE,CAAC;IACjF,YAAY,GAAiC,EAAE,CAAC;IAChD,kBAAkB,GAAuC,EAAE,CAAC;IAErE,OAAO,GAAG,KAAK,CAAC;IAExB;;;;;;OAMG;IACK,eAAe,GAAW,MAAM,CAAC;IAEzC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,YAA0B,EAAE,aAAqB;QACjE,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;QACzE,gEAAgE;QAChE,+DAA+D;QAC/D,kEAAkE;QAClE,iDAAiD;QACjD,EAAE;QACF,+DAA+D;QAC/D,2DAA2D;QAC3D,wDAAwD;QACxD,kCAAkC;QAClC,IAAI,CAAC,OAAO,GAAG,MAAM,YAAY,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAClG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,aAAa,GAAG,KAAK,CAAC;IACtB,WAAW,GAAmB,EAAE,CAAC;IAEzC,uEAAuE;IACvE,6DAA6D;IAC7D,YAAoB,YAA0B,EAAE,aAAqB,EAAE,OAAiB;QACtF,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,KAAK,CAAC,iBAAiB;QAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE3E,mEAAmE;QACnE,kEAAkE;QAClE,4BAA4B;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAErB,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE7D,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC;QAEtC,0DAA0D;QAC1D,+DAA+D;QAC/D,kEAAkE;QAClE,gCAAgC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,QAAQ;YAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,SAAS,CAAC,QAAgB;QACxB,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;IAChD,CAAC;IAED,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,eAAe,CAAC,OAA6B;QAC3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC;IAED,iBAAiB,CAAC,QAAgB,EAAE,OAA+B;QACjE,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,OAA6B;QAC3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAA8B;QAClC,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,OAAoC;QAC9C,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,QAAgB,EAAE,IAAY,EAAE,KAAa,EAAE,KAAa;QACtE,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1F,CAAC;IAED,YAAY,CAAC,QAAgB,EAAE,UAAkB;QAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,6DAA6D;QAC7D,wDAAwD;QACxD,2BAA2B;IAC7B,CAAC;IAEO,eAAe,GAAG,KAAK,CAAC;IAExB,SAAS,CAAC,KAAc;QAC9B,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,oCAAoC;QACpC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBAChD,wDAAwD;gBACxD,wDAAwD;gBACxD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,8DAA8D;YAC9D,8DAA8D;YAC9D,+DAA+D;YAC/D,IACE,KAAK,CAAC,GAAG,KAAK,MAAM;gBACpB,IAAI,CAAC,eAAe,KAAK,MAAM;gBAC/B,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,eAAe,GAAG,CAAC,EACpC,CAAC;gBACD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;gBAC7C,OAAO,CAAC,IAAI,CACV,qDAAqD,IAAI,CAAC,aAAa,GAAG;oBACxE,cAAc,WAAW,SAAS,KAAK,CAAC,GAAG,2BAA2B,CACzE,CAAC;gBACF,MAAM,GAAG,GAAa;oBACpB,aAAa,EAAE,IAAI,CAAC,aAAa;oBACjC,WAAW;oBACX,WAAW,EAAE,KAAK,CAAC,GAAG;iBACvB,CAAC;gBACF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClC,IAAI,CAAC;wBAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAC,yCAAyC,CAAC,CAAC;gBACrE,CAAC;gBACD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC3B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7B,4DAA4D;gBAC5D,uDAAuD;gBACvD,KAAK,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,gBAAgB;gBAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,gBAAgB;gBAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,sDAAsD;YACtD,8DAA8D;YAC9D,kBAAkB;YAClB,OAAO,CAAC,IAAI,CACV,wCAAwC,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAC7F,CAAC;YACF,OAAO;QACT,CAAC;QACD,mEAAmE;IACrE,CAAC;IAED;;;;;;;OAOG;IACK,qBAAqB;QAC3B,IAAI,IAAI,CAAC,eAAe;YAAE,OAAO,CAAC,mBAAmB;QACrD,OAAO,CAAC,IAAI,CACV,kDAAkD,IAAI,CAAC,aAAa,gBAAgB,CACrF,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,OAAuB,CAAC;YAC5B,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;oBAAE,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC1D,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC/B,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChE,OAAO,CAAC,KAAK,CACX,gDAAgD,IAAI,CAAC,aAAa,oBAAoB,MAAM,EAAE,CAC/F,CAAC;gBACF,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;gBACxE,2DAA2D;gBAC3D,6DAA6D;gBAC7D,4BAA4B;YAC9B,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxC,IAAI,CAAC;oBAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,6CAA6C,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;IAEO,kBAAkB,CAAC,MAAoB;QAC7C,kEAAkE;QAClE,kEAAkE;QAClE,oBAAoB;QACpB,IACE,MAAM,CAAC,GAAG,KAAK,MAAM;YACrB,IAAI,CAAC,eAAe,KAAK,MAAM;YAC/B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,eAAe,EAClC,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ;oBAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,KAAK,MAAM;YAAE,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC;IAC/D,CAAC;IAEO,WAAW;QACjB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,aAAa,YAAY,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,MAAe;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAAsB,CAAC,IAAI,KAAK,eAAe,CAAC;AACzG,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,IAAI,eAAe,IAAI,KAAK,CAAC;AACtG,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,IAAI,KAAK,CAAC;AAC9E,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAA0B,CAAC,IAAI,KAAK,iBAAiB,CAAC;AAC/G,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAAqB,CAAC,IAAI,KAAK,cAAc,CAAC;AACvG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,gBAAgB;IACV,OAAO,CAAoB;IAC3B,QAAQ,CAAa;IACrB,gBAAgB,GAAmB,EAAE,CAAC;IAC/C,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,MAAyB,EAAE,OAAmB;QACxD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IACpC,CAAC;IAED,IAAI,OAAO;QACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,SAAS,CAAC,QAAgB;QACxB,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,eAAe,CAAC,OAA6B;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,iBAAiB,CAAC,QAAgB,EAAE,OAA+B;QACjE,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9D,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,eAAe,CAAC,OAA6B;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,OAA8B;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,WAAW,CAAC,OAAoC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,WAAW,CAAC,QAAgB,EAAE,IAAY,EAAE,KAAa,EAAE,KAAa;QACtE,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,YAAY,CAAC,QAAgB,EAAE,UAAkB;QAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,+DAA+D;QAC/D,mEAAmE;QACnE,iEAAiE;QACjE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,CAAC;gBAAC,GAAG,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,MAAM;QACZ,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,CAAC,OAAO,CAAC,aAAa,YAAY,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;CACF"}
|
package/dist/orderbook.d.ts
CHANGED
|
@@ -33,6 +33,13 @@ export declare class OrderBook {
|
|
|
33
33
|
buyLevels(): [number, number][];
|
|
34
34
|
/** Price levels sorted lowest-first (best ask first). */
|
|
35
35
|
sellLevels(): [number, number][];
|
|
36
|
+
/**
|
|
37
|
+
* Reset to just-constructed state — empty levels, initialized=false.
|
|
38
|
+
* Used by MarketView's Phase 2b gap-recovery: refetch the snapshot,
|
|
39
|
+
* clear(), reapply via update(), so the next delta with
|
|
40
|
+
* isAvailable=false doesn't underflow against stale levels.
|
|
41
|
+
*/
|
|
42
|
+
clear(): void;
|
|
36
43
|
}
|
|
37
44
|
/**
|
|
38
45
|
* Container of OrderBook instances, one per market.
|
|
@@ -45,4 +52,6 @@ export declare class OrderBooks {
|
|
|
45
52
|
bestPrice(marketId: number, side: string): number;
|
|
46
53
|
collection(): OrderBook[];
|
|
47
54
|
get(marketId: number): OrderBook;
|
|
55
|
+
/** Clear every contained book — see {@link OrderBook.clear}. */
|
|
56
|
+
clear(): void;
|
|
48
57
|
}
|
package/dist/orderbook.js
CHANGED
|
@@ -118,6 +118,17 @@ export class OrderBook {
|
|
|
118
118
|
sellLevels() {
|
|
119
119
|
return [...this._sells.entries()].sort((a, b) => a[0] - b[0]);
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Reset to just-constructed state — empty levels, initialized=false.
|
|
123
|
+
* Used by MarketView's Phase 2b gap-recovery: refetch the snapshot,
|
|
124
|
+
* clear(), reapply via update(), so the next delta with
|
|
125
|
+
* isAvailable=false doesn't underflow against stale levels.
|
|
126
|
+
*/
|
|
127
|
+
clear() {
|
|
128
|
+
this._buys.clear();
|
|
129
|
+
this._sells.clear();
|
|
130
|
+
this._initialized = false;
|
|
131
|
+
}
|
|
121
132
|
}
|
|
122
133
|
/**
|
|
123
134
|
* Container of OrderBook instances, one per market.
|
|
@@ -146,5 +157,10 @@ export class OrderBooks {
|
|
|
146
157
|
get(marketId) {
|
|
147
158
|
return this._books.get(marketId);
|
|
148
159
|
}
|
|
160
|
+
/** Clear every contained book — see {@link OrderBook.clear}. */
|
|
161
|
+
clear() {
|
|
162
|
+
for (const book of this._books.values())
|
|
163
|
+
book.clear();
|
|
164
|
+
}
|
|
149
165
|
}
|
|
150
166
|
//# sourceMappingURL=orderbook.js.map
|
package/dist/orderbook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.js","sourceRoot":"","sources":["../src/orderbook.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"orderbook.js","sourceRoot":"","sources":["../src/orderbook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST snapshot response bundle: parsed body + the `x-fm-as-of-seq`
|
|
3
|
+
* header value the snapshot was read at. Returned by `Flexemarkets`
|
|
4
|
+
* V1 snapshot methods so `MarketView` (and any other caller that
|
|
5
|
+
* mixes REST snapshots with WS deltas) can reconcile the two
|
|
6
|
+
* streams: apply deltas whose `seq` is greater than `asOfSeq` and
|
|
7
|
+
* skip those whose seq is less than or equal.
|
|
8
|
+
*
|
|
9
|
+
* `asOfSeq` is `-1` when the server didn't stamp the response
|
|
10
|
+
* (older fm-server). Callers that depend on the seq for correctness
|
|
11
|
+
* should treat `-1` as "snapshot reconciliation unavailable" and
|
|
12
|
+
* either wholesale-replace state on every snapshot fetch or fall
|
|
13
|
+
* back to a periodic poll.
|
|
14
|
+
*/
|
|
15
|
+
export interface Snapshot<T> {
|
|
16
|
+
readonly body: T;
|
|
17
|
+
readonly asOfSeq: number;
|
|
18
|
+
}
|
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":""}
|
package/dist/stomp.d.ts
CHANGED
|
@@ -23,8 +23,25 @@ export interface WsException {
|
|
|
23
23
|
body: string;
|
|
24
24
|
exception: Error;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* ORDERS-UPDATE delta from the WS stream, carrying the parsed orders
|
|
28
|
+
* plus the per-marketplace `seq` header fm-server stamps each frame
|
|
29
|
+
* with. Consumers reconcile this against a REST `Snapshot`: apply
|
|
30
|
+
* deltas whose `seq` is greater than the snapshot's `asOfSeq` and
|
|
31
|
+
* skip those whose seq is less than or equal.
|
|
32
|
+
*
|
|
33
|
+
* `seq` is `-1` when the server didn't stamp the header (older
|
|
34
|
+
* fm-server).
|
|
35
|
+
*/
|
|
36
|
+
export interface OrdersUpdate {
|
|
37
|
+
readonly kind: "orders-update";
|
|
38
|
+
readonly orders: Order[];
|
|
39
|
+
readonly seq: number;
|
|
40
|
+
}
|
|
41
|
+
export type FmEvent = Version | Session | Session[] | Holding | OrdersUpdate | WsTransportError | WsException;
|
|
27
42
|
export type EventCallback = (event: FmEvent) => void;
|
|
43
|
+
/** Sentinel for "no seq header" — see OrdersUpdate.seq docstring. */
|
|
44
|
+
export declare const NO_SEQ = -1;
|
|
28
45
|
export declare class EventListener {
|
|
29
46
|
private readonly _wsUrl;
|
|
30
47
|
private readonly _bearerToken;
|
package/dist/stomp.js
CHANGED
|
@@ -7,6 +7,27 @@
|
|
|
7
7
|
import WebSocket from "ws";
|
|
8
8
|
const HEARTBEAT_MS = 30_000;
|
|
9
9
|
const NULL = "\x00";
|
|
10
|
+
/**
|
|
11
|
+
* Prefix on the `/app` SUBSCRIBE destination selecting fm-server's WS
|
|
12
|
+
* API version. Empty string → V0 (`/app/marketplaces/{id}`); `"/v1"` →
|
|
13
|
+
* V1 (`/app/v1/marketplaces/{id}`). V1 omits the bulk ORDERS-UPDATE
|
|
14
|
+
* snapshot on subscribe, keeping inbound frames small. V1 is the
|
|
15
|
+
* default; override with `FM_WS_API_VERSION=v0` if talking to an old
|
|
16
|
+
* fm-server that doesn't speak V1.
|
|
17
|
+
*
|
|
18
|
+
* NB: V1 SUBSCRIBE delivers an empty ORDERS-UPDATE; consumers that
|
|
19
|
+
* need the active book at startup should fetch it via REST
|
|
20
|
+
* (`GET /api/v1/marketplaces/{id}/orders/active`) and reconcile
|
|
21
|
+
* against incoming deltas using the `seq` header.
|
|
22
|
+
*/
|
|
23
|
+
const API_VERSION_PREFIX = (() => {
|
|
24
|
+
const v = (process.env.FM_WS_API_VERSION ?? "v1").trim().toLowerCase();
|
|
25
|
+
if (v === "v0")
|
|
26
|
+
return "";
|
|
27
|
+
if (v === "v1")
|
|
28
|
+
return "/v1";
|
|
29
|
+
throw new Error(`FM_WS_API_VERSION must be 'v0' or 'v1', got: ${v}`);
|
|
30
|
+
})();
|
|
10
31
|
export function encodeFrame(frame) {
|
|
11
32
|
const lines = [frame.command];
|
|
12
33
|
for (const [k, v] of Object.entries(frame.headers)) {
|
|
@@ -46,6 +67,9 @@ export function decodeFrame(raw) {
|
|
|
46
67
|
// Event parsing — mirrors Python _parse_event / Java EventParser
|
|
47
68
|
// ---------------------------------------------------------------------------
|
|
48
69
|
const MESSAGE_TYPE = "message-type";
|
|
70
|
+
const SEQ_HEADER = "seq";
|
|
71
|
+
/** Sentinel for "no seq header" — see OrdersUpdate.seq docstring. */
|
|
72
|
+
export const NO_SEQ = -1;
|
|
49
73
|
function parseEvent(frame, parseHolding, parseOrder) {
|
|
50
74
|
const msgType = frame.headers[MESSAGE_TYPE];
|
|
51
75
|
if (msgType === undefined)
|
|
@@ -66,12 +90,22 @@ function parseEvent(frame, parseHolding, parseOrder) {
|
|
|
66
90
|
return parseSession(data);
|
|
67
91
|
case "HOLDING-UPDATE":
|
|
68
92
|
return parseHolding(data);
|
|
69
|
-
case "ORDERS-UPDATE":
|
|
70
|
-
|
|
93
|
+
case "ORDERS-UPDATE": {
|
|
94
|
+
const seq = _parseSeq(frame.headers[SEQ_HEADER]);
|
|
95
|
+
return { kind: "orders-update", orders: parseOrders(data, parseOrder), seq };
|
|
96
|
+
}
|
|
71
97
|
default:
|
|
72
98
|
return null;
|
|
73
99
|
}
|
|
74
100
|
}
|
|
101
|
+
/** Parse the per-frame `seq` header; falls back to NO_SEQ on absent
|
|
102
|
+
* or malformed values. */
|
|
103
|
+
function _parseSeq(value) {
|
|
104
|
+
if (value === undefined)
|
|
105
|
+
return NO_SEQ;
|
|
106
|
+
const n = Number.parseInt(value, 10);
|
|
107
|
+
return Number.isFinite(n) ? n : NO_SEQ;
|
|
108
|
+
}
|
|
75
109
|
function parseVersion(data) {
|
|
76
110
|
if (typeof data === "object" && data !== null && "version" in data) {
|
|
77
111
|
return { version: data.version ?? 0 };
|
|
@@ -214,11 +248,18 @@ export class EventListener {
|
|
|
214
248
|
this._ws.send(encodeFrame(frame));
|
|
215
249
|
}
|
|
216
250
|
_subscribe() {
|
|
251
|
+
// fm-server publishes broadcasts on the V0 destination paths
|
|
252
|
+
// (/topic/marketplaces/{id}, /user/queue/marketplaces/{id}) for
|
|
253
|
+
// both V0 and V1 clients — only the @SubscribeMapping gating the
|
|
254
|
+
// initial snapshot lives at the /v1 prefix. So pub/sub subscriptions
|
|
255
|
+
// stay on V0 paths regardless of the chosen api-version; only the
|
|
256
|
+
// /app destination flips. Mirrors fm-ui's web-socket.service.ts
|
|
257
|
+
// and the Java SDK Events.java pattern.
|
|
217
258
|
const resource = `/marketplaces/${this._marketplaceId}`;
|
|
218
259
|
for (const dest of [
|
|
219
260
|
`/user/queue${resource}`,
|
|
220
261
|
`/topic${resource}`,
|
|
221
|
-
`/app${resource}`,
|
|
262
|
+
`/app${API_VERSION_PREFIX}${resource}`,
|
|
222
263
|
]) {
|
|
223
264
|
const frame = {
|
|
224
265
|
command: "SUBSCRIBE",
|