@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,325 @@
1
+ /**
2
+ * The field and repeating-group operations every `FIX::FieldMap` exposes.
3
+ * Shared by the message body and by group entries. Group indices are 1-based,
4
+ * as in QuickFIX; `getGroup` returns a snapshot copy.
5
+ */
6
+ export interface NativeFieldMap {
7
+ getField(tag: number): string;
8
+ setField(tag: number, value: string): void;
9
+ isSetField(tag: number): boolean;
10
+ removeField(tag: number): void;
11
+ getFieldIfSet(tag: number): string | undefined;
12
+ /** Own fields plus every field of every nested group entry. */
13
+ totalFields(): number;
14
+ isEmpty(): boolean;
15
+ clear(): void;
16
+ /** Own fields, in wire order, as `[tag, value]` pairs. */
17
+ fields(): [number, string][];
18
+ addGroup(group: NativeGroup): void;
19
+ /** @throws A {@link QuickFixError} (`FieldNotFound`) when absent / out of range. */
20
+ getGroup(index: number, tag: number): NativeGroup;
21
+ /** @throws A {@link QuickFixError} (`FieldNotFound`) when the slot does not exist. */
22
+ replaceGroup(index: number, group: NativeGroup): void;
23
+ removeGroup(tag: number): void;
24
+ removeGroup(index: number, tag: number): void;
25
+ hasGroup(tag: number): boolean;
26
+ hasGroup(index: number, tag: number): boolean;
27
+ groupCount(tag: number): number;
28
+ }
29
+ /**
30
+ * Native `FIX::Message` wrapper. FIX is string-on-the-wire, so every field
31
+ * value crosses the boundary as a string. The {@link NativeFieldMap} methods
32
+ * auto-route well-known header/trailer tags to the right section; `fields()`,
33
+ * `isEmpty()` and `totalFields()` read the body, `clear()` empties everything.
34
+ */
35
+ export interface NativeMessage extends NativeFieldMap {
36
+ getHeaderField(tag: number): string;
37
+ setHeaderField(tag: number, value: string): void;
38
+ getTrailerField(tag: number): string;
39
+ setTrailerField(tag: number, value: string): void;
40
+ headerFields(): [number, string][];
41
+ trailerFields(): [number, string][];
42
+ getMsgType(): string;
43
+ toString(): string;
44
+ toPretty(): string;
45
+ }
46
+ /** Constructor shape for the native `MessageWrap` class. */
47
+ export interface NativeMessageConstructor {
48
+ new (): NativeMessage;
49
+ /**
50
+ * Parse `raw`. With a dictionary the parse is structural (repeating groups
51
+ * become nested groups); without one it is flat. Admin messages always use
52
+ * the session dictionary; application messages use the application one.
53
+ */
54
+ new (raw: string, validate?: boolean, sessionDictionary?: NativeDataDictionary | null, applicationDictionary?: NativeDataDictionary | null): NativeMessage;
55
+ }
56
+ /** Native `FIX::Group` wrapper: one entry of a repeating group. */
57
+ export interface NativeGroup extends NativeFieldMap {
58
+ /** The group's count tag (e.g. 453 NoPartyIDs). */
59
+ field(): number;
60
+ /** The first tag of every entry (e.g. 448 PartyID). */
61
+ delim(): number;
62
+ /** The entry's fields (and nested groups) as a SOH-delimited string, in wire order. */
63
+ toString(): string;
64
+ }
65
+ /** Constructor shape for the native `GroupWrap` class. */
66
+ export interface NativeGroupConstructor {
67
+ /**
68
+ * @param order Optional full field order of an entry, delimiter first, no
69
+ * zeros. Without it, fields sort delimiter-first then by tag number.
70
+ */
71
+ new (field: number, delim: number, order?: readonly number[] | null): NativeGroup;
72
+ }
73
+ /** Native `FIX::SessionID` wrapper. */
74
+ export interface NativeSessionID {
75
+ getBeginString(): string;
76
+ getSenderCompID(): string;
77
+ getTargetCompID(): string;
78
+ getSessionQualifier(): string;
79
+ toString(): string;
80
+ }
81
+ /** Constructor shape for the native `SessionIDWrap` class. */
82
+ export interface NativeSessionIDConstructor {
83
+ new (beginString: string, senderCompID: string, targetCompID: string, qualifier?: string): NativeSessionID;
84
+ }
85
+ /** Native `FIX::SessionSettings` wrapper. */
86
+ export interface NativeSessionSettings {
87
+ getSessions(): NativeSessionID[];
88
+ }
89
+ /**
90
+ * Constructor shape for the native `SessionSettingsWrap` class. `fromString` /
91
+ * `fromFile` MAY appear here as statics (see the module-level equivalents on
92
+ * {@link NativeModule}); we resolve defensively at runtime.
93
+ */
94
+ export interface NativeSessionSettingsConstructor {
95
+ new (): NativeSessionSettings;
96
+ fromString?(cfg: string): NativeSessionSettings;
97
+ fromFile?(path: string): NativeSessionSettings;
98
+ }
99
+ /**
100
+ * Error shape thrown across the native bridge (e.g. from
101
+ * {@link NativeDataDictionary.validate}, message getters, or engine ops).
102
+ *
103
+ * Carries TWO error identifiers:
104
+ * - {@link QuickFixError.fixError} — the QuickFIX runtime exception type as
105
+ * reported by the C++ engine. This is a human-facing string that MAY contain
106
+ * spaces (e.g. `'Session Not Found'`, `'Field not found'`).
107
+ * - {@link QuickFixError.fixErrorName} — a stable, space-free discriminator
108
+ * suitable for `switch`/equality checks (e.g. `'SessionNotFound'`,
109
+ * `'FieldNotFound'`). Prefer this for programmatic branching.
110
+ */
111
+ export interface QuickFixError extends Error {
112
+ /** Always `'QuickFixError'` for errors originating in the native bridge. */
113
+ name: string;
114
+ /** Human-readable message. */
115
+ message: string;
116
+ /**
117
+ * QuickFIX runtime exception type string (may contain spaces), e.g.
118
+ * `'Session Not Found'`. This is the value the native bridge reads when
119
+ * mapping a thrown rejection back to a FIX exception.
120
+ */
121
+ fixError?: string;
122
+ /**
123
+ * Stable, space-free discriminator, e.g. `'SessionNotFound'`. Use this for
124
+ * programmatic checks; it is not subject to QuickFIX's human-facing wording.
125
+ */
126
+ fixErrorName?: string;
127
+ /** Optional extra detail forwarded from the engine where available. */
128
+ detail?: string;
129
+ }
130
+ /** Native `FIX::DataDictionary` wrapper. */
131
+ export interface NativeDataDictionary {
132
+ /**
133
+ * Throws a {@link QuickFixError} if the message is invalid. With `bodyOnly`
134
+ * the BeginString version check and the tag/value validation of the
135
+ * header/trailer fields are skipped; required header/trailer fields are
136
+ * still checked.
137
+ */
138
+ validate(message: NativeMessage, bodyOnly?: boolean): void;
139
+ /** The BeginString the spec declares (e.g. `'FIX.4.4'`), `''` if none. */
140
+ getVersion(): string;
141
+ getFieldName(tag: number): string | undefined;
142
+ getFieldTag(name: string): number | undefined;
143
+ isField(tag: number): boolean;
144
+ isMsgType(msgType: string): boolean;
145
+ }
146
+ /**
147
+ * Constructor shape for the native `DataDictionaryWrap` class. `fromString` /
148
+ * `fromFile` MAY appear here as statics (see module-level equivalents on
149
+ * {@link NativeModule}); we resolve defensively at runtime.
150
+ */
151
+ export interface NativeDataDictionaryConstructor {
152
+ new (): NativeDataDictionary;
153
+ fromString?(xml: string): NativeDataDictionary;
154
+ fromFile?(path: string): NativeDataDictionary;
155
+ }
156
+ /**
157
+ * The handlers object handed to the native engine constructor. Each callback
158
+ * receives raw native handles (the TS layer re-wraps them). Mutation happens by
159
+ * mutating the passed {@link NativeMessage}; rejection happens by throwing.
160
+ */
161
+ export interface NativeApplicationHandlers {
162
+ onCreate?(sessionID: NativeSessionID): void;
163
+ onLogon?(sessionID: NativeSessionID): void;
164
+ onLogout?(sessionID: NativeSessionID): void;
165
+ toAdmin?(message: NativeMessage, sessionID: NativeSessionID): void;
166
+ toApp?(message: NativeMessage, sessionID: NativeSessionID): void;
167
+ fromAdmin?(message: NativeMessage, sessionID: NativeSessionID): void;
168
+ fromApp?(message: NativeMessage, sessionID: NativeSessionID): void;
169
+ }
170
+ /** Options passed to the native `InitiatorWrap` / `AcceptorWrap` constructors. */
171
+ export interface NativeEngineOptions {
172
+ settings: NativeSessionSettings;
173
+ handlers?: NativeApplicationHandlers;
174
+ store?: 'file' | 'memory';
175
+ log?: 'screen' | 'file' | 'none';
176
+ }
177
+ /**
178
+ * Native handle on a live `FIX::Session`.
179
+ *
180
+ * The handle stores only the `FIX::SessionID`; every method re-resolves the
181
+ * engine-owned session via `FIX::Session::lookupSession` and throws a
182
+ * {@link QuickFixError} with `fixErrorName: 'SessionNotFound'` once the owning
183
+ * engine has been stopped.
184
+ *
185
+ * Every member is synchronous: none takes the session mutex QuickFIX holds
186
+ * across application callbacks, so they cannot deadlock the main thread
187
+ * (`logon()`/`logout()` write a plain flag the network thread reads without a
188
+ * lock, as QuickFIX's own `Initiator::stop()` does).
189
+ * `FIX::Session::disconnect()`/`reset()` are not exposed; they are only safe
190
+ * on the engine's own network thread (see `cpp/session_wrap.cpp`).
191
+ */
192
+ export interface NativeSession {
193
+ getSessionID(): NativeSessionID;
194
+ isLoggedOn(): boolean;
195
+ isEnabled(): boolean;
196
+ sentLogon(): boolean;
197
+ sentLogout(): boolean;
198
+ receivedLogon(): boolean;
199
+ isInitiator(): boolean;
200
+ isAcceptor(): boolean;
201
+ /** `nowMs` is an epoch-millisecond timestamp; omitted means "now". */
202
+ isSessionTime(nowMs?: number): boolean;
203
+ isLogonTime(nowMs?: number): boolean;
204
+ getExpectedSenderNum(): number;
205
+ getExpectedTargetNum(): number;
206
+ setNextSenderMsgSeqNum(seqNum: number): void;
207
+ setNextTargetMsgSeqNum(seqNum: number): void;
208
+ getResetOnLogon(): boolean;
209
+ setResetOnLogon(value: boolean): void;
210
+ getResetOnLogout(): boolean;
211
+ setResetOnLogout(value: boolean): void;
212
+ getResetOnDisconnect(): boolean;
213
+ setResetOnDisconnect(value: boolean): void;
214
+ getRefreshOnLogon(): boolean;
215
+ setRefreshOnLogon(value: boolean): void;
216
+ getCheckCompId(): boolean;
217
+ setCheckCompId(value: boolean): void;
218
+ getCheckLatency(): boolean;
219
+ setCheckLatency(value: boolean): void;
220
+ getPersistMessages(): boolean;
221
+ setPersistMessages(value: boolean): void;
222
+ getSendRedundantResendRequests(): boolean;
223
+ setSendRedundantResendRequests(value: boolean): void;
224
+ getValidateLengthAndChecksum(): boolean;
225
+ setValidateLengthAndChecksum(value: boolean): void;
226
+ getSendNextExpectedMsgSeqNum(): boolean;
227
+ setSendNextExpectedMsgSeqNum(value: boolean): void;
228
+ getIsNonStopSession(): boolean;
229
+ setIsNonStopSession(value: boolean): void;
230
+ getLogonTimeout(): number;
231
+ setLogonTimeout(seconds: number): void;
232
+ getLogoutTimeout(): number;
233
+ setLogoutTimeout(seconds: number): void;
234
+ getMaxLatency(): number;
235
+ setMaxLatency(seconds: number): void;
236
+ getTimestampPrecision(): number;
237
+ /** Throws a `RangeError` unless `precision` is an integer in `0..9`. */
238
+ setTimestampPrecision(precision: number): void;
239
+ logon(): void;
240
+ logout(reason?: string): void;
241
+ /** May throw a `QuickFixError` (`IOException`) from the message store. */
242
+ refresh(): void;
243
+ }
244
+ /**
245
+ * Constructor shape for the native `SessionWrap` class. Internal: JS obtains a
246
+ * session through {@link NativeModule.lookupSession} or
247
+ * {@link NativeEngine.getSession}, never by constructing one.
248
+ */
249
+ export interface NativeSessionConstructor {
250
+ new (sessionID: NativeSessionID): NativeSession;
251
+ }
252
+ /**
253
+ * Native engine (SocketInitiator / SocketAcceptor) wrapper.
254
+ *
255
+ * `start`/`stop` run OFF the main thread and resolve a Promise when the engine
256
+ * has finished (re)configuring its sockets, so the Node.js event loop stays free
257
+ * to service the application callbacks the engine fires. `isLoggedOn`/`ref`/
258
+ * `unref`/`getSessions`/`getSession` remain synchronous.
259
+ *
260
+ * Once `stop()` settles the engine is destroyed, which also destroys its
261
+ * `FIX::Session` objects: `getSession` then returns `undefined` and any
262
+ * previously obtained {@link NativeSession} throws `SessionNotFound`.
263
+ */
264
+ export interface NativeEngine {
265
+ start(): Promise<void>;
266
+ stop(force?: boolean): Promise<void>;
267
+ /**
268
+ * No argument: whether ANY of this engine's sessions is logged on. With a
269
+ * SessionID: whether THAT session belongs to this engine and is logged on.
270
+ */
271
+ isLoggedOn(sessionID?: NativeSessionID): boolean;
272
+ /** The SessionIDs this engine was configured with (stable across stop()). */
273
+ getSessions(): NativeSessionID[];
274
+ /** `undefined` if the id is not one of this engine's sessions or stop() has settled. */
275
+ getSession(sessionID: NativeSessionID): NativeSession | undefined;
276
+ ref(): void;
277
+ unref(): void;
278
+ }
279
+ /** Constructor shape for the native `InitiatorWrap` / `AcceptorWrap` classes. */
280
+ export interface NativeEngineConstructor {
281
+ new (options: NativeEngineOptions): NativeEngine;
282
+ }
283
+ /**
284
+ * The full surface of the native addon exported by `load-native.cjs`.
285
+ *
286
+ * FIX constants are not exported by the addon: field tags (`FIELD`) and value
287
+ * groups (`MsgType`, `Side`, ...) are generated on the TS side from the
288
+ * QuickFIX headers (`src/generated/fields.ts`, `src/generated/values.ts`).
289
+ */
290
+ export interface NativeModule {
291
+ version(): string;
292
+ quickfixParseMsgType(raw: string): string;
293
+ /**
294
+ * Runs off the main thread; resolves `true` if accepted for sending.
295
+ *
296
+ * Second argument: an explicit SessionID, or a session qualifier (possibly
297
+ * omitted/empty), in which case QuickFIX resolves the session from the
298
+ * message's own header (BeginString / SenderCompID / TargetCompID).
299
+ */
300
+ sendToTarget(message: NativeMessage, sessionIDOrQualifier?: NativeSessionID | string): Promise<boolean>;
301
+ /** `undefined` if no session with that id exists in this process. */
302
+ lookupSession(sessionID: NativeSessionID): NativeSession | undefined;
303
+ doesSessionExist(sessionID: NativeSessionID): boolean;
304
+ /** Every session registered in this process (all engines). */
305
+ getSessions(): NativeSessionID[];
306
+ numSessions(): number;
307
+ MessageWrap: NativeMessageConstructor;
308
+ GroupWrap: NativeGroupConstructor;
309
+ SessionIDWrap: NativeSessionIDConstructor;
310
+ SessionSettingsWrap: NativeSessionSettingsConstructor;
311
+ DataDictionaryWrap: NativeDataDictionaryConstructor;
312
+ SessionWrap: NativeSessionConstructor;
313
+ InitiatorWrap: NativeEngineConstructor;
314
+ AcceptorWrap: NativeEngineConstructor;
315
+ sessionSettingsFromString?(cfg: string): NativeSessionSettings;
316
+ sessionSettingsFromFile?(path: string): NativeSessionSettings;
317
+ dataDictionaryFromString?(xml: string): NativeDataDictionary;
318
+ dataDictionaryFromFile?(path: string): NativeDataDictionary;
319
+ }
320
+ /**
321
+ * The loaded native addon, typed against the {@link NativeModule} contract.
322
+ * The default import is an `unknown` (per node-gyp-build's declaration); we
323
+ * assert it to the contract here — the single localized cast in the codebase.
324
+ */
325
+ export declare const native: NativeModule;
@@ -0,0 +1,16 @@
1
+ // Loads the compiled native addon. The actual `require('node-gyp-build')(root)`
2
+ // lives in the authored load-native.cjs, which build:ts:copy places next to the
3
+ // compiled output in both dist/esm and dist/cjs. We import it here; the ESM and
4
+ // CJS TS builds each emit the correct interop for pulling in a CommonJS module,
5
+ // so this single source works for both output formats.
6
+ //
7
+ // A plain default import compiles under BOTH tsconfigs (NodeNext ESM and
8
+ // CommonJS/Bundler). We intentionally avoid `import.meta` / `createRequire`
9
+ // here because `import.meta` is not permitted under the CommonJS tsconfig.
10
+ import nativeModule from './load-native.cjs';
11
+ /**
12
+ * The loaded native addon, typed against the {@link NativeModule} contract.
13
+ * The default import is an `unknown` (per node-gyp-build's declaration); we
14
+ * assert it to the contract here — the single localized cast in the codebase.
15
+ */
16
+ export const native = nativeModule;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Ergonomic wrapper around the native `FIX::SessionID`.
3
+ */
4
+ import { type NativeSessionID } from './native.js';
5
+ /**
6
+ * Identifies a FIX session by its `BeginString`, `SenderCompID`,
7
+ * `TargetCompID`, and an optional qualifier.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const id = new SessionID('FIX.4.4', 'CLIENT', 'BROKER');
12
+ * console.log(id.toString()); // FIX.4.4:CLIENT->BROKER
13
+ * ```
14
+ */
15
+ export declare class SessionID {
16
+ #private;
17
+ /**
18
+ * @param beginString FIX version, e.g. `'FIX.4.4'`, or an existing native
19
+ * handle to adopt (bridge path).
20
+ * @param senderCompID The sender's CompID.
21
+ * @param targetCompID The target's CompID.
22
+ * @param qualifier Optional session qualifier.
23
+ */
24
+ constructor(beginString: string | NativeSessionID, senderCompID?: string, targetCompID?: string, qualifier?: string);
25
+ /** @internal Wrap an existing native session-id handle (used by the engine bridge). */
26
+ static fromNative(handle: NativeSessionID): SessionID;
27
+ /** @internal The native handle backing this session id. */
28
+ get nativeHandle(): NativeSessionID;
29
+ /** FIX version, e.g. `'FIX.4.4'`. */
30
+ get beginString(): string;
31
+ /** The sender's CompID. */
32
+ get senderCompID(): string;
33
+ /** The target's CompID. */
34
+ get targetCompID(): string;
35
+ /** The session qualifier (empty string if none). */
36
+ get sessionQualifier(): string;
37
+ /** The canonical string form, e.g. `FIX.4.4:CLIENT->BROKER`. */
38
+ toString(): string;
39
+ }
40
+ /**
41
+ * @internal The native handle behind a {@link SessionID} argument.
42
+ *
43
+ * Duck-typed rather than `instanceof SessionID`: this package ships ESM and
44
+ * CJS builds, and a `SessionID` created by the other build is a different class
45
+ * with the same shape. Both builds load the same native addon, so its
46
+ * `SessionIDWrap` class is the one thing they share, and that is what the
47
+ * handle is checked against. Anything else -- `null`, `{}`, a `Session` -- is
48
+ * a `TypeError` naming the argument, rather than silently degrading to an
49
+ * `undefined` handle that the callee would read as "no session id given".
50
+ */
51
+ export declare function toNativeSessionID(value: unknown, name: string): NativeSessionID;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Ergonomic wrapper around the native `FIX::SessionID`.
3
+ */
4
+ import { native } from './native.js';
5
+ /**
6
+ * Identifies a FIX session by its `BeginString`, `SenderCompID`,
7
+ * `TargetCompID`, and an optional qualifier.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const id = new SessionID('FIX.4.4', 'CLIENT', 'BROKER');
12
+ * console.log(id.toString()); // FIX.4.4:CLIENT->BROKER
13
+ * ```
14
+ */
15
+ export class SessionID {
16
+ /** @internal Underlying native handle. */
17
+ #native;
18
+ /**
19
+ * @param beginString FIX version, e.g. `'FIX.4.4'`, or an existing native
20
+ * handle to adopt (bridge path).
21
+ * @param senderCompID The sender's CompID.
22
+ * @param targetCompID The target's CompID.
23
+ * @param qualifier Optional session qualifier.
24
+ */
25
+ constructor(beginString, senderCompID, targetCompID, qualifier) {
26
+ if (typeof beginString !== 'string') {
27
+ // Adopt an existing native handle (bridge path).
28
+ this.#native = beginString;
29
+ }
30
+ else {
31
+ this.#native = new native.SessionIDWrap(beginString, senderCompID ?? '', targetCompID ?? '', qualifier);
32
+ }
33
+ }
34
+ /** @internal Wrap an existing native session-id handle (used by the engine bridge). */
35
+ static fromNative(handle) {
36
+ return new SessionID(handle);
37
+ }
38
+ /** @internal The native handle backing this session id. */
39
+ get nativeHandle() {
40
+ return this.#native;
41
+ }
42
+ /** FIX version, e.g. `'FIX.4.4'`. */
43
+ get beginString() {
44
+ return this.#native.getBeginString();
45
+ }
46
+ /** The sender's CompID. */
47
+ get senderCompID() {
48
+ return this.#native.getSenderCompID();
49
+ }
50
+ /** The target's CompID. */
51
+ get targetCompID() {
52
+ return this.#native.getTargetCompID();
53
+ }
54
+ /** The session qualifier (empty string if none). */
55
+ get sessionQualifier() {
56
+ return this.#native.getSessionQualifier();
57
+ }
58
+ /** The canonical string form, e.g. `FIX.4.4:CLIENT->BROKER`. */
59
+ toString() {
60
+ return this.#native.toString();
61
+ }
62
+ }
63
+ /**
64
+ * @internal The native handle behind a {@link SessionID} argument.
65
+ *
66
+ * Duck-typed rather than `instanceof SessionID`: this package ships ESM and
67
+ * CJS builds, and a `SessionID` created by the other build is a different class
68
+ * with the same shape. Both builds load the same native addon, so its
69
+ * `SessionIDWrap` class is the one thing they share, and that is what the
70
+ * handle is checked against. Anything else -- `null`, `{}`, a `Session` -- is
71
+ * a `TypeError` naming the argument, rather than silently degrading to an
72
+ * `undefined` handle that the callee would read as "no session id given".
73
+ */
74
+ export function toNativeSessionID(value, name) {
75
+ const handle = typeof value === 'object' && value !== null
76
+ ? value.nativeHandle
77
+ : undefined;
78
+ if (!(handle instanceof native.SessionIDWrap)) {
79
+ throw new TypeError(`${name} must be a SessionID`);
80
+ }
81
+ return handle;
82
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Ergonomic wrapper around the native `FIX::SessionSettings`.
3
+ */
4
+ import { type NativeSessionSettings } from './native.js';
5
+ import { SessionID } from './session-id.js';
6
+ /**
7
+ * Parsed QuickFIX session settings (the `.cfg` configuration).
8
+ *
9
+ * Construct via {@link SessionSettings.fromString} or
10
+ * {@link SessionSettings.fromFile}; direct construction is not supported.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const settings = SessionSettings.fromString(`
15
+ * [DEFAULT]
16
+ * ConnectionType=initiator
17
+ * ...
18
+ * `);
19
+ * for (const id of settings.getSessions()) console.log(id.toString());
20
+ * ```
21
+ */
22
+ export declare class SessionSettings {
23
+ #private;
24
+ /** @internal Use {@link SessionSettings.fromString} / {@link SessionSettings.fromFile}. */
25
+ private constructor();
26
+ /**
27
+ * Parse settings from an in-memory config string.
28
+ *
29
+ * @param cfg The QuickFIX `.cfg` contents.
30
+ * @throws A `QuickFixError` (`fixError: 'ConfigError'`) on invalid config.
31
+ */
32
+ static fromString(cfg: string): SessionSettings;
33
+ /**
34
+ * Load settings from a `.cfg` file on disk.
35
+ *
36
+ * @param path Path to the QuickFIX `.cfg` file.
37
+ * @throws A `QuickFixError` (`fixError: 'ConfigError'`) on invalid config.
38
+ */
39
+ static fromFile(path: string): SessionSettings;
40
+ /** @internal Wrap an existing native handle. */
41
+ static fromNative(handle: NativeSessionSettings): SessionSettings;
42
+ /** @internal The native handle backing these settings. */
43
+ get nativeHandle(): NativeSessionSettings;
44
+ /** The sessions declared by this configuration. */
45
+ getSessions(): SessionID[];
46
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Ergonomic wrapper around the native `FIX::SessionSettings`.
3
+ */
4
+ import { native } from './native.js';
5
+ import { SessionID } from './session-id.js';
6
+ /**
7
+ * Parsed QuickFIX session settings (the `.cfg` configuration).
8
+ *
9
+ * Construct via {@link SessionSettings.fromString} or
10
+ * {@link SessionSettings.fromFile}; direct construction is not supported.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const settings = SessionSettings.fromString(`
15
+ * [DEFAULT]
16
+ * ConnectionType=initiator
17
+ * ...
18
+ * `);
19
+ * for (const id of settings.getSessions()) console.log(id.toString());
20
+ * ```
21
+ */
22
+ export class SessionSettings {
23
+ /** @internal Underlying native handle. */
24
+ #native;
25
+ /** @internal Use {@link SessionSettings.fromString} / {@link SessionSettings.fromFile}. */
26
+ constructor(handle) {
27
+ this.#native = handle;
28
+ }
29
+ /**
30
+ * Parse settings from an in-memory config string.
31
+ *
32
+ * @param cfg The QuickFIX `.cfg` contents.
33
+ * @throws A `QuickFixError` (`fixError: 'ConfigError'`) on invalid config.
34
+ */
35
+ static fromString(cfg) {
36
+ // The native `fromString` may be a module-level fn or a class static;
37
+ // prefer the module-level fn, fall back to the static.
38
+ const handle = native.sessionSettingsFromString?.(cfg) ??
39
+ native.SessionSettingsWrap.fromString?.(cfg);
40
+ if (!handle) {
41
+ throw new Error('native SessionSettings.fromString is unavailable');
42
+ }
43
+ return new SessionSettings(handle);
44
+ }
45
+ /**
46
+ * Load settings from a `.cfg` file on disk.
47
+ *
48
+ * @param path Path to the QuickFIX `.cfg` file.
49
+ * @throws A `QuickFixError` (`fixError: 'ConfigError'`) on invalid config.
50
+ */
51
+ static fromFile(path) {
52
+ const handle = native.sessionSettingsFromFile?.(path) ??
53
+ native.SessionSettingsWrap.fromFile?.(path);
54
+ if (!handle) {
55
+ throw new Error('native SessionSettings.fromFile is unavailable');
56
+ }
57
+ return new SessionSettings(handle);
58
+ }
59
+ /** @internal Wrap an existing native handle. */
60
+ static fromNative(handle) {
61
+ return new SessionSettings(handle);
62
+ }
63
+ /** @internal The native handle backing these settings. */
64
+ get nativeHandle() {
65
+ return this.#native;
66
+ }
67
+ /** The sessions declared by this configuration. */
68
+ getSessions() {
69
+ return this.#native.getSessions().map((h) => SessionID.fromNative(h));
70
+ }
71
+ }