jspurefix 5.5.4 → 5.6.1

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.
@@ -3,6 +3,7 @@ import { IJsFixConfig } from '../../config';
3
3
  import { FixSession } from '../session/fix-session';
4
4
  import { FixMsgAsciiStoreResend, IFixMsgStore, IFixSessionStore, SessionId } from '../../store';
5
5
  import { SessionSequenceCoordinator } from '../session/session-sequence-coordinator';
6
+ import { MsgTransport } from '../factory';
6
7
  import { ILooseObject } from '../../collections/collection';
7
8
  export declare abstract class AsciiSession extends FixSession {
8
9
  readonly config: IJsFixConfig;
@@ -13,6 +14,7 @@ export declare abstract class AsciiSession extends FixSession {
13
14
  protected readonly sessionStore: IFixSessionStore;
14
15
  protected readonly sessionId: SessionId;
15
16
  protected constructor(config: IJsFixConfig);
17
+ run(transport: MsgTransport): Promise<number>;
16
18
  private checkSeqNo;
17
19
  protected checkForwardMsg(msgType: string, view: MsgView): void;
18
20
  private sendReject;
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.AsciiSession = void 0;
4
13
  const types_1 = require("../../types");
@@ -29,6 +38,23 @@ class AsciiSession extends fix_session_1.FixSession {
29
38
  const lastReceivedSeqNum = (_b = config.description.LastReceivedSeqNum) !== null && _b !== void 0 ? _b : 0;
30
39
  this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1);
31
40
  }
41
+ run(transport) {
42
+ const _super = Object.create(null, {
43
+ run: { get: () => super.run }
44
+ });
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ var _a, _b;
47
+ (_a = transport.duplex.readable) === null || _a === void 0 ? void 0 : _a.pause();
48
+ yield this.sessionStore.initialize();
49
+ this.coordinator.initializeFromStore();
50
+ const transmitter = transport.transmitter;
51
+ transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum;
52
+ this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum;
53
+ this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`);
54
+ (_b = transport.duplex.readable) === null || _b === void 0 ? void 0 : _b.resume();
55
+ return yield _super.run.call(this, transport);
56
+ });
57
+ }
32
58
  checkSeqNo(msgType, view) {
33
59
  switch (msgType) {
34
60
  case types_1.MsgType.SequenceReset: {
@@ -93,9 +119,11 @@ class AsciiSession extends fix_session_1.FixSession {
93
119
  break;
94
120
  }
95
121
  }
96
- ret = true;
97
122
  state.lastPeerMsgSeqNum = seqNo;
98
123
  this.coordinator.onMessageReceived(seqNo, false);
124
+ if (msgType !== types_1.MsgType.Logon && msgType !== types_1.MsgType.ResendRequest) {
125
+ ret = true;
126
+ }
99
127
  }
100
128
  else {
101
129
  ret = true;
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected readonly coordinator: SessionSequenceCoordinator\n protected readonly sessionStore: IFixSessionStore\n protected readonly sessionId: SessionId\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // Create session store from factory.\n // Priority: programmatic config > JSON store config > default in-memory\n const storeFactory = config.sessionStoreFactory ?? AsciiSession.createStoreFactory(config.description.store)\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n this.sessionStore = storeFactory.create(this.sessionId)\n\n const clock = new DefaultFixClock()\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true)\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Accept the current message — don't block waiting for gap fill.\n // The gap will be filled by the resend response, but this message is valid.\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo)\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset)\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n const res = this.onLogon(view, userName as string, password as string)\n // currently not using this.\n logger.info(`peerLogon onLogon returns ${res}`)\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && resetSeqNumFlag !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor()\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon() // if res send response else reject, terminate\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,uCAAkE;AAElE,wDAAmD;AACnD,uCAKoB;AACpB,gCAAqC;AACrC,gDAA2C;AAE3C,oEAA+D;AAC/D,0FAAoF;AACpF,oDAAsD;AACtD,8EAAoE;AAKpE,MAAsB,YAAa,SAAQ,wBAAU;IAQnD,YAAuC,MAAoB;;QACzD,KAAK,CAAC,MAAM,CAAC,CAAA;QADwB,WAAM,GAAN,MAAM,CAAc;QAPpD,cAAS,GAAY,IAAI,CAAA;QACtB,UAAK,GAAwB,IAAI,CAAA;QAQzC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,GAAG,eAAO,CAAC,MAAM,CAAA;QAChE,IAAI,CAAC,gBAAgB,GAAG,eAAO,CAAC,KAAK,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,IAAI,yBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACrF,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAInE,MAAM,YAAY,GAAG,MAAA,MAAM,CAAC,mBAAmB,mCAAI,YAAY,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAC5G,IAAI,CAAC,SAAS,GAAG,IAAI,iBAAS,CAC5B,MAAM,CAAC,WAAW,CAAC,WAAW,EAC9B,MAAM,CAAC,WAAW,CAAC,YAAY,EAC/B,MAAM,CAAC,WAAW,CAAC,YAAY,CAChC,CAAA;QACD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAEvD,MAAM,KAAK,GAAG,IAAI,2BAAe,EAAE,CAAA;QACnC,IAAI,CAAC,WAAW,GAAG,IAAI,yDAA0B,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;QAC3E,MAAM,kBAAkB,GAAG,MAAA,MAAM,CAAC,WAAW,CAAC,kBAAkB,mCAAI,CAAC,CAAA;QACrE,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,SAAS,EAAE,kBAAkB,GAAG,CAAC,CAAC,CAAA;IAC1E,CAAC;IAUY,GAAG,CAAE,SAAuB;;;;;;YAKvC,MAAA,SAAS,CAAC,MAAM,CAAC,QAAQ,0CAAE,KAAK,EAAE,CAAA;YAIlC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAA;YAGpC,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAA;YAGtC,MAAM,WAAW,GAAG,SAAS,CAAC,WAAkC,CAAA;YAChE,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAA;YAGzD,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAAA;YAE9E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iCAAiC,IAAI,CAAC,WAAW,CAAC,gBAAgB,oBAAoB,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC,CAAA;YAItJ,MAAA,SAAS,CAAC,MAAM,CAAC,QAAQ,0CAAE,MAAM,EAAE,CAAA;YAEnC,OAAO,MAAM,OAAM,GAAG,YAAC,SAAS,CAAC,CAAA;QACnC,CAAC;KAAA;IAEO,UAAU,CAAE,OAAe,EAAE,IAAa;QAChD,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,eAAO,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC3B,OAAO,IAAI,CAAA;YACb,CAAC;YAED,KAAK,eAAO,CAAC,KAAK,CAAC,CAAC,CAAC;gBAGnB,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE,CAAC;oBACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAA;oBACzF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,SAAS,CAAW,CAAA;oBACvD,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,KAAK,CAAA;oBAC3C,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;oBAChD,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;YAGD,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAA;gBAC/B,MAAM,OAAO,GAAW,KAAK,CAAC,iBAAiB,CAAA;gBAC/C,MAAM,KAAK,GAAW,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,SAAS,CAAW,CAAA;gBAC/D,IAAI,GAAG,GAAY,KAAK,CAAA;gBACxB,MAAM,QAAQ,GAAW,KAAK,GAAG,OAAO,CAAA;gBACxC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;oBAGlB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,WAAW,CAAwB,CAAA;oBAC5E,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;wBACzB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,YAAY,OAAO,+CAA+C,CAAC,CAAA;wBAC5F,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;wBAC/C,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAA;oBAC9D,MAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;oBACvF,IAAI,iBAAiB,EAAE,CAAC;wBACtB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iCAAiC,KAAK,yBAAyB,CAAC,CAAA;wBACxF,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;wBAChD,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,0BAA0B,QAAQ,mBAAmB,OAAO,YAAY,KAAK,EAAE,CAAC,CAAA;oBAC3G,IAAI,CAAC,IAAI,EAAE,CAAA;gBACb,CAAC;qBAAM,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;oBAExB,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,CAAA;oBAG/B,IAAI,OAAO,KAAK,eAAO,CAAC,KAAK,EAAE,CAAC;wBAC9B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;oBACtB,CAAC;oBAGD,IAAI,OAAO,KAAK,eAAO,CAAC,aAAa,EAAE,CAAC;wBACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;oBAC5B,CAAC;oBAGD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;oBACjE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,MAAM,EAAE,CAAC,CAAA;oBAEhD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;wBACpB,KAAK,yCAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC;4BACxC,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;gCAC/C,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;gCACtC,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAA;4BACpE,CAAC;4BACD,MAAK;wBACP,CAAC;wBACD,KAAK,yCAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;4BAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,wCAAwC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;4BAChF,MAAK;wBACP,CAAC;wBACD,KAAK,yCAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;4BAClC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,8CAA8C,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;4BACzF,MAAK;wBACP,CAAC;oBACH,CAAC;oBAGD,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAA;oBAC/B,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;oBAKhD,IAAI,OAAO,KAAK,eAAO,CAAC,KAAK,IAAI,OAAO,KAAK,eAAO,CAAC,aAAa,EAAE,CAAC;wBACnE,GAAG,GAAG,IAAI,CAAA;oBACZ,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,GAAG,GAAG,IAAI,CAAA;oBACV,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAA;oBAC/B,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;gBAClD,CAAC;gBAGD,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAA;gBACzC,CAAC;gBACD,OAAO,GAAG,CAAA;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAES,eAAe,CAAE,OAAe,EAAE,IAAa;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAA;QACnD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,+BAA+B,OAAO,kBAAkB,CAAC,CAAA;YACjF,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,mBAAmB,CAAC,CAAA;YAC/C,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,WAAW,OAAO,sBAAsB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;QACzF,CAAC;IACH,CAAC;IAEO,UAAU,CAAE,OAAe,EAAE,KAAa,EAAE,GAAW,EAAE,MAAc;QAC7E,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QACnC,MAAM,MAAM,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QAC3D,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACtE,IAAI,CAAC,IAAI,CAAC,eAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAES,iBAAiB,CAAE,OAAe,EAAE,WAAmB;;QAC/D,MAAM,MAAM,GAAG,MAAA,IAAI,CAAC,MAAM,CAAC,OAAO,0CAAE,aAAa,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;QACjE,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,WAAW,2BAA2B,OAAO,+CAA+C,OAAO,EAAE,CAAC,CAAA;YACjJ,IAAI,CAAC,IAAI,CAAC,eAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAEO,cAAc,CAAE,OAAe,EAAE,IAAa;;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAA;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,SAAS,CAAW,CAAA;QAExD,MAAM,QAAQ,GAAW,QAAQ,CAAC,MAAA,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,QAAQ,CAAC,mCAAI,EAAE,EAAE,EAAE,CAAC,CAAA;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;QAChC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAW,WAAW,OAAO,gCAAgC,QAAQ,eAAe,QAAQ,EAAE,CAAA;YACvG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,gBAAgB,CAAC,CAAA;YAC3E,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,0BAAW,CAAC,OAAO,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAW,WAAW,OAAO,UAAU,CAAA;YAChD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,cAAc,CAAC,CAAA;YACzE,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;QAC9B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAW,WAAW,OAAO,eAAe,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;YAC1G,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,gBAAgB,CAAC,CAAA;YAC3E,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,YAAY,GAAkB,IAAI,CAAC,eAAe,EAAE,CAAA;QAC1D,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,GAAG,GAAW,WAAW,OAAO,IAAI,YAAY,EAAE,CAAA;YACxD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,+BAA+B,CAAC,CAAA;YAC1F,OAAO,KAAK,CAAA;QACd,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;QACtC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAW,WAAW,OAAO,wBAAwB,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;YACnI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,kBAAkB,CAAC,CAAA;YAC7E,OAAO,KAAK,CAAA;QACd,CAAC;QAED,QAAQ,KAAK,CAAC,KAAK,EAAE,CAAC;YACpB,KAAK,kBAAY,CAAC,uBAAuB,CAAC;YAC1C,KAAK,kBAAY,CAAC,uBAAuB;gBAAE,CAAC;oBAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,YAAY,CAAC,CAAA;oBACxD,IAAI,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;wBAClC,MAAM,GAAG,GAAW,WAAW,OAAO,4BAA4B,YAAY,cAAc,KAAK,CAAC,MAAM,GAAG,CAAA;wBAC3G,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,aAAa,CAAC,CAAA;wBACxE,OAAO,KAAK,CAAA;oBACd,CAAC;oBAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,YAAY,CAAC,CAAA;oBACtD,IAAI,UAAU,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC;wBACpC,MAAM,GAAG,GAAW,WAAW,OAAO,4BAA4B,UAAU,eAAe,KAAK,CAAC,MAAM,EAAE,CAAA;wBACzG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,2BAAmB,CAAC,aAAa,CAAC,CAAA;wBACxE,OAAO,KAAK,CAAA;oBACd,CAAC;gBACH,CAAC;gBACC,MAAK;YAEP,OAAO,CAAC,CAAC,CAAC;gBACR,MAAK;YACP,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAMS,eAAe,CAAE,IAAa;QAEtC,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,mBAAmB,CAAC,CAAA;QAC/C,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,cAAM,CAAC,UAAU,EAAE,cAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC/F,MAAM,QAAQ,GAAG,iBAAiB,KAAK,CAAC;YACtC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE;YACpC,CAAC,CAAC,iBAAiB,CAAA;QAErB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iDAAiD,UAAU,gBAAgB,QAAQ,EAAE,CAAC,CAAA;QAC9G,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,UAAoB,EAAE,QAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,OAA6B,EAAE,EAAE;YAC9G,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,CAAA;YAC5D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;YACzD,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACzB,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;oBACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;gBACjC,CAAC;YACH,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,mBAAmB,CAAC,CAAA;QACjD,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC7B,CAAC,CAAC,CAAA;IACJ,CAAC;IAEkB,qBAAqB;QACtC,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAA;QACtC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAA;IAC5E,CAAC;IAEkB,WAAW,CAAE,OAAe,EAAE,IAAY,EAAE,GAAiB;QAC9E,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAA;QAErC,MAAM,MAAM,GAAG,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,SAA+B,CAAA;QACnD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,IAAI,yBAAiB,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;YAClF,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;gBAE/C,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,+BAA+B,MAAM,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;YACnF,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;gBAC/D,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;YACzE,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAKO,MAAM,CAAC,kBAAkB,CAAE,WAAkD;;QACnF,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,iCAAyB,EAAE,CAAA;QACxD,QAAQ,MAAA,WAAW,CAAC,IAAI,0CAAE,WAAW,EAAE,EAAE,CAAC;YACxC,KAAK,MAAM;gBACT,OAAO,IAAI,+BAAuB,CAAC,MAAA,WAAW,CAAC,SAAS,mCAAI,OAAO,CAAC,CAAA;YACtE;gBACE,OAAO,IAAI,iCAAyB,EAAE,CAAA;QAC1C,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAE,IAAmB;QAC9C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAAC,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,sBAAsB,YAAY,CAAC,eAAe,gCAAgC,IAAI,GAAG,CAAC,CAAA;YACrH,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,iBAAiB,CAAC,CAAA;YAC7C,IAAI,CAAC,IAAI,EAAE,CAAA;YACX,OAAM;QACR,CAAC;QAID,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,WAAW,CAAC,eAAe,IAAI,YAAY,CAAC,eAAe,aAAa,IAAI,GAAG,CAAC,CAAA;QACzI,IAAI,CAAC,SAAS,EAAE,CAAA;IAClB,CAAC;IAED,UAAU;QACR,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAA;QACrC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,KAAK,KAAK,kBAAY,CAAC,gBAAgB,CAAA;QAChD,CAAC;QACD,OAAO,KAAK,KAAK,kBAAY,CAAC,mBAAmB,CAAA;IACnD,CAAC;IAES,YAAY,CAAE,OAAe,EAAE,IAAa;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QAEjC,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,eAAO,CAAC,KAAK,CAAC,CAAC,CAAC;gBAGnB,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;oBACtB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;gBACtB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAA;gBAC/E,CAAC;gBACD,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;gBACrB,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,WAAW,CAAC,CAAC,CAAC;gBACzB,MAAM,GAAG,GAAkB,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,SAAS,CAAC,CAAA;gBAC3D,IAAI,GAAG,EAAE,CAAC;oBACR,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gBACzB,CAAC;gBACD,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,SAAS,CAAC,CAAC,CAAC;gBACvB,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,IAAI,CAAA;gBAC1C,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,mBAAmB,CAAC,CAAA;gBAC/C,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,mBAAmB,CAAC,CAAA;gBACtD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;gBAC1B,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC3B,MAAM,QAAQ,GAAW,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,QAAQ,CAAW,CAAA;gBACjE,MAAM,UAAU,GAAW,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,SAAS,CAAW,CAAA;gBACpE,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,gCAAgC,QAAQ,EAAE,CAAC,CAAA;gBAE7E,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,QAAQ,GAAG,CAAC,CAAA;gBAElD,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;gBACxD,MAAK;YACP,CAAC;YAED,KAAK,eAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,UAAU,CAAC,CAAA;gBACpD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,cAAM,CAAC,IAAI,CAAC,CAAA;gBACxC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,mBAAmB,CAAuB,CAAA;gBAC9E,MAAM,CAAC,IAAI,CAAC,4BAA4B,UAAU,aAAa,MAAM,WAAW,IAAI,GAAG,CAAC,CAAA;gBAKxF,IAAI,UAAU,KAAK,eAAO,CAAC,KAAK;oBAC5B,IAAI,CAAC,YAAY,CAAC,KAAK,KAAK,kBAAY,CAAC,mBAAmB;oBAC5D,MAAM,KAAK,2BAAmB,CAAC,gBAAgB,EAAE,CAAC;oBACpD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAA;gBAChC,CAAC;gBACD,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAES,KAAK,CAAE,OAAe,EAAE,IAAa;QAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,OAAO,sBAAsB,CAAC,CAAA;YAClE,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,OAAO,0BAA0B,CAAC,CAAA;YACtE,QAAQ,OAAO,EAAE,CAAC;gBAChB,KAAK,eAAO,CAAC,KAAK,CAAC,CAAC,CAAC;oBACnB,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,iBAAiB,CAAC,CAAA;oBAC7C,IAAI,CAAC,UAAU,EAAE,CAAA;oBACjB,MAAK;gBACP,CAAC;YACH,CAAC;YACD,OAAM;QACR,CAAC;QAED,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,eAAO,CAAC,KAAK,CAAC;YACnB,KAAK,eAAO,CAAC,MAAM,CAAC;YACpB,KAAK,eAAO,CAAC,WAAW,CAAC;YACzB,KAAK,eAAO,CAAC,MAAM,CAAC;YACpB,KAAK,eAAO,CAAC,aAAa,CAAC;YAC3B,KAAK,eAAO,CAAC,SAAS,CAAC;YACvB,KAAK,eAAO,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;gBAChC,MAAK;YACP,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;gBACnC,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAEO,UAAU,CAAE,WAAmB,GAAG;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QACjC,MAAM,CAAC,IAAI,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAA;QAC5D,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAA;QACb,CAAC,EAAE,QAAQ,CAAC,CAAA;IACd,CAAC;IAEO,SAAS,CAAE,IAAa;;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QACjC,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,cAAM,CAAC,UAAU,EAAE,cAAM,CAAC,YAAY,EAAE,cAAM,CAAC,QAAQ,EAAE,cAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;QAClJ,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,eAAe,CAAwB,CAAA;QACpF,MAAM,CAAC,IAAI,CAAC,wBAAwB,QAAQ,kBAAkB,UAAU,kBAAkB,UAAU,uBAAuB,eAAe,EAAE,CAAC,CAAA;QAG7I,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,MAAC,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,SAAS,CAAY,mCAAI,CAAC,CAAA;YACnE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAA;YAC3D,MAAM,CAAC,IAAI,CAAC,2CAA2C,UAAU,iBAAiB,WAAW,EAAE,CAAC,CAAA;YAEhG,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,WAA8C,CAAA;YAClF,MAAM,kBAAkB,GAAG,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;YAIpF,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YACzD,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,SAAS,GAAG,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,UAAU,CAAA;YAGhD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;gBAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,iCAAiC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,SAAS,uBAAuB,UAAU,EAAE,CAAC,CAAA;QACzG,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAA;QAC/B,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,UAAU,CAAW,CAAA;QACpE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAM,CAAC,YAAY,CAAW,CAAA;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAkB,EAAE,QAAkB,CAAC,CAAA;QAEtE,MAAM,CAAC,IAAI,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAA;QAC/C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,uBAAuB,CAAC,CAAA;YACnD,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAA;YAKjD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAA;YACvD,IAAI,OAAO,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAA;gBAEpF,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAA;gBAClC,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,WAA8C,CAAA;gBAClF,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,SAAS,GAAG,CAAC,CAAA;gBAC3B,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,iBAAiB,GAAG,CAAC,CAAA;gBACvC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;oBAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,8BAAsB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrE,CAAC;YACH,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAA;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;YAChD,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,uBAAuB,CAAC,CAAA;QACrD,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAA;QAEvC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,UAAU,EAAE,CAAA;QACnB,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;QACvC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;IAEO,eAAe;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QACnC,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,uCAAuC,CAAC,CAAA;QACnE,MAAM,EAAE,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,EAAE,CAAA;QACjC,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,CAAC,IAAI,CAAC,eAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;IAEO,aAAa,CAAE,SAAiB;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAA;QACnC,MAAM,EAAE,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,CAAC,SAAS,CAAC,CAAA;QACxC,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,CAAC,IAAI,CAAC,eAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAEO,IAAI;;QACV,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAM;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;QACtC,MAAM,MAAM,GAAe,YAAY,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;QAC9D,MAAM,WAAW,GAA2B,MAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,mCAAI,IAAI,CAAA;QACjG,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QAEjC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;QAEvB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,wBAAU,CAAC,OAAO,CAAC,CAAC,CAAC;gBAExB,MAAK;YACP,CAAC;YAED,KAAK,wBAAU,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC5B,MAAM,CAAC,KAAK,CAAC,0BAA0B,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;gBACjE,IAAI,CAAC,eAAe,EAAE,CAAA;gBACtB,MAAK;YACP,CAAC;YAED,KAAK,wBAAU,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC1B,MAAM,CAAC,KAAK,CAAC,2BAA2B,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;gBAClE,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;gBAClD,MAAK;YACP,CAAC;YAED,KAAK,wBAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACjC,IAAI,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,YAAY,CAAC,0BAA0B,CAAC,EAAE,CAAC;oBAGvF,MAAM,CAAC,IAAI,CAAC,4BAA4B,IAAI,CAAC,WAAW,CAAC,uBAAuB,2BAA2B,CAAC,CAAA;oBAC5G,YAAY,CAAC,iBAAiB,GAAG,IAAI,CAAA;oBACrC,YAAY,CAAC,cAAc,GAAG,IAAI,IAAI,EAAE,CAAA;oBACxC,IAAI,CAAC,QAAQ,CAAC,kBAAY,CAAC,mBAAmB,CAAC,CAAA;gBACjD,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAA;oBACpC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,IAAI,uBAAuB,CAAC,CAAC,CAAA;gBACxE,CAAC;gBACD,MAAK;YACP,CAAC;YAED,KAAK,wBAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACpC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBACvB,IAAI,CAAC,IAAI,EAAE,CAAA;gBACX,MAAK;YACP,CAAC;YAED;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACxC,CAAC;IACH,CAAC;;AApmBH,oCAqmBC;AAvSyB,4BAAe,GAAG,GAAG,AAAN,CAAM;AACrB,uCAA0B,GAAG,CAAC,AAAJ,CAAI","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { SessionState } from '../tcp'\nimport { TickAction } from '../tick-action'\nimport { IMsgApplication } from '../msg-application'\nimport { SegmentType } from '../../buffer/segment/segment-type'\nimport { SessionSequenceCoordinator } from '../session/session-sequence-coordinator'\nimport { DefaultFixClock } from '../session/fix-clock'\nimport { ResendActionType } from '../session/resend-request-manager'\nimport { AsciiMsgTransmitter } from './ascii-msg-transmitter'\nimport { MsgTransport } from '../factory'\nimport { ILooseObject } from '../../collections/collection'\n\nexport abstract class AsciiSession extends FixSession {\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected readonly coordinator: SessionSequenceCoordinator\n protected readonly sessionStore: IFixSessionStore\n protected readonly sessionId: SessionId\n\n protected constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.requestLogoutType = this.respondLogoutType = MsgType.Logout\n this.requestLogonType = MsgType.Logon\n this.store = new FixMsgMemoryStore(this.config.description.SenderCompId, this.config)\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n\n // Create session store from factory.\n // Priority: programmatic config > JSON store config > default in-memory\n const storeFactory = config.sessionStoreFactory ?? AsciiSession.createStoreFactory(config.description.store)\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n this.sessionStore = storeFactory.create(this.sessionId)\n\n const clock = new DefaultFixClock()\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n /**\n * Initialize the session store (reads persisted sequences from file if using FileSessionStore),\n * sync the coordinator and transmitter from the store, then start the session.\n *\n * The transport's readable stream is paused during async store initialization to prevent\n * the AsciiParser (which starts reading immediately in its constructor) from consuming\n * and emitting messages before subscribe() hooks up the message handler.\n */\n public async run (transport: MsgTransport): Promise<number> {\n // Pause the readable stream to prevent data loss during async init.\n // The AsciiParser starts reading from the socket in its constructor,\n // but FixSession.subscribe() hasn't been called yet. Without pausing,\n // the client's Logon can arrive and be parsed into the void.\n transport.duplex.readable?.pause()\n\n // Initialize store — reads persisted .seqnums file if using FileSessionStore.\n // For MemorySessionStore this is a no-op.\n await this.sessionStore.initialize()\n\n // Coordinator becomes the source of truth for sequences\n this.coordinator.initializeFromStore()\n\n // Sync encoder's outgoing sequence from the store\n const transmitter = transport.transmitter as AsciiMsgTransmitter\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n\n // Sync session state's last received sequence from the store\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true)\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false)\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false)\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo)\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset)\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n const res = this.onLogon(view, userName as string, password as string)\n // currently not using this.\n logger.info(`peerLogon onLogon returns ${res}`)\n if (this.acceptor) {\n this.setState(SessionState.InitiationLogonResponse)\n logger.info('acceptor responds to logon request')\n\n // If WE (acceptor) are sending ResetSeqNumFlag=Y but peer didn't request it,\n // reset our sequences before sending our logon response.\n // This handles the broker-reset pattern where client sends N, we respond with Y.\n const weReset = this.config.description.ResetSeqNumFlag\n if (weReset && resetSeqNumFlag !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor()\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear()\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon() // if res send response else reject, terminate\n } else { // as an initiator the acceptor has responded\n logger.info('initiator receives logon response')\n this.setState(SessionState.InitiationLogonReceived)\n }\n // Reset logon retry counter on successful logon\n this.coordinator.resetLogonRetryCount()\n\n if (this.heartbeat) {\n this.startTimer()\n }\n logger.info('system ready, inform app')\n this.onReady(view)\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
@@ -2,6 +2,9 @@ import { IJsFixConfig } from '../../config';
2
2
  import { FixEntity } from '../fix-entity';
3
3
  export declare class TcpAcceptorListener extends FixEntity {
4
4
  readonly config: IJsFixConfig;
5
+ private acceptor;
6
+ private resolveStart;
5
7
  constructor(config: IJsFixConfig);
6
8
  start(): Promise<any>;
9
+ stop(): void;
7
10
  }
@@ -30,6 +30,8 @@ let TcpAcceptorListener = class TcpAcceptorListener extends fix_entity_1.FixEnti
30
30
  constructor(config) {
31
31
  super(config);
32
32
  this.config = config;
33
+ this.acceptor = null;
34
+ this.resolveStart = null;
33
35
  }
34
36
  start() {
35
37
  return __awaiter(this, void 0, void 0, function* () {
@@ -38,31 +40,40 @@ let TcpAcceptorListener = class TcpAcceptorListener extends fix_entity_1.FixEnti
38
40
  const sessionContainer = this.config.sessionContainer;
39
41
  if (!sessionContainer.isRegistered(di_tokens_1.DITokens.FixSession)) {
40
42
  reject(new Error(`application must register a DI token '${di_tokens_1.DITokens.FixSession}' - see src/sample`));
43
+ return;
41
44
  }
42
45
  logger.info('starting.');
43
46
  const acceptor = sessionContainer.resolve(tcp_acceptor_1.TcpAcceptor);
47
+ this.acceptor = acceptor;
44
48
  acceptor.on('transport', (t) => {
45
49
  logger.info(`creates new transport using DI token ${di_tokens_1.DITokens.FixSession}.`);
46
50
  const acceptorSession = sessionContainer.resolve(di_tokens_1.DITokens.FixSession);
47
51
  this.emit('session', acceptorSession, t);
48
52
  acceptorSession.run(t).then(() => {
49
- logger.info('ends');
50
- acceptor.close(() => {
51
- logger.info('acceptor closed.');
52
- resolve(true);
53
- });
53
+ logger.info('session ended normally, acceptor continues listening');
54
54
  }).catch((e) => {
55
- logger.info(`error in session - close listener ${e.message}`);
56
- acceptor.close(() => {
57
- logger.info('acceptor closed.');
58
- reject(e);
59
- });
55
+ logger.warning(`session ended with error: ${e.message}, acceptor continues listening`);
60
56
  });
61
57
  });
58
+ this.resolveStart = resolve;
62
59
  acceptor.listen();
63
60
  }));
64
61
  });
65
62
  }
63
+ stop() {
64
+ if (this.acceptor) {
65
+ const logger = this.config.logFactory.logger('acceptor');
66
+ logger.info('acceptor stopping');
67
+ this.acceptor.close(() => {
68
+ logger.info('acceptor closed.');
69
+ if (this.resolveStart) {
70
+ this.resolveStart(true);
71
+ this.resolveStart = null;
72
+ }
73
+ });
74
+ this.acceptor = null;
75
+ }
76
+ }
66
77
  };
67
78
  exports.TcpAcceptorListener = TcpAcceptorListener;
68
79
  exports.TcpAcceptorListener = TcpAcceptorListener = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"tcp-acceptor-listener.js","sourceRoot":"","sources":["../../../src/transport/tcp/tcp-acceptor-listener.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,iDAA4C;AAE5C,uCAA6C;AAE7C,uDAAkD;AAClD,8CAAyC;AAGlC,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,sBAAS;IAChD,YAA4D,MAAoB;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;IAEhF,CAAC;IAEK,KAAK;;YACT,OAAO,MAAM,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;gBACrG,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACxB,MAAM,QAAQ,GAAgB,gBAAgB,CAAC,OAAO,CAAc,0BAAW,CAAC,CAAA;gBAChF,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAe,EAAE,EAAE;oBAC3C,MAAM,CAAC,IAAI,CAAC,wCAAwC,oBAAQ,CAAC,UAAU,GAAG,CAAC,CAAA;oBAC3E,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;oBACjF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;oBACxC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACnB,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE;4BAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;4BAC/B,OAAO,CAAC,IAAI,CAAC,CAAA;wBACf,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;wBACpB,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;wBAC7D,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE;4BAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;4BAC/B,MAAM,CAAC,CAAC,CAAC,CAAA;wBACX,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBACF,QAAQ,CAAC,MAAM,EAAE,CAAA;YACnB,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AAnCY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,qBAAU,GAAE;IAEG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GADhC,mBAAmB,CAmC/B","sourcesContent":["import { IJsFixConfig } from '../../config'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { TcpAcceptor } from './tcp-acceptor'\nimport { MsgTransport } from '../factory'\nimport { inject, injectable } from 'tsyringe'\nimport { FixSession } from '../session/fix-session'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class TcpAcceptorListener extends FixEntity {\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n }\n\n async start (): Promise<any> {\n return await new Promise<any>(async (resolve, reject) => {\n const logger = this.config.logFactory.logger('acceptor')\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n }\n logger.info('starting.')\n const acceptor: FixAcceptor = sessionContainer.resolve<FixAcceptor>(TcpAcceptor)\n acceptor.on('transport', (t: MsgTransport) => {\n logger.info(`creates new transport using DI token ${DITokens.FixSession}.`)\n const acceptorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.emit('session', acceptorSession, t)\n acceptorSession.run(t).then(() => {\n logger.info('ends')\n acceptor.close(() => {\n logger.info('acceptor closed.')\n resolve(true)\n })\n }).catch((e: Error) => {\n logger.info(`error in session - close listener ${e.message}`)\n acceptor.close(() => {\n logger.info('acceptor closed.')\n reject(e)\n })\n })\n })\n acceptor.listen()\n })\n }\n}\n"]}
1
+ {"version":3,"file":"tcp-acceptor-listener.js","sourceRoot":"","sources":["../../../src/transport/tcp/tcp-acceptor-listener.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,iDAA4C;AAE5C,uCAA6C;AAE7C,uDAAkD;AAClD,8CAAyC;AAGlC,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,sBAAS;IAIhD,YAA4C,MAAoC;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;QAHxE,aAAQ,GAAuB,IAAI,CAAA;QACnC,iBAAY,GAAkC,IAAI,CAAA;IAI1D,CAAC;IAEK,KAAK;;YACT,OAAO,MAAM,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;oBACnG,OAAM;gBACR,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACxB,MAAM,QAAQ,GAAgB,gBAAgB,CAAC,OAAO,CAAc,0BAAW,CAAC,CAAA;gBAChF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAExB,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAe,EAAE,EAAE;oBAC3C,MAAM,CAAC,IAAI,CAAC,wCAAwC,oBAAQ,CAAC,UAAU,GAAG,CAAC,CAAA;oBAC3E,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;oBACjF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;oBAIxC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBAC/B,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAA;oBACrE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;wBACpB,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,OAAO,gCAAgC,CAAC,CAAA;oBACxF,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBAEF,IAAI,CAAC,YAAY,GAAG,OAAO,CAAA;gBAC3B,QAAQ,CAAC,MAAM,EAAE,CAAA;YACnB,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;IAQD,IAAI;QACF,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;YACxD,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;YAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE;gBACvB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;gBAC/B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;oBACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACtB,CAAC;IACH,CAAC;CACF,CAAA;AA3DY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,qBAAU,GAAE;IAKG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GAJhC,mBAAmB,CA2D/B","sourcesContent":["import { IJsFixConfig } from '../../config'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { TcpAcceptor } from './tcp-acceptor'\nimport { MsgTransport } from '../factory'\nimport { inject, injectable } from 'tsyringe'\nimport { FixSession } from '../session/fix-session'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class TcpAcceptorListener extends FixEntity {\n private acceptor: FixAcceptor | null = null\n private resolveStart: ((value: any) => void) | null = null\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n }\n\n async start (): Promise<any> {\n return await new Promise<any>(async (resolve, reject) => {\n const logger = this.config.logFactory.logger('acceptor')\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n return\n }\n logger.info('starting.')\n const acceptor: FixAcceptor = sessionContainer.resolve<FixAcceptor>(TcpAcceptor)\n this.acceptor = acceptor\n\n acceptor.on('transport', (t: MsgTransport) => {\n logger.info(`creates new transport using DI token ${DITokens.FixSession}.`)\n const acceptorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.emit('session', acceptorSession, t)\n // Run the session but do NOT close the listener when it ends.\n // The acceptor keeps listening for new connections (reconnects).\n // This matches the C# TcpAcceptorListener accept-loop pattern.\n acceptorSession.run(t).then(() => {\n logger.info('session ended normally, acceptor continues listening')\n }).catch((e: Error) => {\n logger.warning(`session ended with error: ${e.message}, acceptor continues listening`)\n })\n })\n\n this.resolveStart = resolve\n acceptor.listen()\n })\n }\n\n /**\n * Explicitly stop the acceptor listener. Call this when the application\n * is shutting down (e.g., timeout, SIGINT). Without this call, the\n * acceptor keeps listening indefinitely which is the correct\n * production behaviour for a FIX acceptor.\n */\n stop (): void {\n if (this.acceptor) {\n const logger = this.config.logFactory.logger('acceptor')\n logger.info('acceptor stopping')\n this.acceptor.close(() => {\n logger.info('acceptor closed.')\n if (this.resolveStart) {\n this.resolveStart(true)\n this.resolveStart = null\n }\n })\n this.acceptor = null\n }\n }\n}\n"]}
@@ -1,67 +1,71 @@
1
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:18.687|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
2
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:18.693|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
3
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:18.694|7=1|16=1|10=242|
4
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260414-13:09:18.699|122=20260414-13:09:18.699|123=Y|36=2|10=125|
5
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:20.699|58=5|10=216|
6
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:20.697|58=5|10=215|
7
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:23.513|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=093|
8
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:23.515|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=143|
9
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:23.516|7=1|16=0|10=230|
10
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260414-13:09:23.518|122=20260414-13:09:23.518|123=Y|36=2|10=097|
11
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:25.519|58=5|10=212|
12
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:25.518|58=5|10=212|
13
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:27.979|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
14
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:27.981|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
15
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:27.981|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
16
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:28.505|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=099|
17
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:28.507|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=149|
18
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:29.510|58=5|10=207|
19
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:29.509|58=5|10=215|
20
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:29.982|58=5|10=221|
21
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:32.231|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=090|
22
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:32.232|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=139|
23
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:33.234|58=5|10=205|
24
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:33.233|58=5|10=204|
25
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:35.991|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=106|
26
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:35.993|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
27
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260414-13:09:36.995|58=5|10=220|
28
- 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:39.480|98=0|141=Y|553=js-client|554=pwd-client|10=171|
29
- 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:39.481|45=1|372=A|373=1|58=msgType A missing required tag 108|10=005|
30
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:43.945|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
31
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:43.946|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
32
- 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:43.947|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=155|
33
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:45.948|58=5|10=221|
34
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:45.947|58=5|10=220|
35
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:48.407|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
36
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:48.409|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
37
- 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:48.410|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=066|
38
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:50.410|58=5|10=201|
39
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:50.409|58=5|10=209|
40
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:09:52.418|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
41
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:09:52.418|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
42
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:56.990|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=108|
43
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:56.992|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
44
- 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:56.993|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=038|
45
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:58.995|58=5|10=227|
46
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:58.994|58=5|10=226|
47
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:01.744|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=037|
48
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:01.745|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=136|
49
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:03.750|112=Tue, 14 Apr 2026 13:10:03 GMT|10=123|
50
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:10:05.756|112=Tue, 14 Apr 2026 13:10:05 GMT|10=134|
51
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:07.748|58=5|10=208|
52
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:10:07.747|58=5|10=209|
53
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:10.227|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=083|
54
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:10.228|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=082|
55
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:12.235|112=Tue, 14 Apr 2026 13:10:12 GMT|10=121|
56
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:10:14.236|112=Tue, 14 Apr 2026 13:10:14 GMT|10=127|
57
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260414-13:10:16.241|112=Tue, 14 Apr 2026 13:10:16 GMT|10=128|
58
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260414-13:10:18.230|58=5|10=199|
59
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:18.229|58=5|10=204|
60
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:20.696|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=044|
61
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:20.698|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=097|
62
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:22.701|112=Tue, 14 Apr 2026 13:10:22 GMT|10=121|
63
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:10:24.706|112=Tue, 14 Apr 2026 13:10:24 GMT|10=131|
64
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:25.709|112=Tue, 14 Apr 2026 13:10:25 GMT|10=135|
65
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:10:26.712|112=Tue, 14 Apr 2026 13:10:26 GMT|10=133|
66
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:10:28.699|58=5|10=217|
67
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260414-13:10:28.698|58=5|10=218|
1
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:47.061|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=091|
2
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:47.066|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=144|
3
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:47.066|7=1|16=1|10=231|
4
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260415-11:22:47.070|122=20260415-11:22:47.069|123=Y|36=2|10=091|
5
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:49.069|58=5|10=212|
6
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:22:49.068|58=5|10=212|
7
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:51.559|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
8
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:51.560|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=138|
9
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:51.561|7=1|16=0|10=225|
10
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260415-11:22:51.563|122=20260415-11:22:51.563|123=Y|36=2|10=087|
11
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:53.564|58=5|10=207|
12
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:22:53.563|58=5|10=207|
13
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:56.185|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
14
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:56.187|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=148|
15
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:56.187|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
16
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:56.625|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=097|
17
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:56.626|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=146|
18
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:57.628|58=5|10=212|
19
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:57.627|58=5|10=211|
20
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:22:58.188|58=5|10=215|
21
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:00.001|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=075|
22
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:00.003|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=125|
23
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:01.005|58=5|10=191|
24
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:01.004|58=5|10=190|
25
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:03.370|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=087|
26
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:03.372|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=137|
27
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260415-11:23:04.373|58=5|10=200|
28
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:06.747|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
29
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260415-11:23:06.748|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
30
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:07.749|58=5|10=212|
31
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:07.748|58=5|10=211|
32
+ 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:10.116|98=0|141=Y|553=js-client|554=pwd-client|10=151|
33
+ 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:10.116|45=1|372=A|373=1|58=msgType A missing required tag 108|10=240|
34
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:14.568|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
35
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:14.569|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=147|
36
+ 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:14.571|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=141|
37
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:16.571|58=5|10=206|
38
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:16.570|58=5|10=205|
39
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:19.205|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=091|
40
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:19.206|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=140|
41
+ 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:19.207|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=063|
42
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:21.208|58=5|10=199|
43
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:21.207|58=5|10=198|
44
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:23.207|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=088|
45
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:23.207|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=088|
46
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:27.605|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=094|
47
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:27.607|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=144|
48
+ 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:27.608|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=024|
49
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:29.608|58=5|10=211|
50
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:29.607|58=5|10=210|
51
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:31.974|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=048|
52
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:31.975|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=147|
53
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:33.980|112=Wed, 15 Apr 2026 11:23:33 GMT|10=126|
54
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:35.982|112=Wed, 15 Apr 2026 11:23:35 GMT|10=133|
55
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:37.976|58=5|10=217|
56
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260415-11:23:37.976|58=5|10=219|
57
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:40.340|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=085|
58
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:40.341|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=084|
59
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:42.344|112=Wed, 15 Apr 2026 11:23:42 GMT|10=120|
60
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:44.347|112=Wed, 15 Apr 2026 11:23:44 GMT|10=128|
61
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260415-11:23:46.351|112=Wed, 15 Apr 2026 11:23:46 GMT|10=128|
62
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260415-11:23:48.343|58=5|10=210|
63
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:48.343|58=5|10=207|
64
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:50.924|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=044|
65
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:50.925|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=096|
66
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:52.930|112=Wed, 15 Apr 2026 11:23:52 GMT|10=123|
67
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:54.931|112=Wed, 15 Apr 2026 11:23:54 GMT|10=129|
68
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:55.934|112=Wed, 15 Apr 2026 11:23:55 GMT|10=133|
69
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260415-11:23:56.932|112=Wed, 15 Apr 2026 11:23:56 GMT|10=135|
70
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:58.927|58=5|10=217|
71
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260415-11:23:58.926|58=5|10=218|
@@ -1,67 +1,71 @@
1
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:18.687|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=109|
2
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:18.693|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
3
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:18.694|7=1|16=1|10=242|
4
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260414-13:09:18.699|122=20260414-13:09:18.699|123=Y|36=2|10=125|
5
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:20.697|58=5|10=215|
6
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:20.699|58=5|10=216|
7
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:23.513|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=093|
8
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:23.515|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=143|
9
- 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:23.516|7=1|16=0|10=230|
10
- 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260414-13:09:23.518|122=20260414-13:09:23.518|123=Y|36=2|10=097|
11
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:25.518|58=5|10=212|
12
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:25.519|58=5|10=212|
13
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:27.979|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=113|
14
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:27.981|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=154|
15
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:27.981|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=107|
16
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:28.505|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=099|
17
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:28.507|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=149|
18
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:29.509|58=5|10=215|
19
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:29.510|58=5|10=207|
20
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:32.231|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=090|
21
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:32.232|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=139|
22
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:09:33.233|58=5|10=204|
23
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:33.234|58=5|10=205|
24
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:35.991|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=106|
25
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:35.993|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=156|
26
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260414-13:09:36.995|58=5|10=220|
27
- 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:39.480|98=0|141=Y|553=js-client|554=pwd-client|10=171|
28
- 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:39.481|45=1|372=A|373=1|58=msgType A missing required tag 108|10=005|
29
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:43.945|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=104|
30
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:43.946|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=153|
1
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:47.061|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=091|
2
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:47.066|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=144|
3
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:47.066|7=1|16=1|10=231|
4
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260415-11:22:47.070|122=20260415-11:22:47.069|123=Y|36=2|10=091|
5
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:22:49.068|58=5|10=212|
6
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:49.069|58=5|10=212|
7
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:51.559|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
8
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:51.560|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=138|
9
+ 8=FIX.4.4|9=0000079|35=2|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:51.561|7=1|16=0|10=225|
10
+ 8=FIX.4.4|9=0000112|35=4|49=accept-comp|56=init-comp|34=1|57=fix|43=Y|52=20260415-11:22:51.563|122=20260415-11:22:51.563|123=Y|36=2|10=087|
11
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:22:53.563|58=5|10=207|
12
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:53.564|58=5|10=207|
13
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:56.185|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
14
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:56.187|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=148|
15
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:56.187|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=101|
16
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:22:56.625|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=097|
17
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:22:56.626|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=146|
18
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:22:57.627|58=5|10=211|
19
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:22:57.628|58=5|10=212|
20
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:00.001|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=075|
21
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:00.003|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=125|
22
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:01.004|58=5|10=190|
23
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:01.005|58=5|10=191|
24
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:03.370|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=087|
25
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:03.372|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=137|
26
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=0|57=fix|52=20260415-11:23:04.373|58=5|10=200|
27
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:06.747|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
28
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=5|57=fix|52=20260415-11:23:06.748|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=151|
29
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:07.748|58=5|10=211|
30
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:07.749|58=5|10=212|
31
+ 8=FIX.4.4|9=0000110|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:10.116|98=0|141=Y|553=js-client|554=pwd-client|10=151|
32
+ 8=FIX.4.4|9=0000125|35=3|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:10.116|45=1|372=A|373=1|58=msgType A missing required tag 108|10=240|
33
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:14.568|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=098|
34
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:14.569|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=147|
31
35
  8=FIX4.4|9=0000136|35=ZZ|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:28.980|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=177|
32
- 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:43.947|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=155|
33
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:45.947|58=5|10=220|
34
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:45.948|58=5|10=221|
35
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:48.407|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=102|
36
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:48.409|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=152|
36
+ 8=FIX.4.4|9=0000111|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:14.571|45=2|372=ZZ|373=11|58=msgType ZZ unknown|10=141|
37
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:16.570|58=5|10=205|
38
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:16.571|58=5|10=206|
39
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:19.205|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=091|
40
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:19.206|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=140|
37
41
  8=FIX4.4|9=0000123|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|999=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
38
- 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:48.410|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=066|
39
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:50.409|58=5|10=209|
40
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:50.410|58=5|10=201|
41
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:09:56.990|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=108|
42
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:09:56.992|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=158|
42
+ 8=FIX.4.4|9=0000146|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:19.207|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 143|10=063|
43
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:21.207|58=5|10=198|
44
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:21.208|58=5|10=199|
45
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:27.605|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=094|
46
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:27.607|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=144|
43
47
  8=FIX4.4|9=0000123|35=0|49=init-not!|56=accept-comp|34=2|57=fix|52=20180902-12:25:59.161|112=Sun, 02 Sep 2018 12:25:59 GMT|10=95|
44
- 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:09:56.993|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=038|
45
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:09:58.994|58=5|10=226|
46
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:09:58.995|58=5|10=227|
47
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:01.744|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=037|
48
- 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:01.745|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=136|
49
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:03.750|112=Tue, 14 Apr 2026 13:10:03 GMT|10=123|
50
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:10:05.756|112=Tue, 14 Apr 2026 13:10:05 GMT|10=134|
51
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:10:07.747|58=5|10=209|
52
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:07.748|58=5|10=208|
53
- 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:10.227|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=083|
54
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:10.228|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=082|
55
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:12.235|112=Tue, 14 Apr 2026 13:10:12 GMT|10=121|
56
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:10:14.236|112=Tue, 14 Apr 2026 13:10:14 GMT|10=127|
57
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260414-13:10:16.241|112=Tue, 14 Apr 2026 13:10:16 GMT|10=128|
58
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:18.229|58=5|10=204|
59
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260414-13:10:18.230|58=5|10=199|
60
- 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260414-13:10:20.696|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=044|
61
- 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260414-13:10:20.698|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=097|
62
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260414-13:10:22.701|112=Tue, 14 Apr 2026 13:10:22 GMT|10=121|
63
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260414-13:10:24.706|112=Tue, 14 Apr 2026 13:10:24 GMT|10=131|
64
- 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260414-13:10:25.709|112=Tue, 14 Apr 2026 13:10:25 GMT|10=135|
65
- 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260414-13:10:26.712|112=Tue, 14 Apr 2026 13:10:26 GMT|10=133|
66
- 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260414-13:10:28.698|58=5|10=218|
67
- 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260414-13:10:28.699|58=5|10=217|
48
+ 8=FIX.4.4|9=0000145|35=3|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:27.608|45=2|372=0|373=5|58=msgType 0 checksum failed. received = 95 computed = 59|10=024|
49
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:29.607|58=5|10=210|
50
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:29.608|58=5|10=211|
51
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:31.974|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=048|
52
+ 8=FIX.4.4|9=0000117|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:31.975|98=0|108=30|141=Y|553=js-server|554=pwd-server|10=147|
53
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:33.980|112=Wed, 15 Apr 2026 11:23:33 GMT|10=126|
54
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:35.982|112=Wed, 15 Apr 2026 11:23:35 GMT|10=133|
55
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=4|57=fix|52=20260415-11:23:37.976|58=5|10=219|
56
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:37.976|58=5|10=217|
57
+ 8=FIX.4.4|9=0000117|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:40.340|98=0|108=30|141=Y|553=js-client|554=pwd-client|10=085|
58
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:40.341|98=0|108=2|141=Y|553=js-server|554=pwd-server|10=084|
59
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:42.344|112=Wed, 15 Apr 2026 11:23:42 GMT|10=120|
60
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:44.347|112=Wed, 15 Apr 2026 11:23:44 GMT|10=128|
61
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=4|57=fix|52=20260415-11:23:46.351|112=Wed, 15 Apr 2026 11:23:46 GMT|10=128|
62
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:48.343|58=5|10=207|
63
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=5|57=fix|52=20260415-11:23:48.343|58=5|10=210|
64
+ 8=FIX.4.4|9=0000116|35=A|49=init-comp|56=accept-comp|34=1|57=fix|52=20260415-11:23:50.924|98=0|108=2|141=Y|553=js-client|554=pwd-client|10=044|
65
+ 8=FIX.4.4|9=0000116|35=A|49=accept-comp|56=init-comp|34=1|57=fix|52=20260415-11:23:50.925|98=0|108=5|141=Y|553=js-server|554=pwd-server|10=096|
66
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=2|57=fix|52=20260415-11:23:52.930|112=Wed, 15 Apr 2026 11:23:52 GMT|10=123|
67
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=3|57=fix|52=20260415-11:23:54.931|112=Wed, 15 Apr 2026 11:23:54 GMT|10=129|
68
+ 8=FIX.4.4|9=0000104|35=0|49=accept-comp|56=init-comp|34=2|57=fix|52=20260415-11:23:55.934|112=Wed, 15 Apr 2026 11:23:55 GMT|10=133|
69
+ 8=FIX.4.4|9=0000104|35=0|49=init-comp|56=accept-comp|34=4|57=fix|52=20260415-11:23:56.932|112=Wed, 15 Apr 2026 11:23:56 GMT|10=135|
70
+ 8=FIX.4.4|9=0000075|35=5|49=init-comp|56=accept-comp|34=5|57=fix|52=20260415-11:23:58.926|58=5|10=218|
71
+ 8=FIX.4.4|9=0000075|35=5|49=accept-comp|56=init-comp|34=3|57=fix|52=20260415-11:23:58.927|58=5|10=217|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jspurefix",
3
- "version": "5.5.4",
3
+ "version": "5.6.1",
4
4
  "description": "pure node js fix engine",
5
5
  "keywords": [
6
6
  "typescript",
@@ -16,6 +16,7 @@ import { SessionSequenceCoordinator } from '../session/session-sequence-coordina
16
16
  import { DefaultFixClock } from '../session/fix-clock'
17
17
  import { ResendActionType } from '../session/resend-request-manager'
18
18
  import { AsciiMsgTransmitter } from './ascii-msg-transmitter'
19
+ import { MsgTransport } from '../factory'
19
20
  import { ILooseObject } from '../../collections/collection'
20
21
 
21
22
  export abstract class AsciiSession extends FixSession {
@@ -49,6 +50,44 @@ export abstract class AsciiSession extends FixSession {
49
50
  this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)
50
51
  }
51
52
 
53
+ /**
54
+ * Initialize the session store (reads persisted sequences from file if using FileSessionStore),
55
+ * sync the coordinator and transmitter from the store, then start the session.
56
+ *
57
+ * The transport's readable stream is paused during async store initialization to prevent
58
+ * the AsciiParser (which starts reading immediately in its constructor) from consuming
59
+ * and emitting messages before subscribe() hooks up the message handler.
60
+ */
61
+ public async run (transport: MsgTransport): Promise<number> {
62
+ // Pause the readable stream to prevent data loss during async init.
63
+ // The AsciiParser starts reading from the socket in its constructor,
64
+ // but FixSession.subscribe() hasn't been called yet. Without pausing,
65
+ // the client's Logon can arrive and be parsed into the void.
66
+ transport.duplex.readable?.pause()
67
+
68
+ // Initialize store — reads persisted .seqnums file if using FileSessionStore.
69
+ // For MemorySessionStore this is a no-op.
70
+ await this.sessionStore.initialize()
71
+
72
+ // Coordinator becomes the source of truth for sequences
73
+ this.coordinator.initializeFromStore()
74
+
75
+ // Sync encoder's outgoing sequence from the store
76
+ const transmitter = transport.transmitter as AsciiMsgTransmitter
77
+ transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum
78
+
79
+ // Sync session state's last received sequence from the store
80
+ this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum
81
+
82
+ this.sessionLogger.info(`store initialized: nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)
83
+
84
+ // Resume the stream — super.run() will call subscribe() to hook up the message handler,
85
+ // then the buffered data (including the client's Logon) will be delivered.
86
+ transport.duplex.readable?.resume()
87
+
88
+ return await super.run(transport)
89
+ }
90
+
52
91
  private checkSeqNo (msgType: string, view: MsgView): boolean {
53
92
  switch (msgType) {
54
93
  case MsgType.SequenceReset: {
@@ -130,11 +169,16 @@ export abstract class AsciiSession extends FixSession {
130
169
  }
131
170
  }
132
171
 
133
- // Accept the current messagedon't block waiting for gap fill.
134
- // The gap will be filled by the resend response, but this message is valid.
135
- ret = true
172
+ // Update sequence state regardlessthe gap-triggering message is valid.
136
173
  state.lastPeerMsgSeqNum = seqNo
137
174
  this.coordinator.onMessageReceived(seqNo, false)
175
+
176
+ // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).
177
+ // Don't return true for them — they must not be dispatched to onSessionMsg again.
178
+ // Application messages (and everything else) should be forwarded normally.
179
+ if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {
180
+ ret = true
181
+ }
138
182
  } else {
139
183
  ret = true
140
184
  state.lastPeerMsgSeqNum = seqNo
@@ -9,6 +9,9 @@ import { FixEntity } from '../fix-entity'
9
9
 
10
10
  @injectable()
11
11
  export class TcpAcceptorListener extends FixEntity {
12
+ private acceptor: FixAcceptor | null = null
13
+ private resolveStart: ((value: any) => void) | null = null
14
+
12
15
  constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
13
16
  super(config)
14
17
  }
@@ -19,28 +22,49 @@ export class TcpAcceptorListener extends FixEntity {
19
22
  const sessionContainer = this.config.sessionContainer
20
23
  if (!sessionContainer.isRegistered(DITokens.FixSession)) {
21
24
  reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))
25
+ return
22
26
  }
23
27
  logger.info('starting.')
24
28
  const acceptor: FixAcceptor = sessionContainer.resolve<FixAcceptor>(TcpAcceptor)
29
+ this.acceptor = acceptor
30
+
25
31
  acceptor.on('transport', (t: MsgTransport) => {
26
32
  logger.info(`creates new transport using DI token ${DITokens.FixSession}.`)
27
33
  const acceptorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)
28
34
  this.emit('session', acceptorSession, t)
35
+ // Run the session but do NOT close the listener when it ends.
36
+ // The acceptor keeps listening for new connections (reconnects).
37
+ // This matches the C# TcpAcceptorListener accept-loop pattern.
29
38
  acceptorSession.run(t).then(() => {
30
- logger.info('ends')
31
- acceptor.close(() => {
32
- logger.info('acceptor closed.')
33
- resolve(true)
34
- })
39
+ logger.info('session ended normally, acceptor continues listening')
35
40
  }).catch((e: Error) => {
36
- logger.info(`error in session - close listener ${e.message}`)
37
- acceptor.close(() => {
38
- logger.info('acceptor closed.')
39
- reject(e)
40
- })
41
+ logger.warning(`session ended with error: ${e.message}, acceptor continues listening`)
41
42
  })
42
43
  })
44
+
45
+ this.resolveStart = resolve
43
46
  acceptor.listen()
44
47
  })
45
48
  }
49
+
50
+ /**
51
+ * Explicitly stop the acceptor listener. Call this when the application
52
+ * is shutting down (e.g., timeout, SIGINT). Without this call, the
53
+ * acceptor keeps listening indefinitely — which is the correct
54
+ * production behaviour for a FIX acceptor.
55
+ */
56
+ stop (): void {
57
+ if (this.acceptor) {
58
+ const logger = this.config.logFactory.logger('acceptor')
59
+ logger.info('acceptor stopping')
60
+ this.acceptor.close(() => {
61
+ logger.info('acceptor closed.')
62
+ if (this.resolveStart) {
63
+ this.resolveStart(true)
64
+ this.resolveStart = null
65
+ }
66
+ })
67
+ this.acceptor = null
68
+ }
69
+ }
46
70
  }