jspurefix 5.8.0 → 5.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/dist/buffer/ascii/ascii-parser.d.ts +2 -1
- package/dist/buffer/ascii/ascii-parser.js +5 -3
- package/dist/buffer/ascii/ascii-parser.js.map +1 -1
- package/dist/buffer/tag/tags.d.ts +2 -1
- package/dist/buffer/tag/tags.js +8 -4
- package/dist/buffer/tag/tags.js.map +1 -1
- package/dist/transport/ascii/ascii-session.js +33 -11
- package/dist/transport/ascii/ascii-session.js.map +1 -1
- package/jsfix.test_client.txt +75 -75
- package/jsfix.test_server.txt +72 -72
- package/package.json +9 -9
- package/src/buffer/ascii/ascii-parser.ts +3 -2
- package/src/buffer/tag/tags.ts +8 -4
- package/src/transport/ascii/ascii-session.ts +33 -11
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A fast, fully native TypeScript [FIX protocol](https://www.fixtrading.org/) engi
|
|
|
9
9
|
|
|
10
10
|
- [Features](#features)
|
|
11
11
|
- [Installation](#installation)
|
|
12
|
+
- [Examples](#examples)
|
|
12
13
|
- [Quickstart](#quickstart)
|
|
13
14
|
- [Session Configuration](#session-configuration)
|
|
14
15
|
- [TLS](#tls)
|
|
@@ -50,6 +51,14 @@ cd node_modules/jspurefix && npm run unzip-repo
|
|
|
50
51
|
|
|
51
52
|
A standalone demo project lives at [TimelordUK/jspf-demo](https://github.com/TimelordUK/jspf-demo) — the fastest way to see a working initiator/acceptor.
|
|
52
53
|
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
| description | link |
|
|
57
|
+
|---|---|
|
|
58
|
+
| a good start point showing FIX 4 and 5 market data request/snapshot and custom generated types. | [jspf-md-demo](https://github.com/TimelordUK/jspf-md-demo) |
|
|
59
|
+
| simple example with a custom dictionary that targets cserver | [jspf-cserver](https://github.com/TimelordUK/jspf-cserver) |
|
|
60
|
+
| example trade capture applicaton | [jspf-demo](https://github.com/TimelordUK/jspf-demo) |
|
|
61
|
+
|
|
53
62
|
## Quickstart
|
|
54
63
|
|
|
55
64
|
Import the session types you need from `jspurefix` and the typed FIX messages for your dialect:
|
|
@@ -442,8 +451,8 @@ Numbers below are illustrative — generated messages, single-threaded, parser-o
|
|
|
442
451
|
|
|
443
452
|
| Benchmark | Script | Fields/msg | Length (chars) | I7-4770 @ 3.5 GHz | i7-12700H @ 2.3 GHz | Ryzen 9 7950X @ 4.5 GHz |
|
|
444
453
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
445
|
-
| Heartbeat | `npm run qf-bench-hb` | 10 | 131 | 3.8 µs/msg | 1.9 µs/msg | 1.
|
|
446
|
-
| Logon | `npm run qf-bench-lo` | 22 | 214 | 5.9 µs/msg | 2.8 µs/msg | 2.
|
|
454
|
+
| Heartbeat | `npm run qf-bench-hb` | 10 | 131 | 3.8 µs/msg | 1.9 µs/msg | 1.6 µs/msg |
|
|
455
|
+
| Logon | `npm run qf-bench-lo` | 22 | 214 | 5.9 µs/msg | 2.8 µs/msg | 2.3 µs/msg |
|
|
447
456
|
| Execution Report (large) | `npm run repo44-bench-er` | 646 | 6 571 | 206.2 µs/msg | 93.5 µs/msg | 72.9 µs/msg |
|
|
448
457
|
| Security Definition † | `npm run repo44-bench-sd` | 52 | 557 | — | — | 5.6 µs/msg |
|
|
449
458
|
| Trade Capture † | `npm run repo44-bench-tc` | 112 | 1 137 | — | — | 9.3 µs/msg |
|
|
@@ -7,13 +7,14 @@ export declare class AsciiParser extends MsgParser {
|
|
|
7
7
|
readonly config: IJsFixConfig;
|
|
8
8
|
readonly readStream: Readable | null;
|
|
9
9
|
protected readonly receivingBuffer: ElasticBuffer;
|
|
10
|
+
readonly maxMessageLen: number;
|
|
10
11
|
private static nextId;
|
|
11
12
|
readonly id: number;
|
|
12
13
|
readonly state: AsciiParserState;
|
|
13
14
|
private readonly segmentParser;
|
|
14
15
|
readonly delimiter: number;
|
|
15
16
|
readonly writeDelimiter: number;
|
|
16
|
-
constructor(config: IJsFixConfig, readStream: Readable | null, receivingBuffer: ElasticBuffer);
|
|
17
|
+
constructor(config: IJsFixConfig, readStream: Readable | null, receivingBuffer: ElasticBuffer, maxMessageLen?: number);
|
|
17
18
|
private subscribe;
|
|
18
19
|
reset(): void;
|
|
19
20
|
private msg;
|
|
@@ -29,18 +29,19 @@ const di_tokens_1 = require("../../runtime/di-tokens");
|
|
|
29
29
|
const segment_type_1 = require("../segment/segment-type");
|
|
30
30
|
const ascii_segment_parser_error_1 = require("./ascii-segment-parser-error");
|
|
31
31
|
let AsciiParser = AsciiParser_1 = class AsciiParser extends msg_parser_1.MsgParser {
|
|
32
|
-
constructor(config, readStream, receivingBuffer) {
|
|
32
|
+
constructor(config, readStream, receivingBuffer, maxMessageLen = 160 * 1024) {
|
|
33
33
|
var _a, _b;
|
|
34
34
|
super();
|
|
35
35
|
this.config = config;
|
|
36
36
|
this.readStream = readStream;
|
|
37
37
|
this.receivingBuffer = receivingBuffer;
|
|
38
|
+
this.maxMessageLen = maxMessageLen;
|
|
38
39
|
this.delimiter = (_a = config.delimiter) !== null && _a !== void 0 ? _a : ascii_chars_1.AsciiChars.Soh;
|
|
39
40
|
this.writeDelimiter = (_b = config.logDelimiter) !== null && _b !== void 0 ? _b : ascii_chars_1.AsciiChars.Pipe;
|
|
40
41
|
this.id = AsciiParser_1.nextId++;
|
|
41
42
|
this.segmentParser = config.sessionContainer.resolve(ascii_segment_parser_1.AsciiSegmentParser);
|
|
42
43
|
this.state = config.sessionContainer.resolve(ascii_parser_state_1.AsciiParserState);
|
|
43
|
-
this.state.locations = new tags_1.Tags(this.receivingBuffer.size / 10);
|
|
44
|
+
this.state.locations = new tags_1.Tags(this.receivingBuffer.size / 10, this.maxMessageLen);
|
|
44
45
|
this.state.definitions = this.config.definitions;
|
|
45
46
|
this.state.beginMessage();
|
|
46
47
|
if (readStream !== null) {
|
|
@@ -203,6 +204,7 @@ exports.AsciiParser = AsciiParser = AsciiParser_1 = __decorate([
|
|
|
203
204
|
__param(0, (0, tsyringe_1.inject)(di_tokens_1.DITokens.IJsFixConfig)),
|
|
204
205
|
__param(1, (0, tsyringe_1.inject)(di_tokens_1.DITokens.readStream)),
|
|
205
206
|
__param(2, (0, tsyringe_1.inject)(di_tokens_1.DITokens.ParseBuffer)),
|
|
206
|
-
|
|
207
|
+
__param(3, (0, tsyringe_1.inject)(di_tokens_1.DITokens.maxMessageLen)),
|
|
208
|
+
__metadata("design:paramtypes", [Object, Object, elastic_buffer_1.ElasticBuffer, Number])
|
|
207
209
|
], AsciiParser);
|
|
208
210
|
//# sourceMappingURL=ascii-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ascii-parser.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii-chars'\nimport { AsciiView } from './ascii-view'\nimport { AsciiSegmentParser } from './ascii-segment-parser'\nimport { AsciiParserState } from './ascii-parser-state'\nimport { Structure } from '../structure'\nimport { Tags } from '../tag/tags'\nimport { MsgParser } from '../msg-parser'\nimport { MsgView } from '../msg-view'\nimport { Readable } from 'stream'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { ParseState } from './parse-state'\nimport { IJsFixConfig } from '../../config/js-fix-config'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { SegmentType } from '../segment/segment-type'\nimport { AsciiParserError } from './ascii-segment-parser-error'\n\n@injectable()\nexport class AsciiParser extends MsgParser {\n private static nextId: number = 0\n public readonly id: number\n public readonly state: AsciiParserState\n private readonly segmentParser: AsciiSegmentParser\n public readonly delimiter: number\n public readonly writeDelimiter: number\n\n // allocate enough in receive buffer so buffer does not constant resize back after large messages\n // want to keep one slice of memory and constantly reuse it\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject(DITokens.readStream) public readonly readStream: Readable | null,\n @inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer) {\n super()\n\n this.delimiter = config.delimiter ?? AsciiChars.Soh\n this.writeDelimiter = config.logDelimiter ?? AsciiChars.Pipe\n this.id = AsciiParser.nextId++\n this.segmentParser = config.sessionContainer.resolve<AsciiSegmentParser>(AsciiSegmentParser)\n this.state = config.sessionContainer.resolve<AsciiParserState>(AsciiParserState)\n this.state.locations = new Tags(this.receivingBuffer.size / 10)\n this.state.definitions = this.config.definitions\n this.state.beginMessage()\n if (readStream !== null) {\n this.subscribe()\n }\n }\n\n private subscribe (): void {\n const inst: AsciiParser = this\n const Writable = require('stream').Writable\n const stream = this.readStream\n\n const receiver = new Writable({\n write: (data: Buffer, _: any, done: Function) => {\n try {\n inst.parse(data, data.length)\n done()\n } catch (e) {\n done(e)\n }\n }\n })\n receiver.on('error', (e: Error) => {\n this.emit('error', e)\n })\n\n // receive from say a socket or file and pipe to parser which discovers messages\n stream?.pipe(receiver).on('finish', () => {\n this.emit('done')\n })\n stream?.on('error', (e) => {\n this.emit('error', e)\n })\n stream?.on('end', () => {\n this.emit('end')\n })\n }\n\n public reset (): void {\n this.state.beginMessage()\n }\n\n private msg (ptr: number): void {\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const state = this.state\n if (this.listeners('decoded')) {\n this.emit('decoded', state.msgType, receivingBuffer, ptr)\n }\n this.emit('msg', state.msgType, this.getView(ptr))\n state.beginMessage()\n }\n\n /**\n * useful helper for testing where characters are parsed as if from the transport\n * @param text to be parsed\n */\n public parseText (text: string): void {\n const buff = Buffer.from(text)\n this.parse(buff, buff.length)\n }\n\n private parse (readBuffer: Buffer, end: number): void {\n const state = this.state\n const eq: number = AsciiChars.Eq\n const zero: number = AsciiChars.Zero\n const nine: number = AsciiChars.Nine\n const delimiter: number = this.delimiter\n const writeDelimiter: number = this.writeDelimiter\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const switchDelimiter = writeDelimiter !== delimiter\n let readPtr: number = 0\n\n while (readPtr < end) {\n const charAtPos: number = readBuffer[readPtr]\n\n const writePtr = receivingBuffer.saveChar(charAtPos) - 1\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(writePtr)\n continue\n }\n\n case ParseState.BeginField: {\n const atDigit: boolean = charAtPos >= zero && charAtPos <= nine\n if (atDigit) {\n state.beginTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingTag: {\n const isEquals: boolean = charAtPos === eq\n if (isEquals) {\n state.endTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingRawData: {\n // keep skipping until length read, regardless of delimiter or not\n if (state.incRaw()) {\n // having consumed the declared raw data length, expect delimiter.\n // if not found (e.g. replayed messages with pretty-printed XML where\n // the stored length undershoots), keep scanning forward to the actual\n // delimiter rather than throwing.\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n } else if (charAtPos === delimiter) {\n // hit delimiter before declared length exhausted — store what we have\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n case ParseState.ParsingRawDataLength:\n case ParseState.ParsingValue: {\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n default: {\n const st = state.parseState\n throw new Error(`fix parser in unknown state ${st}`)\n }\n }\n readPtr++\n }\n\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(receivingBuffer.getPos())\n break\n }\n }\n }\n\n private getView (ptr: number): MsgView | null {\n const state = this.state\n const locations = state.locations\n const source = this.receivingBuffer\n const delimiter = this.delimiter\n const definitions = this.config.definitions\n const replace = this.writeDelimiter\n const msgType = state.msgType ?? null\n if (!msgType) return null\n if (state.message) {\n try {\n const structure: Structure | null = this.segmentParser.parse(msgType, locations,\n locations.nextTagPos - 1)\n if (!structure) return null\n return new AsciiView(definitions, structure.msg(),\n source,\n structure,\n ptr,\n delimiter,\n replace)\n } catch (error) {\n if (error instanceof AsciiParserError) {\n error.summary.buffer = source.toString()\n this.emit('error', error)\n }\n throw error\n }\n }\n\n const structure = new Structure(locations, [])\n const segment = new SegmentDescription('unknown', locations.tagPos[0].tag, null, 0, 1, SegmentType.Unknown)\n segment.endPosition = locations.nextTagPos - 1\n return new AsciiView(this.config.definitions, segment, source, structure, ptr, delimiter, replace)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ascii-parser.js","sourceRoot":"","sources":["../../../src/buffer/ascii/ascii-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars } from './ascii-chars'\nimport { AsciiView } from './ascii-view'\nimport { AsciiSegmentParser } from './ascii-segment-parser'\nimport { AsciiParserState } from './ascii-parser-state'\nimport { Structure } from '../structure'\nimport { Tags } from '../tag/tags'\nimport { MsgParser } from '../msg-parser'\nimport { MsgView } from '../msg-view'\nimport { Readable } from 'stream'\nimport { ElasticBuffer } from '../elastic-buffer'\nimport { SegmentDescription } from '../segment/segment-description'\nimport { ParseState } from './parse-state'\nimport { IJsFixConfig } from '../../config/js-fix-config'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { SegmentType } from '../segment/segment-type'\nimport { AsciiParserError } from './ascii-segment-parser-error'\n\n@injectable()\nexport class AsciiParser extends MsgParser {\n private static nextId: number = 0\n public readonly id: number\n public readonly state: AsciiParserState\n private readonly segmentParser: AsciiSegmentParser\n public readonly delimiter: number\n public readonly writeDelimiter: number\n\n // allocate enough in receive buffer so buffer does not constant resize back after large messages\n // want to keep one slice of memory and constantly reuse it\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject(DITokens.readStream) public readonly readStream: Readable | null,\n @inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer,\n @inject(DITokens.maxMessageLen) public readonly maxMessageLen: number = 160 * 1024) {\n super()\n\n this.delimiter = config.delimiter ?? AsciiChars.Soh\n this.writeDelimiter = config.logDelimiter ?? AsciiChars.Pipe\n this.id = AsciiParser.nextId++\n this.segmentParser = config.sessionContainer.resolve<AsciiSegmentParser>(AsciiSegmentParser)\n this.state = config.sessionContainer.resolve<AsciiParserState>(AsciiParserState)\n this.state.locations = new Tags(this.receivingBuffer.size / 10, this.maxMessageLen)\n this.state.definitions = this.config.definitions\n this.state.beginMessage()\n if (readStream !== null) {\n this.subscribe()\n }\n }\n\n private subscribe (): void {\n const inst: AsciiParser = this\n const Writable = require('stream').Writable\n const stream = this.readStream\n\n const receiver = new Writable({\n write: (data: Buffer, _: any, done: Function) => {\n try {\n inst.parse(data, data.length)\n done()\n } catch (e) {\n done(e)\n }\n }\n })\n receiver.on('error', (e: Error) => {\n this.emit('error', e)\n })\n\n // receive from say a socket or file and pipe to parser which discovers messages\n stream?.pipe(receiver).on('finish', () => {\n this.emit('done')\n })\n stream?.on('error', (e) => {\n this.emit('error', e)\n })\n stream?.on('end', () => {\n this.emit('end')\n })\n }\n\n public reset (): void {\n this.state.beginMessage()\n }\n\n private msg (ptr: number): void {\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const state = this.state\n if (this.listeners('decoded')) {\n this.emit('decoded', state.msgType, receivingBuffer, ptr)\n }\n this.emit('msg', state.msgType, this.getView(ptr))\n state.beginMessage()\n }\n\n /**\n * useful helper for testing where characters are parsed as if from the transport\n * @param text to be parsed\n */\n public parseText (text: string): void {\n const buff = Buffer.from(text)\n this.parse(buff, buff.length)\n }\n\n private parse (readBuffer: Buffer, end: number): void {\n const state = this.state\n const eq: number = AsciiChars.Eq\n const zero: number = AsciiChars.Zero\n const nine: number = AsciiChars.Nine\n const delimiter: number = this.delimiter\n const writeDelimiter: number = this.writeDelimiter\n const receivingBuffer: ElasticBuffer = this.receivingBuffer\n const switchDelimiter = writeDelimiter !== delimiter\n let readPtr: number = 0\n\n while (readPtr < end) {\n const charAtPos: number = readBuffer[readPtr]\n\n const writePtr = receivingBuffer.saveChar(charAtPos) - 1\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(writePtr)\n continue\n }\n\n case ParseState.BeginField: {\n const atDigit: boolean = charAtPos >= zero && charAtPos <= nine\n if (atDigit) {\n state.beginTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingTag: {\n const isEquals: boolean = charAtPos === eq\n if (isEquals) {\n state.endTag(writePtr)\n }\n break\n }\n\n case ParseState.ParsingRawData: {\n // keep skipping until length read, regardless of delimiter or not\n if (state.incRaw()) {\n // having consumed the declared raw data length, expect delimiter.\n // if not found (e.g. replayed messages with pretty-printed XML where\n // the stored length undershoots), keep scanning forward to the actual\n // delimiter rather than throwing.\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n } else if (charAtPos === delimiter) {\n // hit delimiter before declared length exhausted — store what we have\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n case ParseState.ParsingRawDataLength:\n case ParseState.ParsingValue: {\n if (charAtPos === delimiter) {\n if (switchDelimiter) {\n receivingBuffer.switchChar(writeDelimiter)\n }\n state.store()\n }\n break\n }\n\n default: {\n const st = state.parseState\n throw new Error(`fix parser in unknown state ${st}`)\n }\n }\n readPtr++\n }\n\n switch (state.parseState) {\n case ParseState.MsgComplete: {\n this.msg(receivingBuffer.getPos())\n break\n }\n }\n }\n\n private getView (ptr: number): MsgView | null {\n const state = this.state\n const locations = state.locations\n const source = this.receivingBuffer\n const delimiter = this.delimiter\n const definitions = this.config.definitions\n const replace = this.writeDelimiter\n const msgType = state.msgType ?? null\n if (!msgType) return null\n if (state.message) {\n try {\n const structure: Structure | null = this.segmentParser.parse(msgType, locations,\n locations.nextTagPos - 1)\n if (!structure) return null\n return new AsciiView(definitions, structure.msg(),\n source,\n structure,\n ptr,\n delimiter,\n replace)\n } catch (error) {\n if (error instanceof AsciiParserError) {\n error.summary.buffer = source.toString()\n this.emit('error', error)\n }\n throw error\n }\n }\n\n const structure = new Structure(locations, [])\n const segment = new SegmentDescription('unknown', locations.tagPos[0].tag, null, 0, 1, SegmentType.Unknown)\n segment.endPosition = locations.nextTagPos - 1\n return new AsciiView(this.config.definitions, segment, source, structure, ptr, delimiter, replace)\n }\n}\n"]}
|
|
@@ -2,13 +2,14 @@ import { TagPos } from './tag-pos';
|
|
|
2
2
|
import { TagType } from './tag-type';
|
|
3
3
|
export declare class Tags {
|
|
4
4
|
readonly startingLength: number;
|
|
5
|
+
readonly maxLength: number;
|
|
5
6
|
static readonly BeginString: number;
|
|
6
7
|
static readonly BodyLengthTag: number;
|
|
7
8
|
static readonly CheckSumTag: number;
|
|
8
9
|
static readonly MsgTag: number;
|
|
9
10
|
tagPos: TagPos[];
|
|
10
11
|
nextTagPos: number;
|
|
11
|
-
constructor(startingLength?: number);
|
|
12
|
+
constructor(startingLength?: number, maxLength?: number);
|
|
12
13
|
static toJSType(tagType: TagType): string;
|
|
13
14
|
static toType(type: string): TagType;
|
|
14
15
|
clone(): Tags;
|
package/dist/buffer/tag/tags.js
CHANGED
|
@@ -5,9 +5,10 @@ const tag_pos_1 = require("./tag-pos");
|
|
|
5
5
|
const types_1 = require("../../types");
|
|
6
6
|
const tag_type_1 = require("./tag-type");
|
|
7
7
|
class Tags {
|
|
8
|
-
constructor(startingLength = 30 * 1000) {
|
|
8
|
+
constructor(startingLength = 30 * 1000, maxLength = 1024 * 1024) {
|
|
9
9
|
this.startingLength = startingLength;
|
|
10
|
-
this.
|
|
10
|
+
this.maxLength = maxLength;
|
|
11
|
+
this.tagPos = new Array(Math.min(this.startingLength, this.maxLength));
|
|
11
12
|
this.nextTagPos = 0;
|
|
12
13
|
}
|
|
13
14
|
static toJSType(tagType) {
|
|
@@ -80,7 +81,7 @@ class Tags {
|
|
|
80
81
|
}
|
|
81
82
|
clone() {
|
|
82
83
|
const next = this.nextTagPos;
|
|
83
|
-
const cloned = new Tags(next);
|
|
84
|
+
const cloned = new Tags(next, this.maxLength);
|
|
84
85
|
cloned.nextTagPos = next;
|
|
85
86
|
for (let i = 0; i < next; ++i) {
|
|
86
87
|
cloned.tagPos[i] = this.tagPos[i].clone();
|
|
@@ -105,7 +106,10 @@ class Tags {
|
|
|
105
106
|
this.nextTagPos++;
|
|
106
107
|
}
|
|
107
108
|
expand() {
|
|
108
|
-
|
|
109
|
+
if (this.tagPos.length >= this.maxLength) {
|
|
110
|
+
throw new Error(`tag count exceeds maximum of ${this.maxLength} - message too large or stream misaligned`);
|
|
111
|
+
}
|
|
112
|
+
const size = Math.min(this.tagPos.length * 2, this.maxLength);
|
|
109
113
|
const tagPos = new Array(size);
|
|
110
114
|
for (let i = 0; i < this.tagPos.length; ++i) {
|
|
111
115
|
tagPos[i] = this.tagPos[i];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/buffer/tag/tags.ts"],"names":[],"mappings":";;;AAAA,uCAAkC;AAClC,uCAAoC;AACpC,yCAAoC;AAEpC,MAAa,IAAI;IASf,YAA6B,iBAAyB,EAAE,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../src/buffer/tag/tags.ts"],"names":[],"mappings":"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","sourcesContent":["import { TagPos } from './tag-pos'\nimport { MsgTag } from '../../types'\nimport { TagType } from './tag-type'\n\nexport class Tags {\n public static readonly BeginString: number = MsgTag.BeginString\n public static readonly BodyLengthTag: number = MsgTag.BodyLength\n public static readonly CheckSumTag: number = MsgTag.CheckSum\n public static readonly MsgTag: number = MsgTag.MsgType\n\n public tagPos: TagPos[] = new Array(Math.min(this.startingLength, this.maxLength))\n public nextTagPos: number = 0\n\n constructor (public readonly startingLength: number = 30 * 1000,\n public readonly maxLength: number = 1024 * 1024) {\n }\n\n public static toJSType (tagType: TagType): string {\n switch (tagType) {\n case TagType.String:\n return 'string'\n\n case TagType.Int:\n case TagType.Float:\n case TagType.Length:\n return 'number'\n\n case TagType.RawData:\n return 'Buffer'\n\n case TagType.Boolean:\n return 'boolean'\n\n case TagType.UtcTimestamp:\n case TagType.UtcDateOnly:\n case TagType.UtcTimeOnly:\n case TagType.LocalDate:\n return 'Date'\n\n default:\n return 'string'\n }\n }\n\n public static toType (type: string): TagType {\n type = type || 'string'\n switch (type.toLowerCase()) {\n case 'currency':\n case 'string':\n case 'char': {\n return TagType.String\n }\n\n case 'int':\n case 'numingroup':\n case 'seqnum': {\n return TagType.Int\n }\n\n case 'qty':\n case 'percentage':\n case 'amt':\n case 'price':\n case 'priceoffset':\n case 'float': {\n return TagType.Float\n }\n\n case 'length': {\n return TagType.Length\n }\n\n case 'boolean': {\n return TagType.Boolean\n }\n\n case 'utctimestamp': {\n return TagType.UtcTimestamp\n }\n\n case 'localmktdate': {\n return TagType.LocalDate\n }\n\n case 'utcdateonly': {\n return TagType.UtcDateOnly\n }\n\n case 'utctimeonly': {\n return TagType.UtcTimeOnly\n }\n\n case 'data': {\n return TagType.RawData\n }\n\n default: {\n return TagType.String\n }\n }\n }\n\n public clone (): Tags {\n const next: number = this.nextTagPos\n const cloned: Tags = new Tags(next, this.maxLength)\n cloned.nextTagPos = next\n for (let i = 0; i < next; ++i) {\n cloned.tagPos[i] = this.tagPos[i].clone()\n }\n return cloned\n }\n\n public reset (): void {\n this.nextTagPos = 0\n }\n\n public store (start: number, len: number, tag: number): void {\n const tagPtr: number = this.nextTagPos\n if (tagPtr === this.tagPos.length) {\n this.expand()\n }\n const tp: TagPos = this.tagPos[tagPtr]\n if (tp) {\n tp.assign(tagPtr, tag, start, len)\n } else {\n this.tagPos[tagPtr] = new TagPos(tagPtr, tag, start, len)\n }\n this.nextTagPos++\n }\n\n private expand (): void {\n if (this.tagPos.length >= this.maxLength) {\n throw new Error(`tag count exceeds maximum of ${this.maxLength} - message too large or stream misaligned`)\n }\n const size = Math.min(this.tagPos.length * 2, this.maxLength)\n const tagPos = new Array(size)\n for (let i = 0; i < this.tagPos.length; ++i) {\n tagPos[i] = this.tagPos[i]\n }\n this.tagPos = tagPos\n }\n}\n"]}
|
|
@@ -65,7 +65,9 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
65
65
|
this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence');
|
|
66
66
|
const seqNo = view.getTyped(types_1.MsgTag.MsgSeqNum);
|
|
67
67
|
this.sessionState.lastPeerMsgSeqNum = seqNo;
|
|
68
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
68
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e) => {
|
|
69
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`);
|
|
70
|
+
});
|
|
69
71
|
return true;
|
|
70
72
|
}
|
|
71
73
|
}
|
|
@@ -79,14 +81,18 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
79
81
|
const possDupFlag = view.getTyped(types_1.MsgTag.PossDupFlag);
|
|
80
82
|
if (possDupFlag === true) {
|
|
81
83
|
this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`);
|
|
82
|
-
this.coordinator.onMessageReceived(seqNo, true)
|
|
84
|
+
this.coordinator.onMessageReceived(seqNo, true).catch((e) => {
|
|
85
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`);
|
|
86
|
+
});
|
|
83
87
|
return true;
|
|
84
88
|
}
|
|
85
89
|
const pendingRequests = this.coordinator.pendingResendRequests;
|
|
86
90
|
const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end);
|
|
87
91
|
if (inPendingGapRange) {
|
|
88
92
|
this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`);
|
|
89
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
93
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e) => {
|
|
94
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`);
|
|
95
|
+
});
|
|
90
96
|
return true;
|
|
91
97
|
}
|
|
92
98
|
this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`);
|
|
@@ -120,7 +126,9 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
120
126
|
}
|
|
121
127
|
}
|
|
122
128
|
state.lastPeerMsgSeqNum = seqNo;
|
|
123
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
129
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e) => {
|
|
130
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`);
|
|
131
|
+
});
|
|
124
132
|
if (msgType !== types_1.MsgType.Logon && msgType !== types_1.MsgType.ResendRequest) {
|
|
125
133
|
ret = true;
|
|
126
134
|
}
|
|
@@ -128,7 +136,9 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
128
136
|
else {
|
|
129
137
|
ret = true;
|
|
130
138
|
state.lastPeerMsgSeqNum = seqNo;
|
|
131
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
139
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e) => {
|
|
140
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`);
|
|
141
|
+
});
|
|
132
142
|
}
|
|
133
143
|
if (ret) {
|
|
134
144
|
this.coordinator.resetTimeoutRecovery();
|
|
@@ -259,7 +269,9 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
259
269
|
}
|
|
260
270
|
this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum;
|
|
261
271
|
if (this.store) {
|
|
262
|
-
this.store.clear()
|
|
272
|
+
this.store.clear().catch((e) => {
|
|
273
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`);
|
|
274
|
+
});
|
|
263
275
|
this.resender = new store_1.FixMsgAsciiStoreResend(this.store, this.config);
|
|
264
276
|
}
|
|
265
277
|
this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter === null || transmitter === void 0 ? void 0 : transmitter.msgSeqNum}`);
|
|
@@ -344,7 +356,9 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
344
356
|
const gapFillSeq = view.getTyped(types_1.MsgTag.MsgSeqNum);
|
|
345
357
|
logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`);
|
|
346
358
|
this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1;
|
|
347
|
-
this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo)
|
|
359
|
+
this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e) => {
|
|
360
|
+
this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`);
|
|
361
|
+
});
|
|
348
362
|
break;
|
|
349
363
|
}
|
|
350
364
|
case types_1.MsgType.Reject: {
|
|
@@ -413,13 +427,17 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
413
427
|
logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`);
|
|
414
428
|
const transmitter = (_b = this.transport) === null || _b === void 0 ? void 0 : _b.transmitter;
|
|
415
429
|
const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null;
|
|
416
|
-
this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset)
|
|
430
|
+
this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e) => {
|
|
431
|
+
this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`);
|
|
432
|
+
});
|
|
417
433
|
if (transmitter) {
|
|
418
434
|
transmitter.msgSeqNum = savedEncoderSeqNum !== null && savedEncoderSeqNum !== void 0 ? savedEncoderSeqNum : 1;
|
|
419
435
|
}
|
|
420
436
|
this.sessionState.lastPeerMsgSeqNum = peerSeqNum;
|
|
421
437
|
if (this.store) {
|
|
422
|
-
this.store.clear()
|
|
438
|
+
this.store.clear().catch((e) => {
|
|
439
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`);
|
|
440
|
+
});
|
|
423
441
|
this.resender = new store_1.FixMsgAsciiStoreResend(this.store, this.config);
|
|
424
442
|
}
|
|
425
443
|
logger.info(`reset complete: encoderSeqNum=${transmitter === null || transmitter === void 0 ? void 0 : transmitter.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`);
|
|
@@ -435,14 +453,18 @@ class AsciiSession extends fix_session_1.FixSession {
|
|
|
435
453
|
const weReset = this.config.description.ResetSeqNumFlag;
|
|
436
454
|
if (weReset && resetSeqNumFlag !== true) {
|
|
437
455
|
logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences');
|
|
438
|
-
this.coordinator.resetAsAcceptor()
|
|
456
|
+
this.coordinator.resetAsAcceptor().catch((e) => {
|
|
457
|
+
this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`);
|
|
458
|
+
});
|
|
439
459
|
const transmitter = (_c = this.transport) === null || _c === void 0 ? void 0 : _c.transmitter;
|
|
440
460
|
if (transmitter) {
|
|
441
461
|
transmitter.msgSeqNum = 1;
|
|
442
462
|
}
|
|
443
463
|
this.sessionState.lastPeerMsgSeqNum = 0;
|
|
444
464
|
if (this.store) {
|
|
445
|
-
this.store.clear()
|
|
465
|
+
this.store.clear().catch((e) => {
|
|
466
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`);
|
|
467
|
+
});
|
|
446
468
|
this.resender = new store_1.FixMsgAsciiStoreResend(this.store, this.config);
|
|
447
469
|
}
|
|
448
470
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { MsgTransport } from '../factory'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected readonly coordinator: SessionSequenceCoordinator\n protected readonly sessionStore: IFixSessionStore\n protected readonly sessionId: SessionId\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // Create session store from factory.\n // Priority: programmatic config > JSON store config > default in-memory\n const storeFactory = config.sessionStoreFactory ?? AsciiSession.createStoreFactory(config.description.store)\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n this.sessionStore = storeFactory.create(this.sessionId)\n\n const clock = new DefaultFixClock()\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n /**\n * Initialize the session store (reads persisted sequences from file if using FileSessionStore),\n * sync the coordinator and transmitter from the store, then start the session.\n *\n * The transport's readable stream is paused during async store initialization to prevent\n * the AsciiParser (which starts reading immediately in its constructor) from consuming\n * and emitting messages before subscribe() hooks up the message handler.\n */\n public async run (transport: MsgTransport): Promise<number> {\n // Pause the readable stream to prevent data loss during async init.\n // The AsciiParser starts reading from the socket in its constructor,\n // but FixSession.subscribe() hasn't been called yet. Without pausing,\n // the client's Logon can arrive and be parsed into the void.\n transport.duplex.readable?.pause()\n\n // Initialize store — reads persisted .seqnums file if using FileSessionStore.\n // For MemorySessionStore this is a no-op.\n await this.sessionStore.initialize()\n\n // Coordinator becomes the source of truth for sequences\n this.coordinator.initializeFromStore()\n\n // Sync encoder's outgoing sequence from the store\n const transmitter = transport.transmitter as AsciiMsgTransmitter\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n\n // Sync session state's last received sequence from the store\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true)\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo)\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset)\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n const res = this.onLogon(view, userName as string, password as string)\n // currently not using this.\n logger.info(`peerLogon onLogon returns ${res}`)\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && resetSeqNumFlag !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor()\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon() // if res send response else reject, terminate\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { MsgTransport } from '../factory'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected readonly coordinator: SessionSequenceCoordinator\n protected readonly sessionStore: IFixSessionStore\n protected readonly sessionId: SessionId\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // Create session store from factory.\n // Priority: programmatic config > JSON store config > default in-memory\n const storeFactory = config.sessionStoreFactory ?? AsciiSession.createStoreFactory(config.description.store)\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n this.sessionStore = storeFactory.create(this.sessionId)\n\n const clock = new DefaultFixClock()\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n /**\n * Initialize the session store (reads persisted sequences from file if using FileSessionStore),\n * sync the coordinator and transmitter from the store, then start the session.\n *\n * The transport's readable stream is paused during async store initialization to prevent\n * the AsciiParser (which starts reading immediately in its constructor) from consuming\n * and emitting messages before subscribe() hooks up the message handler.\n */\n public async run (transport: MsgTransport): Promise<number> {\n // Pause the readable stream to prevent data loss during async init.\n // The AsciiParser starts reading from the socket in its constructor,\n // but FixSession.subscribe() hasn't been called yet. Without pausing,\n // the client's Logon can arrive and be parsed into the void.\n transport.duplex.readable?.pause()\n\n // Initialize store — reads persisted .seqnums file if using FileSessionStore.\n // For MemorySessionStore this is a no-op.\n await this.sessionStore.initialize()\n\n // Coordinator becomes the source of truth for sequences\n this.coordinator.initializeFromStore()\n\n // Sync encoder's outgoing sequence from the store\n const transmitter = transport.transmitter as AsciiMsgTransmitter\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n\n // Sync session state's last received sequence from the store\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)\n })\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)\n })\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n const res = this.onLogon(view, userName as string, password as string)\n // currently not using this.\n logger.info(`peerLogon onLogon returns ${res}`)\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && resetSeqNumFlag !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor().catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)\n })\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon() // if res send response else reject, terminate\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
|
package/jsfix.test_client.txt
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
2
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
3
|
-
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
4
|
-
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=
|
|
5
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
6
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
7
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
8
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
9
|
-
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
10
|
-
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=
|
|
11
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
12
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
13
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
14
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
15
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
16
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
17
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
18
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
19
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
20
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
21
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
22
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
23
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
24
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
25
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
26
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
27
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=
|
|
28
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
29
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=
|
|
30
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
31
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
32
|
-
8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
33
|
-
8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
34
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
35
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
36
|
-
8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
37
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
38
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
39
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
40
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
41
|
-
8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
42
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
43
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
44
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
45
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
46
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
47
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
48
|
-
8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
49
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
50
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
51
|
-
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
52
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
53
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
54
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
55
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
56
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=
|
|
57
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
58
|
-
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
59
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
60
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
61
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=
|
|
62
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=
|
|
63
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
64
|
-
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
65
|
-
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
66
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
67
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
68
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
69
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=
|
|
70
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
71
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=
|
|
72
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
73
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
74
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
75
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
1
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:29.697|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=116|
|
|
2
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:29.702|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
|
|
3
|
+
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:29.702|7=1|16=1|10=238|
|
|
4
|
+
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260627-11:27:29.707|122=20260627-11:27:29.707|123=Y|36=2|10=117|
|
|
5
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:31.707|58=5|10=212|
|
|
6
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:27:31.705|58=5|10=211|
|
|
7
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:34.546|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=105|
|
|
8
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:34.548|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
|
|
9
|
+
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:34.549|7=1|16=0|10=242|
|
|
10
|
+
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260627-11:27:34.551|122=20260627-11:27:34.551|123=Y|36=2|10=103|
|
|
11
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:36.551|58=5|10=214|
|
|
12
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:27:36.550|58=5|10=214|
|
|
13
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:39.042|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
|
|
14
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:39.044|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
|
|
15
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:39.044|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
|
|
16
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:39.579|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=116|
|
|
17
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:39.580|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
|
|
18
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:40.583|58=5|10=214|
|
|
19
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:40.582|58=5|10=213|
|
|
20
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:27:41.045|58=5|10=209|
|
|
21
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:43.284|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
|
|
22
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:43.285|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
|
|
23
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:44.288|58=5|10=220|
|
|
24
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:44.287|58=5|10=219|
|
|
25
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:47.058|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
26
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:47.059|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
|
|
27
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260627-11:27:48.061|58=5|10=211|
|
|
28
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:50.563|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
|
|
29
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260627-11:27:50.564|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
|
|
30
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:51.566|58=5|10=217|
|
|
31
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:51.565|58=5|10=216|
|
|
32
|
+
8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:54.044|98=0|141=Y|553=js-client|554=pwd-client|10=168|
|
|
33
|
+
8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:54.045|45=1|372=A|373=1|58=msgType A missing required tag 108|10=002|
|
|
34
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:58.638|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
|
|
35
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:58.640|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
|
|
36
|
+
8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:58.641|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=156|
|
|
37
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:00.643|58=5|10=209|
|
|
38
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:00.642|58=5|10=208|
|
|
39
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:03.398|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
40
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:03.400|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=139|
|
|
41
|
+
8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:03.403|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=064|
|
|
42
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:05.404|58=5|10=209|
|
|
43
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:05.403|58=5|10=208|
|
|
44
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:07.400|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=095|
|
|
45
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:07.400|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=095|
|
|
46
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:11.905|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=100|
|
|
47
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:11.906|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=149|
|
|
48
|
+
8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:11.907|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=029|
|
|
49
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:13.907|58=5|10=216|
|
|
50
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:13.906|58=5|10=215|
|
|
51
|
+
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:16.395|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=058|
|
|
52
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:16.396|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=157|
|
|
53
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:18.402|112=Sat, 27 Jun 2026 11:28:18 GMT|10=157|
|
|
54
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:20.404|112=Sat, 27 Jun 2026 11:28:20 GMT|10=146|
|
|
55
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:22.399|58=5|10=220|
|
|
56
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260627-11:28:22.398|58=5|10=221|
|
|
57
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:24.881|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
58
|
+
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:24.882|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=106|
|
|
59
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:26.887|112=Sat, 27 Jun 2026 11:28:26 GMT|10=172|
|
|
60
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:28.892|112=Sat, 27 Jun 2026 11:28:28 GMT|10=173|
|
|
61
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260627-11:28:30.895|112=Sat, 27 Jun 2026 11:28:30 GMT|10=163|
|
|
62
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260627-11:28:32.884|58=5|10=223|
|
|
63
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:32.883|58=5|10=219|
|
|
64
|
+
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:35.599|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=065|
|
|
65
|
+
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:35.600|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=099|
|
|
66
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:37.604|112=Sat, 27 Jun 2026 11:28:37 GMT|10=163|
|
|
67
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:39.608|112=Sat, 27 Jun 2026 11:28:39 GMT|10=172|
|
|
68
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:40.609|112=Sat, 27 Jun 2026 11:28:40 GMT|10=156|
|
|
69
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260627-11:28:41.611|112=Sat, 27 Jun 2026 11:28:41 GMT|10=153|
|
|
70
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:43.602|58=5|10=211|
|
|
71
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260627-11:28:43.602|58=5|10=213|
|
|
72
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:30:11.370|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=089|
|
|
73
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:30:11.380|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=138|
|
|
74
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:30:12.385|58=5|10=207|
|
|
75
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:30:12.383|58=5|10=205|
|
package/jsfix.test_server.txt
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
2
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
3
|
-
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
4
|
-
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=
|
|
5
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
6
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
7
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
8
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
9
|
-
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
10
|
-
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=
|
|
11
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
12
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
13
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
14
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
15
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
16
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
17
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
18
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
19
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
20
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
21
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
22
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
23
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
24
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
25
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
26
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=
|
|
27
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
28
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=
|
|
29
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
30
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
31
|
-
8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
32
|
-
8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
33
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
34
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
1
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:29.697|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=116|
|
|
2
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:29.702|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
|
|
3
|
+
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:29.702|7=1|16=1|10=238|
|
|
4
|
+
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260627-11:27:29.707|122=20260627-11:27:29.707|123=Y|36=2|10=117|
|
|
5
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:27:31.705|58=5|10=211|
|
|
6
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:31.707|58=5|10=212|
|
|
7
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:34.546|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=105|
|
|
8
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:34.548|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
|
|
9
|
+
8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:34.549|7=1|16=0|10=242|
|
|
10
|
+
8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260627-11:27:34.551|122=20260627-11:27:34.551|123=Y|36=2|10=103|
|
|
11
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:27:36.550|58=5|10=214|
|
|
12
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:36.551|58=5|10=214|
|
|
13
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:39.042|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
|
|
14
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:39.044|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
|
|
15
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:39.044|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
|
|
16
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:39.579|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=116|
|
|
17
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:39.580|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
|
|
18
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:40.582|58=5|10=213|
|
|
19
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:40.583|58=5|10=214|
|
|
20
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:43.284|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
|
|
21
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:43.285|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
|
|
22
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:44.287|58=5|10=219|
|
|
23
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:44.288|58=5|10=220|
|
|
24
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:47.058|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
25
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:47.059|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
|
|
26
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260627-11:27:48.061|58=5|10=211|
|
|
27
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:50.563|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
|
|
28
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260627-11:27:50.564|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=155|
|
|
29
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:27:51.565|58=5|10=216|
|
|
30
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:51.566|58=5|10=217|
|
|
31
|
+
8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:54.044|98=0|141=Y|553=js-client|554=pwd-client|10=168|
|
|
32
|
+
8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:54.045|45=1|372=A|373=1|58=msgType A missing required tag 108|10=002|
|
|
33
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:27:58.638|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
|
|
34
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:27:58.640|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
|
|
35
35
|
8=FIX4.4|9=0000136|35=ZZ|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:28.980|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=177|
|
|
36
|
-
8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
37
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
38
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
39
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
40
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
36
|
+
8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:27:58.641|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=156|
|
|
37
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:00.642|58=5|10=208|
|
|
38
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:00.643|58=5|10=209|
|
|
39
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:03.398|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
40
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:03.400|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=139|
|
|
41
41
|
8=FIX4.4|9=0000123|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|999=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
|
|
42
|
-
8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
43
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
44
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
45
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
46
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
42
|
+
8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:03.403|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=064|
|
|
43
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:05.403|58=5|10=208|
|
|
44
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:05.404|58=5|10=209|
|
|
45
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:11.905|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=100|
|
|
46
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:11.906|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=149|
|
|
47
47
|
8=FIX4.4|9=0000123|35=0|49=init-not!|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|112=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
|
|
48
|
-
8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
49
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
50
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
51
|
-
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
52
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
53
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
54
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
55
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=
|
|
56
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
57
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
58
|
-
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
59
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
60
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
61
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=
|
|
62
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
63
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=
|
|
64
|
-
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
65
|
-
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
66
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
67
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=
|
|
68
|
-
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
69
|
-
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=
|
|
70
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=
|
|
71
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=
|
|
72
|
-
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=
|
|
73
|
-
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=
|
|
74
|
-
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=
|
|
75
|
-
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=
|
|
48
|
+
8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:11.907|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=029|
|
|
49
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:13.906|58=5|10=215|
|
|
50
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:13.907|58=5|10=216|
|
|
51
|
+
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:16.395|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=058|
|
|
52
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:16.396|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=157|
|
|
53
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:18.402|112=Sat, 27 Jun 2026 11:28:18 GMT|10=157|
|
|
54
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:20.404|112=Sat, 27 Jun 2026 11:28:20 GMT|10=146|
|
|
55
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260627-11:28:22.398|58=5|10=221|
|
|
56
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:22.399|58=5|10=220|
|
|
57
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:24.881|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
|
|
58
|
+
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:24.882|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=106|
|
|
59
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:26.887|112=Sat, 27 Jun 2026 11:28:26 GMT|10=172|
|
|
60
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:28.892|112=Sat, 27 Jun 2026 11:28:28 GMT|10=173|
|
|
61
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260627-11:28:30.895|112=Sat, 27 Jun 2026 11:28:30 GMT|10=163|
|
|
62
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:32.883|58=5|10=219|
|
|
63
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260627-11:28:32.884|58=5|10=223|
|
|
64
|
+
8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:28:35.599|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=065|
|
|
65
|
+
8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:28:35.600|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=099|
|
|
66
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:28:37.604|112=Sat, 27 Jun 2026 11:28:37 GMT|10=163|
|
|
67
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260627-11:28:39.608|112=Sat, 27 Jun 2026 11:28:39 GMT|10=172|
|
|
68
|
+
8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:28:40.609|112=Sat, 27 Jun 2026 11:28:40 GMT|10=156|
|
|
69
|
+
8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260627-11:28:41.611|112=Sat, 27 Jun 2026 11:28:41 GMT|10=153|
|
|
70
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260627-11:28:43.602|58=5|10=213|
|
|
71
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260627-11:28:43.602|58=5|10=211|
|
|
72
|
+
8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260627-11:30:11.370|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=089|
|
|
73
|
+
8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260627-11:30:11.380|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=138|
|
|
74
|
+
8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260627-11:30:12.383|58=5|10=205|
|
|
75
|
+
8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260627-11:30:12.385|58=5|10=207|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jspurefix",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.4",
|
|
4
4
|
"description": "pure node js fix engine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"repo44-bench-tc": "node dist/jsfix-cmd jsfix-cmd --dict=repo44 --fix=data/examples/FIX.4.4/repo/trade-capture/fix.txt --benchmark --delimiter=\"|\" --repeats=30000",
|
|
45
45
|
"repo44-bench-sd": "node dist/jsfix-cmd --dict=repo44 --fix=data/examples/FIX.4.4/repo/security-definition/fix.txt --benchmark --delimiter=\"|\" --repeats=150000",
|
|
46
46
|
"repo44-bench-lo": "node dist/jsfix-cmd --dict=repo44 --fix=data/examples/FIX.4.4/repo/logon/fix.txt --benchmark --delimiter=\"|\" --repeats=250000",
|
|
47
|
-
"qf-bench-lo": "node dist/jsfix-cmd --session=data/session/test-initiator.json --fix=data/examples/FIX.4.4/quickfix/logon/fix.txt --benchmark --delimiter=\"|\" --repeats=
|
|
48
|
-
"qf-bench-hb": "node dist/jsfix-cmd --session=data/session/test-initiator.json --fix=data/examples/FIX.4.4/quickfix/heartbeat/fix.txt --benchmark --delimiter=\"|\" --repeats=
|
|
47
|
+
"qf-bench-lo": "node dist/jsfix-cmd --session=data/session/test-initiator.json --fix=data/examples/FIX.4.4/quickfix/logon/fix.txt --benchmark --delimiter=\"|\" --repeats=1000000",
|
|
48
|
+
"qf-bench-hb": "node dist/jsfix-cmd --session=data/session/test-initiator.json --fix=data/examples/FIX.4.4/quickfix/heartbeat/fix.txt --benchmark --delimiter=\"|\" --repeats=1000000",
|
|
49
49
|
"fixml": "node dist/jsfix-cmd --dict=repofixml",
|
|
50
50
|
"tcp-qf-md": "node dist/sample/tcp/qf-md/app",
|
|
51
51
|
"tcp-tls-tc": "node dist/sample/tcp/tls-trade-capture/app",
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
"author": "",
|
|
75
75
|
"license": "MIT",
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@jest/globals": "^30.
|
|
77
|
+
"@jest/globals": "^30.4.1",
|
|
78
78
|
"align-text": "^1.0.2",
|
|
79
|
-
"axios": "^1.
|
|
79
|
+
"axios": "^1.16.1",
|
|
80
80
|
"express": "^5.2.1",
|
|
81
81
|
"lodash": "^4.18.1",
|
|
82
82
|
"mathjs": "^15.2.0",
|
|
@@ -99,16 +99,16 @@
|
|
|
99
99
|
"@types/lodash": "^4.17.24",
|
|
100
100
|
"@types/mathjs": "^9.4.2",
|
|
101
101
|
"@types/minimist": "^1.2.5",
|
|
102
|
-
"@types/node": "^25.
|
|
102
|
+
"@types/node": "^25.9.1",
|
|
103
103
|
"@types/request-promise-native": "^1.0.21",
|
|
104
104
|
"@types/sax": "^1.2.7",
|
|
105
105
|
"@types/winston": "^2.4.4",
|
|
106
106
|
"eslint": "^9.39.4",
|
|
107
107
|
"eslint-config-love": "^151.0.0",
|
|
108
|
-
"jest": "^30.
|
|
108
|
+
"jest": "^30.4.2",
|
|
109
109
|
"madge": "^8.0.0",
|
|
110
110
|
"standard": "^17.1.2",
|
|
111
|
-
"ts-jest": "^29.4.
|
|
112
|
-
"typescript": "^6.0.
|
|
111
|
+
"ts-jest": "^29.4.11",
|
|
112
|
+
"typescript": "^6.0.3"
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -30,7 +30,8 @@ export class AsciiParser extends MsgParser {
|
|
|
30
30
|
|
|
31
31
|
constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,
|
|
32
32
|
@inject(DITokens.readStream) public readonly readStream: Readable | null,
|
|
33
|
-
@inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer
|
|
33
|
+
@inject(DITokens.ParseBuffer) protected readonly receivingBuffer: ElasticBuffer,
|
|
34
|
+
@inject(DITokens.maxMessageLen) public readonly maxMessageLen: number = 160 * 1024) {
|
|
34
35
|
super()
|
|
35
36
|
|
|
36
37
|
this.delimiter = config.delimiter ?? AsciiChars.Soh
|
|
@@ -38,7 +39,7 @@ export class AsciiParser extends MsgParser {
|
|
|
38
39
|
this.id = AsciiParser.nextId++
|
|
39
40
|
this.segmentParser = config.sessionContainer.resolve<AsciiSegmentParser>(AsciiSegmentParser)
|
|
40
41
|
this.state = config.sessionContainer.resolve<AsciiParserState>(AsciiParserState)
|
|
41
|
-
this.state.locations = new Tags(this.receivingBuffer.size / 10)
|
|
42
|
+
this.state.locations = new Tags(this.receivingBuffer.size / 10, this.maxMessageLen)
|
|
42
43
|
this.state.definitions = this.config.definitions
|
|
43
44
|
this.state.beginMessage()
|
|
44
45
|
if (readStream !== null) {
|
package/src/buffer/tag/tags.ts
CHANGED
|
@@ -8,10 +8,11 @@ export class Tags {
|
|
|
8
8
|
public static readonly CheckSumTag: number = MsgTag.CheckSum
|
|
9
9
|
public static readonly MsgTag: number = MsgTag.MsgType
|
|
10
10
|
|
|
11
|
-
public tagPos: TagPos[] = new Array(this.startingLength)
|
|
11
|
+
public tagPos: TagPos[] = new Array(Math.min(this.startingLength, this.maxLength))
|
|
12
12
|
public nextTagPos: number = 0
|
|
13
13
|
|
|
14
|
-
constructor (public readonly startingLength: number = 30 * 1000
|
|
14
|
+
constructor (public readonly startingLength: number = 30 * 1000,
|
|
15
|
+
public readonly maxLength: number = 1024 * 1024) {
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
public static toJSType (tagType: TagType): string {
|
|
@@ -101,7 +102,7 @@ export class Tags {
|
|
|
101
102
|
|
|
102
103
|
public clone (): Tags {
|
|
103
104
|
const next: number = this.nextTagPos
|
|
104
|
-
const cloned: Tags = new Tags(next)
|
|
105
|
+
const cloned: Tags = new Tags(next, this.maxLength)
|
|
105
106
|
cloned.nextTagPos = next
|
|
106
107
|
for (let i = 0; i < next; ++i) {
|
|
107
108
|
cloned.tagPos[i] = this.tagPos[i].clone()
|
|
@@ -128,7 +129,10 @@ export class Tags {
|
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
private expand (): void {
|
|
131
|
-
|
|
132
|
+
if (this.tagPos.length >= this.maxLength) {
|
|
133
|
+
throw new Error(`tag count exceeds maximum of ${this.maxLength} - message too large or stream misaligned`)
|
|
134
|
+
}
|
|
135
|
+
const size = Math.min(this.tagPos.length * 2, this.maxLength)
|
|
132
136
|
const tagPos = new Array(size)
|
|
133
137
|
for (let i = 0; i < this.tagPos.length; ++i) {
|
|
134
138
|
tagPos[i] = this.tagPos[i]
|
|
@@ -101,7 +101,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
101
101
|
this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')
|
|
102
102
|
const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number
|
|
103
103
|
this.sessionState.lastPeerMsgSeqNum = seqNo
|
|
104
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
104
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {
|
|
105
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)
|
|
106
|
+
})
|
|
105
107
|
return true
|
|
106
108
|
}
|
|
107
109
|
}
|
|
@@ -119,7 +121,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
119
121
|
const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined
|
|
120
122
|
if (possDupFlag === true) {
|
|
121
123
|
this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)
|
|
122
|
-
this.coordinator.onMessageReceived(seqNo, true)
|
|
124
|
+
this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {
|
|
125
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)
|
|
126
|
+
})
|
|
123
127
|
return true
|
|
124
128
|
}
|
|
125
129
|
// Check if this is a delayed message that fills a pending gap range.
|
|
@@ -127,7 +131,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
127
131
|
const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)
|
|
128
132
|
if (inPendingGapRange) {
|
|
129
133
|
this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)
|
|
130
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
134
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {
|
|
135
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)
|
|
136
|
+
})
|
|
131
137
|
return true
|
|
132
138
|
}
|
|
133
139
|
// serious problem ... drop immediately
|
|
@@ -171,7 +177,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
171
177
|
|
|
172
178
|
// Update sequence state regardless — the gap-triggering message is valid.
|
|
173
179
|
state.lastPeerMsgSeqNum = seqNo
|
|
174
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
180
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {
|
|
181
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)
|
|
182
|
+
})
|
|
175
183
|
|
|
176
184
|
// Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).
|
|
177
185
|
// Don't return true for them — they must not be dispatched to onSessionMsg again.
|
|
@@ -182,7 +190,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
182
190
|
} else {
|
|
183
191
|
ret = true
|
|
184
192
|
state.lastPeerMsgSeqNum = seqNo
|
|
185
|
-
this.coordinator.onMessageReceived(seqNo, false)
|
|
193
|
+
this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {
|
|
194
|
+
this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)
|
|
195
|
+
})
|
|
186
196
|
}
|
|
187
197
|
|
|
188
198
|
// Reset timeout recovery on successful message receipt
|
|
@@ -333,7 +343,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
333
343
|
this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum
|
|
334
344
|
|
|
335
345
|
if (this.store) {
|
|
336
|
-
this.store.clear()
|
|
346
|
+
this.store.clear().catch((e: Error) => {
|
|
347
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`)
|
|
348
|
+
})
|
|
337
349
|
this.resender = new FixMsgAsciiStoreResend(this.store, this.config)
|
|
338
350
|
}
|
|
339
351
|
|
|
@@ -439,7 +451,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
439
451
|
// expect newSeqNo to be the next message's sequence number.
|
|
440
452
|
this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1
|
|
441
453
|
// Notify coordinator to update expected target and clear pending resend requests
|
|
442
|
-
this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo)
|
|
454
|
+
this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {
|
|
455
|
+
this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)
|
|
456
|
+
})
|
|
443
457
|
break
|
|
444
458
|
}
|
|
445
459
|
|
|
@@ -524,7 +538,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
524
538
|
|
|
525
539
|
// Fire-and-forget the async coordinator call (store updates resolve on next microtask)
|
|
526
540
|
// but compute the expected values synchronously since we know the reset outcome
|
|
527
|
-
this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset)
|
|
541
|
+
this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {
|
|
542
|
+
this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)
|
|
543
|
+
})
|
|
528
544
|
if (transmitter) {
|
|
529
545
|
transmitter.msgSeqNum = savedEncoderSeqNum ?? 1
|
|
530
546
|
}
|
|
@@ -532,7 +548,9 @@ export abstract class AsciiSession extends FixSession {
|
|
|
532
548
|
|
|
533
549
|
// Recreate resender with empty store
|
|
534
550
|
if (this.store) {
|
|
535
|
-
this.store.clear()
|
|
551
|
+
this.store.clear().catch((e: Error) => {
|
|
552
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`)
|
|
553
|
+
})
|
|
536
554
|
this.resender = new FixMsgAsciiStoreResend(this.store, this.config)
|
|
537
555
|
}
|
|
538
556
|
logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)
|
|
@@ -555,14 +573,18 @@ export abstract class AsciiSession extends FixSession {
|
|
|
555
573
|
if (weReset && resetSeqNumFlag !== true) {
|
|
556
574
|
logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')
|
|
557
575
|
// Fire-and-forget async coordinator call, set values synchronously
|
|
558
|
-
this.coordinator.resetAsAcceptor()
|
|
576
|
+
this.coordinator.resetAsAcceptor().catch((e: Error) => {
|
|
577
|
+
this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)
|
|
578
|
+
})
|
|
559
579
|
const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined
|
|
560
580
|
if (transmitter) {
|
|
561
581
|
transmitter.msgSeqNum = 1
|
|
562
582
|
}
|
|
563
583
|
this.sessionState.lastPeerMsgSeqNum = 0
|
|
564
584
|
if (this.store) {
|
|
565
|
-
this.store.clear()
|
|
585
|
+
this.store.clear().catch((e: Error) => {
|
|
586
|
+
this.sessionLogger.warning(`store.clear failed: ${e.message}`)
|
|
587
|
+
})
|
|
566
588
|
this.resender = new FixMsgAsciiStoreResend(this.store, this.config)
|
|
567
589
|
}
|
|
568
590
|
}
|