jspurefix 3.4.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,8 @@ export declare class FixMsgAsciiStoreResend {
9
9
  constructor(store: IFixMsgStore, config: IJsFixConfig);
10
10
  getResendRequest(startSeq: number, endSeq: number): Promise<IFixMsgStoreRecord[]>;
11
11
  private inflateRange;
12
- gap(beginGap: number, seqNum: number, arr: IFixMsgStoreRecord[]): void;
13
- inflate(record: IFixMsgStoreRecord): void;
14
- sequenceResetGap(startGap: number, newSeq: number): IFixMsgStoreRecord;
12
+ private gap;
13
+ private inflate;
14
+ private sequenceResetGap;
15
+ private prepareRecordForRetransmission;
15
16
  }
@@ -33,9 +33,13 @@ class FixMsgAsciiStoreResend {
33
33
  }
34
34
  inflateRange(startSeq, endSeq, input) {
35
35
  const toResend = [];
36
+ if (input.length === 0) {
37
+ this.gap(startSeq, endSeq + 1, toResend);
38
+ return toResend;
39
+ }
36
40
  let expected = startSeq;
37
41
  for (let i = 0; i < input.length; ++i) {
38
- const record = input[i].clone();
42
+ const record = this.prepareRecordForRetransmission(input[i]);
39
43
  const seqNum = record.seqNum;
40
44
  const toGap = seqNum - expected;
41
45
  if (toGap > 0) {
@@ -52,9 +56,9 @@ class FixMsgAsciiStoreResend {
52
56
  }
53
57
  return toResend;
54
58
  }
55
- gap(beginGap, seqNum, arr) {
59
+ gap(beginGap, newSeq, arr) {
56
60
  if (beginGap > 0) {
57
- arr.push(this.sequenceResetGap(beginGap, seqNum));
61
+ arr.push(this.sequenceResetGap(beginGap, newSeq));
58
62
  }
59
63
  }
60
64
  inflate(record) {
@@ -76,8 +80,20 @@ class FixMsgAsciiStoreResend {
76
80
  const gapFill = factory === null || factory === void 0 ? void 0 : factory.sequenceReset(newSeq, true);
77
81
  gapFill.StandardHeader = factory === null || factory === void 0 ? void 0 : factory.header(types_1.MsgType.SequenceReset, startGap);
78
82
  gapFill.StandardHeader.PossDupFlag = true;
79
- gapFill.NewSeqNo = newSeq;
80
- return new fix_msg_store_record_1.FixMsgStoreRecord(types_1.MsgType.SequenceReset, new Date(), newSeq, gapFill, null);
83
+ return new fix_msg_store_record_1.FixMsgStoreRecord(types_1.MsgType.SequenceReset, new Date(), startGap, gapFill, null);
84
+ }
85
+ prepareRecordForRetransmission(originalRecord) {
86
+ const retransmitted = originalRecord.clone();
87
+ const factory = this.config.factory;
88
+ if (!retransmitted.obj) {
89
+ retransmitted.obj = {};
90
+ }
91
+ const header = factory === null || factory === void 0 ? void 0 : factory.header(retransmitted.msgType, retransmitted.seqNum, new Date(), {
92
+ PossDupFlag: true,
93
+ OrigSendingTime: retransmitted.timestamp
94
+ });
95
+ retransmitted.obj = Object.assign(Object.assign({}, retransmitted.obj), { StandardHeader: header });
96
+ return retransmitted;
81
97
  }
82
98
  }
83
99
  exports.FixMsgAsciiStoreResend = FixMsgAsciiStoreResend;
@@ -1 +1 @@
1
- {"version":3,"file":"fix-msg-ascii-store-resend.js","sourceRoot":"","sources":["../../src/store/fix-msg-ascii-store-resend.ts"],"names":[],"mappings":"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","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\r\nimport { FixMsgStoreRecord, IFixMsgStoreRecord } from './fix-msg-store-record'\r\nimport { IJsFixConfig } from '../config'\r\nimport { MsgType } from '../types'\r\nimport { ElasticBuffer, MsgView } from '../buffer'\r\nimport { AsciiParser } from '../buffer/ascii'\r\nimport { ISequenceReset, IStandardHeader } from '../types/FIX4.4/repo'\r\n\r\nexport class FixMsgAsciiStoreResend {\r\n parser: AsciiParser\r\n constructor (public readonly store: IFixMsgStore, public readonly config: IJsFixConfig) {\r\n this.parser = new AsciiParser(this.config, null, new ElasticBuffer(160 * 1024))\r\n }\r\n\r\n public async getResendRequest (startSeq: number, endSeq: number): Promise<IFixMsgStoreRecord[]> {\r\n // need to cover request from start to end where any missing numbers are\r\n // included as gaps to allow vector of messages to be sent by the session\r\n // on a request\r\n\r\n return await new Promise((resolve, reject) => {\r\n this.store.getSeqNumRange(startSeq, endSeq).then(res => {\r\n resolve(this.inflateRange(startSeq, endSeq, res))\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n })\r\n }\r\n\r\n private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {\r\n const toResend: IFixMsgStoreRecord[] = []\r\n let expected = startSeq\r\n for (let i = 0; i < input.length; ++i) {\r\n const record = input[i].clone()\r\n const seqNum = record.seqNum\r\n const toGap = seqNum - expected\r\n if (toGap > 0) {\r\n this.gap(expected, seqNum, toResend)\r\n }\r\n expected = seqNum + 1\r\n if (record.encoded) {\r\n this.inflate(record)\r\n }\r\n toResend.push(record)\r\n }\r\n if (endSeq - expected > 0) {\r\n this.gap(expected, endSeq + 1, toResend)\r\n }\r\n return toResend\r\n }\r\n\r\n public gap (beginGap: number, seqNum: number, arr: IFixMsgStoreRecord[]): void {\r\n if (beginGap > 0) {\r\n arr.push(this.sequenceResetGap(beginGap, seqNum))\r\n }\r\n }\r\n\r\n // if records were sent as encoded text then inflate back to object\r\n // so can be resent or examined\r\n\r\n public inflate (record: IFixMsgStoreRecord): void {\r\n if (record.obj) return\r\n if (!record.encoded) return\r\n const parser = this.parser\r\n parser.on('error', (_: Error) => {\r\n record.obj = null\r\n })\r\n parser.on('msg', (view: MsgView) => {\r\n record.obj = view.toObject()\r\n })\r\n // inline parse\r\n parser.parseText(record.encoded)\r\n }\r\n\r\n public sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {\r\n const factory = this.config.factory\r\n const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset\r\n gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap) as IStandardHeader\r\n gapFill.StandardHeader.PossDupFlag = true\r\n gapFill.NewSeqNo = newSeq\r\n return new FixMsgStoreRecord(\r\n MsgType.SequenceReset,\r\n new Date(),\r\n newSeq,\r\n gapFill,\r\n null)\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"fix-msg-ascii-store-resend.js","sourceRoot":"","sources":["../../src/store/fix-msg-ascii-store-resend.ts"],"names":[],"mappings":"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","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\r\nimport { FixMsgStoreRecord, IFixMsgStoreRecord } from './fix-msg-store-record'\r\nimport { IJsFixConfig } from '../config'\r\nimport { MsgType } from '../types'\r\nimport { ElasticBuffer, MsgView } from '../buffer'\r\nimport { AsciiParser } from '../buffer/ascii'\r\nimport { ISequenceReset, IStandardHeader } from '../types/FIX4.4/repo'\r\n\r\nexport class FixMsgAsciiStoreResend {\r\n parser: AsciiParser\r\n constructor (public readonly store: IFixMsgStore, public readonly config: IJsFixConfig) {\r\n this.parser = new AsciiParser(this.config, null, new ElasticBuffer(160 * 1024))\r\n }\r\n\r\n public async getResendRequest (startSeq: number, endSeq: number): Promise<IFixMsgStoreRecord[]> {\r\n // need to cover request from start to end where any missing numbers are\r\n // included as gaps to allow vector of messages to be sent by the session\r\n // on a request\r\n\r\n return await new Promise((resolve, reject) => {\r\n this.store.getSeqNumRange(startSeq, endSeq).then(res => {\r\n resolve(this.inflateRange(startSeq, endSeq, res))\r\n }).catch(e => {\r\n reject(e)\r\n })\r\n })\r\n }\r\n\r\n private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {\r\n const toResend: IFixMsgStoreRecord[] = []\r\n // If no records for this given sequence number range, returns a single gap fill\r\n if (input.length === 0) {\r\n this.gap(startSeq, endSeq + 1, toResend)\r\n return toResend\r\n }\r\n\r\n let expected = startSeq\r\n for (let i = 0; i < input.length; ++i) {\r\n const record = this.prepareRecordForRetransmission(input[i])\r\n const seqNum = record.seqNum\r\n const toGap = seqNum - expected\r\n if (toGap > 0) {\r\n this.gap(expected, seqNum, toResend)\r\n }\r\n expected = seqNum + 1\r\n if (record.encoded) {\r\n this.inflate(record)\r\n }\r\n toResend.push(record)\r\n }\r\n if (endSeq - expected > 0) {\r\n this.gap(expected, endSeq + 1, toResend)\r\n }\r\n return toResend\r\n }\r\n\r\n private gap (beginGap: number, newSeq: number, arr: IFixMsgStoreRecord[]): void {\r\n if (beginGap > 0) {\r\n arr.push(this.sequenceResetGap(beginGap, newSeq))\r\n }\r\n }\r\n\r\n // if records were sent as encoded text then inflate back to object\r\n // so can be resent or examined\r\n\r\n private inflate (record: IFixMsgStoreRecord): void {\r\n if (record.obj) return\r\n if (!record.encoded) return\r\n const parser = this.parser\r\n parser.on('error', (_: Error) => {\r\n record.obj = null\r\n })\r\n parser.on('msg', (view: MsgView) => {\r\n record.obj = view.toObject()\r\n })\r\n // inline parse\r\n parser.parseText(record.encoded)\r\n }\r\n\r\n /**\r\n * A continuous sequence of messages not being retransmitted should be skipped over using a\r\n * single SequenceReset(35=4) message with GapFillFlag(123) set to “Y” and MsgSeqNum(34) set\r\n * to the sequence number of the first skipped message and NewSeqNo(36) must always be set\r\n * to the value of the next sequence number to be expected by the peer immediately following\r\n * the messages being skipped.\r\n */\r\n private sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {\r\n const factory = this.config.factory\r\n const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset\r\n gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap) as IStandardHeader\r\n gapFill.StandardHeader.PossDupFlag = true\r\n\r\n return new FixMsgStoreRecord(\r\n MsgType.SequenceReset,\r\n new Date(),\r\n startGap,\r\n gapFill,\r\n null,\r\n )\r\n }\r\n\r\n /**\r\n * Prepares the FIX message as response to ResendRequest (2).\r\n *\r\n * The FIX session processor retransmitting a message with the PossDupFlag(43) set to \"Y\" must modify the following fields:\r\n *\r\n * SendingTime(52) set to the current sending time\r\n * OrigSendingTime(122) set to the SendingTime(52) from the original message\r\n * Recalculate the BodyLength(9)\r\n * Recalculate the CheckSum(10)\r\n *\r\n * If the message is encrypted, SecureDataLen(90) and SecureData(91) may also require re-encryption and re-encoding\r\n *\r\n * @see https://www.fixtrading.org/standards/fix-session-layer-online/#message-recovery\r\n *\r\n * @param originalRecord the FIX message to be retransmitted as possible duplicate\r\n * @returns the FIX message ready to be retransmitted\r\n */\r\n private prepareRecordForRetransmission (originalRecord: IFixMsgStoreRecord): IFixMsgStoreRecord {\r\n const retransmitted = originalRecord.clone() // We don't want to accidently change any fields of the original record\r\n\r\n const factory = this.config.factory\r\n if (!retransmitted.obj) {\r\n retransmitted.obj = {}\r\n }\r\n\r\n // Rebuilds header with the updated fields\r\n const header = factory?.header(\r\n retransmitted.msgType,\r\n retransmitted.seqNum,\r\n new Date(), // SendingTime(52)\r\n {\r\n PossDupFlag: true,\r\n OrigSendingTime: retransmitted.timestamp\r\n }\r\n )\r\n retransmitted.obj = {\r\n ...retransmitted.obj,\r\n StandardHeader: header\r\n }\r\n return retransmitted\r\n }\r\n}\r\n"]}
@@ -42,6 +42,7 @@ test('client store states', () => __awaiter(void 0, void 0, void 0, function* ()
42
42
  expect(s1.length).toEqual(1);
43
43
  }));
44
44
  test('server replay request from seq=1 to seq=10', () => __awaiter(void 0, void 0, void 0, function* () {
45
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
45
46
  const vec = yield server.recovery.getResendRequest(1, 10);
46
47
  expect(vec).toBeTruthy();
47
48
  expect(Array.isArray(vec));
@@ -49,18 +50,27 @@ test('server replay request from seq=1 to seq=10', () => __awaiter(void 0, void
49
50
  checkSeqReset(vec[0], 1, 2);
50
51
  expect(vec[1].msgType).toEqual(types_1.MsgType.TradeCaptureReportRequestAck);
51
52
  expect(vec[1].seqNum).toEqual(2);
53
+ expect((_b = (_a = vec[1].obj) === null || _a === void 0 ? void 0 : _a.StandardHeader) === null || _b === void 0 ? void 0 : _b.PossDupFlag).toBeTruthy();
54
+ expect((_d = (_c = vec[1].obj) === null || _c === void 0 ? void 0 : _c.StandardHeader) === null || _d === void 0 ? void 0 : _d.OrigSendingTime).toBeDefined();
52
55
  for (let i = 2; i <= 6; ++i) {
53
56
  expect(vec[i].msgType).toEqual(types_1.MsgType.TradeCaptureReport);
54
57
  expect(vec[i].seqNum).toEqual(i + 1);
58
+ expect((_f = (_e = vec[i].obj) === null || _e === void 0 ? void 0 : _e.StandardHeader) === null || _f === void 0 ? void 0 : _f.PossDupFlag).toBeTruthy();
59
+ expect((_h = (_g = vec[i].obj) === null || _g === void 0 ? void 0 : _g.StandardHeader) === null || _h === void 0 ? void 0 : _h.OrigSendingTime).toBeDefined();
55
60
  }
56
61
  expect(vec[7].msgType).toEqual(types_1.MsgType.TradeCaptureReportRequestAck);
57
62
  expect(vec[7].seqNum).toEqual(8);
63
+ expect((_k = (_j = vec[7].obj) === null || _j === void 0 ? void 0 : _j.StandardHeader) === null || _k === void 0 ? void 0 : _k.PossDupFlag).toBeTruthy();
64
+ expect((_m = (_l = vec[7].obj) === null || _l === void 0 ? void 0 : _l.StandardHeader) === null || _m === void 0 ? void 0 : _m.OrigSendingTime).toBeDefined();
58
65
  for (let i = 8; i < 10; ++i) {
59
66
  expect(vec[i].msgType).toEqual(types_1.MsgType.TradeCaptureReport);
60
67
  expect(vec[i].seqNum).toEqual(i + 1);
68
+ expect((_p = (_o = vec[1].obj) === null || _o === void 0 ? void 0 : _o.StandardHeader) === null || _p === void 0 ? void 0 : _p.PossDupFlag).toBeTruthy();
69
+ expect((_r = (_q = vec[i].obj) === null || _q === void 0 ? void 0 : _q.StandardHeader) === null || _r === void 0 ? void 0 : _r.OrigSendingTime).toBeDefined();
61
70
  }
62
71
  }));
63
72
  test('client replay request from seq=1 to seq=10', () => __awaiter(void 0, void 0, void 0, function* () {
73
+ var _s, _t, _u, _v;
64
74
  const vec = yield client.recovery.getResendRequest(1, 10);
65
75
  expect(vec).toBeTruthy();
66
76
  expect(Array.isArray(vec));
@@ -68,13 +78,16 @@ test('client replay request from seq=1 to seq=10', () => __awaiter(void 0, void
68
78
  checkSeqReset(vec[0], 1, 2);
69
79
  expect(vec[1].msgType).toEqual(types_1.MsgType.TradeCaptureReportRequest);
70
80
  expect(vec[1].seqNum).toEqual(2);
81
+ expect((_t = (_s = vec[1].obj) === null || _s === void 0 ? void 0 : _s.StandardHeader) === null || _t === void 0 ? void 0 : _t.PossDupFlag).toBeTruthy();
82
+ expect((_v = (_u = vec[1].obj) === null || _u === void 0 ? void 0 : _u.StandardHeader) === null || _v === void 0 ? void 0 : _v.OrigSendingTime).toBeDefined();
71
83
  checkSeqReset(vec[2], 3, 11);
72
84
  }));
73
85
  function checkSeqReset(rec, from, to) {
74
86
  const reset = rec.obj;
75
87
  expect(rec.msgType).toEqual(types_1.MsgType.SequenceReset);
76
88
  expect(rec.obj).toBeTruthy();
77
- expect(rec.seqNum).toEqual(to);
89
+ expect(rec.seqNum).toEqual(from);
90
+ expect(reset.NewSeqNo).toEqual(to);
78
91
  expect(reset.GapFillFlag).toBeTruthy();
79
92
  expect(reset.StandardHeader.MsgType).toEqual(types_1.MsgType.SequenceReset);
80
93
  expect(reset.StandardHeader.PossDupFlag).toBeTruthy();
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-store-replay.test.js","sourceRoot":"","sources":["../../../src/test/ascii/ascii-store-replay.test.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata'\r\n\r\nimport * as path from 'path'\r\n\r\nimport {\r\n IFixMsgStoreRecord\r\n} from '../../store'\r\nimport { MsgType } from '../../types'\r\nimport { ISequenceReset } from '../../types/FIX4.4/repo'\r\n\r\nimport { Setup } from '../env/setup'\r\nimport { TestRecovery } from '../env/test-recovery'\r\n\r\nconst root: string = path.join(__dirname, '../../../data')\r\n\r\nlet server: TestRecovery\r\nlet client: TestRecovery\r\nlet setup: Setup\r\n\r\nbeforeAll(async () => {\r\n setup = new Setup(\r\n 'session/test-initiator.json',\r\n 'session/test-acceptor.json')\r\n await setup.init()\r\n const serverConfig = setup.serverConfig\r\n const clientConfig = setup.clientConfig\r\n const views = await setup.server.replayer.replayFixFile(path.join(root, 'examples/FIX.4.4/jsfix.test_client.txt'))\r\n server = new TestRecovery(views, serverConfig)\r\n client = new TestRecovery(views, clientConfig)\r\n await server.populate()\r\n await client.populate()\r\n}, 45000)\r\n\r\ntest('expect 15 messages in log', () => {\r\n expect(server.views.length).toEqual(15)\r\n expect(client.views.length).toEqual(15)\r\n})\r\n\r\n/*\r\nclient: (all client messages)\r\n8=FIX4.4|9=000124|35=AD|49=init-tls-comp|56=accept-tls-comp|34=2|57=fix|52=20210307-16:16:44.388|568=all-trades|569=0|263=1|580=1|75=20210307|10=187|\r\n8=FIX4.4|9=000112|35=0|49=init-tls-comp|56=accept-tls-comp|34=3|57=fix|52=20210307-16:17:14.431|112=Sun, 07 Mar 2021 16:17:14 GMT|10=220|\r\n8=FIX4.4|9=000109|35=5|49=init-tls-comp|56=accept-tls-comp|34=4|57=fix|52=20210307-16:17:16.397|58=test_client initiate logout|10=191|\r\n */\r\n\r\n/*\r\nserver: (application only)\r\n\r\n8=FIX4.4|9=000112|35=AQ|49=accept-tls-comp|56=init-tls-comp|34=2|57=fix|52=20210307-16:16:44.429|568=all-trades|569=0|749=0|750=0|10=142|\r\n8=FIX4.4|9=000209|35=AE|49=accept-tls-comp|56=init-tls-comp|34=3|57=fix|52=20210307-16:16:44.430|571=100000|487=0|856=0|828=0|17=600000|39=2|570=N|55=Platinum|48=Platinum.INC|32=172|31=7.36|75=20210307|60=20210307-16:16:44.430|10=043|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=4|57=fix|52=20210307-16:16:44.431|571=100001|487=0|856=0|828=0|17=600001|39=2|570=N|55=Gold|48=Gold.INC|32=175|31=83.67|75=20210307|60=20210307-16:16:44.430|10=219|\r\n8=FIX4.4|9=000210|35=AE|49=accept-tls-comp|56=init-tls-comp|34=5|57=fix|52=20210307-16:16:44.432|571=100002|487=0|856=0|828=0|17=600002|39=2|570=N|55=Platinum|48=Platinum.INC|32=146|31=41.79|75=20210307|60=20210307-16:16:44.430|10=097|\r\n8=FIX4.4|9=000211|35=AE|49=accept-tls-comp|56=init-tls-comp|34=6|57=fix|52=20210307-16:16:44.432|571=100003|487=0|856=0|828=0|17=600003|39=2|570=N|55=Magnesium|48=Magnesium.INC|32=156|31=8.02|75=20210307|60=20210307-16:16:44.430|10=227|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=7|57=fix|52=20210307-16:16:44.432|571=100004|487=0|856=0|828=0|17=600004|39=2|570=N|55=Gold|48=Gold.INC|32=136|31=32.13|75=20210307|60=20210307-16:16:44.430|10=211|\r\n8=FIX4.4|9=000112|35=AQ|49=accept-tls-comp|56=init-tls-comp|34=8|57=fix|52=20210307-16:16:44.433|568=all-trades|569=0|749=0|750=1|10=144|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=9|57=fix|52=20210307-16:16:59.449|571=100005|487=0|856=0|828=0|17=600005|39=2|570=N|55=Gold|48=Gold.INC|32=166|31=53.91|75=20210307|60=20210307-16:16:59.449|10=001|\r\n8=FIX4.4|9=000206|35=AE|49=accept-tls-comp|56=init-tls-comp|34=10|57=fix|52=20210307-16:17:14.477|571=100006|487=0|856=0|828=0|17=600006|39=2|570=N|55=Silver|48=Silver.INC|32=105|31=61.2|75=20210307|60=20210307-16:17:14.477|10=191|\r\n */\r\n\r\ntest('server store states', async () => {\r\n const s1 = await server.recovery.store.getState()\r\n expect(s1.length).toEqual(9)\r\n})\r\n\r\ntest('client store states', async () => {\r\n const s1 = await client.recovery.store.getState()\r\n expect(s1.length).toEqual(1)\r\n})\r\n\r\ntest('server replay request from seq=1 to seq=10', async () => {\r\n const vec = await server.recovery.getResendRequest(1, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(10)\r\n\r\n checkSeqReset(vec[0], 1, 2)\r\n\r\n expect(vec[1].msgType).toEqual(MsgType.TradeCaptureReportRequestAck)\r\n expect(vec[1].seqNum).toEqual(2)\r\n\r\n for (let i = 2; i <= 6; ++i) {\r\n expect(vec[i].msgType).toEqual(MsgType.TradeCaptureReport)\r\n expect(vec[i].seqNum).toEqual(i + 1)\r\n }\r\n\r\n expect(vec[7].msgType).toEqual(MsgType.TradeCaptureReportRequestAck)\r\n expect(vec[7].seqNum).toEqual(8)\r\n\r\n for (let i = 8; i < 10; ++i) {\r\n expect(vec[i].msgType).toEqual(MsgType.TradeCaptureReport)\r\n expect(vec[i].seqNum).toEqual(i + 1)\r\n }\r\n})\r\n\r\ntest('client replay request from seq=1 to seq=10', async () => {\r\n const vec = await client.recovery.getResendRequest(1, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(3)\r\n\r\n checkSeqReset(vec[0], 1, 2)\r\n\r\n expect(vec[1].msgType).toEqual(MsgType.TradeCaptureReportRequest)\r\n expect(vec[1].seqNum).toEqual(2)\r\n\r\n checkSeqReset(vec[2], 3, 11)\r\n})\r\n\r\nfunction checkSeqReset (rec: IFixMsgStoreRecord, from: number, to: number): void {\r\n const reset: ISequenceReset = rec.obj as ISequenceReset\r\n expect(rec.msgType).toEqual(MsgType.SequenceReset)\r\n expect(rec.obj).toBeTruthy()\r\n expect(rec.seqNum).toEqual(to)\r\n expect(reset.GapFillFlag).toBeTruthy()\r\n expect(reset.StandardHeader.MsgType).toEqual(MsgType.SequenceReset)\r\n expect(reset.StandardHeader.PossDupFlag).toBeTruthy()\r\n expect(reset.StandardHeader.MsgSeqNum).toEqual(from)\r\n}\r\n\r\n// expect to gap fill entire request - and move expected seqNo to 11\r\n// which will be the next message sent\r\ntest('client replay request from seq=4 to seq=10', async () => {\r\n const vec = await client.recovery.getResendRequest(4, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(1)\r\n checkSeqReset(vec[0], 4, 11)\r\n})\r\n"]}
1
+ {"version":3,"file":"ascii-store-replay.test.js","sourceRoot":"","sources":["../../../src/test/ascii/ascii-store-replay.test.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata'\r\n\r\nimport * as path from 'path'\r\n\r\nimport {\r\n IFixMsgStoreRecord\r\n} from '../../store'\r\nimport { MsgType } from '../../types'\r\nimport { ISequenceReset } from '../../types/FIX4.4/repo'\r\n\r\nimport { Setup } from '../env/setup'\r\nimport { TestRecovery } from '../env/test-recovery'\r\n\r\nconst root: string = path.join(__dirname, '../../../data')\r\n\r\nlet server: TestRecovery\r\nlet client: TestRecovery\r\nlet setup: Setup\r\n\r\nbeforeAll(async () => {\r\n setup = new Setup(\r\n 'session/test-initiator.json',\r\n 'session/test-acceptor.json')\r\n await setup.init()\r\n const serverConfig = setup.serverConfig\r\n const clientConfig = setup.clientConfig\r\n const views = await setup.server.replayer.replayFixFile(path.join(root, 'examples/FIX.4.4/jsfix.test_client.txt'))\r\n server = new TestRecovery(views, serverConfig)\r\n client = new TestRecovery(views, clientConfig)\r\n await server.populate()\r\n await client.populate()\r\n}, 45000)\r\n\r\ntest('expect 15 messages in log', () => {\r\n expect(server.views.length).toEqual(15)\r\n expect(client.views.length).toEqual(15)\r\n})\r\n\r\n/*\r\nclient: (all client messages)\r\n8=FIX4.4|9=000124|35=AD|49=init-tls-comp|56=accept-tls-comp|34=2|57=fix|52=20210307-16:16:44.388|568=all-trades|569=0|263=1|580=1|75=20210307|10=187|\r\n8=FIX4.4|9=000112|35=0|49=init-tls-comp|56=accept-tls-comp|34=3|57=fix|52=20210307-16:17:14.431|112=Sun, 07 Mar 2021 16:17:14 GMT|10=220|\r\n8=FIX4.4|9=000109|35=5|49=init-tls-comp|56=accept-tls-comp|34=4|57=fix|52=20210307-16:17:16.397|58=test_client initiate logout|10=191|\r\n */\r\n\r\n/*\r\nserver: (application only)\r\n\r\n8=FIX4.4|9=000112|35=AQ|49=accept-tls-comp|56=init-tls-comp|34=2|57=fix|52=20210307-16:16:44.429|568=all-trades|569=0|749=0|750=0|10=142|\r\n8=FIX4.4|9=000209|35=AE|49=accept-tls-comp|56=init-tls-comp|34=3|57=fix|52=20210307-16:16:44.430|571=100000|487=0|856=0|828=0|17=600000|39=2|570=N|55=Platinum|48=Platinum.INC|32=172|31=7.36|75=20210307|60=20210307-16:16:44.430|10=043|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=4|57=fix|52=20210307-16:16:44.431|571=100001|487=0|856=0|828=0|17=600001|39=2|570=N|55=Gold|48=Gold.INC|32=175|31=83.67|75=20210307|60=20210307-16:16:44.430|10=219|\r\n8=FIX4.4|9=000210|35=AE|49=accept-tls-comp|56=init-tls-comp|34=5|57=fix|52=20210307-16:16:44.432|571=100002|487=0|856=0|828=0|17=600002|39=2|570=N|55=Platinum|48=Platinum.INC|32=146|31=41.79|75=20210307|60=20210307-16:16:44.430|10=097|\r\n8=FIX4.4|9=000211|35=AE|49=accept-tls-comp|56=init-tls-comp|34=6|57=fix|52=20210307-16:16:44.432|571=100003|487=0|856=0|828=0|17=600003|39=2|570=N|55=Magnesium|48=Magnesium.INC|32=156|31=8.02|75=20210307|60=20210307-16:16:44.430|10=227|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=7|57=fix|52=20210307-16:16:44.432|571=100004|487=0|856=0|828=0|17=600004|39=2|570=N|55=Gold|48=Gold.INC|32=136|31=32.13|75=20210307|60=20210307-16:16:44.430|10=211|\r\n8=FIX4.4|9=000112|35=AQ|49=accept-tls-comp|56=init-tls-comp|34=8|57=fix|52=20210307-16:16:44.433|568=all-trades|569=0|749=0|750=1|10=144|\r\n8=FIX4.4|9=000202|35=AE|49=accept-tls-comp|56=init-tls-comp|34=9|57=fix|52=20210307-16:16:59.449|571=100005|487=0|856=0|828=0|17=600005|39=2|570=N|55=Gold|48=Gold.INC|32=166|31=53.91|75=20210307|60=20210307-16:16:59.449|10=001|\r\n8=FIX4.4|9=000206|35=AE|49=accept-tls-comp|56=init-tls-comp|34=10|57=fix|52=20210307-16:17:14.477|571=100006|487=0|856=0|828=0|17=600006|39=2|570=N|55=Silver|48=Silver.INC|32=105|31=61.2|75=20210307|60=20210307-16:17:14.477|10=191|\r\n */\r\n\r\ntest('server store states', async () => {\r\n const s1 = await server.recovery.store.getState()\r\n expect(s1.length).toEqual(9)\r\n})\r\n\r\ntest('client store states', async () => {\r\n const s1 = await client.recovery.store.getState()\r\n expect(s1.length).toEqual(1)\r\n})\r\n\r\ntest('server replay request from seq=1 to seq=10', async () => {\r\n const vec = await server.recovery.getResendRequest(1, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(10)\r\n\r\n checkSeqReset(vec[0], 1, 2)\r\n\r\n expect(vec[1].msgType).toEqual(MsgType.TradeCaptureReportRequestAck)\r\n expect(vec[1].seqNum).toEqual(2)\r\n expect(vec[1].obj?.StandardHeader?.PossDupFlag).toBeTruthy()\r\n expect(vec[1].obj?.StandardHeader?.OrigSendingTime).toBeDefined()\r\n\r\n for (let i = 2; i <= 6; ++i) {\r\n expect(vec[i].msgType).toEqual(MsgType.TradeCaptureReport)\r\n expect(vec[i].seqNum).toEqual(i + 1)\r\n expect(vec[i].obj?.StandardHeader?.PossDupFlag).toBeTruthy()\r\n expect(vec[i].obj?.StandardHeader?.OrigSendingTime).toBeDefined()\r\n }\r\n\r\n expect(vec[7].msgType).toEqual(MsgType.TradeCaptureReportRequestAck)\r\n expect(vec[7].seqNum).toEqual(8)\r\n expect(vec[7].obj?.StandardHeader?.PossDupFlag).toBeTruthy()\r\n expect(vec[7].obj?.StandardHeader?.OrigSendingTime).toBeDefined()\r\n\r\n for (let i = 8; i < 10; ++i) {\r\n expect(vec[i].msgType).toEqual(MsgType.TradeCaptureReport)\r\n expect(vec[i].seqNum).toEqual(i + 1)\r\n expect(vec[1].obj?.StandardHeader?.PossDupFlag).toBeTruthy()\r\n expect(vec[i].obj?.StandardHeader?.OrigSendingTime).toBeDefined()\r\n }\r\n})\r\n\r\ntest('client replay request from seq=1 to seq=10', async () => {\r\n const vec = await client.recovery.getResendRequest(1, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(3)\r\n\r\n checkSeqReset(vec[0], 1, 2)\r\n\r\n expect(vec[1].msgType).toEqual(MsgType.TradeCaptureReportRequest)\r\n expect(vec[1].seqNum).toEqual(2)\r\n expect(vec[1].obj?.StandardHeader?.PossDupFlag).toBeTruthy()\r\n expect(vec[1].obj?.StandardHeader?.OrigSendingTime).toBeDefined()\r\n\r\n checkSeqReset(vec[2], 3, 11)\r\n})\r\n\r\nfunction checkSeqReset (rec: IFixMsgStoreRecord, from: number, to: number): void {\r\n const reset: ISequenceReset = rec.obj as ISequenceReset\r\n expect(rec.msgType).toEqual(MsgType.SequenceReset)\r\n expect(rec.obj).toBeTruthy()\r\n expect(rec.seqNum).toEqual(from)\r\n expect(reset.NewSeqNo).toEqual(to)\r\n expect(reset.GapFillFlag).toBeTruthy()\r\n expect(reset.StandardHeader.MsgType).toEqual(MsgType.SequenceReset)\r\n expect(reset.StandardHeader.PossDupFlag).toBeTruthy()\r\n expect(reset.StandardHeader.MsgSeqNum).toEqual(from)\r\n}\r\n\r\n// expect to gap fill entire request - and move expected seqNo to 11\r\n// which will be the next message sent\r\ntest('client replay request from seq=4 to seq=10', async () => {\r\n const vec = await client.recovery.getResendRequest(4, 10)\r\n expect(vec).toBeTruthy()\r\n expect(Array.isArray(vec))\r\n expect(vec.length).toEqual(1)\r\n checkSeqReset(vec[0], 4, 11)\r\n})\r\n"]}
@@ -74,25 +74,74 @@ test('end to end logon', () => __awaiter(void 0, void 0, void 0, function* () {
74
74
  test('session send resendRequest when logged on', () => __awaiter(void 0, void 0, void 0, function* () {
75
75
  const runner = new skeleton_runner_1.SkeletonRunner(experiment, 2);
76
76
  const factory = experiment.client.config.factory;
77
- const resend = factory === null || factory === void 0 ? void 0 : factory.resendRequest(1, 2);
77
+ const resend = factory === null || factory === void 0 ? void 0 : factory.resendRequest(1, 1);
78
78
  expect(resend).toBeTruthy();
79
79
  if (!resend)
80
80
  return;
81
81
  runner.sendMsg(types_1.MsgType.ResendRequest, resend);
82
- try {
83
- const cViews = experiment.client.views;
84
- const sViews = experiment.server.views;
85
- yield runner.wait();
86
- const last = experiment.client.views[experiment.client.views.length - 1];
87
- expect(last).toBeTruthy();
88
- const clientResets = countOfType('SequenceReset', cViews);
89
- const serverResets = countOfType('SequenceReset', sViews);
90
- expect(clientResets).toEqual(1);
91
- expect(serverResets).toEqual(0);
92
- }
93
- catch (e) {
94
- expect(true).toEqual(false);
95
- }
82
+ const cViews = experiment.client.views;
83
+ const sViews = experiment.server.views;
84
+ yield runner.wait();
85
+ expect(cViews).toHaveLength(3);
86
+ expect(sViews).toHaveLength(3);
87
+ const resendRequestView = sViews[1];
88
+ expect(resendRequestView.segment.name).toBe('ResendRequest');
89
+ expect(resendRequestView.getTyped('MsgSeqNum')).toBe(2);
90
+ expect(resendRequestView.getTyped('BeginSeqNo')).toBe(1);
91
+ expect(resendRequestView.getTyped('EndSeqNo')).toBe(1);
92
+ const seqResetView = cViews[1];
93
+ expect(seqResetView.segment.name).toBe('SequenceReset');
94
+ expect(seqResetView.getTyped('MsgSeqNum')).toBe(1);
95
+ expect(seqResetView.getTyped('NewSeqNo')).toBe(2);
96
+ expect(seqResetView.getTyped('GapFillFlag')).toBe(true);
97
+ expect(seqResetView.getTyped('PossDupFlag')).toBe(true);
98
+ const logoutSView = sViews[2];
99
+ expect(logoutSView.segment.name).toBe('Logout');
100
+ expect(logoutSView.getTyped('MsgSeqNum')).toBe(3);
101
+ const logoutCView = cViews[2];
102
+ expect(logoutCView.segment.name).toBe('Logout');
103
+ expect(logoutCView.getTyped('MsgSeqNum')).toBe(2);
104
+ const clientResets = countOfType('SequenceReset', cViews);
105
+ const serverResets = countOfType('SequenceReset', sViews);
106
+ console.log('SERVER VIEWS', sViews.map((a => a.toJson())));
107
+ console.log('CLIENT VIEWS', cViews.map((a => a.toJson())));
108
+ expect(clientResets).toEqual(1);
109
+ expect(serverResets).toEqual(0);
110
+ }));
111
+ test('session send resendRequest with endSeqNo = 0 when logged on', () => __awaiter(void 0, void 0, void 0, function* () {
112
+ const runner = new skeleton_runner_1.SkeletonRunner(experiment, 2);
113
+ const factory = experiment.client.config.factory;
114
+ const resend = factory === null || factory === void 0 ? void 0 : factory.resendRequest(1, 0);
115
+ expect(resend).toBeTruthy();
116
+ if (!resend)
117
+ return;
118
+ runner.sendMsg(types_1.MsgType.ResendRequest, resend);
119
+ const cViews = experiment.client.views;
120
+ const sViews = experiment.server.views;
121
+ yield runner.wait();
122
+ expect(cViews).toHaveLength(3);
123
+ expect(sViews).toHaveLength(3);
124
+ const resendRequestView = sViews[1];
125
+ expect(resendRequestView.segment.name).toBe('ResendRequest');
126
+ expect(resendRequestView.getTyped('MsgSeqNum')).toBe(2);
127
+ expect(resendRequestView.getTyped('BeginSeqNo')).toBe(1);
128
+ expect(resendRequestView.getTyped('EndSeqNo')).toBe(0);
129
+ const seqResetView = cViews[1];
130
+ expect(seqResetView.segment.name).toBe('SequenceReset');
131
+ expect(seqResetView.getTyped('MsgSeqNum')).toBe(1);
132
+ expect(seqResetView.getTyped('NewSeqNo')).toBe(2);
133
+ expect(seqResetView.getTyped('GapFillFlag')).toBe(true);
134
+ expect(seqResetView.getTyped('PossDupFlag')).toBe(true);
135
+ const logoutSView = sViews[2];
136
+ expect(logoutSView.segment.name).toBe('Logout');
137
+ expect(logoutSView.getTyped('MsgSeqNum')).toBe(3);
138
+ const logoutCView = cViews[2];
139
+ expect(logoutCView.segment.name).toBe('Logout');
140
+ expect(logoutCView.getTyped('MsgSeqNum')).toBe(2);
141
+ const clientResets = countOfType('SequenceReset', cViews);
142
+ const serverResets = countOfType('SequenceReset', sViews);
143
+ expect(clientResets).toEqual(1);
144
+ expect(serverResets).toEqual(0);
96
145
  }));
97
146
  test('session send logon when logged on', () => __awaiter(void 0, void 0, void 0, function* () {
98
147
  var _d, _e, _f;
@@ -1 +1 @@
1
- {"version":3,"file":"session.test.js","sourceRoot":"","sources":["../../../src/test/ascii/session.test.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,4BAAyB;AAIzB,uCAA0D;AAK1D,wCAAoC;AACpC,kDAA8C;AAC9C,4DAAuD;AAEvD,MAAM,QAAQ,GAAW,iJAAiJ,CAAA;AAC1K,MAAM,SAAS,GAAW,mIAAmI,CAAA;AAE7J,IAAI,KAAY,CAAA;AAChB,IAAI,UAAsB,CAAA;AAE1B,UAAU,CAAC,GAAS,EAAE;IACpB,KAAK,GAAG,IAAI,aAAK,EAAE,CAAA;IACnB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;IAClB,UAAU,GAAG,IAAI,uBAAU,CAAC,KAAK,CAAC,CAAA;AACpC,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAET,MAAM,aAAa;IACjB,YACkB,KAAa,EACb,OAAe,EACf,IAAa;QAFb,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAS;IAC/B,CAAC;CACF;AAED,SAAe,8BAA8B,CAAE,IAAY,EAAE,GAAiB;;QAC5E,OAAO,MAAM,IAAI,OAAO,CAAM,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAA;YACvC,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAA;YACvC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE;gBACvC,MAAM,CAAC,CAAC,CAAC,CAAA;YACX,CAAC,CAAC,CAAA;YACF,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,OAAe,EAAE,IAAa,EAAE,EAAE;gBACxD,OAAO,CAAC,IAAI,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;YAC1D,CAAC,CAAC,CAAA;YACF,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAQ,EAAE,EAAE;gBACpC,MAAM,CAAC,CAAC,CAAC,CAAA;YACX,CAAC,CAAC,CAAA;YACF,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;YAC/B,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAA;QACnC,CAAC,CAAC,CAAA;IACJ,CAAC;CAAA;AAED,SAAe,YAAY,CAAE,gBAAwB,CAAC,EAAE,WAA0B,IAAI;;QACpF,MAAM,MAAM,GAAmB,IAAI,gCAAc,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;QAC5E,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACzB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;CAAA;AAED,IAAI,CAAC,kBAAkB,EAAE,GAAS,EAAE;;IAClC,MAAM,EAAE,GAAG,MAAA,MAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,0CAAE,MAAM,0CAAE,OAAO,0CAAE,KAAK,EAAY,CAAA;IACjE,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,CAAA;IACvB,IAAI,CAAC,EAAE;QAAE,OAAM;IACf,MAAM,GAAG,GAAkB,MAAM,8BAA8B,CAAC,eAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAClF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAChC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAkB,CAAA;IACpD,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAA;IAC7B,OAAO,QAAQ,CAAC,cAAc,CAAA;IAC9B,OAAO,QAAQ,CAAC,eAAe,CAAA;IAC/B,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAC9B,CAAC,CAAA,CAAC,CAAA;AAEF,IAAI,CAAC,2CAA2C,EAAE,GAAS,EAAE;IAC3D,MAAM,MAAM,GAAmB,IAAI,gCAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IAChE,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAA;IAChD,MAAM,MAAM,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAA;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAM;IACnB,MAAM,CAAC,OAAO,CAAC,eAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;QACtC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QACnB,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACxE,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAA;QACzB,MAAM,YAAY,GAAG,WAAW,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QACzD,MAAM,YAAY,GAAG,WAAW,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;QACzD,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC/B,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;AACH,CAAC,CAAA,CAAC,CAAA;AAEF,IAAI,CAAC,mCAAmC,EAAE,GAAS,EAAE;;IACnD,MAAM,MAAM,GAAmB,IAAI,gCAAc,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,MAAA,MAAA,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,0CAAE,MAAM,0CAAE,OAAO,0CAAE,KAAK,EAAE,CAAA;IAC1D,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAA;IAC1B,IAAI,CAAC,KAAK;QAAE,OAAM;IAClB,MAAM,CAAC,OAAO,CAAC,eAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;IACrB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACpD,CAAC;AACH,CAAC,CAAA,CAAC,CAAA;AAEF,IAAI,CAAC,wBAAwB,EAAE,GAAS,EAAE;IACxC,MAAM,YAAY,EAAE,CAAA;IACpB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IAEtC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAClD,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAGlD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAEhC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAClD,CAAC,CAAA,CAAC,CAAA;AAEF,SAAS,WAAW,CAAE,KAAgB;IACpC,MAAM,KAAK,GAAa,KAAK,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,eAAC,OAAA,MAAC,MAAA,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,0CAAE,QAAQ,EAAsB,0CAAE,SAAS,CAAA,EAAA,CAAC,CAAA;IAC1H,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,MAAc,EAAE,EAAE;QACvD,OAAO,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACzC,CAAC,EAAE,CAAC,CAAC,CAAA;IACL,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED,IAAI,CAAC,WAAW,EAAE,GAAS,EAAE;IAC3B,MAAM,YAAY,EAAE,CAAA;IACpB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IAEtC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;AACrB,CAAC,CAAA,CAAC,CAAA;AAEF,SAAS,WAAW,CAAE,CAAsB,EAAE,IAAY,EAAE,CAAe;IACzE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,CAAoB,CAAA;YAChC,IAAI,GAAG,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,SAAS,GAAG,CAAC,CAAA;YACnB,CAAC;YACD,MAAK;QACP,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,IAAI,CAAC,mBAAmB,EAAE,GAAS,EAAE;IACnC,UAAU,CAAC,aAAa,CAAC,OAAO,GAAG,WAAW,CAAA;IAC9C,MAAM,YAAY,EAAE,CAAA;IACpB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IAEtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAChC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAChC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAClD,CAAC,CAAA,CAAC,CAAA;AAEF,SAAS,WAAW,CAAE,IAAY,EAAE,KAAgB;IAClD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,CAAU,EAAE,EAAE;QAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,CAAC,CAAA;AACP,CAAC;AAED,SAAS,8BAA8B,CAAE,CAAsB,EAAE,IAAY,EAAE,CAAe;IAC5F,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,MAAM,KAAK,GAAG,CAAW,CAAA;YAEzB,OAAO,KAAK,CAAC,UAAU,CAAA;YACvB,MAAK;QACP,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,IAAI,CAAC,iCAAiC,EAAE,GAAS,EAAE;IACjD,UAAU,CAAC,aAAa,CAAC,OAAO,GAAG,8BAA8B,CAAA;IACjE,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IAErB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAY,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAa,CAAA;IACvD,MAAM,CAAC,MAAM,CAAC,mBAAmB,KAAK,2BAAmB,CAAC,kBAAkB,CAAC,CAAA;IAC7E,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAA;AACnE,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAIT,SAAe,cAAc,CAAE,UAAsB,EAAE,OAAe;;QACpE,MAAM,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;QACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;QAEtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAChC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACjD,CAAC;CAAA;AAED,IAAI,CAAC,yBAAyB,EAAE,GAAS,EAAE;IACzC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,WAAkC,CAAA;IACzE,MAAM,OAAO,GAAG,QAAQ;SACrB,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACjD,MAAM,MAAM,GAAY,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAa,CAAA;IACvD,MAAM,CAAC,MAAM,CAAC,mBAAmB,KAAK,2BAAmB,CAAC,cAAc,CAAC,CAAA;IACzE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;AACnD,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAET,IAAI,CAAC,uBAAuB,EAAE,GAAS,EAAE;IACvC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,WAAkC,CAAA;IACzE,MAAM,OAAO,GAAG,SAAS;SACtB,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACnD,MAAM,MAAM,GAAY,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAa,CAAA;IACxE,MAAM,CAAC,MAAM,CAAC,mBAAmB,KAAK,2BAAmB,CAAC,gBAAgB,CAAC,CAAA;IAC3E,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;AACrB,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAET,IAAI,CAAC,+BAA+B,EAAE,GAAS,EAAE;IAC/C,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,WAAkC,CAAA;IACzE,MAAM,OAAO,GAAG,SAAS;SACtB,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC;SACvC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACnD,MAAM,MAAM,GAAY,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAa,CAAA;IACvD,MAAM,CAAC,MAAM,CAAC,mBAAmB,KAAK,2BAAmB,CAAC,aAAa,CAAC,CAAA;IACxE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;AACrB,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAGT,IAAI,CAAC,6BAA6B,EAAE,GAAS,EAAE;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAA;IAC9D,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,CAAA;IACnD,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IACrB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IAEtC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,wBAAwB,GAAG,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,CAAC,wBAAwB,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAA;AAC1D,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAET,IAAI,CAAC,6BAA6B,EAAE,GAAS,EAAE;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAA;IAC9D,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,CAAA;IACnD,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IAErB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,wBAAwB,GAAG,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,CAAC,wBAAwB,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAA;AAC1D,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA;AAET,IAAI,CAAC,yBAAyB,EAAE,GAAS,EAAE;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAA;IAC9D,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,CAAA;IACnD,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,CAAA;IACnD,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IACrB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAA;IAEtC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,wBAAwB,GAAG,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,yBAAyB,GAAG,WAAW,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACpE,MAAM,WAAW,GAAG,wBAAwB,GAAG,yBAAyB,CAAA;IACxE,MAAM,wBAAwB,GAAG,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,yBAAyB,GAAG,WAAW,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACpE,MAAM,WAAW,GAAG,wBAAwB,GAAG,yBAAyB,CAAA;IACxE,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACvE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,WAAW,CAAC,MAAM,CAAC,CAAA;IACnB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAA;IACxD,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,GAAG,MAAM,CAAA;AAC1D,CAAC,CAAA,EAAE,KAAK,CAAC,CAAA","sourcesContent":["import 'reflect-metadata'\r\n\r\nimport { MsgView } from '../../buffer'\r\nimport { ISessionDescription } from '../../transport'\r\nimport { MsgType, SessionRejectReason } from '../../types'\r\nimport { ILooseObject } from '../../collections/collection'\r\nimport { IStandardHeader, IReject, ILogon } from '../../types/FIX4.4/repo'\r\n\r\nimport { AsciiMsgTransmitter } from '../../transport/ascii/ascii-msg-transmitter'\r\nimport { Setup } from '../env/setup'\r\nimport { Experiment } from '../env/experiment'\r\nimport { SkeletonRunner } from '../env/skeleton-runner'\r\n\r\nconst logonMsg: string = '8=FIX4.4|9=0000136|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20180902-12:25:28.980|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=177|'\r\nconst heartbeat: string = '8=FIX4.4|9=0000123|35=0|49=init-comp|56=accept-comp|34=1|57=fix|52=20180902-12:25:59.161|112=Sun, 02 Sep 2018 12:25:59 GMT|10=95|'\r\n\r\nlet setup: Setup\r\nlet experiment: Experiment\r\n\r\nbeforeEach(async () => {\r\n setup = new Setup()\r\n await setup.init()\r\n experiment = new Experiment(setup)\r\n}, 30000)\r\n\r\nclass ParsingResult {\r\n constructor (\r\n public readonly event: string,\r\n public readonly msgType: string,\r\n public readonly view: MsgView) {\r\n }\r\n}\r\n\r\nasync function clientToServerWaitFirstMessage (type: string, obj: ILooseObject): Promise<ParsingResult> {\r\n return await new Promise<any>((resolve, reject) => {\r\n const clt = experiment.client.transport\r\n const svt = experiment.server.transport\r\n clt.transmitter.on('error', (e: Error) => {\r\n reject(e)\r\n })\r\n svt.receiver.on('msg', (msgType: string, view: MsgView) => {\r\n resolve(new ParsingResult('msg', msgType, view.clone()))\r\n })\r\n clt.receiver.on('error', (e: Error) => {\r\n reject(e)\r\n })\r\n clt.transmitter.send(type, obj)\r\n experiment.client.transport.end()\r\n })\r\n}\r\n\r\nasync function runSkeletons (logoutSeconds: number = 1, followOn: string | null = null): Promise<void> {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, logoutSeconds)\r\n runner.sendText(followOn)\r\n await runner.wait()\r\n}\r\n\r\ntest('end to end logon', async () => {\r\n const lo = experiment?.client?.config?.factory?.logon() as ILogon\r\n expect(lo).toBeTruthy()\r\n if (!lo) return\r\n const res: ParsingResult = await clientToServerWaitFirstMessage(MsgType.Logon, lo)\r\n expect(res.event).toEqual('msg')\r\n expect(res.msgType).toEqual('A')\r\n const received = res.view.toObject() as ILooseObject\r\n expect(received).toBeTruthy()\r\n delete received.StandardHeader\r\n delete received.StandardTrailer\r\n expect(received).toEqual(lo)\r\n})\r\n\r\ntest('session send resendRequest when logged on', async () => {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, 2)\r\n const factory = experiment.client.config.factory\r\n const resend = factory?.resendRequest(1, 2)\r\n expect(resend).toBeTruthy()\r\n if (!resend) return\r\n runner.sendMsg(MsgType.ResendRequest, resend)\r\n try {\r\n const cViews = experiment.client.views\r\n const sViews = experiment.server.views\r\n await runner.wait()\r\n const last = experiment.client.views[experiment.client.views.length - 1]\r\n expect(last).toBeTruthy()\r\n const clientResets = countOfType('SequenceReset', cViews)\r\n const serverResets = countOfType('SequenceReset', sViews)\r\n expect(clientResets).toEqual(1)\r\n expect(serverResets).toEqual(0)\r\n } catch (e) {\r\n expect(true).toEqual(false)\r\n }\r\n})\r\n\r\ntest('session send logon when logged on', async () => {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, 2)\r\n const logon = experiment?.client?.config?.factory?.logon()\r\n expect(logon).toBeTruthy()\r\n if (!logon) return\r\n runner.sendMsg(MsgType.Logon, logon)\r\n try {\r\n await runner.wait()\r\n } catch (e) {\r\n expect(experiment.server.errors.length).toEqual(1)\r\n }\r\n})\r\n\r\ntest('session logon / logout', async () => {\r\n await runSkeletons()\r\n const cViews = experiment.client.views\r\n const sViews = experiment.server.views\r\n\r\n expect(experiment.client.errors.length).toEqual(0)\r\n expect(experiment.server.errors.length).toEqual(0)\r\n\r\n // both sides should now have logged on and logged off\r\n expect(cViews.length).toEqual(2)\r\n expect(sViews.length).toEqual(2)\r\n\r\n expect(cViews[0].segment.name).toEqual('Logon')\r\n expect(cViews[1].segment.name).toEqual('Logout')\r\n\r\n expect(sViews[0].segment.name).toEqual('Logon')\r\n expect(sViews[1].segment.name).toEqual('Logout')\r\n})\r\n\r\nfunction checkSeqNos (views: MsgView[]): void {\r\n const seqNo: number[] = views.map((v: MsgView) => (v.getView('StandardHeader')?.toObject() as IStandardHeader)?.MsgSeqNum)\r\n expect(seqNo).toBeTruthy()\r\n const delta = seqNo.reduce((c: number, latest: number) => {\r\n return latest - c === 1 ? c + 1 : c - 1\r\n }, 0)\r\n expect(delta).toEqual(seqNo.length)\r\n}\r\n\r\ntest('seq No OK', async () => {\r\n await runSkeletons()\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(cviews.length >= 2).toEqual(true)\r\n expect(sviews.length >= 2).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n})\r\n\r\nfunction mutateSeqNo (_: ISessionDescription, type: string, o: ILooseObject): ILooseObject {\r\n switch (type) {\r\n case 'StandardHeader': {\r\n const hdr = o as IStandardHeader\r\n if (hdr.MsgSeqNum === 2) {\r\n hdr.MsgSeqNum = 0\r\n }\r\n break\r\n }\r\n }\r\n return o\r\n}\r\n\r\ntest('out of seq logout', async () => {\r\n experiment.clientFactory.mutator = mutateSeqNo\r\n await runSkeletons()\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on but out of seq logout will terminate sessions so no logout returned\r\n expect(cviews.length).toEqual(1)\r\n expect(cviews[0].segment.name).toEqual('Logon')\r\n expect(sviews.length).toEqual(2)\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n expect(sviews[1].segment.name).toEqual('Logout')\r\n})\r\n\r\nfunction countOfType (type: string, views: MsgView[]): number {\r\n return views.reduce((c: number, v: MsgView) => {\r\n return v.segment.name === type ? c + 1 : c\r\n }, 0)\r\n}\r\n\r\nfunction mutateRemoveRequiredHeartBtInt (_: ISessionDescription, type: string, o: ILooseObject): ILooseObject {\r\n switch (type) {\r\n case 'A': {\r\n const logon = o as ILogon\r\n // @ts-expect-error - this is for test purposed\r\n delete logon.HeartBtInt\r\n break\r\n }\r\n }\r\n return o\r\n}\r\n\r\ntest('client logon reject missing 108', async () => {\r\n experiment.clientFactory.mutator = mutateRemoveRequiredHeartBtInt\r\n await runSkeletons(2)\r\n // client sends logon, server rejects\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n expect(cviews.length === 1).toEqual(true)\r\n expect(sviews.length === 1).toEqual(true)\r\n expect(cviews[0].segment.name).toEqual('Reject')\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n const reject: IReject = cviews[0].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.RequiredTagMissing)\r\n expect(reject.Text).toEqual('msgType A missing required tag 108')\r\n}, 10000)\r\n\r\n// transport.transmitter\r\n\r\nasync function runCheckReject (experiment: Experiment, changed: string): Promise<void> {\r\n await runSkeletons(2, changed)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // client sends logon, server rejects\r\n expect(cviews.length).toEqual(3)\r\n expect(sviews.length).toEqual(3)\r\n expect(cviews[0].segment.name).toEqual('Logon')\r\n expect(cviews[1].segment.name).toEqual('Reject')\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n}\r\n\r\ntest('client unknown msg type', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = logonMsg\r\n .replace('35=A', '35=ZZ')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('unknown')\r\n const reject: IReject = cviews[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.InvalidMsgType)\r\n expect(reject.Text).toEqual('msgType ZZ unknown')\r\n}, 10000)\r\n\r\ntest('heartbeat invalid tag', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = heartbeat\r\n .replace('112=', '999=')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n await runSkeletons(2, changed)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('Heartbeat')\r\n const reject: IReject = experiment.client.views[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.InvalidTagNumber)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n}, 10000)\r\n\r\ntest('heartbeat invalid sender comp', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = heartbeat\r\n .replace('49=init-comp', '49=init-not!')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('Heartbeat')\r\n const reject: IReject = cviews[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.CompIDProblem)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n}, 10000)\r\n\r\n// client will send heartbeats to server, server with 30 second heartbeat will not heartbeat\r\ntest('client heartbeats to server', async () => {\r\n const preset = experiment.client.config.description.HeartBtInt\r\n experiment.client.config.description.HeartBtInt = 2\r\n await runSkeletons(6)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(cviews.length === 2).toEqual(true)\r\n expect(sviews.length > 2).toEqual(true)\r\n const serverReceivesHeartbeats = countOfType('Heartbeat', sviews)\r\n expect(serverReceivesHeartbeats >= 2 && serverReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.client.config.description.HeartBtInt = preset\r\n}, 10000)\r\n\r\ntest('server heartbeats to client', async () => {\r\n const preset = experiment.server.config.description.HeartBtInt\r\n experiment.server.config.description.HeartBtInt = 2\r\n await runSkeletons(6)\r\n // both sides should now have logged on and logged off\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n expect(sviews.length === 2).toEqual(true)\r\n expect(cviews.length > 2).toEqual(true)\r\n const clientReceivesHeartbeats = countOfType('Heartbeat', cviews)\r\n expect(clientReceivesHeartbeats >= 2 && clientReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.server.config.description.HeartBtInt = preset\r\n}, 10000)\r\n\r\ntest('client server heartbeat', async () => {\r\n const preset = experiment.server.config.description.HeartBtInt\r\n experiment.server.config.description.HeartBtInt = 5\r\n experiment.client.config.description.HeartBtInt = 2\r\n await runSkeletons(8)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(sviews.length > 2).toEqual(true)\r\n expect(cviews.length > 2).toEqual(true)\r\n const clientReceivesHeartbeats = countOfType('Heartbeat', cviews)\r\n const clientReceivesTestRequest = countOfType('TestRequest', cviews)\r\n const clientTotal = clientReceivesHeartbeats + clientReceivesTestRequest\r\n const serverReceivesHeartbeats = countOfType('Heartbeat', sviews)\r\n const serverReceivesTestRequest = countOfType('TestRequest', sviews)\r\n const serverTotal = serverReceivesHeartbeats + serverReceivesTestRequest\r\n expect(clientTotal >= 1 && clientReceivesHeartbeats <= 4).toEqual(true)\r\n expect(serverTotal >= 3 && serverReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.server.config.description.HeartBtInt = preset\r\n experiment.client.config.description.HeartBtInt = preset\r\n}, 15000)\r\n"]}
1
+ {"version":3,"file":"session.test.js","sourceRoot":"","sources":["../../../src/test/ascii/session.test.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata'\r\n\r\nimport { MsgView } from '../../buffer'\r\nimport { ISessionDescription } from '../../transport'\r\nimport { MsgType, SessionRejectReason } from '../../types'\r\nimport { ILooseObject } from '../../collections/collection'\r\nimport { IStandardHeader, IReject, ILogon } from '../../types/FIX4.4/repo'\r\n\r\nimport { AsciiMsgTransmitter } from '../../transport/ascii/ascii-msg-transmitter'\r\nimport { Setup } from '../env/setup'\r\nimport { Experiment } from '../env/experiment'\r\nimport { SkeletonRunner } from '../env/skeleton-runner'\r\n\r\nconst logonMsg: string = '8=FIX4.4|9=0000136|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20180902-12:25:28.980|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=177|'\r\nconst heartbeat: string = '8=FIX4.4|9=0000123|35=0|49=init-comp|56=accept-comp|34=1|57=fix|52=20180902-12:25:59.161|112=Sun, 02 Sep 2018 12:25:59 GMT|10=95|'\r\n\r\nlet setup: Setup\r\nlet experiment: Experiment\r\n\r\nbeforeEach(async () => {\r\n setup = new Setup()\r\n await setup.init()\r\n experiment = new Experiment(setup)\r\n}, 30000)\r\n\r\nclass ParsingResult {\r\n constructor (\r\n public readonly event: string,\r\n public readonly msgType: string,\r\n public readonly view: MsgView) {\r\n }\r\n}\r\n\r\nasync function clientToServerWaitFirstMessage (type: string, obj: ILooseObject): Promise<ParsingResult> {\r\n return await new Promise<any>((resolve, reject) => {\r\n const clt = experiment.client.transport\r\n const svt = experiment.server.transport\r\n clt.transmitter.on('error', (e: Error) => {\r\n reject(e)\r\n })\r\n svt.receiver.on('msg', (msgType: string, view: MsgView) => {\r\n resolve(new ParsingResult('msg', msgType, view.clone()))\r\n })\r\n clt.receiver.on('error', (e: Error) => {\r\n reject(e)\r\n })\r\n clt.transmitter.send(type, obj)\r\n experiment.client.transport.end()\r\n })\r\n}\r\n\r\nasync function runSkeletons (logoutSeconds: number = 1, followOn: string | null = null): Promise<void> {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, logoutSeconds)\r\n runner.sendText(followOn)\r\n await runner.wait()\r\n}\r\n\r\ntest('end to end logon', async () => {\r\n const lo = experiment?.client?.config?.factory?.logon() as ILogon\r\n expect(lo).toBeTruthy()\r\n if (!lo) return\r\n const res: ParsingResult = await clientToServerWaitFirstMessage(MsgType.Logon, lo)\r\n expect(res.event).toEqual('msg')\r\n expect(res.msgType).toEqual('A')\r\n const received = res.view.toObject() as ILooseObject\r\n expect(received).toBeTruthy()\r\n delete received.StandardHeader\r\n delete received.StandardTrailer\r\n expect(received).toEqual(lo)\r\n})\r\n\r\ntest('session send resendRequest when logged on', async () => {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, 2)\r\n const factory = experiment.client.config.factory\r\n const resend = factory?.resendRequest(1, 1)\r\n expect(resend).toBeTruthy()\r\n if (!resend) return\r\n runner.sendMsg(MsgType.ResendRequest, resend)\r\n\r\n const cViews = experiment.client.views\r\n const sViews = experiment.server.views\r\n await runner.wait()\r\n\r\n expect(cViews).toHaveLength(3)\r\n expect(sViews).toHaveLength(3)\r\n\r\n const resendRequestView = sViews[1]\r\n expect(resendRequestView.segment.name).toBe('ResendRequest')\r\n expect(resendRequestView.getTyped('MsgSeqNum')).toBe(2)\r\n expect(resendRequestView.getTyped('BeginSeqNo')).toBe(1)\r\n expect(resendRequestView.getTyped('EndSeqNo')).toBe(1)\r\n\r\n const seqResetView = cViews[1]\r\n expect(seqResetView.segment.name).toBe('SequenceReset')\r\n expect(seqResetView.getTyped('MsgSeqNum')).toBe(1)\r\n expect(seqResetView.getTyped('NewSeqNo')).toBe(2)\r\n expect(seqResetView.getTyped('GapFillFlag')).toBe(true)\r\n expect(seqResetView.getTyped('PossDupFlag')).toBe(true)\r\n\r\n const logoutSView = sViews[2]\r\n expect(logoutSView.segment.name).toBe('Logout')\r\n expect(logoutSView.getTyped('MsgSeqNum')).toBe(3)\r\n\r\n const logoutCView = cViews[2]\r\n expect(logoutCView.segment.name).toBe('Logout')\r\n expect(logoutCView.getTyped('MsgSeqNum')).toBe(2)\r\n\r\n const clientResets = countOfType('SequenceReset', cViews)\r\n const serverResets = countOfType('SequenceReset', sViews)\r\n console.log('SERVER VIEWS', sViews.map((a => a.toJson())));\r\n console.log('CLIENT VIEWS', cViews.map((a => a.toJson())));\r\n expect(clientResets).toEqual(1)\r\n expect(serverResets).toEqual(0)\r\n})\r\n\r\ntest('session send resendRequest with endSeqNo = 0 when logged on', async () => {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, 2)\r\n const factory = experiment.client.config.factory\r\n\r\n const resend = factory?.resendRequest(1, 0)\r\n expect(resend).toBeTruthy()\r\n if (!resend) return\r\n runner.sendMsg(MsgType.ResendRequest, resend)\r\n\r\n const cViews = experiment.client.views\r\n const sViews = experiment.server.views\r\n await runner.wait()\r\n\r\n expect(cViews).toHaveLength(3)\r\n expect(sViews).toHaveLength(3)\r\n\r\n const resendRequestView = sViews[1]\r\n expect(resendRequestView.segment.name).toBe('ResendRequest')\r\n expect(resendRequestView.getTyped('MsgSeqNum')).toBe(2)\r\n expect(resendRequestView.getTyped('BeginSeqNo')).toBe(1)\r\n expect(resendRequestView.getTyped('EndSeqNo')).toBe(0)\r\n\r\n const seqResetView = cViews[1]\r\n expect(seqResetView.segment.name).toBe('SequenceReset')\r\n expect(seqResetView.getTyped('MsgSeqNum')).toBe(1)\r\n expect(seqResetView.getTyped('NewSeqNo')).toBe(2)\r\n expect(seqResetView.getTyped('GapFillFlag')).toBe(true)\r\n expect(seqResetView.getTyped('PossDupFlag')).toBe(true)\r\n\r\n const logoutSView = sViews[2]\r\n expect(logoutSView.segment.name).toBe('Logout')\r\n expect(logoutSView.getTyped('MsgSeqNum')).toBe(3)\r\n\r\n const logoutCView = cViews[2]\r\n expect(logoutCView.segment.name).toBe('Logout')\r\n expect(logoutCView.getTyped('MsgSeqNum')).toBe(2)\r\n\r\n const clientResets = countOfType('SequenceReset', cViews)\r\n const serverResets = countOfType('SequenceReset', sViews)\r\n expect(clientResets).toEqual(1)\r\n expect(serverResets).toEqual(0)\r\n})\r\n\r\ntest('session send logon when logged on', async () => {\r\n const runner: SkeletonRunner = new SkeletonRunner(experiment, 2)\r\n const logon = experiment?.client?.config?.factory?.logon()\r\n expect(logon).toBeTruthy()\r\n if (!logon) return\r\n runner.sendMsg(MsgType.Logon, logon)\r\n try {\r\n await runner.wait()\r\n } catch (e) {\r\n expect(experiment.server.errors.length).toEqual(1)\r\n }\r\n})\r\n\r\ntest('session logon / logout', async () => {\r\n await runSkeletons()\r\n const cViews = experiment.client.views\r\n const sViews = experiment.server.views\r\n\r\n expect(experiment.client.errors.length).toEqual(0)\r\n expect(experiment.server.errors.length).toEqual(0)\r\n\r\n // both sides should now have logged on and logged off\r\n expect(cViews.length).toEqual(2)\r\n expect(sViews.length).toEqual(2)\r\n\r\n expect(cViews[0].segment.name).toEqual('Logon')\r\n expect(cViews[1].segment.name).toEqual('Logout')\r\n\r\n expect(sViews[0].segment.name).toEqual('Logon')\r\n expect(sViews[1].segment.name).toEqual('Logout')\r\n})\r\n\r\nfunction checkSeqNos (views: MsgView[]): void {\r\n const seqNo: number[] = views.map((v: MsgView) => (v.getView('StandardHeader')?.toObject() as IStandardHeader)?.MsgSeqNum)\r\n expect(seqNo).toBeTruthy()\r\n const delta = seqNo.reduce((c: number, latest: number) => {\r\n return latest - c === 1 ? c + 1 : c - 1\r\n }, 0)\r\n expect(delta).toEqual(seqNo.length)\r\n}\r\n\r\ntest('seq No OK', async () => {\r\n await runSkeletons()\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(cviews.length >= 2).toEqual(true)\r\n expect(sviews.length >= 2).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n})\r\n\r\nfunction mutateSeqNo (_: ISessionDescription, type: string, o: ILooseObject): ILooseObject {\r\n switch (type) {\r\n case 'StandardHeader': {\r\n const hdr = o as IStandardHeader\r\n if (hdr.MsgSeqNum === 2) {\r\n hdr.MsgSeqNum = 0\r\n }\r\n break\r\n }\r\n }\r\n return o\r\n}\r\n\r\ntest('out of seq logout', async () => {\r\n experiment.clientFactory.mutator = mutateSeqNo\r\n await runSkeletons()\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on but out of seq logout will terminate sessions so no logout returned\r\n expect(cviews.length).toEqual(1)\r\n expect(cviews[0].segment.name).toEqual('Logon')\r\n expect(sviews.length).toEqual(2)\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n expect(sviews[1].segment.name).toEqual('Logout')\r\n})\r\n\r\nfunction countOfType (type: string, views: MsgView[]): number {\r\n return views.reduce((c: number, v: MsgView) => {\r\n return v.segment.name === type ? c + 1 : c\r\n }, 0)\r\n}\r\n\r\nfunction mutateRemoveRequiredHeartBtInt (_: ISessionDescription, type: string, o: ILooseObject): ILooseObject {\r\n switch (type) {\r\n case 'A': {\r\n const logon = o as ILogon\r\n // @ts-expect-error - this is for test purposed\r\n delete logon.HeartBtInt\r\n break\r\n }\r\n }\r\n return o\r\n}\r\n\r\ntest('client logon reject missing 108', async () => {\r\n experiment.clientFactory.mutator = mutateRemoveRequiredHeartBtInt\r\n await runSkeletons(2)\r\n // client sends logon, server rejects\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n expect(cviews.length === 1).toEqual(true)\r\n expect(sviews.length === 1).toEqual(true)\r\n expect(cviews[0].segment.name).toEqual('Reject')\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n const reject: IReject = cviews[0].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.RequiredTagMissing)\r\n expect(reject.Text).toEqual('msgType A missing required tag 108')\r\n}, 10000)\r\n\r\n// transport.transmitter\r\n\r\nasync function runCheckReject (experiment: Experiment, changed: string): Promise<void> {\r\n await runSkeletons(2, changed)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // client sends logon, server rejects\r\n expect(cviews.length).toEqual(3)\r\n expect(sviews.length).toEqual(3)\r\n expect(cviews[0].segment.name).toEqual('Logon')\r\n expect(cviews[1].segment.name).toEqual('Reject')\r\n expect(sviews[0].segment.name).toEqual('Logon')\r\n}\r\n\r\ntest('client unknown msg type', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = logonMsg\r\n .replace('35=A', '35=ZZ')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('unknown')\r\n const reject: IReject = cviews[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.InvalidMsgType)\r\n expect(reject.Text).toEqual('msgType ZZ unknown')\r\n}, 10000)\r\n\r\ntest('heartbeat invalid tag', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = heartbeat\r\n .replace('112=', '999=')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n await runSkeletons(2, changed)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('Heartbeat')\r\n const reject: IReject = experiment.client.views[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.InvalidTagNumber)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n}, 10000)\r\n\r\ntest('heartbeat invalid sender comp', async () => {\r\n const at = experiment.client.transport.transmitter as AsciiMsgTransmitter\r\n const changed = heartbeat\r\n .replace('49=init-comp', '49=init-not!')\r\n .replace('34=1', `34=${at.msgSeqNum + 1}`)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n await runCheckReject(experiment, changed)\r\n expect(sviews[1].segment.name).toEqual('Heartbeat')\r\n const reject: IReject = cviews[1].toObject() as IReject\r\n expect(reject.SessionRejectReason === SessionRejectReason.CompIDProblem)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n}, 10000)\r\n\r\n// client will send heartbeats to server, server with 30 second heartbeat will not heartbeat\r\ntest('client heartbeats to server', async () => {\r\n const preset = experiment.client.config.description.HeartBtInt\r\n experiment.client.config.description.HeartBtInt = 2\r\n await runSkeletons(6)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(cviews.length === 2).toEqual(true)\r\n expect(sviews.length > 2).toEqual(true)\r\n const serverReceivesHeartbeats = countOfType('Heartbeat', sviews)\r\n expect(serverReceivesHeartbeats >= 2 && serverReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.client.config.description.HeartBtInt = preset\r\n}, 10000)\r\n\r\ntest('server heartbeats to client', async () => {\r\n const preset = experiment.server.config.description.HeartBtInt\r\n experiment.server.config.description.HeartBtInt = 2\r\n await runSkeletons(6)\r\n // both sides should now have logged on and logged off\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n expect(sviews.length === 2).toEqual(true)\r\n expect(cviews.length > 2).toEqual(true)\r\n const clientReceivesHeartbeats = countOfType('Heartbeat', cviews)\r\n expect(clientReceivesHeartbeats >= 2 && clientReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.server.config.description.HeartBtInt = preset\r\n}, 10000)\r\n\r\ntest('client server heartbeat', async () => {\r\n const preset = experiment.server.config.description.HeartBtInt\r\n experiment.server.config.description.HeartBtInt = 5\r\n experiment.client.config.description.HeartBtInt = 2\r\n await runSkeletons(8)\r\n const cviews = experiment.client.views\r\n const sviews = experiment.server.views\r\n // both sides should now have logged on and logged off\r\n expect(sviews.length > 2).toEqual(true)\r\n expect(cviews.length > 2).toEqual(true)\r\n const clientReceivesHeartbeats = countOfType('Heartbeat', cviews)\r\n const clientReceivesTestRequest = countOfType('TestRequest', cviews)\r\n const clientTotal = clientReceivesHeartbeats + clientReceivesTestRequest\r\n const serverReceivesHeartbeats = countOfType('Heartbeat', sviews)\r\n const serverReceivesTestRequest = countOfType('TestRequest', sviews)\r\n const serverTotal = serverReceivesHeartbeats + serverReceivesTestRequest\r\n expect(clientTotal >= 1 && clientReceivesHeartbeats <= 4).toEqual(true)\r\n expect(serverTotal >= 3 && serverReceivesHeartbeats <= 4).toEqual(true)\r\n checkSeqNos(cviews)\r\n checkSeqNos(sviews)\r\n experiment.server.config.description.HeartBtInt = preset\r\n experiment.client.config.description.HeartBtInt = preset\r\n}, 15000)\r\n"]}
@@ -137,7 +137,10 @@ class AsciiSession extends fix_session_1.FixSession {
137
137
  }
138
138
  onResendRequest(view) {
139
139
  this.setState(tcp_1.SessionState.HandleResendRequest);
140
- const [beginSeqNo, endSeqNo] = view.getTypedTags([types_1.MsgTag.BeginSeqNo, types_1.MsgTag.EndSeqNo]);
140
+ const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([types_1.MsgTag.BeginSeqNo, types_1.MsgTag.EndSeqNo]);
141
+ const endSeqNo = requestedEndSeqNo === 0
142
+ ? this.sessionState.lastSentSeqNum()
143
+ : requestedEndSeqNo;
141
144
  this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`);
142
145
  this.resender.getResendRequest(beginSeqNo, endSeqNo).then((records) => {
143
146
  const validRecords = records.filter(rec => rec.obj !== null);
@@ -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'\r\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\r\nimport { IJsFixConfig } from '../../config'\r\nimport { FixSession } from '../session/fix-session'\r\nimport { FixMsgAsciiStoreResend, FixMsgMemoryStore, IFixMsgStore, IFixMsgStoreRecord } from '../../store'\r\nimport { SessionState } from '../tcp'\r\nimport { TickAction } from '../tick-action'\r\nimport { IMsgApplication } from '../msg-application'\r\nimport { SegmentType } from '../../buffer/segment/segment-type'\r\n\r\nexport abstract class AsciiSession extends FixSession {\r\n public heartbeat: boolean = true\r\n protected store: IFixMsgStore | null = null\r\n protected resender: FixMsgAsciiStoreResend\r\n\r\n protected constructor (public readonly config: IJsFixConfig) {\r\n super(config)\r\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\r\n this.requestLogonType = MsgType.Logon\r\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\r\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\r\n }\r\n\r\n private checkSeqNo (msgType: string, view: MsgView): boolean {\r\n switch (msgType) {\r\n case MsgType.SequenceReset: {\r\n return true\r\n }\r\n\r\n default: {\r\n const state = this.sessionState\r\n const lastSeq: number = state.lastPeerMsgSeqNum\r\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum)\r\n let ret: boolean = false\r\n const seqDelta: number = seqNo - lastSeq\r\n if (seqDelta <= 0) {\r\n // serious problem ... drop immediately\r\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\r\n this.stop()\r\n } else if (seqDelta > 1) {\r\n // resend request required as have missed messages.\r\n\r\n // We process a Logon beforehand to confirm the connection even we out of sync\r\n if (msgType === MsgType.Logon) {\r\n this.peerLogon(view)\r\n }\r\n // If the out of sync message is a resend request itself, then we handle it first in order\r\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\r\n if (msgType === MsgType.ResendRequest) {\r\n this.onResendRequest(view)\r\n }\r\n this.sendResendRequest(lastSeq, seqNo)\r\n } else {\r\n ret = true\r\n state.lastPeerMsgSeqNum = seqNo\r\n }\r\n return ret\r\n }\r\n }\r\n }\r\n\r\n protected checkForwardMsg (msgType: string, view: MsgView): void {\r\n const okToForward = this.validStateApplicationMsg()\r\n if (okToForward) {\r\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\r\n this.setState(SessionState.ActiveNormalSession)\r\n this.onApplicationMsg(msgType, view)\r\n } else {\r\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\r\n }\r\n }\r\n\r\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\r\n const factory = this.config.factory\r\n const reject = factory?.reject(msgType, seqNo, msg, reason)\r\n if (reject) {\r\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\r\n this.send(MsgType.Reject, reject)\r\n }\r\n }\r\n\r\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\r\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\r\n if (resend) {\r\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\r\n this.send(MsgType.ResendRequest, resend)\r\n }\r\n }\r\n\r\n private checkIntegrity (msgType: string, view: MsgView): boolean {\r\n const state = this.sessionState\r\n const seqNum = view.getTyped(MsgTag.MsgSeqNum)\r\n\r\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\r\n const computed = view.checksum()\r\n if (received !== computed) {\r\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\r\n return false\r\n }\r\n\r\n if (view.segment.type === SegmentType.Unknown) {\r\n const msg: string = `msgType ${msgType} unknown`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\r\n return false\r\n }\r\n\r\n const invalid = view.invalid()\r\n if (invalid.length > 0) {\r\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\r\n return false\r\n }\r\n\r\n const undefinedMsg: string | null = view.undefinedForMsg()\r\n if (undefinedMsg) {\r\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\r\n return false\r\n }\r\n\r\n const missingRequired = view.missing()\r\n if (missingRequired.length > 0) {\r\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\r\n return false\r\n }\r\n\r\n switch (state.state) {\r\n case SessionState.InitiationLogonReceived:\r\n case SessionState.InitiationLogonResponse: {\r\n const targetCompId = view.getString(MsgTag.TargetCompID)\r\n if (targetCompId !== state.compId) {\r\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\r\n return false\r\n }\r\n\r\n const peerCompId = view.getString(MsgTag.SenderCompID)\r\n if (peerCompId !== state.peerCompId) {\r\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\r\n return false\r\n }\r\n }\r\n break\r\n\r\n default: {\r\n break\r\n }\r\n }\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * Override to resend stored messages following a sequence reset.\r\n * @protected\r\n */\r\n protected onResendRequest (view: MsgView): void {\r\n // if no records are in store then send a gap fill for entire sequence\r\n this.setState(SessionState.HandleResendRequest)\r\n const [beginSeqNo, endSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\r\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\r\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\r\n const validRecords = records.filter(rec => rec.obj !== null)\r\n this.sessionLogger.info(`sending ${validRecords.length}`)\r\n validRecords.forEach(rec => {\r\n if (rec.obj) {\r\n this.send(rec.msgType, rec.obj)\r\n }\r\n })\r\n this.setState(SessionState.ActiveNormalSession)\r\n }).catch(e => {\r\n this.sessionLogger.error(e)\r\n })\r\n }\r\n\r\n okForLogon (): boolean {\r\n const state = this.sessionState.state\r\n if (this.acceptor) {\r\n return state === SessionState.WaitingForALogon\r\n }\r\n return state === SessionState.InitiationLogonSent\r\n }\r\n\r\n protected onSessionMsg (msgType: string, view: MsgView): void {\r\n const logger = this.sessionLogger\r\n\r\n switch (msgType) {\r\n case MsgType.Logon: {\r\n // only valid to receive a logon when in LogonSent or WaitingALogon\r\n // else will drop connection immediately.\r\n if (this.okForLogon()) {\r\n this.peerLogon(view)\r\n } else {\r\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\r\n }\r\n break\r\n }\r\n\r\n case MsgType.Logout: {\r\n this.peerLogout(view)\r\n break\r\n }\r\n\r\n case MsgType.TestRequest: {\r\n const req: string | null = view.getString(MsgTag.TestReqID)\r\n if (req) {\r\n this.sendHeartbeat(req)\r\n }\r\n break\r\n }\r\n\r\n case MsgType.Heartbeat: {\r\n this.sessionState.lastTestRequestAt = null\r\n this.setState(SessionState.ActiveNormalSession)\r\n break\r\n }\r\n\r\n case MsgType.ResendRequest: {\r\n logger.info(`peer sends '${msgType}' resend request.`)\r\n this.onResendRequest(view)\r\n break\r\n }\r\n\r\n case MsgType.SequenceReset: {\r\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo)\r\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\r\n // expect newSeqNo to be the next message's sequence number.\r\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\r\n break\r\n }\r\n\r\n case MsgType.Reject: {\r\n logger.info(`peer rejects type '${msgType}' with text '${view.getTyped(MsgTag.Text)}'`)\r\n break\r\n }\r\n }\r\n }\r\n\r\n protected onMsg (msgType: string, view: MsgView): void {\r\n if (!this.checkSeqNo(msgType, view)) {\r\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\r\n return\r\n }\r\n\r\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\r\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\r\n switch (msgType) {\r\n case MsgType.Logon: {\r\n this.setState(SessionState.PeerLogonRejected)\r\n this.startTimer()\r\n break\r\n }\r\n }\r\n return\r\n }\r\n\r\n switch (msgType) {\r\n case MsgType.Logon:\r\n case MsgType.Logout:\r\n case MsgType.TestRequest:\r\n case MsgType.Reject:\r\n case MsgType.SequenceReset:\r\n case MsgType.Heartbeat:\r\n case MsgType.ResendRequest: {\r\n this.onSessionMsg(msgType, view)\r\n break\r\n }\r\n\r\n default: {\r\n this.checkForwardMsg(msgType, view)\r\n break\r\n }\r\n }\r\n }\r\n\r\n private startTimer (interval: number = 200): void {\r\n const logger = this.sessionLogger\r\n logger.info(`start heartbeat timer. interval = ${interval}`)\r\n this.timer = setInterval(() => {\r\n this.tick()\r\n }, interval)\r\n }\r\n\r\n private peerLogon (view: MsgView): void {\r\n const logger = this.sessionLogger\r\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\r\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, userName = ${userName}`)\r\n const state = this.sessionState\r\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt)\r\n state.peerCompId = view.getTyped(MsgTag.SenderCompID)\r\n const res = this.onLogon(view, userName as string, password as string)\r\n // currently not using this.\r\n logger.info(`peerLogon onLogon returns ${res}`)\r\n if (this.acceptor) {\r\n this.setState(SessionState.InitiationLogonResponse)\r\n logger.info('acceptor responds to logon request')\r\n this.sendLogon() // if res send response else reject, terminate\r\n } else { // as an initiator the acceptor has responded\r\n logger.info('initiator receives logon response')\r\n this.setState(SessionState.InitiationLogonReceived)\r\n }\r\n if (this.heartbeat) {\r\n this.startTimer()\r\n }\r\n logger.info('system ready, inform app')\r\n this.onReady(view)\r\n }\r\n\r\n private sendTestRequest (): void {\r\n const factory = this.config.factory\r\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\r\n const tr = factory?.testRequest()\r\n if (tr) {\r\n this.send(MsgType.TestRequest, tr)\r\n }\r\n }\r\n\r\n private sendHeartbeat (testReqId: string): void {\r\n const factory = this.config.factory\r\n const hb = factory?.heartbeat(testReqId)\r\n if (hb) {\r\n this.send(MsgType.Heartbeat, hb)\r\n }\r\n }\r\n\r\n private tick (): void {\r\n if (!this.transport) return\r\n const sessionState = this.sessionState\r\n const action: TickAction = sessionState.calcAction(new Date())\r\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\r\n const logger = this.sessionLogger\r\n\r\n switch (action) {\r\n case TickAction.Nothing: {\r\n // all is well\r\n break\r\n }\r\n\r\n case TickAction.TestRequest: {\r\n logger.debug(`send test req. state = ${sessionState.toString()}`)\r\n this.sendTestRequest()\r\n break\r\n }\r\n\r\n case TickAction.Heartbeat: {\r\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\r\n this.sendHeartbeat(sessionState.now.toUTCString())\r\n break\r\n }\r\n\r\n case TickAction.TerminateOnError: {\r\n logger.info(sessionState.toString())\r\n this.terminate(new Error(`${application?.name}: peer not responding`))\r\n break\r\n }\r\n\r\n case TickAction.Stop: {\r\n logger.info(sessionState.toString())\r\n logger.info('stopping')\r\n this.stop()\r\n break\r\n }\r\n\r\n default:\r\n throw new Error('unexpected action')\r\n }\r\n }\r\n}\r\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'\r\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\r\nimport { IJsFixConfig } from '../../config'\r\nimport { FixSession } from '../session/fix-session'\r\nimport { FixMsgAsciiStoreResend, FixMsgMemoryStore, IFixMsgStore, IFixMsgStoreRecord } from '../../store'\r\nimport { SessionState } from '../tcp'\r\nimport { TickAction } from '../tick-action'\r\nimport { IMsgApplication } from '../msg-application'\r\nimport { SegmentType } from '../../buffer/segment/segment-type'\r\n\r\nexport abstract class AsciiSession extends FixSession {\r\n public heartbeat: boolean = true\r\n protected store: IFixMsgStore | null = null\r\n protected resender: FixMsgAsciiStoreResend\r\n\r\n protected constructor (public readonly config: IJsFixConfig) {\r\n super(config)\r\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\r\n this.requestLogonType = MsgType.Logon\r\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\r\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\r\n }\r\n\r\n private checkSeqNo (msgType: string, view: MsgView): boolean {\r\n switch (msgType) {\r\n case MsgType.SequenceReset: {\r\n return true\r\n }\r\n\r\n default: {\r\n const state = this.sessionState\r\n const lastSeq: number = state.lastPeerMsgSeqNum\r\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum)\r\n let ret: boolean = false\r\n const seqDelta: number = seqNo - lastSeq\r\n if (seqDelta <= 0) {\r\n // serious problem ... drop immediately\r\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\r\n this.stop()\r\n } else if (seqDelta > 1) {\r\n // resend request required as have missed messages.\r\n\r\n // We process a Logon beforehand to confirm the connection even we out of sync\r\n if (msgType === MsgType.Logon) {\r\n this.peerLogon(view)\r\n }\r\n // If the out of sync message is a resend request itself, then we handle it first in order\r\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\r\n if (msgType === MsgType.ResendRequest) {\r\n this.onResendRequest(view)\r\n }\r\n this.sendResendRequest(lastSeq, seqNo)\r\n } else {\r\n ret = true\r\n state.lastPeerMsgSeqNum = seqNo\r\n }\r\n return ret\r\n }\r\n }\r\n }\r\n\r\n protected checkForwardMsg (msgType: string, view: MsgView): void {\r\n const okToForward = this.validStateApplicationMsg()\r\n if (okToForward) {\r\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\r\n this.setState(SessionState.ActiveNormalSession)\r\n this.onApplicationMsg(msgType, view)\r\n } else {\r\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\r\n }\r\n }\r\n\r\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\r\n const factory = this.config.factory\r\n const reject = factory?.reject(msgType, seqNo, msg, reason)\r\n if (reject) {\r\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\r\n this.send(MsgType.Reject, reject)\r\n }\r\n }\r\n\r\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\r\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\r\n if (resend) {\r\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\r\n this.send(MsgType.ResendRequest, resend)\r\n }\r\n }\r\n\r\n private checkIntegrity (msgType: string, view: MsgView): boolean {\r\n const state = this.sessionState\r\n const seqNum = view.getTyped(MsgTag.MsgSeqNum)\r\n\r\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\r\n const computed = view.checksum()\r\n if (received !== computed) {\r\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\r\n return false\r\n }\r\n\r\n if (view.segment.type === SegmentType.Unknown) {\r\n const msg: string = `msgType ${msgType} unknown`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\r\n return false\r\n }\r\n\r\n const invalid = view.invalid()\r\n if (invalid.length > 0) {\r\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\r\n return false\r\n }\r\n\r\n const undefinedMsg: string | null = view.undefinedForMsg()\r\n if (undefinedMsg) {\r\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\r\n return false\r\n }\r\n\r\n const missingRequired = view.missing()\r\n if (missingRequired.length > 0) {\r\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\r\n return false\r\n }\r\n\r\n switch (state.state) {\r\n case SessionState.InitiationLogonReceived:\r\n case SessionState.InitiationLogonResponse: {\r\n const targetCompId = view.getString(MsgTag.TargetCompID)\r\n if (targetCompId !== state.compId) {\r\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\r\n return false\r\n }\r\n\r\n const peerCompId = view.getString(MsgTag.SenderCompID)\r\n if (peerCompId !== state.peerCompId) {\r\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\r\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\r\n return false\r\n }\r\n }\r\n break\r\n\r\n default: {\r\n break\r\n }\r\n }\r\n\r\n return true\r\n }\r\n\r\n /**\r\n * Override to resend stored messages following a sequence reset.\r\n * @protected\r\n */\r\n protected onResendRequest (view: MsgView): void {\r\n // if no records are in store then send a gap fill for entire sequence\r\n this.setState(SessionState.HandleResendRequest)\r\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\r\n const endSeqNo = requestedEndSeqNo === 0\r\n ? this.sessionState.lastSentSeqNum()\r\n : requestedEndSeqNo\r\n\r\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\r\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\r\n const validRecords = records.filter(rec => rec.obj !== null)\r\n this.sessionLogger.info(`sending ${validRecords.length}`)\r\n validRecords.forEach(rec => {\r\n if (rec.obj) {\r\n this.send(rec.msgType, rec.obj)\r\n }\r\n })\r\n this.setState(SessionState.ActiveNormalSession)\r\n }).catch(e => {\r\n this.sessionLogger.error(e)\r\n })\r\n }\r\n\r\n okForLogon (): boolean {\r\n const state = this.sessionState.state\r\n if (this.acceptor) {\r\n return state === SessionState.WaitingForALogon\r\n }\r\n return state === SessionState.InitiationLogonSent\r\n }\r\n\r\n protected onSessionMsg (msgType: string, view: MsgView): void {\r\n const logger = this.sessionLogger\r\n\r\n switch (msgType) {\r\n case MsgType.Logon: {\r\n // only valid to receive a logon when in LogonSent or WaitingALogon\r\n // else will drop connection immediately.\r\n if (this.okForLogon()) {\r\n this.peerLogon(view)\r\n } else {\r\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\r\n }\r\n break\r\n }\r\n\r\n case MsgType.Logout: {\r\n this.peerLogout(view)\r\n break\r\n }\r\n\r\n case MsgType.TestRequest: {\r\n const req: string | null = view.getString(MsgTag.TestReqID)\r\n if (req) {\r\n this.sendHeartbeat(req)\r\n }\r\n break\r\n }\r\n\r\n case MsgType.Heartbeat: {\r\n this.sessionState.lastTestRequestAt = null\r\n this.setState(SessionState.ActiveNormalSession)\r\n break\r\n }\r\n\r\n case MsgType.ResendRequest: {\r\n logger.info(`peer sends '${msgType}' resend request.`)\r\n this.onResendRequest(view)\r\n break\r\n }\r\n\r\n case MsgType.SequenceReset: {\r\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo)\r\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\r\n // expect newSeqNo to be the next message's sequence number.\r\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\r\n break\r\n }\r\n\r\n case MsgType.Reject: {\r\n logger.info(`peer rejects type '${msgType}' with text '${view.getTyped(MsgTag.Text)}'`)\r\n break\r\n }\r\n }\r\n }\r\n\r\n protected onMsg (msgType: string, view: MsgView): void {\r\n if (!this.checkSeqNo(msgType, view)) {\r\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\r\n return\r\n }\r\n\r\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\r\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\r\n switch (msgType) {\r\n case MsgType.Logon: {\r\n this.setState(SessionState.PeerLogonRejected)\r\n this.startTimer()\r\n break\r\n }\r\n }\r\n return\r\n }\r\n\r\n switch (msgType) {\r\n case MsgType.Logon:\r\n case MsgType.Logout:\r\n case MsgType.TestRequest:\r\n case MsgType.Reject:\r\n case MsgType.SequenceReset:\r\n case MsgType.Heartbeat:\r\n case MsgType.ResendRequest: {\r\n this.onSessionMsg(msgType, view)\r\n break\r\n }\r\n\r\n default: {\r\n this.checkForwardMsg(msgType, view)\r\n break\r\n }\r\n }\r\n }\r\n\r\n private startTimer (interval: number = 200): void {\r\n const logger = this.sessionLogger\r\n logger.info(`start heartbeat timer. interval = ${interval}`)\r\n this.timer = setInterval(() => {\r\n this.tick()\r\n }, interval)\r\n }\r\n\r\n private peerLogon (view: MsgView): void {\r\n const logger = this.sessionLogger\r\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\r\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, userName = ${userName}`)\r\n const state = this.sessionState\r\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt)\r\n state.peerCompId = view.getTyped(MsgTag.SenderCompID)\r\n const res = this.onLogon(view, userName as string, password as string)\r\n // currently not using this.\r\n logger.info(`peerLogon onLogon returns ${res}`)\r\n if (this.acceptor) {\r\n this.setState(SessionState.InitiationLogonResponse)\r\n logger.info('acceptor responds to logon request')\r\n this.sendLogon() // if res send response else reject, terminate\r\n } else { // as an initiator the acceptor has responded\r\n logger.info('initiator receives logon response')\r\n this.setState(SessionState.InitiationLogonReceived)\r\n }\r\n if (this.heartbeat) {\r\n this.startTimer()\r\n }\r\n logger.info('system ready, inform app')\r\n this.onReady(view)\r\n }\r\n\r\n private sendTestRequest (): void {\r\n const factory = this.config.factory\r\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\r\n const tr = factory?.testRequest()\r\n if (tr) {\r\n this.send(MsgType.TestRequest, tr)\r\n }\r\n }\r\n\r\n private sendHeartbeat (testReqId: string): void {\r\n const factory = this.config.factory\r\n const hb = factory?.heartbeat(testReqId)\r\n if (hb) {\r\n this.send(MsgType.Heartbeat, hb)\r\n }\r\n }\r\n\r\n private tick (): void {\r\n if (!this.transport) return\r\n const sessionState = this.sessionState\r\n const action: TickAction = sessionState.calcAction(new Date())\r\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\r\n const logger = this.sessionLogger\r\n\r\n switch (action) {\r\n case TickAction.Nothing: {\r\n // all is well\r\n break\r\n }\r\n\r\n case TickAction.TestRequest: {\r\n logger.debug(`send test req. state = ${sessionState.toString()}`)\r\n this.sendTestRequest()\r\n break\r\n }\r\n\r\n case TickAction.Heartbeat: {\r\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\r\n this.sendHeartbeat(sessionState.now.toUTCString())\r\n break\r\n }\r\n\r\n case TickAction.TerminateOnError: {\r\n logger.info(sessionState.toString())\r\n this.terminate(new Error(`${application?.name}: peer not responding`))\r\n break\r\n }\r\n\r\n case TickAction.Stop: {\r\n logger.info(sessionState.toString())\r\n logger.info('stopping')\r\n this.stop()\r\n break\r\n }\r\n\r\n default:\r\n throw new Error('unexpected action')\r\n }\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspurefix",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "pure node js fix engine",
5
5
  "keywords": [
6
6
  "typescript",
@@ -75,15 +75,15 @@
75
75
  "license": "MIT",
76
76
  "dependencies": {
77
77
  "align-text": "^1.0.2",
78
- "axios": "^1.6.2",
78
+ "axios": "^1.6.5",
79
79
  "express": "^4.18.2",
80
80
  "lodash": "^4.17.21",
81
- "mathjs": "^12.1.0",
81
+ "mathjs": "^12.3.0",
82
82
  "minimist": "^1.2.8",
83
83
  "minimist-options": "^4.1.0",
84
- "moment": "^2.29.4",
84
+ "moment": "^2.30.1",
85
85
  "node-fs-extra": "^0.8.2",
86
- "reflect-metadata": "^0.1.13",
86
+ "reflect-metadata": "^0.2.1",
87
87
  "sax": "^1.3.0",
88
88
  "tsyringe": "^4.8.0",
89
89
  "uuid": "^9.0.1",
@@ -94,23 +94,23 @@
94
94
  "devDependencies": {
95
95
  "@types/express": "^4.17.21",
96
96
  "@types/express-serve-static-core": "^4.17.41",
97
- "@types/jest": "^29.5.10",
97
+ "@types/jest": "^29.5.11",
98
98
  "@types/lodash": "^4.14.202",
99
99
  "@types/mathjs": "^9.4.1",
100
100
  "@types/minimist": "^1.2.5",
101
- "@types/node": "^20.10.1",
101
+ "@types/node": "^20.11.5",
102
102
  "@types/request-promise-native": "^1.0.21",
103
103
  "@types/sax": "^1.2.7",
104
104
  "@types/uuid": "^9.0.7",
105
105
  "@types/winston": "^2.4.4",
106
- "@typescript-eslint/eslint-plugin": "^6.13.1",
107
- "@typescript-eslint/parser": "^6.13.1",
108
- "eslint": "^8.54.0",
109
- "eslint-config-standard-with-typescript": "^40.0.0",
106
+ "@typescript-eslint/eslint-plugin": "^6.19.0",
107
+ "@typescript-eslint/parser": "^6.19.0",
108
+ "eslint": "^8.56.0",
109
+ "eslint-config-standard-with-typescript": "^43.0.1",
110
110
  "jest": "^29.7.0",
111
111
  "madge": "^6.1.0",
112
112
  "standard": "^17.1.0",
113
113
  "ts-jest": "^29.1.1",
114
- "typescript": "^5.3.2"
114
+ "typescript": "^5.3.3"
115
115
  }
116
116
  }
@@ -28,9 +28,15 @@ export class FixMsgAsciiStoreResend {
28
28
 
29
29
  private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {
30
30
  const toResend: IFixMsgStoreRecord[] = []
31
+ // If no records for this given sequence number range, returns a single gap fill
32
+ if (input.length === 0) {
33
+ this.gap(startSeq, endSeq + 1, toResend)
34
+ return toResend
35
+ }
36
+
31
37
  let expected = startSeq
32
38
  for (let i = 0; i < input.length; ++i) {
33
- const record = input[i].clone()
39
+ const record = this.prepareRecordForRetransmission(input[i])
34
40
  const seqNum = record.seqNum
35
41
  const toGap = seqNum - expected
36
42
  if (toGap > 0) {
@@ -48,16 +54,16 @@ export class FixMsgAsciiStoreResend {
48
54
  return toResend
49
55
  }
50
56
 
51
- public gap (beginGap: number, seqNum: number, arr: IFixMsgStoreRecord[]): void {
57
+ private gap (beginGap: number, newSeq: number, arr: IFixMsgStoreRecord[]): void {
52
58
  if (beginGap > 0) {
53
- arr.push(this.sequenceResetGap(beginGap, seqNum))
59
+ arr.push(this.sequenceResetGap(beginGap, newSeq))
54
60
  }
55
61
  }
56
62
 
57
63
  // if records were sent as encoded text then inflate back to object
58
64
  // so can be resent or examined
59
65
 
60
- public inflate (record: IFixMsgStoreRecord): void {
66
+ private inflate (record: IFixMsgStoreRecord): void {
61
67
  if (record.obj) return
62
68
  if (!record.encoded) return
63
69
  const parser = this.parser
@@ -71,17 +77,67 @@ export class FixMsgAsciiStoreResend {
71
77
  parser.parseText(record.encoded)
72
78
  }
73
79
 
74
- public sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {
80
+ /**
81
+ * A continuous sequence of messages not being retransmitted should be skipped over using a
82
+ * single SequenceReset(35=4) message with GapFillFlag(123) set to “Y” and MsgSeqNum(34) set
83
+ * to the sequence number of the first skipped message and NewSeqNo(36) must always be set
84
+ * to the value of the next sequence number to be expected by the peer immediately following
85
+ * the messages being skipped.
86
+ */
87
+ private sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {
75
88
  const factory = this.config.factory
76
89
  const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset
77
90
  gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap) as IStandardHeader
78
91
  gapFill.StandardHeader.PossDupFlag = true
79
- gapFill.NewSeqNo = newSeq
92
+
80
93
  return new FixMsgStoreRecord(
81
94
  MsgType.SequenceReset,
82
95
  new Date(),
83
- newSeq,
96
+ startGap,
84
97
  gapFill,
85
- null)
98
+ null,
99
+ )
100
+ }
101
+
102
+ /**
103
+ * Prepares the FIX message as response to ResendRequest (2).
104
+ *
105
+ * The FIX session processor retransmitting a message with the PossDupFlag(43) set to "Y" must modify the following fields:
106
+ *
107
+ * SendingTime(52) set to the current sending time
108
+ * OrigSendingTime(122) set to the SendingTime(52) from the original message
109
+ * Recalculate the BodyLength(9)
110
+ * Recalculate the CheckSum(10)
111
+ *
112
+ * If the message is encrypted, SecureDataLen(90) and SecureData(91) may also require re-encryption and re-encoding
113
+ *
114
+ * @see https://www.fixtrading.org/standards/fix-session-layer-online/#message-recovery
115
+ *
116
+ * @param originalRecord the FIX message to be retransmitted as possible duplicate
117
+ * @returns the FIX message ready to be retransmitted
118
+ */
119
+ private prepareRecordForRetransmission (originalRecord: IFixMsgStoreRecord): IFixMsgStoreRecord {
120
+ const retransmitted = originalRecord.clone() // We don't want to accidently change any fields of the original record
121
+
122
+ const factory = this.config.factory
123
+ if (!retransmitted.obj) {
124
+ retransmitted.obj = {}
125
+ }
126
+
127
+ // Rebuilds header with the updated fields
128
+ const header = factory?.header(
129
+ retransmitted.msgType,
130
+ retransmitted.seqNum,
131
+ new Date(), // SendingTime(52)
132
+ {
133
+ PossDupFlag: true,
134
+ OrigSendingTime: retransmitted.timestamp
135
+ }
136
+ )
137
+ retransmitted.obj = {
138
+ ...retransmitted.obj,
139
+ StandardHeader: header
140
+ }
141
+ return retransmitted
86
142
  }
87
143
  }
@@ -160,7 +160,11 @@ export abstract class AsciiSession extends FixSession {
160
160
  protected onResendRequest (view: MsgView): void {
161
161
  // if no records are in store then send a gap fill for entire sequence
162
162
  this.setState(SessionState.HandleResendRequest)
163
- const [beginSeqNo, endSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])
163
+ const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])
164
+ const endSeqNo = requestedEndSeqNo === 0
165
+ ? this.sessionState.lastSentSeqNum()
166
+ : requestedEndSeqNo
167
+
164
168
  this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)
165
169
  this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {
166
170
  const validRecords = records.filter(rec => rec.obj !== null)