ctrader-ts 0.1.0

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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +301 -0
  3. package/assets/banner.png +0 -0
  4. package/dist/bin/auth.d.ts +3 -0
  5. package/dist/bin/auth.d.ts.map +1 -0
  6. package/dist/bin/auth.js +193 -0
  7. package/dist/bin/auth.js.map +1 -0
  8. package/dist/cli/index.d.ts +3 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +359 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/src/client.d.ts +310 -0
  13. package/dist/src/client.d.ts.map +1 -0
  14. package/dist/src/client.js +507 -0
  15. package/dist/src/client.js.map +1 -0
  16. package/dist/src/config.d.ts +18 -0
  17. package/dist/src/config.d.ts.map +1 -0
  18. package/dist/src/config.js +70 -0
  19. package/dist/src/config.js.map +1 -0
  20. package/dist/src/connect.d.ts +20 -0
  21. package/dist/src/connect.d.ts.map +1 -0
  22. package/dist/src/connect.js +36 -0
  23. package/dist/src/connect.js.map +1 -0
  24. package/dist/src/connection.d.ts +51 -0
  25. package/dist/src/connection.d.ts.map +1 -0
  26. package/dist/src/connection.js +292 -0
  27. package/dist/src/connection.js.map +1 -0
  28. package/dist/src/enums.d.ts +341 -0
  29. package/dist/src/enums.d.ts.map +1 -0
  30. package/dist/src/enums.js +369 -0
  31. package/dist/src/enums.js.map +1 -0
  32. package/dist/src/errors.d.ts +24 -0
  33. package/dist/src/errors.d.ts.map +1 -0
  34. package/dist/src/errors.js +47 -0
  35. package/dist/src/errors.js.map +1 -0
  36. package/dist/src/helpers.d.ts +28 -0
  37. package/dist/src/helpers.d.ts.map +1 -0
  38. package/dist/src/helpers.js +113 -0
  39. package/dist/src/helpers.js.map +1 -0
  40. package/dist/src/index.d.ts +12 -0
  41. package/dist/src/index.d.ts.map +1 -0
  42. package/dist/src/index.js +11 -0
  43. package/dist/src/index.js.map +1 -0
  44. package/dist/src/modules/account.d.ts +67 -0
  45. package/dist/src/modules/account.d.ts.map +1 -0
  46. package/dist/src/modules/account.js +168 -0
  47. package/dist/src/modules/account.js.map +1 -0
  48. package/dist/src/modules/auth.d.ts +20 -0
  49. package/dist/src/modules/auth.d.ts.map +1 -0
  50. package/dist/src/modules/auth.js +43 -0
  51. package/dist/src/modules/auth.js.map +1 -0
  52. package/dist/src/modules/market.d.ts +53 -0
  53. package/dist/src/modules/market.d.ts.map +1 -0
  54. package/dist/src/modules/market.js +192 -0
  55. package/dist/src/modules/market.js.map +1 -0
  56. package/dist/src/modules/trading.d.ts +80 -0
  57. package/dist/src/modules/trading.d.ts.map +1 -0
  58. package/dist/src/modules/trading.js +150 -0
  59. package/dist/src/modules/trading.js.map +1 -0
  60. package/dist/src/symbol-cache.d.ts +14 -0
  61. package/dist/src/symbol-cache.d.ts.map +1 -0
  62. package/dist/src/symbol-cache.js +41 -0
  63. package/dist/src/symbol-cache.js.map +1 -0
  64. package/dist/src/types.d.ts +413 -0
  65. package/dist/src/types.d.ts.map +1 -0
  66. package/dist/src/types.js +2 -0
  67. package/dist/src/types.js.map +1 -0
  68. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACtH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,OAAO,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBzE"}
@@ -0,0 +1,36 @@
1
+ import { resolveConfig, endpointForEnvironment, DEMO_ENDPOINT, LIVE_ENDPOINT } from "./config.js";
2
+ import { CTrader } from "./client.js";
3
+ export { DEMO_ENDPOINT, LIVE_ENDPOINT };
4
+ /**
5
+ * Connect to cTrader Open API and authenticate in one call.
6
+ *
7
+ * Reads credentials from ~/.config/ctrader-ts/config.json, then env vars
8
+ * (CTRADER_CLIENT_ID, CTRADER_CLIENT_SECRET, CTRADER_ACCESS_TOKEN,
9
+ * CTRADER_ACCOUNT_ID, CTRADER_ENVIRONMENT), then any overrides passed here.
10
+ *
11
+ * @example
12
+ * const ct = await connect();
13
+ * const pos = await ct.buy("EURUSD", { volume: 0.01 });
14
+ * await ct.close(pos.position!);
15
+ *
16
+ * @example
17
+ * const ct = await connect({ environment: "live" });
18
+ */
19
+ export async function connect(overrides) {
20
+ const config = resolveConfig(overrides);
21
+ const endpoint = endpointForEnvironment(config.environment);
22
+ const client = new CTrader({
23
+ endpoint,
24
+ accountId: config.accountId,
25
+ onReconnect: async () => {
26
+ await client.raw.auth.authenticateApp(config.clientId, config.clientSecret);
27
+ await client.raw.auth.authenticateAccount(config.accountId, config.accessToken);
28
+ await client.raw.market.restoreSubscriptions();
29
+ },
30
+ });
31
+ await client.connection.connect();
32
+ await client.raw.auth.authenticateApp(config.clientId, config.clientSecret);
33
+ await client.raw.auth.authenticateAccount(config.accountId, config.accessToken);
34
+ return client;
35
+ }
36
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAsB,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACtH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAyB;IACtD,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC;QAC1B,QAAQ;QACR,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,KAAK,IAAI,EAAE;YACvB,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;YAC5E,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YAChF,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAChD,CAAC;KACD,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAClC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IAC5E,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAEhF,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { ConnectionState } from "./types.js";
2
+ type PayloadHandler = (payload: Record<string, unknown>) => void;
3
+ export type ConnectionEvent = "stateChange" | "error" | "message";
4
+ type ConnectionEventHandler = (data: unknown) => void;
5
+ export interface CTraderConnectionConfig {
6
+ endpoint: string;
7
+ maxReconnectAttempts?: number;
8
+ requestTimeoutMs?: number;
9
+ /** Called after WebSocket reconnects (not initial connect). Use for re-auth + subscription restore. */
10
+ onReconnect?: () => Promise<void>;
11
+ }
12
+ export declare class CTraderConnection {
13
+ private ws;
14
+ private readonly endpoint;
15
+ private readonly maxReconnectAttempts;
16
+ private readonly requestTimeoutMs;
17
+ private readonly onReconnect;
18
+ private hasConnectedOnce;
19
+ private _state;
20
+ private shouldReconnect;
21
+ private reconnectTimer;
22
+ private reconnectAttempt;
23
+ private heartbeatInterval;
24
+ private heartbeatCheckInterval;
25
+ private lastHeartbeatAt;
26
+ private readonly pending;
27
+ private readonly payloadHandlers;
28
+ private readonly eventHandlers;
29
+ constructor(config: CTraderConnectionConfig);
30
+ get state(): ConnectionState;
31
+ get isConnected(): boolean;
32
+ connect(): Promise<void>;
33
+ disconnect(): void;
34
+ send(payloadType: number, payload?: Record<string, unknown>): string;
35
+ request(payloadType: number, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
36
+ on(payloadType: number, handler: PayloadHandler): () => void;
37
+ off(payloadType: number, handler: PayloadHandler): void;
38
+ onEvent(event: ConnectionEvent, handler: ConnectionEventHandler): () => void;
39
+ offEvent(event: ConnectionEvent, handler: ConnectionEventHandler): void;
40
+ private handleMessage;
41
+ private startHeartbeat;
42
+ private stopHeartbeat;
43
+ private scheduleReconnect;
44
+ private doReconnect;
45
+ private setState;
46
+ private rejectPending;
47
+ private makeError;
48
+ private emit;
49
+ }
50
+ export {};
51
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/connection.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,YAAY,CAAC;AAe5E,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAC;AAClE,KAAK,sBAAsB,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uGAAuG;IACvG,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;IAChE,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,MAAM,CAA+C;IAC7D,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAE7B,OAAO,CAAC,iBAAiB,CAA+C;IACxE,OAAO,CAAC,sBAAsB,CAA+C;IAC7E,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0C;IAC1E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAG1B;gBAEQ,MAAM,EAAE,uBAAuB;IAO3C,IAAI,KAAK,IAAI,eAAe,CAE3B;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoDxB,UAAU,IAAI,IAAI;IAmBlB,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAapE,OAAO,CACL,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAanC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI;IAU5D,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAIvD,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAU5E,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAIvE,OAAO,CAAC,aAAa;IA2DrB,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,IAAI;CAYb"}
@@ -0,0 +1,292 @@
1
+ import { CTraderError, NotConnectedError, RequestTimeoutError, } from "./errors.js";
2
+ import { PayloadType } from "./enums.js";
3
+ const REQUEST_TIMEOUT_MS = 15_000;
4
+ const HEARTBEAT_INTERVAL_MS = 25_000;
5
+ const HEARTBEAT_TIMEOUT_MS = 60_000;
6
+ const INITIAL_RECONNECT_DELAY_MS = 2_000;
7
+ const MAX_RECONNECT_DELAY_MS = 60_000;
8
+ export class CTraderConnection {
9
+ ws = null;
10
+ endpoint;
11
+ maxReconnectAttempts;
12
+ requestTimeoutMs;
13
+ onReconnect;
14
+ hasConnectedOnce = false;
15
+ _state = { status: "disconnected" };
16
+ shouldReconnect = false;
17
+ reconnectTimer = null;
18
+ reconnectAttempt = 0;
19
+ heartbeatInterval = null;
20
+ heartbeatCheckInterval = null;
21
+ lastHeartbeatAt = 0;
22
+ pending = new Map();
23
+ payloadHandlers = new Map();
24
+ eventHandlers = new Map();
25
+ constructor(config) {
26
+ this.endpoint = config.endpoint;
27
+ this.maxReconnectAttempts = config.maxReconnectAttempts ?? 0;
28
+ this.requestTimeoutMs = config.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
29
+ this.onReconnect = config.onReconnect;
30
+ }
31
+ get state() {
32
+ return this._state;
33
+ }
34
+ get isConnected() {
35
+ return this._state.status === "connected";
36
+ }
37
+ connect() {
38
+ return new Promise((resolve, reject) => {
39
+ if (this._state.status === "connected") {
40
+ resolve();
41
+ return;
42
+ }
43
+ this.shouldReconnect = true;
44
+ this.reconnectAttempt = 0;
45
+ this.setState({ status: "connecting", attempt: 1 });
46
+ const ws = new WebSocket(this.endpoint);
47
+ this.ws = ws;
48
+ const onOpen = () => {
49
+ cleanup();
50
+ this.reconnectAttempt = 0;
51
+ this.hasConnectedOnce = true;
52
+ this.setState({ status: "connected", since: Date.now() });
53
+ this.startHeartbeat();
54
+ resolve();
55
+ };
56
+ const onError = (event) => {
57
+ cleanup();
58
+ this.emit("error", event);
59
+ reject(new Error("WebSocket connection failed"));
60
+ };
61
+ const cleanup = () => {
62
+ ws.removeEventListener("open", onOpen);
63
+ ws.removeEventListener("error", onError);
64
+ };
65
+ ws.addEventListener("open", onOpen);
66
+ ws.addEventListener("error", onError);
67
+ ws.addEventListener("message", (event) => {
68
+ this.handleMessage(event);
69
+ });
70
+ ws.addEventListener("close", () => {
71
+ this.stopHeartbeat();
72
+ this.rejectPending(new Error("Connection closed"));
73
+ if (this._state.status !== "disconnected") {
74
+ this.setState({ status: "disconnected" });
75
+ }
76
+ this.scheduleReconnect();
77
+ });
78
+ });
79
+ }
80
+ disconnect() {
81
+ this.shouldReconnect = false;
82
+ if (this.reconnectTimer !== null) {
83
+ clearTimeout(this.reconnectTimer);
84
+ this.reconnectTimer = null;
85
+ }
86
+ this.stopHeartbeat();
87
+ this.rejectPending(new Error("Client disconnected"));
88
+ if (this.ws !== null) {
89
+ this.ws.close();
90
+ this.ws = null;
91
+ }
92
+ this.setState({ status: "disconnected" });
93
+ }
94
+ send(payloadType, payload) {
95
+ if (this.ws === null || this.ws.readyState !== WebSocket.OPEN) {
96
+ throw new NotConnectedError();
97
+ }
98
+ const clientMsgId = crypto.randomUUID();
99
+ const envelope = payload !== undefined
100
+ ? { clientMsgId, payloadType, payload }
101
+ : { clientMsgId, payloadType };
102
+ this.ws.send(JSON.stringify(envelope));
103
+ return clientMsgId;
104
+ }
105
+ request(payloadType, payload) {
106
+ return new Promise((resolve, reject) => {
107
+ const clientMsgId = this.send(payloadType, payload);
108
+ const timeout = setTimeout(() => {
109
+ this.pending.delete(clientMsgId);
110
+ reject(new RequestTimeoutError(payloadType, clientMsgId, this.requestTimeoutMs));
111
+ }, this.requestTimeoutMs);
112
+ this.pending.set(clientMsgId, { resolve, reject, timeout });
113
+ });
114
+ }
115
+ on(payloadType, handler) {
116
+ let handlers = this.payloadHandlers.get(payloadType);
117
+ if (handlers === undefined) {
118
+ handlers = new Set();
119
+ this.payloadHandlers.set(payloadType, handlers);
120
+ }
121
+ handlers.add(handler);
122
+ return () => this.off(payloadType, handler);
123
+ }
124
+ off(payloadType, handler) {
125
+ this.payloadHandlers.get(payloadType)?.delete(handler);
126
+ }
127
+ onEvent(event, handler) {
128
+ let handlers = this.eventHandlers.get(event);
129
+ if (handlers === undefined) {
130
+ handlers = new Set();
131
+ this.eventHandlers.set(event, handlers);
132
+ }
133
+ handlers.add(handler);
134
+ return () => this.offEvent(event, handler);
135
+ }
136
+ offEvent(event, handler) {
137
+ this.eventHandlers.get(event)?.delete(handler);
138
+ }
139
+ handleMessage(event) {
140
+ const raw = typeof event.data === "string" ? event.data : String(event.data);
141
+ let envelope;
142
+ try {
143
+ envelope = JSON.parse(raw);
144
+ }
145
+ catch {
146
+ return;
147
+ }
148
+ this.emit("message", envelope);
149
+ const { clientMsgId, payloadType, payload } = envelope;
150
+ if (payloadType === PayloadType.HEARTBEAT_EVENT) {
151
+ this.lastHeartbeatAt = Date.now();
152
+ return;
153
+ }
154
+ if (clientMsgId !== undefined && this.pending.has(clientMsgId)) {
155
+ const req = this.pending.get(clientMsgId);
156
+ this.pending.delete(clientMsgId);
157
+ clearTimeout(req.timeout);
158
+ if (payloadType === PayloadType.ERROR_RES ||
159
+ payloadType === PayloadType.OA_ERROR_RES) {
160
+ const err = payload;
161
+ req.reject(this.makeError(err));
162
+ return;
163
+ }
164
+ req.resolve(payload ?? {});
165
+ return;
166
+ }
167
+ if (payloadType === PayloadType.ERROR_RES ||
168
+ payloadType === PayloadType.OA_ERROR_RES) {
169
+ const err = payload;
170
+ this.emit("error", this.makeError(err));
171
+ return;
172
+ }
173
+ const handlers = this.payloadHandlers.get(payloadType);
174
+ if (handlers !== undefined) {
175
+ for (const handler of handlers) {
176
+ try {
177
+ handler(payload ?? {});
178
+ }
179
+ catch (e) {
180
+ this.emit("error", e);
181
+ }
182
+ }
183
+ }
184
+ }
185
+ startHeartbeat() {
186
+ this.stopHeartbeat();
187
+ this.lastHeartbeatAt = Date.now();
188
+ this.heartbeatInterval = setInterval(() => {
189
+ if (this.ws?.readyState === WebSocket.OPEN) {
190
+ const envelope = { payloadType: PayloadType.HEARTBEAT_EVENT };
191
+ this.ws.send(JSON.stringify(envelope));
192
+ }
193
+ }, HEARTBEAT_INTERVAL_MS);
194
+ this.heartbeatCheckInterval = setInterval(() => {
195
+ if (Date.now() - this.lastHeartbeatAt > HEARTBEAT_TIMEOUT_MS) {
196
+ this.ws?.close();
197
+ }
198
+ }, 10_000);
199
+ }
200
+ stopHeartbeat() {
201
+ if (this.heartbeatInterval !== null) {
202
+ clearInterval(this.heartbeatInterval);
203
+ this.heartbeatInterval = null;
204
+ }
205
+ if (this.heartbeatCheckInterval !== null) {
206
+ clearInterval(this.heartbeatCheckInterval);
207
+ this.heartbeatCheckInterval = null;
208
+ }
209
+ }
210
+ scheduleReconnect() {
211
+ if (!this.shouldReconnect)
212
+ return;
213
+ this.reconnectAttempt++;
214
+ if (this.maxReconnectAttempts > 0 &&
215
+ this.reconnectAttempt > this.maxReconnectAttempts) {
216
+ this.setState({ status: "disconnected" });
217
+ return;
218
+ }
219
+ const delay = Math.min(INITIAL_RECONNECT_DELAY_MS * 2 ** (this.reconnectAttempt - 1), MAX_RECONNECT_DELAY_MS);
220
+ this.setState({
221
+ status: "reconnecting",
222
+ attempt: this.reconnectAttempt,
223
+ nextRetryMs: delay,
224
+ });
225
+ this.reconnectTimer = setTimeout(() => {
226
+ this.reconnectTimer = null;
227
+ this.doReconnect();
228
+ }, delay);
229
+ }
230
+ doReconnect() {
231
+ if (!this.shouldReconnect)
232
+ return;
233
+ this.setState({ status: "connecting", attempt: this.reconnectAttempt });
234
+ const ws = new WebSocket(this.endpoint);
235
+ this.ws = ws;
236
+ ws.addEventListener("open", () => {
237
+ this.setState({ status: "connected", since: Date.now() });
238
+ this.startHeartbeat();
239
+ if (this.hasConnectedOnce && this.onReconnect !== undefined) {
240
+ this.onReconnect().catch((e) => this.emit("error", e));
241
+ }
242
+ });
243
+ ws.addEventListener("message", (event) => {
244
+ this.handleMessage(event);
245
+ });
246
+ ws.addEventListener("error", (event) => {
247
+ this.emit("error", event);
248
+ });
249
+ ws.addEventListener("close", () => {
250
+ this.stopHeartbeat();
251
+ this.rejectPending(new Error("Connection closed"));
252
+ this.setState({ status: "disconnected" });
253
+ this.scheduleReconnect();
254
+ });
255
+ }
256
+ setState(state) {
257
+ this._state = state;
258
+ this.emit("stateChange", state);
259
+ }
260
+ rejectPending(error) {
261
+ for (const [, req] of this.pending) {
262
+ clearTimeout(req.timeout);
263
+ req.reject(error);
264
+ }
265
+ this.pending.clear();
266
+ }
267
+ makeError(err) {
268
+ const opts = {
269
+ code: err?.errorCode ?? "UNKNOWN",
270
+ description: err?.description ?? "Unknown error",
271
+ };
272
+ if (err?.retryAfter !== undefined)
273
+ opts.retryAfter = err.retryAfter;
274
+ if (err?.maintenanceEndTimestamp !== undefined)
275
+ opts.maintenanceEndTimestamp = err.maintenanceEndTimestamp;
276
+ return new CTraderError(opts);
277
+ }
278
+ emit(event, data) {
279
+ const handlers = this.eventHandlers.get(event);
280
+ if (handlers !== undefined) {
281
+ for (const handler of handlers) {
282
+ try {
283
+ handler(data);
284
+ }
285
+ catch {
286
+ // Handler errors must not crash the connection
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/connection.ts"],"names":[],"mappings":"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"}