@homaiohq/napi-quickfix 0.0.0-stage → 0.2.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 (104) hide show
  1. package/CMakeLists.txt +135 -0
  2. package/LICENSE +21 -0
  3. package/README.md +638 -2
  4. package/THIRD_PARTY_LICENSES +48 -0
  5. package/cpp/acceptor_wrap.cpp +468 -0
  6. package/cpp/acceptor_wrap.h +116 -0
  7. package/cpp/addon.cpp +87 -0
  8. package/cpp/application_bridge.cpp +466 -0
  9. package/cpp/application_bridge.h +204 -0
  10. package/cpp/data_dictionary_wrap.cpp +165 -0
  11. package/cpp/data_dictionary_wrap.h +59 -0
  12. package/cpp/engine_common.cpp +5 -0
  13. package/cpp/engine_common.h +127 -0
  14. package/cpp/engine_workers.h +167 -0
  15. package/cpp/errors.h +142 -0
  16. package/cpp/field_map_ops.h +492 -0
  17. package/cpp/group_wrap.cpp +221 -0
  18. package/cpp/group_wrap.h +76 -0
  19. package/cpp/initiator_wrap.cpp +492 -0
  20. package/cpp/initiator_wrap.h +104 -0
  21. package/cpp/message_wrap.cpp +288 -0
  22. package/cpp/message_wrap.h +95 -0
  23. package/cpp/session_id_wrap.cpp +91 -0
  24. package/cpp/session_id_wrap.h +46 -0
  25. package/cpp/session_op_gate.h +201 -0
  26. package/cpp/session_settings_wrap.cpp +98 -0
  27. package/cpp/session_settings_wrap.h +40 -0
  28. package/cpp/session_static.cpp +220 -0
  29. package/cpp/session_wrap.cpp +438 -0
  30. package/cpp/session_wrap.h +144 -0
  31. package/dist/cjs/acceptor.d.ts +29 -0
  32. package/dist/cjs/acceptor.js +38 -0
  33. package/dist/cjs/application.d.ts +115 -0
  34. package/dist/cjs/application.js +62 -0
  35. package/dist/cjs/data-dictionary.d.ts +67 -0
  36. package/dist/cjs/data-dictionary.js +105 -0
  37. package/dist/cjs/engine.d.ts +152 -0
  38. package/dist/cjs/engine.js +183 -0
  39. package/dist/cjs/enums.d.ts +56 -0
  40. package/dist/cjs/enums.js +44 -0
  41. package/dist/cjs/field-value.d.ts +12 -0
  42. package/dist/cjs/field-value.js +40 -0
  43. package/dist/cjs/generated/fields.d.ts +6122 -0
  44. package/dist/cjs/generated/fields.js +6127 -0
  45. package/dist/cjs/generated/values.d.ts +8548 -0
  46. package/dist/cjs/generated/values.js +8580 -0
  47. package/dist/cjs/group.d.ts +126 -0
  48. package/dist/cjs/group.js +185 -0
  49. package/dist/cjs/index.d.ts +68 -0
  50. package/dist/cjs/index.js +73 -0
  51. package/dist/cjs/initiator.d.ts +29 -0
  52. package/dist/cjs/initiator.js +38 -0
  53. package/dist/cjs/load-native.cjs +5 -0
  54. package/dist/cjs/message.d.ts +238 -0
  55. package/dist/cjs/message.js +299 -0
  56. package/dist/cjs/native.d.ts +325 -0
  57. package/dist/cjs/native.js +22 -0
  58. package/dist/cjs/package.json +1 -0
  59. package/dist/cjs/session-id.d.ts +51 -0
  60. package/dist/cjs/session-id.js +87 -0
  61. package/dist/cjs/session-settings.d.ts +46 -0
  62. package/dist/cjs/session-settings.js +75 -0
  63. package/dist/cjs/session.d.ts +213 -0
  64. package/dist/cjs/session.js +337 -0
  65. package/dist/esm/acceptor.d.ts +29 -0
  66. package/dist/esm/acceptor.js +34 -0
  67. package/dist/esm/application.d.ts +115 -0
  68. package/dist/esm/application.js +57 -0
  69. package/dist/esm/data-dictionary.d.ts +67 -0
  70. package/dist/esm/data-dictionary.js +101 -0
  71. package/dist/esm/engine.d.ts +152 -0
  72. package/dist/esm/engine.js +179 -0
  73. package/dist/esm/enums.d.ts +56 -0
  74. package/dist/esm/enums.js +35 -0
  75. package/dist/esm/field-value.d.ts +12 -0
  76. package/dist/esm/field-value.js +37 -0
  77. package/dist/esm/generated/fields.d.ts +6122 -0
  78. package/dist/esm/generated/fields.js +6124 -0
  79. package/dist/esm/generated/values.d.ts +8548 -0
  80. package/dist/esm/generated/values.js +8564 -0
  81. package/dist/esm/group.d.ts +126 -0
  82. package/dist/esm/group.js +181 -0
  83. package/dist/esm/index.d.ts +68 -0
  84. package/dist/esm/index.js +43 -0
  85. package/dist/esm/initiator.d.ts +29 -0
  86. package/dist/esm/initiator.js +34 -0
  87. package/dist/esm/load-native.cjs +5 -0
  88. package/dist/esm/message.d.ts +238 -0
  89. package/dist/esm/message.js +293 -0
  90. package/dist/esm/native.d.ts +325 -0
  91. package/dist/esm/native.js +16 -0
  92. package/dist/esm/session-id.d.ts +51 -0
  93. package/dist/esm/session-id.js +82 -0
  94. package/dist/esm/session-settings.d.ts +46 -0
  95. package/dist/esm/session-settings.js +71 -0
  96. package/dist/esm/session.d.ts +213 -0
  97. package/dist/esm/session.js +329 -0
  98. package/package.json +95 -4
  99. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  100. package/prebuilds/darwin-x64/node.napi.node +0 -0
  101. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  102. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  103. package/prebuilds/win32-x64/node.napi.node +0 -0
  104. package/src/load-native.cjs +5 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Ergonomic wrapper around a live native `FIX::Session`.
3
+ */
4
+ import { type NativeSession } from './native.js';
5
+ import { SessionID } from './session-id.js';
6
+ /**
7
+ * A handle on one live FIX session (wraps `FIX::Session`).
8
+ *
9
+ * Obtain one with {@link lookupSession} (any session in the process) or
10
+ * {@link Engine.getSession} (a session of a particular engine); sessions
11
+ * cannot be constructed directly.
12
+ *
13
+ * **Lifetime.** The underlying `FIX::Session` is owned by its engine. This
14
+ * handle stores only the {@link SessionID} and the identity of the engine it
15
+ * was obtained from, and re-resolves the session on every call, so it never
16
+ * dangles: once that engine has been stopped (which destroys its sessions)
17
+ * every method throws a {@link QuickFixError} whose `fixErrorName` is
18
+ * `'SessionNotFound'` -- also after a new engine has been created with the
19
+ * same id. A handle never crosses over to another engine's session; obtain a
20
+ * new one from the new engine.
21
+ *
22
+ * **Everything is synchronous.** State queries, sequence-number access, the
23
+ * runtime option getters/setters, {@link Session.logon}, {@link Session.logout}
24
+ * and {@link Session.refresh} never take the mutex QuickFIX holds while running
25
+ * your application handlers, so they cannot deadlock the main thread, and calls
26
+ * made in program order take effect in program order. ({@link Session.logon} /
27
+ * {@link Session.logout} flip a plain flag the engine's network thread reads
28
+ * without a lock, exactly as QuickFIX's own `Initiator::stop()` does; the
29
+ * engine picks the change up on its next pass.) QuickFIX's
30
+ * `Session::disconnect()` / `reset()` are deliberately not exposed: they are
31
+ * only safe on the engine's own network thread (see ARCHITECTURE.md §5). Use
32
+ * {@link Session.logout} to bring a session down, and the sequence-number
33
+ * setters to reset its numbering -- on a quiet session; see
34
+ * {@link Session.setNextSenderMsgSeqNum}.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const session = initiator.getSession(sessionID)!;
39
+ * if (session.isLoggedOn()) {
40
+ * console.log('next outbound seq', session.getExpectedSenderNum());
41
+ * session.logout('maintenance');
42
+ * }
43
+ * ```
44
+ */
45
+ export declare class Session {
46
+ #private;
47
+ /** @internal Use {@link lookupSession} / {@link Engine.getSession}. */
48
+ private constructor();
49
+ /** @internal Wrap an existing native session handle. */
50
+ static fromNative(handle: NativeSession): Session;
51
+ /** @internal The native handle backing this session. */
52
+ get nativeHandle(): NativeSession;
53
+ /** The id this handle refers to. Always available, even after the session is gone. */
54
+ get sessionID(): SessionID;
55
+ /** `true` once a Logon has been both sent and received. */
56
+ isLoggedOn(): boolean;
57
+ /**
58
+ * Whether the session is enabled. `false` after {@link Session.logout} until
59
+ * {@link Session.logon}; a disabled initiator session is not reconnected.
60
+ */
61
+ isEnabled(): boolean;
62
+ /** Whether this side has sent a Logon on the current connection. */
63
+ sentLogon(): boolean;
64
+ /** Whether this side has sent a Logout on the current connection. */
65
+ sentLogout(): boolean;
66
+ /** Whether a Logon has been received on the current connection. */
67
+ receivedLogon(): boolean;
68
+ /** `true` for a session owned by an {@link Initiator}. */
69
+ isInitiator(): boolean;
70
+ /** `true` for a session owned by an {@link Acceptor}. */
71
+ isAcceptor(): boolean;
72
+ /**
73
+ * Whether `now` (default: the current time) falls inside the session's
74
+ * configured `StartTime`/`EndTime` window. Throws `RangeError` for an
75
+ * invalid `Date`.
76
+ */
77
+ isSessionTime(now?: Date): boolean;
78
+ /**
79
+ * Whether `now` (default: the current time) falls inside the session's
80
+ * configured `LogonTime`/`LogoutTime` window. Throws `RangeError` for an
81
+ * invalid `Date`.
82
+ */
83
+ isLogonTime(now?: Date): boolean;
84
+ /** The MsgSeqNum (tag 34) the next outbound message will carry. */
85
+ getExpectedSenderNum(): number;
86
+ /** The MsgSeqNum (tag 34) expected on the next inbound message. */
87
+ getExpectedTargetNum(): number;
88
+ /**
89
+ * Set the MsgSeqNum the next outbound message will carry (writes to the
90
+ * message store; a file store may throw `IOException`).
91
+ *
92
+ * **Call it on a quiet session.** The setter is not serialised against a
93
+ * message the engine is sending or receiving on this session at the same
94
+ * time: QuickFIX reads the next number into the outbound header, runs your
95
+ * `toApp`/`toAdmin` handler, then increments from the store, all under a
96
+ * lock this call does not (and must not) take. A value set inside that
97
+ * window -- from a handler, or while a {@link sendToTarget} promise or a
98
+ * heartbeat is in flight on this session -- is overwritten by the increment,
99
+ * and the session ends up one off from its counterparty (a Resend Request or
100
+ * a "MsgSeqNum too low" Logout). Set it before {@link Engine.start}, from a
101
+ * `'logout'` event, or when you know nothing is in flight; never from a
102
+ * handler.
103
+ *
104
+ * @throws `RangeError` if `seqNum` is not a positive safe integer (MsgSeqNum is
105
+ * 1-based).
106
+ */
107
+ setNextSenderMsgSeqNum(seqNum: number): void;
108
+ /**
109
+ * Set the MsgSeqNum expected on the next inbound message (writes to the
110
+ * message store; a file store may throw `IOException`).
111
+ *
112
+ * **Call it on a quiet session.** Like {@link Session.setNextSenderMsgSeqNum},
113
+ * it is not serialised against a message the engine is processing on this
114
+ * session: QuickFIX checks the inbound number, runs your `fromApp`/`fromAdmin`
115
+ * handler, then increments the expected number from the store under a lock
116
+ * this call does not take, so a value set meanwhile is overwritten. Set it
117
+ * before {@link Engine.start}, from a `'logout'` event, or when you know
118
+ * nothing is in flight; never from a handler.
119
+ *
120
+ * @throws `RangeError` if `seqNum` is not a positive safe integer (MsgSeqNum is
121
+ * 1-based).
122
+ */
123
+ setNextTargetMsgSeqNum(seqNum: number): void;
124
+ /** `ResetOnLogon` */
125
+ getResetOnLogon(): boolean;
126
+ setResetOnLogon(value: boolean): void;
127
+ /** `ResetOnLogout` */
128
+ getResetOnLogout(): boolean;
129
+ setResetOnLogout(value: boolean): void;
130
+ /** `ResetOnDisconnect` */
131
+ getResetOnDisconnect(): boolean;
132
+ setResetOnDisconnect(value: boolean): void;
133
+ /** `RefreshOnLogon` */
134
+ getRefreshOnLogon(): boolean;
135
+ setRefreshOnLogon(value: boolean): void;
136
+ /** `CheckCompID` */
137
+ getCheckCompId(): boolean;
138
+ setCheckCompId(value: boolean): void;
139
+ /** `CheckLatency` */
140
+ getCheckLatency(): boolean;
141
+ setCheckLatency(value: boolean): void;
142
+ /** `PersistMessages` */
143
+ getPersistMessages(): boolean;
144
+ setPersistMessages(value: boolean): void;
145
+ /** `SendRedundantResendRequests` */
146
+ getSendRedundantResendRequests(): boolean;
147
+ setSendRedundantResendRequests(value: boolean): void;
148
+ /** `ValidateLengthAndChecksum` */
149
+ getValidateLengthAndChecksum(): boolean;
150
+ setValidateLengthAndChecksum(value: boolean): void;
151
+ /** `SendNextExpectedMsgSeqNum` */
152
+ getSendNextExpectedMsgSeqNum(): boolean;
153
+ setSendNextExpectedMsgSeqNum(value: boolean): void;
154
+ /** `NonStopSession` */
155
+ getIsNonStopSession(): boolean;
156
+ setIsNonStopSession(value: boolean): void;
157
+ /** `LogonTimeout`, in seconds. */
158
+ getLogonTimeout(): number;
159
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
160
+ setLogonTimeout(seconds: number): void;
161
+ /** `LogoutTimeout`, in seconds. */
162
+ getLogoutTimeout(): number;
163
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
164
+ setLogoutTimeout(seconds: number): void;
165
+ /** `MaxLatency`, in seconds. */
166
+ getMaxLatency(): number;
167
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
168
+ setMaxLatency(seconds: number): void;
169
+ /** `TimestampPrecision` (number of sub-second digits, `0..9`). */
170
+ getTimestampPrecision(): number;
171
+ /** @throws `RangeError` unless `precision` is an integer in `0..9`. */
172
+ setTimestampPrecision(precision: number): void;
173
+ /**
174
+ * Enable the session. An initiator session reconnects and logs on at its
175
+ * next `ReconnectInterval`; an acceptor session accepts the next inbound
176
+ * Logon. Takes effect immediately ({@link Session.isEnabled} is `true` on
177
+ * return); observe the handshake through the engine's `'logon'` event.
178
+ */
179
+ logon(): void;
180
+ /**
181
+ * Disable the session and initiate a graceful Logout (sent with `reason` as
182
+ * tag 58 on the next engine tick). The session stays disabled — it will not
183
+ * reconnect — until {@link Session.logon}. Takes effect immediately
184
+ * ({@link Session.isEnabled} is `false` on return); observe completion
185
+ * through the engine's `'logout'` event.
186
+ */
187
+ logout(reason?: string): void;
188
+ /**
189
+ * Re-read the session state (sequence numbers etc.) from the message store.
190
+ *
191
+ * @throws {QuickFixError} `IOException` if the store cannot be read.
192
+ */
193
+ refresh(): void;
194
+ }
195
+ /**
196
+ * Look up a live session by id, across every engine in this process.
197
+ *
198
+ * @returns The {@link Session}, or `undefined` if no session with that id
199
+ * exists (never created, or its engine has been stopped).
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const session = lookupSession(new SessionID('FIX.4.4', 'CLIENT', 'BROKER'));
204
+ * console.log(session?.isLoggedOn());
205
+ * ```
206
+ */
207
+ export declare function lookupSession(sessionID: SessionID): Session | undefined;
208
+ /** Whether a session with this id exists in this process. */
209
+ export declare function doesSessionExist(sessionID: SessionID): boolean;
210
+ /** The ids of every session in this process, across all engines. */
211
+ export declare function getSessions(): SessionID[];
212
+ /** The number of sessions in this process, across all engines. */
213
+ export declare function numSessions(): number;
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Session = void 0;
4
+ exports.lookupSession = lookupSession;
5
+ exports.doesSessionExist = doesSessionExist;
6
+ exports.getSessions = getSessions;
7
+ exports.numSessions = numSessions;
8
+ /**
9
+ * Ergonomic wrapper around a live native `FIX::Session`.
10
+ */
11
+ const native_js_1 = require("./native.js");
12
+ const session_id_js_1 = require("./session-id.js");
13
+ /**
14
+ * A handle on one live FIX session (wraps `FIX::Session`).
15
+ *
16
+ * Obtain one with {@link lookupSession} (any session in the process) or
17
+ * {@link Engine.getSession} (a session of a particular engine); sessions
18
+ * cannot be constructed directly.
19
+ *
20
+ * **Lifetime.** The underlying `FIX::Session` is owned by its engine. This
21
+ * handle stores only the {@link SessionID} and the identity of the engine it
22
+ * was obtained from, and re-resolves the session on every call, so it never
23
+ * dangles: once that engine has been stopped (which destroys its sessions)
24
+ * every method throws a {@link QuickFixError} whose `fixErrorName` is
25
+ * `'SessionNotFound'` -- also after a new engine has been created with the
26
+ * same id. A handle never crosses over to another engine's session; obtain a
27
+ * new one from the new engine.
28
+ *
29
+ * **Everything is synchronous.** State queries, sequence-number access, the
30
+ * runtime option getters/setters, {@link Session.logon}, {@link Session.logout}
31
+ * and {@link Session.refresh} never take the mutex QuickFIX holds while running
32
+ * your application handlers, so they cannot deadlock the main thread, and calls
33
+ * made in program order take effect in program order. ({@link Session.logon} /
34
+ * {@link Session.logout} flip a plain flag the engine's network thread reads
35
+ * without a lock, exactly as QuickFIX's own `Initiator::stop()` does; the
36
+ * engine picks the change up on its next pass.) QuickFIX's
37
+ * `Session::disconnect()` / `reset()` are deliberately not exposed: they are
38
+ * only safe on the engine's own network thread (see ARCHITECTURE.md §5). Use
39
+ * {@link Session.logout} to bring a session down, and the sequence-number
40
+ * setters to reset its numbering -- on a quiet session; see
41
+ * {@link Session.setNextSenderMsgSeqNum}.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * const session = initiator.getSession(sessionID)!;
46
+ * if (session.isLoggedOn()) {
47
+ * console.log('next outbound seq', session.getExpectedSenderNum());
48
+ * session.logout('maintenance');
49
+ * }
50
+ * ```
51
+ */
52
+ class Session {
53
+ /** @internal Underlying native handle. */
54
+ #native;
55
+ /** @internal Use {@link lookupSession} / {@link Engine.getSession}. */
56
+ constructor(handle) {
57
+ this.#native = handle;
58
+ }
59
+ /** @internal Wrap an existing native session handle. */
60
+ static fromNative(handle) {
61
+ return new Session(handle);
62
+ }
63
+ /** @internal The native handle backing this session. */
64
+ get nativeHandle() {
65
+ return this.#native;
66
+ }
67
+ /** The id this handle refers to. Always available, even after the session is gone. */
68
+ get sessionID() {
69
+ return session_id_js_1.SessionID.fromNative(this.#native.getSessionID());
70
+ }
71
+ // --- state -----------------------------------------------------------------
72
+ /** `true` once a Logon has been both sent and received. */
73
+ isLoggedOn() {
74
+ return this.#native.isLoggedOn();
75
+ }
76
+ /**
77
+ * Whether the session is enabled. `false` after {@link Session.logout} until
78
+ * {@link Session.logon}; a disabled initiator session is not reconnected.
79
+ */
80
+ isEnabled() {
81
+ return this.#native.isEnabled();
82
+ }
83
+ /** Whether this side has sent a Logon on the current connection. */
84
+ sentLogon() {
85
+ return this.#native.sentLogon();
86
+ }
87
+ /** Whether this side has sent a Logout on the current connection. */
88
+ sentLogout() {
89
+ return this.#native.sentLogout();
90
+ }
91
+ /** Whether a Logon has been received on the current connection. */
92
+ receivedLogon() {
93
+ return this.#native.receivedLogon();
94
+ }
95
+ /** `true` for a session owned by an {@link Initiator}. */
96
+ isInitiator() {
97
+ return this.#native.isInitiator();
98
+ }
99
+ /** `true` for a session owned by an {@link Acceptor}. */
100
+ isAcceptor() {
101
+ return this.#native.isAcceptor();
102
+ }
103
+ /**
104
+ * Whether `now` (default: the current time) falls inside the session's
105
+ * configured `StartTime`/`EndTime` window. Throws `RangeError` for an
106
+ * invalid `Date`.
107
+ */
108
+ isSessionTime(now) {
109
+ return this.#native.isSessionTime(now?.getTime());
110
+ }
111
+ /**
112
+ * Whether `now` (default: the current time) falls inside the session's
113
+ * configured `LogonTime`/`LogoutTime` window. Throws `RangeError` for an
114
+ * invalid `Date`.
115
+ */
116
+ isLogonTime(now) {
117
+ return this.#native.isLogonTime(now?.getTime());
118
+ }
119
+ // --- sequence numbers --------------------------------------------------------
120
+ /** The MsgSeqNum (tag 34) the next outbound message will carry. */
121
+ getExpectedSenderNum() {
122
+ return this.#native.getExpectedSenderNum();
123
+ }
124
+ /** The MsgSeqNum (tag 34) expected on the next inbound message. */
125
+ getExpectedTargetNum() {
126
+ return this.#native.getExpectedTargetNum();
127
+ }
128
+ /**
129
+ * Set the MsgSeqNum the next outbound message will carry (writes to the
130
+ * message store; a file store may throw `IOException`).
131
+ *
132
+ * **Call it on a quiet session.** The setter is not serialised against a
133
+ * message the engine is sending or receiving on this session at the same
134
+ * time: QuickFIX reads the next number into the outbound header, runs your
135
+ * `toApp`/`toAdmin` handler, then increments from the store, all under a
136
+ * lock this call does not (and must not) take. A value set inside that
137
+ * window -- from a handler, or while a {@link sendToTarget} promise or a
138
+ * heartbeat is in flight on this session -- is overwritten by the increment,
139
+ * and the session ends up one off from its counterparty (a Resend Request or
140
+ * a "MsgSeqNum too low" Logout). Set it before {@link Engine.start}, from a
141
+ * `'logout'` event, or when you know nothing is in flight; never from a
142
+ * handler.
143
+ *
144
+ * @throws `RangeError` if `seqNum` is not a positive safe integer (MsgSeqNum is
145
+ * 1-based).
146
+ */
147
+ setNextSenderMsgSeqNum(seqNum) {
148
+ this.#native.setNextSenderMsgSeqNum(seqNum);
149
+ }
150
+ /**
151
+ * Set the MsgSeqNum expected on the next inbound message (writes to the
152
+ * message store; a file store may throw `IOException`).
153
+ *
154
+ * **Call it on a quiet session.** Like {@link Session.setNextSenderMsgSeqNum},
155
+ * it is not serialised against a message the engine is processing on this
156
+ * session: QuickFIX checks the inbound number, runs your `fromApp`/`fromAdmin`
157
+ * handler, then increments the expected number from the store under a lock
158
+ * this call does not take, so a value set meanwhile is overwritten. Set it
159
+ * before {@link Engine.start}, from a `'logout'` event, or when you know
160
+ * nothing is in flight; never from a handler.
161
+ *
162
+ * @throws `RangeError` if `seqNum` is not a positive safe integer (MsgSeqNum is
163
+ * 1-based).
164
+ */
165
+ setNextTargetMsgSeqNum(seqNum) {
166
+ this.#native.setNextTargetMsgSeqNum(seqNum);
167
+ }
168
+ // --- runtime options -----------------------------------------------------------
169
+ // Each pair mirrors a QuickFIX session setting; the setter changes the LIVE
170
+ // session only (the SessionSettings it was created from are not updated).
171
+ /** `ResetOnLogon` */
172
+ getResetOnLogon() {
173
+ return this.#native.getResetOnLogon();
174
+ }
175
+ setResetOnLogon(value) {
176
+ this.#native.setResetOnLogon(value);
177
+ }
178
+ /** `ResetOnLogout` */
179
+ getResetOnLogout() {
180
+ return this.#native.getResetOnLogout();
181
+ }
182
+ setResetOnLogout(value) {
183
+ this.#native.setResetOnLogout(value);
184
+ }
185
+ /** `ResetOnDisconnect` */
186
+ getResetOnDisconnect() {
187
+ return this.#native.getResetOnDisconnect();
188
+ }
189
+ setResetOnDisconnect(value) {
190
+ this.#native.setResetOnDisconnect(value);
191
+ }
192
+ /** `RefreshOnLogon` */
193
+ getRefreshOnLogon() {
194
+ return this.#native.getRefreshOnLogon();
195
+ }
196
+ setRefreshOnLogon(value) {
197
+ this.#native.setRefreshOnLogon(value);
198
+ }
199
+ /** `CheckCompID` */
200
+ getCheckCompId() {
201
+ return this.#native.getCheckCompId();
202
+ }
203
+ setCheckCompId(value) {
204
+ this.#native.setCheckCompId(value);
205
+ }
206
+ /** `CheckLatency` */
207
+ getCheckLatency() {
208
+ return this.#native.getCheckLatency();
209
+ }
210
+ setCheckLatency(value) {
211
+ this.#native.setCheckLatency(value);
212
+ }
213
+ /** `PersistMessages` */
214
+ getPersistMessages() {
215
+ return this.#native.getPersistMessages();
216
+ }
217
+ setPersistMessages(value) {
218
+ this.#native.setPersistMessages(value);
219
+ }
220
+ /** `SendRedundantResendRequests` */
221
+ getSendRedundantResendRequests() {
222
+ return this.#native.getSendRedundantResendRequests();
223
+ }
224
+ setSendRedundantResendRequests(value) {
225
+ this.#native.setSendRedundantResendRequests(value);
226
+ }
227
+ /** `ValidateLengthAndChecksum` */
228
+ getValidateLengthAndChecksum() {
229
+ return this.#native.getValidateLengthAndChecksum();
230
+ }
231
+ setValidateLengthAndChecksum(value) {
232
+ this.#native.setValidateLengthAndChecksum(value);
233
+ }
234
+ /** `SendNextExpectedMsgSeqNum` */
235
+ getSendNextExpectedMsgSeqNum() {
236
+ return this.#native.getSendNextExpectedMsgSeqNum();
237
+ }
238
+ setSendNextExpectedMsgSeqNum(value) {
239
+ this.#native.setSendNextExpectedMsgSeqNum(value);
240
+ }
241
+ /** `NonStopSession` */
242
+ getIsNonStopSession() {
243
+ return this.#native.getIsNonStopSession();
244
+ }
245
+ setIsNonStopSession(value) {
246
+ this.#native.setIsNonStopSession(value);
247
+ }
248
+ /** `LogonTimeout`, in seconds. */
249
+ getLogonTimeout() {
250
+ return this.#native.getLogonTimeout();
251
+ }
252
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
253
+ setLogonTimeout(seconds) {
254
+ this.#native.setLogonTimeout(seconds);
255
+ }
256
+ /** `LogoutTimeout`, in seconds. */
257
+ getLogoutTimeout() {
258
+ return this.#native.getLogoutTimeout();
259
+ }
260
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
261
+ setLogoutTimeout(seconds) {
262
+ this.#native.setLogoutTimeout(seconds);
263
+ }
264
+ /** `MaxLatency`, in seconds. */
265
+ getMaxLatency() {
266
+ return this.#native.getMaxLatency();
267
+ }
268
+ /** @throws {RangeError} if `seconds` is not an integer in the int32 range. */
269
+ setMaxLatency(seconds) {
270
+ this.#native.setMaxLatency(seconds);
271
+ }
272
+ /** `TimestampPrecision` (number of sub-second digits, `0..9`). */
273
+ getTimestampPrecision() {
274
+ return this.#native.getTimestampPrecision();
275
+ }
276
+ /** @throws `RangeError` unless `precision` is an integer in `0..9`. */
277
+ setTimestampPrecision(precision) {
278
+ this.#native.setTimestampPrecision(precision);
279
+ }
280
+ // --- control -----------------------------------------------------------------------
281
+ /**
282
+ * Enable the session. An initiator session reconnects and logs on at its
283
+ * next `ReconnectInterval`; an acceptor session accepts the next inbound
284
+ * Logon. Takes effect immediately ({@link Session.isEnabled} is `true` on
285
+ * return); observe the handshake through the engine's `'logon'` event.
286
+ */
287
+ logon() {
288
+ this.#native.logon();
289
+ }
290
+ /**
291
+ * Disable the session and initiate a graceful Logout (sent with `reason` as
292
+ * tag 58 on the next engine tick). The session stays disabled — it will not
293
+ * reconnect — until {@link Session.logon}. Takes effect immediately
294
+ * ({@link Session.isEnabled} is `false` on return); observe completion
295
+ * through the engine's `'logout'` event.
296
+ */
297
+ logout(reason) {
298
+ this.#native.logout(reason);
299
+ }
300
+ /**
301
+ * Re-read the session state (sequence numbers etc.) from the message store.
302
+ *
303
+ * @throws {QuickFixError} `IOException` if the store cannot be read.
304
+ */
305
+ refresh() {
306
+ this.#native.refresh();
307
+ }
308
+ }
309
+ exports.Session = Session;
310
+ /**
311
+ * Look up a live session by id, across every engine in this process.
312
+ *
313
+ * @returns The {@link Session}, or `undefined` if no session with that id
314
+ * exists (never created, or its engine has been stopped).
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * const session = lookupSession(new SessionID('FIX.4.4', 'CLIENT', 'BROKER'));
319
+ * console.log(session?.isLoggedOn());
320
+ * ```
321
+ */
322
+ function lookupSession(sessionID) {
323
+ const handle = native_js_1.native.lookupSession((0, session_id_js_1.toNativeSessionID)(sessionID, 'sessionID'));
324
+ return handle ? Session.fromNative(handle) : undefined;
325
+ }
326
+ /** Whether a session with this id exists in this process. */
327
+ function doesSessionExist(sessionID) {
328
+ return native_js_1.native.doesSessionExist((0, session_id_js_1.toNativeSessionID)(sessionID, 'sessionID'));
329
+ }
330
+ /** The ids of every session in this process, across all engines. */
331
+ function getSessions() {
332
+ return native_js_1.native.getSessions().map((h) => session_id_js_1.SessionID.fromNative(h));
333
+ }
334
+ /** The number of sessions in this process, across all engines. */
335
+ function numSessions() {
336
+ return native_js_1.native.numSessions();
337
+ }
@@ -0,0 +1,29 @@
1
+ import { Engine, type EngineOptions } from './engine.js';
2
+ export type { EngineOptions } from './engine.js';
3
+ /**
4
+ * A FIX session acceptor (wraps `FIX::SocketAcceptor`). Acceptors listen for
5
+ * inbound connections from initiators as configured in
6
+ * {@link EngineOptions.settings}.
7
+ *
8
+ * Extends {@link Engine} (an {@link import('node:events').EventEmitter}), so you
9
+ * can observe lifecycle/message events in addition to supplying `handlers`.
10
+ * Remember: only `handlers` may mutate outbound messages or reject inbound ones;
11
+ * events are observe-only.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const acceptor = new Acceptor({
16
+ * settings: SessionSettings.fromString(cfg),
17
+ * handlers: {
18
+ * fromApp: (msg, id) => { void sendToTarget(makeReply(msg), id); },
19
+ * },
20
+ * });
21
+ * await acceptor.start();
22
+ * // ... later
23
+ * await acceptor.stop();
24
+ * ```
25
+ */
26
+ export declare class Acceptor extends Engine {
27
+ /** @param options Engine options. */
28
+ constructor(options: EngineOptions);
29
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * FIX session acceptor (server side — listens for initiators).
3
+ */
4
+ import { native } from './native.js';
5
+ import { Engine } from './engine.js';
6
+ /**
7
+ * A FIX session acceptor (wraps `FIX::SocketAcceptor`). Acceptors listen for
8
+ * inbound connections from initiators as configured in
9
+ * {@link EngineOptions.settings}.
10
+ *
11
+ * Extends {@link Engine} (an {@link import('node:events').EventEmitter}), so you
12
+ * can observe lifecycle/message events in addition to supplying `handlers`.
13
+ * Remember: only `handlers` may mutate outbound messages or reject inbound ones;
14
+ * events are observe-only.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const acceptor = new Acceptor({
19
+ * settings: SessionSettings.fromString(cfg),
20
+ * handlers: {
21
+ * fromApp: (msg, id) => { void sendToTarget(makeReply(msg), id); },
22
+ * },
23
+ * });
24
+ * await acceptor.start();
25
+ * // ... later
26
+ * await acceptor.stop();
27
+ * ```
28
+ */
29
+ export class Acceptor extends Engine {
30
+ /** @param options Engine options. */
31
+ constructor(options) {
32
+ super(native.AcceptorWrap, options);
33
+ }
34
+ }