@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,126 @@
1
+ /**
2
+ * Ergonomic wrapper around the native `FIX::Group`: one entry of a repeating
3
+ * group.
4
+ */
5
+ import { type NativeGroup } from './native.js';
6
+ /**
7
+ * One entry of a FIX repeating group.
8
+ *
9
+ * A group is identified by its **count tag** (`field`, e.g. `453 NoPartyIDs`)
10
+ * and its **delimiter** (`delim`, the first tag of every entry, e.g.
11
+ * `448 PartyID`). Build an entry, fill its fields, then
12
+ * {@link Message.addGroup} it; QuickFIX maintains the count field for you.
13
+ *
14
+ * Field values are accepted as `string | number` on input (numbers are written
15
+ * without exponent notation) and always returned as `string`, exactly as on
16
+ * {@link Message}. Groups nest: an entry can carry its own repeating groups
17
+ * through the same `addGroup` / `getGroup` API.
18
+ *
19
+ * Entries read back with `getGroup` are **snapshot copies**: mutating one does
20
+ * not change the message it came from. Write it back with
21
+ * {@link Message.replaceGroup}.
22
+ *
23
+ * Group indices are **1-based**, as in QuickFIX.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { Group, Message, FIELD } from '@homaiohq/napi-quickfix';
28
+ *
29
+ * const party = new Group(FIELD.NoPartyIDs, FIELD.PartyID)
30
+ * .setField(FIELD.PartyID, 'TRADER-1')
31
+ * .setField(FIELD.PartyIDSource, 'D')
32
+ * .setField(FIELD.PartyRole, 11);
33
+ * order.addGroup(party);
34
+ *
35
+ * order.groupCount(FIELD.NoPartyIDs); // 1
36
+ * order.getGroup(1, FIELD.NoPartyIDs).getField(FIELD.PartyID); // 'TRADER-1'
37
+ * ```
38
+ */
39
+ export declare class Group {
40
+ #private;
41
+ /**
42
+ * Create an empty group entry.
43
+ *
44
+ * @param field The group's count tag (e.g. `FIELD.NoPartyIDs`), or an
45
+ * existing native handle to adopt (internal).
46
+ * @param delim The delimiter: the first tag of every entry (e.g.
47
+ * `FIELD.PartyID`).
48
+ * @param order Optional complete field order of an entry, delimiter first
49
+ * (e.g. `[448, 447, 452]`). Fields not listed sort after the listed ones by
50
+ * tag number. Without it, fields sort delimiter-first then by tag number,
51
+ * which already matches the standard dictionaries for most groups.
52
+ */
53
+ constructor(field: number | NativeGroup, delim?: number, order?: readonly number[]);
54
+ /** @internal Wrap an existing native group handle. */
55
+ static fromNative(handle: NativeGroup): Group;
56
+ /** @internal The native handle backing this group. */
57
+ get nativeHandle(): NativeGroup;
58
+ /** The group's count tag (e.g. `453` for `NoPartyIDs`). */
59
+ get field(): number;
60
+ /** The delimiter: the first tag of every entry (e.g. `448` for `PartyID`). */
61
+ get delim(): number;
62
+ /**
63
+ * Read a field by tag.
64
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) if absent.
65
+ */
66
+ getField(tag: number): string;
67
+ /** Set a field. Returns `this` for chaining. */
68
+ setField(tag: number, value: string | number): this;
69
+ /** Whether a field is present. */
70
+ isSetField(tag: number): boolean;
71
+ /** Remove a field (no-op if absent). Returns `this` for chaining. */
72
+ removeField(tag: number): this;
73
+ /** Read a field by tag, or `undefined` if absent. */
74
+ getFieldIfSet(tag: number): string | undefined;
75
+ /** The number of fields, including every field of every nested group entry. */
76
+ totalFields(): number;
77
+ /** Whether the entry has no fields of its own. */
78
+ isEmpty(): boolean;
79
+ /** Remove every field and nested group. Returns `this` for chaining. */
80
+ clear(): this;
81
+ /** The entry's own fields, in wire order, as `[tag, value]` pairs. */
82
+ fields(): [number, string][];
83
+ /** Iterates the entry's own fields as `[tag, value]` pairs (see {@link Group.fields}). */
84
+ [Symbol.iterator](): IterableIterator<[number, string]>;
85
+ /**
86
+ * Append a nested group entry under its own count tag (a copy is stored; the
87
+ * count field is updated). Returns `this` for chaining.
88
+ * @throws `TypeError` when `group.delim` differs from the delimiter of the
89
+ * entries already stored under `group.field`.
90
+ */
91
+ addGroup(group: Group): this;
92
+ /**
93
+ * A snapshot copy of the `index`-th entry (1-based) of the nested group `tag`.
94
+ * Mutations do not affect this entry; write them back with
95
+ * {@link Group.replaceGroup}.
96
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) when the tag
97
+ * has no entries or `index` is out of range.
98
+ */
99
+ getGroup(index: number, tag: number): Group;
100
+ /**
101
+ * Overwrite the `index`-th entry (1-based) under `group.field` with a copy of
102
+ * `group`. Returns `this` for chaining.
103
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) when that
104
+ * entry does not exist.
105
+ * @throws `TypeError` when `group.delim` differs from the stored entry's
106
+ * delimiter.
107
+ */
108
+ replaceGroup(index: number, group: Group): this;
109
+ /**
110
+ * Remove every entry of the nested group `tag` (and its count field), or
111
+ * only the `index`-th entry (1-based). Returns `this`.
112
+ *
113
+ * Removing every entry of a tag that has none is a no-op.
114
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) when the
115
+ * `index`-th entry does not exist.
116
+ */
117
+ removeGroup(tag: number): this;
118
+ removeGroup(index: number, tag: number): this;
119
+ /** Whether the nested group `tag` has any entry, or has an `index`-th entry (1-based). */
120
+ hasGroup(tag: number): boolean;
121
+ hasGroup(index: number, tag: number): boolean;
122
+ /** The number of entries of the nested group `tag` (0 if none). */
123
+ groupCount(tag: number): number;
124
+ /** The entry's fields (and nested groups) as a SOH-delimited string, in wire order. */
125
+ toString(): string;
126
+ }
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Group = void 0;
4
+ /**
5
+ * Ergonomic wrapper around the native `FIX::Group`: one entry of a repeating
6
+ * group.
7
+ */
8
+ const native_js_1 = require("./native.js");
9
+ const field_value_js_1 = require("./field-value.js");
10
+ /**
11
+ * One entry of a FIX repeating group.
12
+ *
13
+ * A group is identified by its **count tag** (`field`, e.g. `453 NoPartyIDs`)
14
+ * and its **delimiter** (`delim`, the first tag of every entry, e.g.
15
+ * `448 PartyID`). Build an entry, fill its fields, then
16
+ * {@link Message.addGroup} it; QuickFIX maintains the count field for you.
17
+ *
18
+ * Field values are accepted as `string | number` on input (numbers are written
19
+ * without exponent notation) and always returned as `string`, exactly as on
20
+ * {@link Message}. Groups nest: an entry can carry its own repeating groups
21
+ * through the same `addGroup` / `getGroup` API.
22
+ *
23
+ * Entries read back with `getGroup` are **snapshot copies**: mutating one does
24
+ * not change the message it came from. Write it back with
25
+ * {@link Message.replaceGroup}.
26
+ *
27
+ * Group indices are **1-based**, as in QuickFIX.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { Group, Message, FIELD } from '@homaiohq/napi-quickfix';
32
+ *
33
+ * const party = new Group(FIELD.NoPartyIDs, FIELD.PartyID)
34
+ * .setField(FIELD.PartyID, 'TRADER-1')
35
+ * .setField(FIELD.PartyIDSource, 'D')
36
+ * .setField(FIELD.PartyRole, 11);
37
+ * order.addGroup(party);
38
+ *
39
+ * order.groupCount(FIELD.NoPartyIDs); // 1
40
+ * order.getGroup(1, FIELD.NoPartyIDs).getField(FIELD.PartyID); // 'TRADER-1'
41
+ * ```
42
+ */
43
+ class Group {
44
+ /** @internal Underlying native handle. */
45
+ #native;
46
+ /**
47
+ * Create an empty group entry.
48
+ *
49
+ * @param field The group's count tag (e.g. `FIELD.NoPartyIDs`), or an
50
+ * existing native handle to adopt (internal).
51
+ * @param delim The delimiter: the first tag of every entry (e.g.
52
+ * `FIELD.PartyID`).
53
+ * @param order Optional complete field order of an entry, delimiter first
54
+ * (e.g. `[448, 447, 452]`). Fields not listed sort after the listed ones by
55
+ * tag number. Without it, fields sort delimiter-first then by tag number,
56
+ * which already matches the standard dictionaries for most groups.
57
+ */
58
+ constructor(field, delim, order) {
59
+ if (typeof field !== 'number') {
60
+ // Adopt an existing native handle (getGroup path).
61
+ this.#native = field;
62
+ }
63
+ else {
64
+ if (typeof delim !== 'number') {
65
+ throw new TypeError('new Group(field: number, delim: number, order?: number[])');
66
+ }
67
+ this.#native = new native_js_1.native.GroupWrap(field, delim, order);
68
+ }
69
+ }
70
+ /** @internal Wrap an existing native group handle. */
71
+ static fromNative(handle) {
72
+ return new Group(handle);
73
+ }
74
+ /** @internal The native handle backing this group. */
75
+ get nativeHandle() {
76
+ return this.#native;
77
+ }
78
+ /** The group's count tag (e.g. `453` for `NoPartyIDs`). */
79
+ get field() {
80
+ return this.#native.field();
81
+ }
82
+ /** The delimiter: the first tag of every entry (e.g. `448` for `PartyID`). */
83
+ get delim() {
84
+ return this.#native.delim();
85
+ }
86
+ /**
87
+ * Read a field by tag.
88
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) if absent.
89
+ */
90
+ getField(tag) {
91
+ return this.#native.getField(tag);
92
+ }
93
+ /** Set a field. Returns `this` for chaining. */
94
+ setField(tag, value) {
95
+ this.#native.setField(tag, (0, field_value_js_1.formatFieldValue)(value));
96
+ return this;
97
+ }
98
+ /** Whether a field is present. */
99
+ isSetField(tag) {
100
+ return this.#native.isSetField(tag);
101
+ }
102
+ /** Remove a field (no-op if absent). Returns `this` for chaining. */
103
+ removeField(tag) {
104
+ this.#native.removeField(tag);
105
+ return this;
106
+ }
107
+ /** Read a field by tag, or `undefined` if absent. */
108
+ getFieldIfSet(tag) {
109
+ return this.#native.getFieldIfSet(tag);
110
+ }
111
+ /** The number of fields, including every field of every nested group entry. */
112
+ totalFields() {
113
+ return this.#native.totalFields();
114
+ }
115
+ /** Whether the entry has no fields of its own. */
116
+ isEmpty() {
117
+ return this.#native.isEmpty();
118
+ }
119
+ /** Remove every field and nested group. Returns `this` for chaining. */
120
+ clear() {
121
+ this.#native.clear();
122
+ return this;
123
+ }
124
+ /** The entry's own fields, in wire order, as `[tag, value]` pairs. */
125
+ fields() {
126
+ return this.#native.fields();
127
+ }
128
+ /** Iterates the entry's own fields as `[tag, value]` pairs (see {@link Group.fields}). */
129
+ [Symbol.iterator]() {
130
+ return this.fields()[Symbol.iterator]();
131
+ }
132
+ /**
133
+ * Append a nested group entry under its own count tag (a copy is stored; the
134
+ * count field is updated). Returns `this` for chaining.
135
+ * @throws `TypeError` when `group.delim` differs from the delimiter of the
136
+ * entries already stored under `group.field`.
137
+ */
138
+ addGroup(group) {
139
+ this.#native.addGroup(group.nativeHandle);
140
+ return this;
141
+ }
142
+ /**
143
+ * A snapshot copy of the `index`-th entry (1-based) of the nested group `tag`.
144
+ * Mutations do not affect this entry; write them back with
145
+ * {@link Group.replaceGroup}.
146
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) when the tag
147
+ * has no entries or `index` is out of range.
148
+ */
149
+ getGroup(index, tag) {
150
+ return Group.fromNative(this.#native.getGroup(index, tag));
151
+ }
152
+ /**
153
+ * Overwrite the `index`-th entry (1-based) under `group.field` with a copy of
154
+ * `group`. Returns `this` for chaining.
155
+ * @throws A `QuickFixError` (`fixErrorName: 'FieldNotFound'`) when that
156
+ * entry does not exist.
157
+ * @throws `TypeError` when `group.delim` differs from the stored entry's
158
+ * delimiter.
159
+ */
160
+ replaceGroup(index, group) {
161
+ this.#native.replaceGroup(index, group.nativeHandle);
162
+ return this;
163
+ }
164
+ removeGroup(a, b) {
165
+ if (b === undefined) {
166
+ this.#native.removeGroup(a);
167
+ }
168
+ else {
169
+ this.#native.removeGroup(a, b);
170
+ }
171
+ return this;
172
+ }
173
+ hasGroup(a, b) {
174
+ return b === undefined ? this.#native.hasGroup(a) : this.#native.hasGroup(a, b);
175
+ }
176
+ /** The number of entries of the nested group `tag` (0 if none). */
177
+ groupCount(tag) {
178
+ return this.#native.groupCount(tag);
179
+ }
180
+ /** The entry's fields (and nested groups) as a SOH-delimited string, in wire order. */
181
+ toString() {
182
+ return this.#native.toString();
183
+ }
184
+ }
185
+ exports.Group = Group;
@@ -0,0 +1,68 @@
1
+ import type { Message } from './message.js';
2
+ import { type SessionID } from './session-id.js';
3
+ export { Message, createMessage, parseMessage } from './message.js';
4
+ export type { MessageParseOptions, MessageJSON } from './message.js';
5
+ export { Group } from './group.js';
6
+ export { SessionID } from './session-id.js';
7
+ export { SessionSettings } from './session-settings.js';
8
+ export { DataDictionary } from './data-dictionary.js';
9
+ export { Initiator } from './initiator.js';
10
+ export { Acceptor } from './acceptor.js';
11
+ export { Engine } from './engine.js';
12
+ export type { EngineOptions, EngineEvents } from './engine.js';
13
+ export { Session, lookupSession, doesSessionExist, getSessions, numSessions } from './session.js';
14
+ export { FixReject, fixReject } from './application.js';
15
+ export type { ApplicationHandlers, FixRejectKind } from './application.js';
16
+ export type { QuickFixError } from './native.js';
17
+ export { enums, FIELD, VALUES, MsgType, Side, OrdType, TimeInForce } from './enums.js';
18
+ export type { Enums, EnumGroup, FieldName, ValueGroups, ValueGroupName } from './enums.js';
19
+ /**
20
+ * Send a message to the target session identified by `sessionID`.
21
+ *
22
+ * Wraps `FIX::Session::sendToTarget`. The session must exist and be logged on
23
+ * for delivery; otherwise the engine queues or drops per its configuration.
24
+ *
25
+ * Runs off the main thread and resolves once the engine has accepted (or
26
+ * rejected) the message, so the event loop stays free for callbacks. On a
27
+ * missing session the returned Promise rejects with a
28
+ * {@link QuickFixError} (`fixErrorName: 'SessionNotFound'`). The send is
29
+ * bound to the engine that owns the session when it is called: if that
30
+ * engine is stopped before the send reaches its session, the Promise rejects
31
+ * with `SessionNotFound` rather than running through an engine created later
32
+ * with the same id.
33
+ *
34
+ * @param message The message to send.
35
+ * @param sessionID The destination session.
36
+ * @returns A Promise resolving to `true` if the message was accepted for sending.
37
+ * @throws {TypeError} synchronously if `sessionID` is neither a {@link SessionID}
38
+ * nor a qualifier string (it is not routed by the header instead).
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * import { sendToTarget, createMessage, SessionID, FIELD, MsgType } from '@homaiohq/napi-quickfix';
43
+ * const order = createMessage({ [FIELD.MsgType]: MsgType.NewOrderSingle });
44
+ * await sendToTarget(order, new SessionID('FIX.4.4', 'CLIENT', 'BROKER'));
45
+ * ```
46
+ */
47
+ export declare function sendToTarget(message: Message, sessionID: SessionID): Promise<boolean>;
48
+ /**
49
+ * Send a message to the session identified by the message's **own header**
50
+ * (`BeginString`, `SenderCompID`, `TargetCompID`) plus an optional session
51
+ * qualifier.
52
+ *
53
+ * Wraps the `FIX::Session::sendToTarget(message, qualifier)` overload. Same
54
+ * threading and error behaviour as the SessionID form; a message whose header
55
+ * does not identify an existing session rejects with
56
+ * `fixErrorName: 'SessionNotFound'`.
57
+ *
58
+ * @param message The message to send; its header must carry tags 8, 49 and 56.
59
+ * @param qualifier Optional session qualifier (`SessionQualifier` in the settings).
60
+ */
61
+ export declare function sendToTarget(message: Message, qualifier?: string): Promise<boolean>;
62
+ /** The QuickFIX engine / addon version string. */
63
+ export declare const version: () => string;
64
+ /**
65
+ * Parse the MsgType (tag 35) out of a raw FIX wire string. Low-level helper;
66
+ * prefer {@link Message.parse} + {@link Message.getMsgType} for general use.
67
+ */
68
+ export declare const quickfixParseMsgType: (raw: string) => string;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.quickfixParseMsgType = exports.version = exports.TimeInForce = exports.OrdType = exports.Side = exports.MsgType = exports.VALUES = exports.FIELD = exports.enums = exports.fixReject = exports.FixReject = exports.numSessions = exports.getSessions = exports.doesSessionExist = exports.lookupSession = exports.Session = exports.Engine = exports.Acceptor = exports.Initiator = exports.DataDictionary = exports.SessionSettings = exports.SessionID = exports.Group = exports.parseMessage = exports.createMessage = exports.Message = void 0;
4
+ exports.sendToTarget = sendToTarget;
5
+ /**
6
+ * `@homaiohq/napi-quickfix` — a modern Node-API binding for the QuickFIX C++
7
+ * FIX-protocol engine.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ const native_js_1 = require("./native.js");
12
+ const session_id_js_1 = require("./session-id.js");
13
+ // --- Pure layer -----------------------------------------------------------
14
+ var message_js_1 = require("./message.js");
15
+ Object.defineProperty(exports, "Message", { enumerable: true, get: function () { return message_js_1.Message; } });
16
+ Object.defineProperty(exports, "createMessage", { enumerable: true, get: function () { return message_js_1.createMessage; } });
17
+ Object.defineProperty(exports, "parseMessage", { enumerable: true, get: function () { return message_js_1.parseMessage; } });
18
+ var group_js_1 = require("./group.js");
19
+ Object.defineProperty(exports, "Group", { enumerable: true, get: function () { return group_js_1.Group; } });
20
+ var session_id_js_2 = require("./session-id.js");
21
+ Object.defineProperty(exports, "SessionID", { enumerable: true, get: function () { return session_id_js_2.SessionID; } });
22
+ var session_settings_js_1 = require("./session-settings.js");
23
+ Object.defineProperty(exports, "SessionSettings", { enumerable: true, get: function () { return session_settings_js_1.SessionSettings; } });
24
+ var data_dictionary_js_1 = require("./data-dictionary.js");
25
+ Object.defineProperty(exports, "DataDictionary", { enumerable: true, get: function () { return data_dictionary_js_1.DataDictionary; } });
26
+ // --- Session engine -------------------------------------------------------
27
+ var initiator_js_1 = require("./initiator.js");
28
+ Object.defineProperty(exports, "Initiator", { enumerable: true, get: function () { return initiator_js_1.Initiator; } });
29
+ var acceptor_js_1 = require("./acceptor.js");
30
+ Object.defineProperty(exports, "Acceptor", { enumerable: true, get: function () { return acceptor_js_1.Acceptor; } });
31
+ var engine_js_1 = require("./engine.js");
32
+ Object.defineProperty(exports, "Engine", { enumerable: true, get: function () { return engine_js_1.Engine; } });
33
+ var session_js_1 = require("./session.js");
34
+ Object.defineProperty(exports, "Session", { enumerable: true, get: function () { return session_js_1.Session; } });
35
+ Object.defineProperty(exports, "lookupSession", { enumerable: true, get: function () { return session_js_1.lookupSession; } });
36
+ Object.defineProperty(exports, "doesSessionExist", { enumerable: true, get: function () { return session_js_1.doesSessionExist; } });
37
+ Object.defineProperty(exports, "getSessions", { enumerable: true, get: function () { return session_js_1.getSessions; } });
38
+ Object.defineProperty(exports, "numSessions", { enumerable: true, get: function () { return session_js_1.numSessions; } });
39
+ var application_js_1 = require("./application.js");
40
+ Object.defineProperty(exports, "FixReject", { enumerable: true, get: function () { return application_js_1.FixReject; } });
41
+ Object.defineProperty(exports, "fixReject", { enumerable: true, get: function () { return application_js_1.fixReject; } });
42
+ // --- Enums / constants ----------------------------------------------------
43
+ // Every other value group (ExecType, OrdStatus, SecurityType, ...) is reachable
44
+ // as `enums.<Field>` / `VALUES.<Field>`, or by name from the
45
+ // `@homaiohq/napi-quickfix/values` subpath, which keeps this namespace small.
46
+ var enums_js_1 = require("./enums.js");
47
+ Object.defineProperty(exports, "enums", { enumerable: true, get: function () { return enums_js_1.enums; } });
48
+ Object.defineProperty(exports, "FIELD", { enumerable: true, get: function () { return enums_js_1.FIELD; } });
49
+ Object.defineProperty(exports, "VALUES", { enumerable: true, get: function () { return enums_js_1.VALUES; } });
50
+ Object.defineProperty(exports, "MsgType", { enumerable: true, get: function () { return enums_js_1.MsgType; } });
51
+ Object.defineProperty(exports, "Side", { enumerable: true, get: function () { return enums_js_1.Side; } });
52
+ Object.defineProperty(exports, "OrdType", { enumerable: true, get: function () { return enums_js_1.OrdType; } });
53
+ Object.defineProperty(exports, "TimeInForce", { enumerable: true, get: function () { return enums_js_1.TimeInForce; } });
54
+ function sendToTarget(message, sessionIDOrQualifier) {
55
+ // Dispatch on the primitive, not `instanceof SessionID`: this package ships
56
+ // ESM and CJS builds, and a SessionID created by the other build is a
57
+ // different class with the same shape (see toNativeSessionID). Anything
58
+ // else is a TypeError here rather than an `undefined` target the native
59
+ // layer would read as "route by the message header".
60
+ const target = typeof sessionIDOrQualifier === 'string' || sessionIDOrQualifier === undefined
61
+ ? sessionIDOrQualifier
62
+ : (0, session_id_js_1.toNativeSessionID)(sessionIDOrQualifier, 'sessionID');
63
+ return native_js_1.native.sendToTarget(message.nativeHandle, target);
64
+ }
65
+ /** The QuickFIX engine / addon version string. */
66
+ const version = () => native_js_1.native.version();
67
+ exports.version = version;
68
+ /**
69
+ * Parse the MsgType (tag 35) out of a raw FIX wire string. Low-level helper;
70
+ * prefer {@link Message.parse} + {@link Message.getMsgType} for general use.
71
+ */
72
+ const quickfixParseMsgType = (raw) => native_js_1.native.quickfixParseMsgType(raw);
73
+ exports.quickfixParseMsgType = quickfixParseMsgType;
@@ -0,0 +1,29 @@
1
+ import { Engine, type EngineOptions } from './engine.js';
2
+ export type { EngineOptions } from './engine.js';
3
+ /**
4
+ * A FIX session initiator (wraps `FIX::SocketInitiator`). Initiators establish
5
+ * outbound connections to acceptors as configured in {@link EngineOptions.settings}.
6
+ *
7
+ * Extends {@link Engine} (an {@link import('node:events').EventEmitter}), so you
8
+ * can observe lifecycle/message events in addition to supplying `handlers`.
9
+ * Remember: only `handlers` may mutate outbound messages or reject inbound ones;
10
+ * events are observe-only.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const initiator = new Initiator({
15
+ * settings: SessionSettings.fromString(cfg),
16
+ * handlers: { onLogon: (id) => console.log('up', id.toString()) },
17
+ * store: 'memory',
18
+ * log: 'none',
19
+ * });
20
+ * initiator.on('fromApp', (msg) => console.log('recv', msg.getMsgType()));
21
+ * await initiator.start();
22
+ * // ... later
23
+ * await initiator.stop();
24
+ * ```
25
+ */
26
+ export declare class Initiator extends Engine {
27
+ /** @param options Engine options. */
28
+ constructor(options: EngineOptions);
29
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Initiator = void 0;
4
+ /**
5
+ * FIX session initiator (client side — connects out to acceptors).
6
+ */
7
+ const native_js_1 = require("./native.js");
8
+ const engine_js_1 = require("./engine.js");
9
+ /**
10
+ * A FIX session initiator (wraps `FIX::SocketInitiator`). Initiators establish
11
+ * outbound connections to acceptors as configured in {@link EngineOptions.settings}.
12
+ *
13
+ * Extends {@link Engine} (an {@link import('node:events').EventEmitter}), so you
14
+ * can observe lifecycle/message events in addition to supplying `handlers`.
15
+ * Remember: only `handlers` may mutate outbound messages or reject inbound ones;
16
+ * events are observe-only.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const initiator = new Initiator({
21
+ * settings: SessionSettings.fromString(cfg),
22
+ * handlers: { onLogon: (id) => console.log('up', id.toString()) },
23
+ * store: 'memory',
24
+ * log: 'none',
25
+ * });
26
+ * initiator.on('fromApp', (msg) => console.log('recv', msg.getMsgType()));
27
+ * await initiator.start();
28
+ * // ... later
29
+ * await initiator.stop();
30
+ * ```
31
+ */
32
+ class Initiator extends engine_js_1.Engine {
33
+ /** @param options Engine options. */
34
+ constructor(options) {
35
+ super(native_js_1.native.InitiatorWrap, options);
36
+ }
37
+ }
38
+ exports.Initiator = Initiator;
@@ -0,0 +1,5 @@
1
+ // Authored (NOT compiled by tsc). Copied verbatim into dist/esm and dist/cjs by
2
+ // build:ts:copy. From either of those directories, two levels up is the package
3
+ // root, where prebuilds/ lives (and build/Release/*.node in local dev).
4
+ const path = require('node:path');
5
+ module.exports = require('node-gyp-build')(path.join(__dirname, '..', '..'));