jspurefix 5.11.1 → 5.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +13 -1
  2. package/dist/buffer/fixml/fixml-parser.js +1 -1
  3. package/dist/buffer/fixml/fixml-parser.js.map +1 -1
  4. package/dist/config/empty-log-factory.d.ts +2 -2
  5. package/dist/config/empty-log-factory.js +1 -1
  6. package/dist/config/empty-log-factory.js.map +1 -1
  7. package/dist/config/get-js-fx-logger.d.ts +2 -2
  8. package/dist/config/get-js-fx-logger.js.map +1 -1
  9. package/dist/config/js-fix-logger-factory.d.ts +2 -2
  10. package/dist/config/js-fix-logger-factory.js.map +1 -1
  11. package/dist/config/js-fix-logger.d.ts +9 -8
  12. package/dist/config/js-fix-logger.js +4 -4
  13. package/dist/config/js-fix-logger.js.map +1 -1
  14. package/dist/config/js-fix-winston-log-factory.d.ts +2 -2
  15. package/dist/config/js-fix-winston-log-factory.js +2 -2
  16. package/dist/config/js-fix-winston-log-factory.js.map +1 -1
  17. package/dist/config/winston-logger.d.ts +5 -2
  18. package/dist/config/winston-logger.js +57 -9
  19. package/dist/config/winston-logger.js.map +1 -1
  20. package/dist/dictionary/fragment-safety.d.ts +26 -0
  21. package/dist/dictionary/fragment-safety.js +154 -0
  22. package/dist/dictionary/fragment-safety.js.map +1 -0
  23. package/dist/dictionary/index.d.ts +1 -0
  24. package/dist/dictionary/index.js +1 -0
  25. package/dist/dictionary/index.js.map +1 -1
  26. package/dist/runtime/make-config.js +1 -1
  27. package/dist/runtime/make-config.js.map +1 -1
  28. package/dist/runtime/session-launcher.js +1 -1
  29. package/dist/runtime/session-launcher.js.map +1 -1
  30. package/dist/sample/http/oms/http-client.js +1 -1
  31. package/dist/sample/http/oms/http-client.js.map +1 -1
  32. package/dist/sample/http/oms/http-server.js +1 -1
  33. package/dist/sample/http/oms/http-server.js.map +1 -1
  34. package/dist/sample/tcp/qf-md/md-client.js +1 -1
  35. package/dist/sample/tcp/qf-md/md-client.js.map +1 -1
  36. package/dist/sample/tcp/qf-md/md-server.js +1 -1
  37. package/dist/sample/tcp/qf-md/md-server.js.map +1 -1
  38. package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js +1 -1
  39. package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js.map +1 -1
  40. package/dist/sample/tcp/recovering-skeleton/skeleton-client.js +1 -1
  41. package/dist/sample/tcp/recovering-skeleton/skeleton-client.js.map +1 -1
  42. package/dist/sample/tcp/recovering-skeleton/skeleton-server.js +1 -1
  43. package/dist/sample/tcp/recovering-skeleton/skeleton-server.js.map +1 -1
  44. package/dist/sample/tcp/skeleton/skeleton-session.js +1 -1
  45. package/dist/sample/tcp/skeleton/skeleton-session.js.map +1 -1
  46. package/dist/sample/tcp/trade-capture/trade-capture-client.js +1 -1
  47. package/dist/sample/tcp/trade-capture/trade-capture-client.js.map +1 -1
  48. package/dist/sample/tcp/trade-capture/trade-capture-server.js +1 -1
  49. package/dist/sample/tcp/trade-capture/trade-capture-server.js.map +1 -1
  50. package/dist/store/fix-msg-memory-store.js +1 -1
  51. package/dist/store/fix-msg-memory-store.js.map +1 -1
  52. package/dist/transport/ascii/ascii-msg-transmitter.js +1 -1
  53. package/dist/transport/ascii/ascii-msg-transmitter.js.map +1 -1
  54. package/dist/transport/ascii/ascii-session.js +1 -1
  55. package/dist/transport/ascii/ascii-session.js.map +1 -1
  56. package/dist/transport/http/http-acceptor-listener.js +1 -1
  57. package/dist/transport/http/http-acceptor-listener.js.map +1 -1
  58. package/dist/transport/http/http-acceptor.js +2 -2
  59. package/dist/transport/http/http-acceptor.js.map +1 -1
  60. package/dist/transport/http/http-initiator.js +1 -1
  61. package/dist/transport/http/http-initiator.js.map +1 -1
  62. package/dist/transport/http/http-json-sample-adapter.js +1 -1
  63. package/dist/transport/http/http-json-sample-adapter.js.map +1 -1
  64. package/dist/transport/session/fix-session.js +3 -3
  65. package/dist/transport/session/fix-session.js.map +1 -1
  66. package/dist/transport/session/session-registry.js +1 -1
  67. package/dist/transport/session/session-registry.js.map +1 -1
  68. package/dist/transport/tcp/recovering-tcp-initiator.js +1 -1
  69. package/dist/transport/tcp/recovering-tcp-initiator.js.map +1 -1
  70. package/dist/transport/tcp/tcp-acceptor-listener.js +2 -2
  71. package/dist/transport/tcp/tcp-acceptor-listener.js.map +1 -1
  72. package/dist/transport/tcp/tcp-acceptor.js +2 -2
  73. package/dist/transport/tcp/tcp-acceptor.js.map +1 -1
  74. package/dist/transport/tcp/tcp-initiator-connector.js +2 -2
  75. package/dist/transport/tcp/tcp-initiator-connector.js.map +1 -1
  76. package/dist/transport/tcp/tcp-initiator.js +1 -1
  77. package/dist/transport/tcp/tcp-initiator.js.map +1 -1
  78. package/docs/instrumentation.md +360 -0
  79. package/docs/scattered-components.md +280 -0
  80. package/jsfix.test_client.txt +62 -62
  81. package/jsfix.test_server.txt +72 -72
  82. package/package.json +1 -1
  83. package/src/buffer/fixml/fixml-parser.ts +1 -1
  84. package/src/config/empty-log-factory.ts +2 -2
  85. package/src/config/get-js-fx-logger.ts +2 -2
  86. package/src/config/js-fix-logger-factory.ts +8 -2
  87. package/src/config/js-fix-logger.ts +23 -8
  88. package/src/config/js-fix-winston-log-factory.ts +3 -3
  89. package/src/config/winston-logger.ts +93 -10
  90. package/src/dictionary/fragment-safety.ts +225 -0
  91. package/src/dictionary/index.ts +1 -0
  92. package/src/runtime/make-config.ts +1 -1
  93. package/src/runtime/session-launcher.ts +1 -1
  94. package/src/sample/http/oms/http-client.ts +1 -1
  95. package/src/sample/http/oms/http-server.ts +1 -1
  96. package/src/sample/tcp/qf-md/md-client.ts +1 -1
  97. package/src/sample/tcp/qf-md/md-server.ts +1 -1
  98. package/src/sample/tcp/recovering-skeleton/respawn-acceptor.ts +2 -1
  99. package/src/sample/tcp/recovering-skeleton/skeleton-client.ts +1 -1
  100. package/src/sample/tcp/recovering-skeleton/skeleton-server.ts +1 -1
  101. package/src/sample/tcp/skeleton/skeleton-session.ts +1 -1
  102. package/src/sample/tcp/trade-capture/trade-capture-client.ts +2 -1
  103. package/src/sample/tcp/trade-capture/trade-capture-server.ts +2 -1
  104. package/src/store/fix-msg-memory-store.ts +2 -1
  105. package/src/transport/ascii/ascii-msg-transmitter.ts +2 -1
  106. package/src/transport/ascii/ascii-session.ts +2 -1
  107. package/src/transport/http/http-acceptor-listener.ts +2 -1
  108. package/src/transport/http/http-acceptor.ts +2 -1
  109. package/src/transport/http/http-initiator.ts +2 -1
  110. package/src/transport/http/http-json-sample-adapter.ts +1 -1
  111. package/src/transport/session/fix-session.ts +2 -1
  112. package/src/transport/session/session-registry.ts +1 -1
  113. package/src/transport/tcp/recovering-tcp-initiator.ts +2 -1
  114. package/src/transport/tcp/tcp-acceptor-listener.ts +4 -2
  115. package/src/transport/tcp/tcp-acceptor.ts +2 -1
  116. package/src/transport/tcp/tcp-initiator-connector.ts +4 -2
  117. package/src/transport/tcp/tcp-initiator.ts +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton-session.js","sourceRoot":"","sources":["../../../../src/sample/tcp/skeleton/skeleton-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\nimport { ILooseObject } from '../../../collections/collection'\nimport { FixMsgStoreRecord } from '../../../store'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../../runtime'\n\n@injectable()\nexport class SkeletonSession extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject('logoutSeconds') public readonly logoutSeconds: number,\n @inject('useInMemoryStore') public useInMemoryStore: boolean) {\n super(config)\n this.logReceivedMsgs = true\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n this.logger = config.logFactory.logger(`${this.me}`)\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n // dispatch messages\n if (this.useInMemoryStore) {\n const rec = FixMsgStoreRecord.toMsgStoreRecord(view)\n this.store?.put(rec).then(r => {\n this.logger.info(`store state ${JSON.stringify(r, null, 4)}`)\n this.dispatch(msgType, view)\n }).catch(e => {\n this.logger.error(e)\n })\n } else {\n this.dispatch(msgType, view)\n }\n }\n\n private dispatch (msgType: string, view: MsgView): void {\n const o = view.toObject()\n switch (msgType) {\n default: {\n this.logger.info(`received message type ${msgType} ${JSON.stringify(o, null, 4)}`)\n break\n }\n }\n }\n\n public sendMessage (msgType: string, obj: ILooseObject): void {\n this.send(msgType, obj)\n }\n\n protected onDecoded (msgType: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (msgType: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n this.logger.info(`peer logs in user ${user}`)\n return true\n }\n\n protected onReady (view: MsgView): void {\n this.logger.info('onReady')\n const logoutSeconds = this.logoutSeconds\n const t = this.config?.description?.application?.type\n switch (t) {\n case 'initiator': {\n this.logger.info(`will logout after ${logoutSeconds}`)\n setTimeout(() => {\n this.done()\n }, logoutSeconds * 1000)\n break\n }\n\n case 'acceptor': {\n this.logger.info('acceptor is ready for requests')\n break\n }\n\n default: {\n this.logger.warning(`unknown type ${t}`)\n break\n }\n }\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n }\n}\n"]}
1
+ {"version":3,"file":"skeleton-session.js","sourceRoot":"","sources":["../../../../src/sample/tcp/skeleton/skeleton-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\nimport { ILooseObject } from '../../../collections/collection'\nimport { FixMsgStoreRecord } from '../../../store'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../../runtime'\n\n@injectable()\nexport class SkeletonSession extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig,\n @inject('logoutSeconds') public readonly logoutSeconds: number,\n @inject('useInMemoryStore') public useInMemoryStore: boolean) {\n super(config)\n this.logReceivedMsgs = true\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n this.logger = config.logFactory.logger(`${this.me}`, { component: 'SkeletonSession', app: this.me })\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n // dispatch messages\n if (this.useInMemoryStore) {\n const rec = FixMsgStoreRecord.toMsgStoreRecord(view)\n this.store?.put(rec).then(r => {\n this.logger.info(`store state ${JSON.stringify(r, null, 4)}`)\n this.dispatch(msgType, view)\n }).catch(e => {\n this.logger.error(e)\n })\n } else {\n this.dispatch(msgType, view)\n }\n }\n\n private dispatch (msgType: string, view: MsgView): void {\n const o = view.toObject()\n switch (msgType) {\n default: {\n this.logger.info(`received message type ${msgType} ${JSON.stringify(o, null, 4)}`)\n break\n }\n }\n }\n\n public sendMessage (msgType: string, obj: ILooseObject): void {\n this.send(msgType, obj)\n }\n\n protected onDecoded (msgType: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (msgType: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n this.logger.info(`peer logs in user ${user}`)\n return true\n }\n\n protected onReady (view: MsgView): void {\n this.logger.info('onReady')\n const logoutSeconds = this.logoutSeconds\n const t = this.config?.description?.application?.type\n switch (t) {\n case 'initiator': {\n this.logger.info(`will logout after ${logoutSeconds}`)\n setTimeout(() => {\n this.done()\n }, logoutSeconds * 1000)\n break\n }\n\n case 'acceptor': {\n this.logger.info('acceptor is ready for requests')\n break\n }\n\n default: {\n this.logger.warning(`unknown type ${t}`)\n break\n }\n }\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n }\n}\n"]}
@@ -12,7 +12,7 @@ class TradeCaptureClient extends transport_1.AsciiSession {
12
12
  this.logReceivedMsgs = true;
13
13
  this.reports = new Map();
14
14
  this.fixLog = config.logFactory.plain(`jsfix.${(_b = (_a = config === null || config === void 0 ? void 0 : config.description) === null || _a === void 0 ? void 0 : _a.application) === null || _b === void 0 ? void 0 : _b.name}.txt`);
15
- this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`);
15
+ this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`, { component: 'TradeCaptureClient', app: this.me });
16
16
  }
17
17
  onApplicationMsg(msgType, view) {
18
18
  this.logger.info(`${view.toJson()}`);
@@ -1 +1 @@
1
- {"version":3,"file":"trade-capture-client.js","sourceRoot":"","sources":["../../../../src/sample/tcp/trade-capture/trade-capture-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { MsgType } from '../../../types'\nimport {\n ITradeCaptureReport, ITradeCaptureReportRequest,\n ITradeCaptureReportRequestAck\n} from '../../../types/FIX4.4/repo'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\nimport { TradeFactory } from './trade-factory'\n\nexport class TradeCaptureClient extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n private readonly reports: Map<string, ITradeCaptureReport>\n\n constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.logReceivedMsgs = true\n this.reports = new Map<string, ITradeCaptureReport>()\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`)\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n this.logger.info(`${view.toJson()}`)\n switch (msgType) {\n case MsgType.TradeCaptureReport: {\n // create an object and cast to the interface\n const tc: ITradeCaptureReport = view.toObject() as ITradeCaptureReport\n this.reports.set(tc.TradeReportID, tc)\n this.logger.info(`[reports: ${this.reports.size}] received tc ExecID = ${tc.ExecID} TradeReportID = ${tc.TradeReportID} Symbol = ${tc.Instrument.Symbol} ${tc.LastQty} @ ${tc.LastPx}`)\n break\n }\n\n case MsgType.TradeCaptureReportRequestAck: {\n const tc: ITradeCaptureReportRequestAck = view.toObject() as ITradeCaptureReportRequestAck\n this.logger.info(`received tcr ack ${tc.TradeRequestID} ${tc.TradeRequestStatus}`)\n break\n }\n }\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n }\n\n protected onDecoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n private logoutTimer (logoutSeconds: number = 32): void {\n setTimeout(() => {\n this.done()\n }, logoutSeconds * 1000)\n }\n\n protected onReady (view: MsgView): void {\n this.logger.info('ready')\n const tcr: ITradeCaptureReportRequest = TradeFactory.tradeCaptureReportRequest('all-trades', new Date())\n // send request to server\n this.send(MsgType.TradeCaptureReportRequest, tcr)\n const logoutSeconds = 32\n this.logger.info(`will logout after ${logoutSeconds}`)\n this.logoutTimer()\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n this.logger.info(`onLogon user ${user} ${password?.length}`)\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"trade-capture-client.js","sourceRoot":"","sources":["../../../../src/sample/tcp/trade-capture/trade-capture-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { MsgType } from '../../../types'\nimport {\n ITradeCaptureReport, ITradeCaptureReportRequest,\n ITradeCaptureReportRequestAck\n} from '../../../types/FIX4.4/repo'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\nimport { TradeFactory } from './trade-factory'\n\nexport class TradeCaptureClient extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n private readonly reports: Map<string, ITradeCaptureReport>\n\n constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.logReceivedMsgs = true\n this.reports = new Map<string, ITradeCaptureReport>()\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`,\n { component: 'TradeCaptureClient', app: this.me })\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n this.logger.info(`${view.toJson()}`)\n switch (msgType) {\n case MsgType.TradeCaptureReport: {\n // create an object and cast to the interface\n const tc: ITradeCaptureReport = view.toObject() as ITradeCaptureReport\n this.reports.set(tc.TradeReportID, tc)\n this.logger.info(`[reports: ${this.reports.size}] received tc ExecID = ${tc.ExecID} TradeReportID = ${tc.TradeReportID} Symbol = ${tc.Instrument.Symbol} ${tc.LastQty} @ ${tc.LastPx}`)\n break\n }\n\n case MsgType.TradeCaptureReportRequestAck: {\n const tc: ITradeCaptureReportRequestAck = view.toObject() as ITradeCaptureReportRequestAck\n this.logger.info(`received tcr ack ${tc.TradeRequestID} ${tc.TradeRequestStatus}`)\n break\n }\n }\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n }\n\n protected onDecoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n private logoutTimer (logoutSeconds: number = 32): void {\n setTimeout(() => {\n this.done()\n }, logoutSeconds * 1000)\n }\n\n protected onReady (view: MsgView): void {\n this.logger.info('ready')\n const tcr: ITradeCaptureReportRequest = TradeFactory.tradeCaptureReportRequest('all-trades', new Date())\n // send request to server\n this.send(MsgType.TradeCaptureReportRequest, tcr)\n const logoutSeconds = 32\n this.logger.info(`will logout after ${logoutSeconds}`)\n this.logoutTimer()\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n this.logger.info(`onLogon user ${user} ${password?.length}`)\n return true\n }\n}\n"]}
@@ -13,7 +13,7 @@ class TradeCaptureServer extends transport_1.AsciiSession {
13
13
  this.tradeFactory = new trade_factory_1.TradeFactory();
14
14
  this.timerHandle = null;
15
15
  this.logReceivedMsgs = true;
16
- this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`);
16
+ this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`, { component: 'TradeCaptureServer', app: this.me });
17
17
  this.fixLog = config.logFactory.plain(`jsfix.${(_b = (_a = config === null || config === void 0 ? void 0 : config.description) === null || _a === void 0 ? void 0 : _a.application) === null || _b === void 0 ? void 0 : _b.name}.txt`);
18
18
  }
19
19
  onApplicationMsg(msgType, view) {
@@ -1 +1 @@
1
- {"version":3,"file":"trade-capture-server.js","sourceRoot":"","sources":["../../../../src/sample/tcp/trade-capture/trade-capture-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { MsgType } from '../../../types'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\n// interfaces generated by compiler to make messages easy in an IDE\nimport {\n ITradeCaptureReportRequest, ITradeCaptureReport, MsgTag, SessionRejectReason,\n SubscriptionRequestType, TradeRequestStatus\n} from '../../../types/FIX4.4/repo'\nimport { TradeFactory } from './trade-factory'\n\nexport class TradeCaptureServer extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n private readonly tradeFactory: TradeFactory = new TradeFactory()\n private timerHandle: NodeJS.Timeout | null = null\n\n constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.logReceivedMsgs = true\n this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`)\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n this.logger.info(`${view.toJson()}`)\n switch (msgType) {\n case MsgType.TradeCaptureReportRequest: {\n this.tradeCaptureReportRequest(view.toObject() as ITradeCaptureReportRequest)\n break\n }\n\n default: {\n const seqNum = view.getTyped(MsgTag.MsgSeqNum)\n const msg = this.config.factory?.reject(msgType, seqNum as number, `${this.me}: unexpected msg type '${msgType}'`, SessionRejectReason.InvalidMsgType)\n if (msg) {\n this.send(msgType, msg)\n }\n break\n }\n }\n }\n\n protected onReady (_: MsgView): void {\n // server waits for client to make a request\n this.logger.info('ready for requests.')\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n if (this.timerHandle) {\n clearInterval(this.timerHandle)\n }\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n return true\n }\n\n protected onDecoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n private tradeCaptureReportRequest (tcr: ITradeCaptureReportRequest): void {\n this.logger.info(`received tcr ${tcr.TradeRequestID}`)\n // send back an ack.\n this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Accepted))\n // send some trades\n const batch: ITradeCaptureReport[] = this.tradeFactory.batchOfTradeCaptureReport(5)\n batch.forEach((tc: ITradeCaptureReport) => {\n this.send(MsgType.TradeCaptureReport, tc)\n })\n this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Completed))\n // start sending the odd 'live' trade\n switch (tcr.SubscriptionRequestType) {\n case SubscriptionRequestType.SnapshotAndUpdates: {\n this.timerHandle = setInterval(() => {\n if (Math.random() < 0.4) {\n const tc: ITradeCaptureReport = this.tradeFactory.singleTradeCaptureReport()\n this.send(MsgType.TradeCaptureReport, tc)\n }\n }, 5000)\n break\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"trade-capture-server.js","sourceRoot":"","sources":["../../../../src/sample/tcp/trade-capture/trade-capture-server.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../../buffer'\nimport { AsciiSession } from '../../../transport'\nimport { MsgType } from '../../../types'\nimport { IJsFixLogger, IJsFixConfig } from '../../../config'\n// interfaces generated by compiler to make messages easy in an IDE\nimport {\n ITradeCaptureReportRequest, ITradeCaptureReport, MsgTag, SessionRejectReason,\n SubscriptionRequestType, TradeRequestStatus\n} from '../../../types/FIX4.4/repo'\nimport { TradeFactory } from './trade-factory'\n\nexport class TradeCaptureServer extends AsciiSession {\n private readonly logger: IJsFixLogger\n private readonly fixLog: IJsFixLogger\n private readonly tradeFactory: TradeFactory = new TradeFactory()\n private timerHandle: NodeJS.Timeout | null = null\n\n constructor (public readonly config: IJsFixConfig) {\n super(config)\n this.logReceivedMsgs = true\n this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`,\n { component: 'TradeCaptureServer', app: this.me })\n this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)\n }\n\n protected onApplicationMsg (msgType: string, view: MsgView): void {\n this.logger.info(`${view.toJson()}`)\n switch (msgType) {\n case MsgType.TradeCaptureReportRequest: {\n this.tradeCaptureReportRequest(view.toObject() as ITradeCaptureReportRequest)\n break\n }\n\n default: {\n const seqNum = view.getTyped(MsgTag.MsgSeqNum)\n const msg = this.config.factory?.reject(msgType, seqNum as number, `${this.me}: unexpected msg type '${msgType}'`, SessionRejectReason.InvalidMsgType)\n if (msg) {\n this.send(msgType, msg)\n }\n break\n }\n }\n }\n\n protected onReady (_: MsgView): void {\n // server waits for client to make a request\n this.logger.info('ready for requests.')\n }\n\n protected onStopped (): void {\n this.logger.info('stopped')\n if (this.timerHandle) {\n clearInterval(this.timerHandle)\n }\n }\n\n protected onLogon (view: MsgView, user: string, password: string): boolean {\n return true\n }\n\n protected onDecoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n protected onEncoded (_: string, txt: string): void {\n this.fixLog.info(txt)\n }\n\n private tradeCaptureReportRequest (tcr: ITradeCaptureReportRequest): void {\n this.logger.info(`received tcr ${tcr.TradeRequestID}`)\n // send back an ack.\n this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Accepted))\n // send some trades\n const batch: ITradeCaptureReport[] = this.tradeFactory.batchOfTradeCaptureReport(5)\n batch.forEach((tc: ITradeCaptureReport) => {\n this.send(MsgType.TradeCaptureReport, tc)\n })\n this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Completed))\n // start sending the odd 'live' trade\n switch (tcr.SubscriptionRequestType) {\n case SubscriptionRequestType.SnapshotAndUpdates: {\n this.timerHandle = setInterval(() => {\n if (Math.random() < 0.4) {\n const tc: ITradeCaptureReport = this.tradeFactory.singleTradeCaptureReport()\n this.send(MsgType.TradeCaptureReport, tc)\n }\n }, 5000)\n break\n }\n }\n }\n}\n"]}
@@ -27,7 +27,7 @@ class FixMsgMemoryStore {
27
27
  types_1.MsgType.TestRequest,
28
28
  types_1.MsgType.SequenceReset
29
29
  ];
30
- this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`);
30
+ this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`, { component: 'FixMsgMemoryStore', store: this.id });
31
31
  this.setExcMsgType([]);
32
32
  }
33
33
  static search(ar, target, isDate) {
@@ -1 +1 @@
1
- {"version":3,"file":"fix-msg-memory-store.js","sourceRoot":"","sources":["../../src/store/fix-msg-memory-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\nimport { IJsFixConfig, IJsFixLogger } from '../config'\nimport { IFixMsgStoreRecord } from './fix-msg-store-record'\nimport { MsgType } from '../types'\nimport { IFixMsgStoreState } from './fix-msg-store-state'\n\nexport class FixMsgMemoryStore implements IFixMsgStore {\n protected readonly logger: IJsFixLogger\n public heartbeat: boolean = true\n private sortedBySeqNum: IFixMsgStoreRecord[] = []\n private readonly excluded: Map<string, boolean> = new Map<string, boolean>()\n public length: number = 0\n private readonly sessionMessages: string[] = [\n MsgType.Logon,\n MsgType.Logout,\n MsgType.ResendRequest,\n MsgType.Heartbeat,\n MsgType.TestRequest,\n MsgType.SequenceReset\n ]\n\n public constructor (public readonly id: string, public readonly config: IJsFixConfig) {\n this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`)\n this.setExcMsgType([])\n }\n\n public static search (ar: IFixMsgStoreRecord[], target: number, isDate?: boolean): number {\n let m: number = 0\n let n: number = ar.length - 1\n while (m <= n) {\n const k: number = (n + m) >> 1\n const check: number = isDate ? ar[k].timestamp.getDate() : ar[k].seqNum\n const cmp: number = target - check\n if (cmp > 0) {\n m = k + 1\n } else if (cmp < 0) {\n n = k - 1\n } else {\n return k\n }\n }\n return -m - 1\n }\n\n public async getMsgType (msgType: string): Promise<IFixMsgStoreRecord[]> {\n return await new Promise((resolve, reject: any) => {\n const data = this.sortedBySeqNum\n if (data === null) reject(new Error('no store'))\n const required = data.filter(x => x.msgType === msgType)\n resolve(required)\n })\n }\n\n private getIndex (seq: number): number {\n const arr = this.sortedBySeqNum\n let index = FixMsgMemoryStore.search(arr, seq)\n if (index < 0) {\n index = -(index + 1)\n }\n return index\n }\n\n private bounded (fromIdx: number, toIdx: number): boolean {\n const arr = this.sortedBySeqNum\n return fromIdx >= 0 && fromIdx <= arr.length && toIdx >= fromIdx && toIdx <= arr.length\n }\n\n public async get (from: number): Promise<IFixMsgStoreRecord> {\n return await new Promise((resolve, reject) => {\n this.getSeqNumRange(from, from).then(res => {\n if (res.length > 0) {\n const record = res[0].clone()\n resolve(record)\n } else {\n reject(new Error(`${from} not in store`))\n }\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public async getSeqNumRange (from: number, to?: number): Promise<IFixMsgStoreRecord[]> {\n return await new Promise((resolve, reject) => {\n to = to ?? 0\n const arr = this.sortedBySeqNum\n if (from < 0) reject(new Error(`illegal from ${from}`))\n if (to < 0) reject(new Error(`illegal to ${to}`))\n const fromIdx = this.getIndex(from)\n const toEnd = to === 0 || isNaN(to)\n const toIdx = toEnd ? arr.length - 1 : this.getIndex(to)\n if (this.bounded(fromIdx, toIdx)) {\n resolve(arr.slice(fromIdx, toIdx + 1))\n } else {\n reject(new Error(`incorrect bounds from=${from}, fromIdx=${fromIdx}, to=${to}, toIdx=${toIdx}, length=${arr.length}`))\n }\n })\n }\n\n private buildState (): IFixMsgStoreState {\n const arr = this.sortedBySeqNum\n return {\n firstSeq: arr.length > 0 ? arr[0].seqNum : 0,\n lastSeq: arr.length > 0 ? arr[arr.length - 1].seqNum : 0,\n id: this.id,\n length: arr.length\n }\n }\n\n public async getState (): Promise<IFixMsgStoreState> {\n return await new Promise((resolve, reject) => {\n try {\n resolve(this.buildState())\n } catch (e) {\n reject(e)\n }\n })\n }\n\n public async clear (): Promise<IFixMsgStoreState> {\n this.sortedBySeqNum = []\n return await new Promise((resolve, reject) => {\n try {\n resolve(this.buildState())\n } catch (e) {\n reject(e)\n }\n })\n }\n\n public async put (record: IFixMsgStoreRecord): Promise<IFixMsgStoreState> {\n return await new Promise((resolve, reject) => {\n if (this.excluded.has(record.msgType)) {\n resolve(this.buildState())\n } else {\n const arr = this.sortedBySeqNum\n const idx = FixMsgMemoryStore.search(arr, record.seqNum)\n if (idx >= 0) { // seen this before\n reject(new Error(`this seqNum ${record.seqNum} already in store`))\n }\n arr.splice(-idx, 0, record)\n this.length = arr.length\n resolve(this.buildState())\n }\n })\n }\n\n public setExcMsgType (exclude: string[]): void {\n this.excluded.clear()\n this.excludeRange(this.sessionMessages)\n this.excludeRange(exclude)\n }\n\n private excludeRange (exclude: string[]): void {\n exclude.forEach(s => {\n this.excluded.set(s, true)\n })\n }\n\n async exists (seqNum: number): Promise<boolean> {\n return await new Promise((resolve, reject) => {\n try {\n const arr = this.sortedBySeqNum\n const index = FixMsgMemoryStore.search(arr, seqNum)\n resolve(index >= 0)\n } catch (e) {\n reject(e)\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"fix-msg-memory-store.js","sourceRoot":"","sources":["../../src/store/fix-msg-memory-store.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,oCAAkC;AAGlC,MAAa,iBAAiB;IAe5B,YAAoC,EAAU,EAAkB,MAAoB;QAAhD,OAAE,GAAF,EAAE,CAAQ;QAAkB,WAAM,GAAN,MAAM,CAAc;QAb7E,cAAS,GAAY,IAAI,CAAA;QACxB,mBAAc,GAAyB,EAAE,CAAA;QAChC,aAAQ,GAAyB,IAAI,GAAG,EAAmB,CAAA;QACrE,WAAM,GAAW,CAAC,CAAA;QACR,oBAAe,GAAa;YAC3C,eAAO,CAAC,KAAK;YACb,eAAO,CAAC,MAAM;YACd,eAAO,CAAC,aAAa;YACrB,eAAO,CAAC,SAAS;YACjB,eAAO,CAAC,WAAW;YACnB,eAAO,CAAC,aAAa;SACtB,CAAA;QAGC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,oBAAoB,EACnE,EAAE,SAAS,EAAE,mBAAmB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;QACrD,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;IACxB,CAAC;IAEM,MAAM,CAAC,MAAM,CAAE,EAAwB,EAAE,MAAc,EAAE,MAAgB;QAC9E,IAAI,CAAC,GAAW,CAAC,CAAA;QACjB,IAAI,CAAC,GAAW,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;QAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACd,MAAM,CAAC,GAAW,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;YAC9B,MAAM,KAAK,GAAW,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YACvE,MAAM,GAAG,GAAW,MAAM,GAAG,KAAK,CAAA;YAClC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,CAAC;iBAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACnB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACX,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,CAAA;YACV,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC,GAAG,CAAC,CAAA;IACf,CAAC;IAEY,UAAU,CAAE,OAAe;;YACtC,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAW,EAAE,EAAE;gBAChD,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAA;gBAChC,IAAI,IAAI,KAAK,IAAI;oBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;gBAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAA;gBACxD,OAAO,CAAC,QAAQ,CAAC,CAAA;YACnB,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEO,QAAQ,CAAE,GAAW;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;QAC/B,IAAI,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAC9C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QACtB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,OAAO,CAAE,OAAe,EAAE,KAAa;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;QAC/B,OAAO,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,CAAA;IACzF,CAAC;IAEY,GAAG,CAAE,IAAY;;YAC5B,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;oBACzC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnB,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAA;wBAC7B,OAAO,CAAC,MAAM,CAAC,CAAA;oBACjB,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,eAAe,CAAC,CAAC,CAAA;oBAC3C,CAAC;gBACH,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEY,cAAc,CAAE,IAAY,EAAE,EAAW;;YACpD,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,EAAE,GAAG,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,CAAA;gBACZ,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;gBAC/B,IAAI,IAAI,GAAG,CAAC;oBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,CAAA;gBACvD,IAAI,EAAE,GAAG,CAAC;oBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAA;gBACjD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;gBACnC,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAA;gBACnC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;gBACxD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;oBACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAA;gBACxC,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,IAAI,aAAa,OAAO,QAAQ,EAAE,WAAW,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;gBACxH,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEO,UAAU;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;QAC/B,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxD,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAA;IACH,CAAC;IAEY,QAAQ;;YACnB,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC5B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEY,KAAK;;YAChB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;YACxB,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC;oBACH,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC5B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEY,GAAG,CAAE,MAA0B;;YAC1C,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBACtC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC5B,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;oBAC/B,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;oBACxD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;wBACb,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,MAAM,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAA;oBACpE,CAAC;oBACD,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;oBAC3B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;oBACxB,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;gBAC5B,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;IAEM,aAAa,CAAE,OAAiB;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;QACrB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QACvC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAEO,YAAY,CAAE,OAAiB;QACrC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QAC5B,CAAC,CAAC,CAAA;IACJ,CAAC;IAEK,MAAM,CAAE,MAAc;;YAC1B,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAA;oBAC/B,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;oBACnD,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAA;gBACrB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KAAA;CACF;AArKD,8CAqKC","sourcesContent":["import { IFixMsgStore } from './fix-msg-store'\nimport { IJsFixConfig, IJsFixLogger } from '../config'\nimport { IFixMsgStoreRecord } from './fix-msg-store-record'\nimport { MsgType } from '../types'\nimport { IFixMsgStoreState } from './fix-msg-store-state'\n\nexport class FixMsgMemoryStore implements IFixMsgStore {\n protected readonly logger: IJsFixLogger\n public heartbeat: boolean = true\n private sortedBySeqNum: IFixMsgStoreRecord[] = []\n private readonly excluded: Map<string, boolean> = new Map<string, boolean>()\n public length: number = 0\n private readonly sessionMessages: string[] = [\n MsgType.Logon,\n MsgType.Logout,\n MsgType.ResendRequest,\n MsgType.Heartbeat,\n MsgType.TestRequest,\n MsgType.SequenceReset\n ]\n\n public constructor (public readonly id: string, public readonly config: IJsFixConfig) {\n this.logger = config.logFactory.logger(`${this.id}:FixMsgMemoryStore`,\n { component: 'FixMsgMemoryStore', store: this.id })\n this.setExcMsgType([])\n }\n\n public static search (ar: IFixMsgStoreRecord[], target: number, isDate?: boolean): number {\n let m: number = 0\n let n: number = ar.length - 1\n while (m <= n) {\n const k: number = (n + m) >> 1\n const check: number = isDate ? ar[k].timestamp.getDate() : ar[k].seqNum\n const cmp: number = target - check\n if (cmp > 0) {\n m = k + 1\n } else if (cmp < 0) {\n n = k - 1\n } else {\n return k\n }\n }\n return -m - 1\n }\n\n public async getMsgType (msgType: string): Promise<IFixMsgStoreRecord[]> {\n return await new Promise((resolve, reject: any) => {\n const data = this.sortedBySeqNum\n if (data === null) reject(new Error('no store'))\n const required = data.filter(x => x.msgType === msgType)\n resolve(required)\n })\n }\n\n private getIndex (seq: number): number {\n const arr = this.sortedBySeqNum\n let index = FixMsgMemoryStore.search(arr, seq)\n if (index < 0) {\n index = -(index + 1)\n }\n return index\n }\n\n private bounded (fromIdx: number, toIdx: number): boolean {\n const arr = this.sortedBySeqNum\n return fromIdx >= 0 && fromIdx <= arr.length && toIdx >= fromIdx && toIdx <= arr.length\n }\n\n public async get (from: number): Promise<IFixMsgStoreRecord> {\n return await new Promise((resolve, reject) => {\n this.getSeqNumRange(from, from).then(res => {\n if (res.length > 0) {\n const record = res[0].clone()\n resolve(record)\n } else {\n reject(new Error(`${from} not in store`))\n }\n }).catch(e => {\n reject(e)\n })\n })\n }\n\n public async getSeqNumRange (from: number, to?: number): Promise<IFixMsgStoreRecord[]> {\n return await new Promise((resolve, reject) => {\n to = to ?? 0\n const arr = this.sortedBySeqNum\n if (from < 0) reject(new Error(`illegal from ${from}`))\n if (to < 0) reject(new Error(`illegal to ${to}`))\n const fromIdx = this.getIndex(from)\n const toEnd = to === 0 || isNaN(to)\n const toIdx = toEnd ? arr.length - 1 : this.getIndex(to)\n if (this.bounded(fromIdx, toIdx)) {\n resolve(arr.slice(fromIdx, toIdx + 1))\n } else {\n reject(new Error(`incorrect bounds from=${from}, fromIdx=${fromIdx}, to=${to}, toIdx=${toIdx}, length=${arr.length}`))\n }\n })\n }\n\n private buildState (): IFixMsgStoreState {\n const arr = this.sortedBySeqNum\n return {\n firstSeq: arr.length > 0 ? arr[0].seqNum : 0,\n lastSeq: arr.length > 0 ? arr[arr.length - 1].seqNum : 0,\n id: this.id,\n length: arr.length\n }\n }\n\n public async getState (): Promise<IFixMsgStoreState> {\n return await new Promise((resolve, reject) => {\n try {\n resolve(this.buildState())\n } catch (e) {\n reject(e)\n }\n })\n }\n\n public async clear (): Promise<IFixMsgStoreState> {\n this.sortedBySeqNum = []\n return await new Promise((resolve, reject) => {\n try {\n resolve(this.buildState())\n } catch (e) {\n reject(e)\n }\n })\n }\n\n public async put (record: IFixMsgStoreRecord): Promise<IFixMsgStoreState> {\n return await new Promise((resolve, reject) => {\n if (this.excluded.has(record.msgType)) {\n resolve(this.buildState())\n } else {\n const arr = this.sortedBySeqNum\n const idx = FixMsgMemoryStore.search(arr, record.seqNum)\n if (idx >= 0) { // seen this before\n reject(new Error(`this seqNum ${record.seqNum} already in store`))\n }\n arr.splice(-idx, 0, record)\n this.length = arr.length\n resolve(this.buildState())\n }\n })\n }\n\n public setExcMsgType (exclude: string[]): void {\n this.excluded.clear()\n this.excludeRange(this.sessionMessages)\n this.excludeRange(exclude)\n }\n\n private excludeRange (exclude: string[]): void {\n exclude.forEach(s => {\n this.excluded.set(s, true)\n })\n }\n\n async exists (seqNum: number): Promise<boolean> {\n return await new Promise((resolve, reject) => {\n try {\n const arr = this.sortedBySeqNum\n const index = FixMsgMemoryStore.search(arr, seqNum)\n resolve(index >= 0)\n } catch (e) {\n reject(e)\n }\n })\n }\n}\n"]}
@@ -45,7 +45,7 @@ let AsciiMsgTransmitter = class AsciiMsgTransmitter extends msg_transmitter_1.Ms
45
45
  reportUnknownFields(config) {
46
46
  var _a, _b;
47
47
  const name = (_b = (_a = config.description.application) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'na';
48
- const logger = config.logFactory.logger(`${name}:encoder`);
48
+ const logger = config.logFactory.logger(`${name}:encoder`, { component: 'AsciiMsgTransmitter', app: name });
49
49
  const reported = new Set();
50
50
  this.encoder.onUnknownField = (fieldName, setName) => {
51
51
  const key = `${setName}.${fieldName}`;
@@ -1 +1 @@
1
- {"version":3,"file":"ascii-msg-transmitter.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-msg-transmitter.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars, AsciiEncoder, TimeFormatter } from '../../buffer/ascii'\nimport { MsgTransmitter } from '../msg-transmitter'\nimport { ILooseObject } from '../../collections/collection'\nimport { IContainedSet } from '../../dictionary/contained'\nimport { MessageDefinition } from '../../dictionary/definition'\nimport { IJsFixConfig } from '../../config'\nimport { IStandardHeader } from '../../types/FIX4.4/repo'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ElasticBuffer } from '../../buffer'\n\n@injectable()\nexport class AsciiMsgTransmitter extends MsgTransmitter {\n public msgSeqNum: number\n public time: Date\n\n private readonly header: IContainedSet | undefined\n private readonly trailer: IContainedSet | undefined\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config.sessionContainer.resolve<ElasticBuffer>(DITokens.TransmitBuffer), config.definitions, config.description)\n this.msgSeqNum = (config.description.LastSentSeqNum ?? 0) + 1 // adding 1 as this the next sequence # to use.\n const buffer = this.buffer\n const tf: TimeFormatter = new TimeFormatter(buffer)\n this.encoder = new AsciiEncoder(buffer, config.definitions, tf,\n config.delimiter ?? AsciiChars.Soh,\n config.logDelimiter ?? AsciiChars.Pipe)\n const components = config.definitions.component\n this.header = components.get('StandardHeader')\n this.trailer = components.get('StandardTrailer')\n this.reportUnknownFields(config)\n }\n\n /**\n * A field the dictionary does not declare on the message being encoded has no tag,\n * so it cannot be written and is dropped. Say so once per offending field - the\n * alternative, and what this library did for years, is that a bespoke Logon tag\n * simply never appears on the wire and nothing anywhere explains why.\n */\n private reportUnknownFields (config: IJsFixConfig): void {\n const name = config.description.application?.name ?? 'na'\n const logger = config.logFactory.logger(`${name}:encoder`)\n const reported = new Set<string>()\n this.encoder.onUnknownField = (fieldName: string, setName: string) => {\n const key = `${setName}.${fieldName}`\n if (reported.has(key)) return\n reported.add(key)\n logger.warning(`field '${fieldName}' is not declared on ${setName} in this dictionary - it will not be sent`)\n this.emit('unknown-field', fieldName, setName)\n }\n }\n\n private checksum (): number {\n const buffer = this.buffer\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n let checksum: number = buffer.sum()\n if (encoder.delimiter !== encoder.logDelimiter) {\n const changes = encoder.tags.nextTagPos\n checksum -= changes * encoder.logDelimiter\n checksum += changes * encoder.delimiter\n }\n checksum = checksum % 256\n return checksum\n }\n\n public encodeMessage (msgType: string, obj: ILooseObject): (ILooseObject | null) {\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n const factory = this.config.factory\n let headerProps: Partial<IStandardHeader> = {}\n const { StandardHeader, ...bodyProps } = obj\n if (StandardHeader) {\n const { BeginString, BodyLength, MsgType, SenderCompID, SendingTime, TargetCompID, TargetSubID, ...hp } = StandardHeader\n headerProps = hp // pick up any optional applied by application\n headerProps.OrigSendingTime = SendingTime // when first sent\n }\n\n const msgSeqNum = this.msgSeqNum\n const sendingTime = this.time || new Date()\n const hdr: ILooseObject | null = factory?.header(msgType, msgSeqNum, sendingTime, headerProps) ?? null\n // Only increment sequence number if this is not a duplicate message.\n if (!hdr) return null\n if (!headerProps.PossDupFlag) {\n this.msgSeqNum++\n }\n\n const buffer = this.buffer\n buffer.reset()\n const msgDef: MessageDefinition | undefined = this.definitions.message.get(msgType)\n if (!msgDef) {\n this.emit('error', new Error(`ascii transmitter cannot find definition for ${msgType}`))\n return null\n }\n const headerName: string = this.header?.name ?? 'header'\n const trailerName: string = this.trailer?.name ?? 'trailer'\n encoder.encode(hdr, headerName)\n encoder.encode(bodyProps, msgDef.name)\n const lenPos = encoder.bodyLengthPos\n const bodyLength: number = Math.max(4, this.config.description.BodyLengthChars ?? 7)\n const len = buffer.getPos() - encoder.msgTypePos\n buffer.patchPaddedNumberAtPos(lenPos, len, bodyLength)\n const checksum: number = this.checksum()\n const trl: ILooseObject | null = factory?.trailer(checksum) ?? null\n if (trl) {\n encoder.encode(trl, trailerName)\n }\n return hdr\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-msg-transmitter.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-msg-transmitter.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsciiChars, AsciiEncoder, TimeFormatter } from '../../buffer/ascii'\nimport { MsgTransmitter } from '../msg-transmitter'\nimport { ILooseObject } from '../../collections/collection'\nimport { IContainedSet } from '../../dictionary/contained'\nimport { MessageDefinition } from '../../dictionary/definition'\nimport { IJsFixConfig } from '../../config'\nimport { IStandardHeader } from '../../types/FIX4.4/repo'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { ElasticBuffer } from '../../buffer'\n\n@injectable()\nexport class AsciiMsgTransmitter extends MsgTransmitter {\n public msgSeqNum: number\n public time: Date\n\n private readonly header: IContainedSet | undefined\n private readonly trailer: IContainedSet | undefined\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config.sessionContainer.resolve<ElasticBuffer>(DITokens.TransmitBuffer), config.definitions, config.description)\n this.msgSeqNum = (config.description.LastSentSeqNum ?? 0) + 1 // adding 1 as this the next sequence # to use.\n const buffer = this.buffer\n const tf: TimeFormatter = new TimeFormatter(buffer)\n this.encoder = new AsciiEncoder(buffer, config.definitions, tf,\n config.delimiter ?? AsciiChars.Soh,\n config.logDelimiter ?? AsciiChars.Pipe)\n const components = config.definitions.component\n this.header = components.get('StandardHeader')\n this.trailer = components.get('StandardTrailer')\n this.reportUnknownFields(config)\n }\n\n /**\n * A field the dictionary does not declare on the message being encoded has no tag,\n * so it cannot be written and is dropped. Say so once per offending field - the\n * alternative, and what this library did for years, is that a bespoke Logon tag\n * simply never appears on the wire and nothing anywhere explains why.\n */\n private reportUnknownFields (config: IJsFixConfig): void {\n const name = config.description.application?.name ?? 'na'\n const logger = config.logFactory.logger(`${name}:encoder`,\n { component: 'AsciiMsgTransmitter', app: name })\n const reported = new Set<string>()\n this.encoder.onUnknownField = (fieldName: string, setName: string) => {\n const key = `${setName}.${fieldName}`\n if (reported.has(key)) return\n reported.add(key)\n logger.warning(`field '${fieldName}' is not declared on ${setName} in this dictionary - it will not be sent`)\n this.emit('unknown-field', fieldName, setName)\n }\n }\n\n private checksum (): number {\n const buffer = this.buffer\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n let checksum: number = buffer.sum()\n if (encoder.delimiter !== encoder.logDelimiter) {\n const changes = encoder.tags.nextTagPos\n checksum -= changes * encoder.logDelimiter\n checksum += changes * encoder.delimiter\n }\n checksum = checksum % 256\n return checksum\n }\n\n public encodeMessage (msgType: string, obj: ILooseObject): (ILooseObject | null) {\n const encoder: AsciiEncoder = this.encoder as AsciiEncoder\n const factory = this.config.factory\n let headerProps: Partial<IStandardHeader> = {}\n const { StandardHeader, ...bodyProps } = obj\n if (StandardHeader) {\n const { BeginString, BodyLength, MsgType, SenderCompID, SendingTime, TargetCompID, TargetSubID, ...hp } = StandardHeader\n headerProps = hp // pick up any optional applied by application\n headerProps.OrigSendingTime = SendingTime // when first sent\n }\n\n const msgSeqNum = this.msgSeqNum\n const sendingTime = this.time || new Date()\n const hdr: ILooseObject | null = factory?.header(msgType, msgSeqNum, sendingTime, headerProps) ?? null\n // Only increment sequence number if this is not a duplicate message.\n if (!hdr) return null\n if (!headerProps.PossDupFlag) {\n this.msgSeqNum++\n }\n\n const buffer = this.buffer\n buffer.reset()\n const msgDef: MessageDefinition | undefined = this.definitions.message.get(msgType)\n if (!msgDef) {\n this.emit('error', new Error(`ascii transmitter cannot find definition for ${msgType}`))\n return null\n }\n const headerName: string = this.header?.name ?? 'header'\n const trailerName: string = this.trailer?.name ?? 'trailer'\n encoder.encode(hdr, headerName)\n encoder.encode(bodyProps, msgDef.name)\n const lenPos = encoder.bodyLengthPos\n const bodyLength: number = Math.max(4, this.config.description.BodyLengthChars ?? 7)\n const len = buffer.getPos() - encoder.msgTypePos\n buffer.patchPaddedNumberAtPos(lenPos, len, bodyLength)\n const checksum: number = this.checksum()\n const trl: ILooseObject | null = factory?.trailer(checksum) ?? null\n if (trl) {\n encoder.encode(trl, trailerName)\n }\n return hdr\n }\n}\n"]}
@@ -491,7 +491,7 @@ class AsciiSession extends fix_session_1.FixSession {
491
491
  const logger = this.sessionLogger;
492
492
  logger.info(`wildcard acceptor: binding session identity to peer SenderCompID '${peerCompId}'`);
493
493
  (0, clone_session_description_1.asMutable)(this.config.description).TargetCompID = peerCompId;
494
- this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`);
494
+ this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`, { component: 'FixSession', app: this.me, peer: peerCompId });
495
495
  this.sessionId = new store_1.SessionId(this.config.description.BeginString, this.config.description.SenderCompId, peerCompId);
496
496
  this.sessionStore = this.storeFactory().create(this.sessionId);
497
497
  yield this.sessionStore.initialize();
@@ -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 MemorySessionStore, MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { asMutable } from '../session/clone-session-description'\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 /**\n * TargetCompID value which tells an acceptor to take its target from whichever\n * counterparty logs on, rather than from static configuration.\n */\n public static readonly WildcardCompId = '*'\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected coordinator: SessionSequenceCoordinator\n protected sessionStore: IFixSessionStore\n protected sessionId: SessionId\n private registered: boolean = false\n /** acceptor configured with TargetCompID '*' - identity comes from the peer Logon */\n protected readonly wildcardTarget: boolean\n private identityBound: boolean\n private bindInProgress: boolean = false\n private logonVerdictPending: boolean = false\n private readonly pendingRx: Array<{ msgType: string, view: MsgView }> = []\n private readonly clock: DefaultFixClock = new DefaultFixClock()\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 // A wildcard TargetCompID lets one acceptor serve counterparties it was not\n // statically configured for - the peer's SenderCompID becomes our target, and\n // therefore our SessionId and store, once the Logon arrives. An initiator has\n // to know who it is calling, so '*' is meaningless there.\n this.wildcardTarget = config.description.TargetCompID === AsciiSession.WildcardCompId\n if (this.wildcardTarget && this.initiator) {\n throw new Error(`TargetCompID '${AsciiSession.WildcardCompId}' is only valid for acceptors, not initiators`)\n }\n this.identityBound = !this.wildcardTarget\n\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n // Until the peer identifies itself there is nothing worth persisting, so a\n // wildcard session starts on a throwaway in-memory store. The real store -\n // keyed on the peer's comp id - is created by bindIdentity.\n this.sessionStore = this.wildcardTarget\n ? new MemorySessionStore(this.sessionId)\n : this.storeFactory().create(this.sessionId)\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n private storeFactory (): IFixSessionStoreFactory {\n // Priority: programmatic config > JSON store config > default in-memory\n return this.config.sessionStoreFactory ?? AsciiSession.createStoreFactory(this.config.description.store)\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 if (this.wildcardTarget && !this.identityBound) {\n // Nothing to recover yet - the SessionId is not known until the peer logs on,\n // so store initialisation, sequence sync and registry claim all happen in\n // bindIdentity. Resume and wait for the Logon.\n this.sessionLogger.info('wildcard acceptor: awaiting peer Logon to establish session identity')\n transport.duplex.readable?.resume()\n return await super.run(transport)\n }\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 // Claim this SessionId. A counterparty which reconnected before its previous\n // socket was detected as dead would otherwise leave two live sessions writing\n // to one store - see issue #153.\n this.claimSessionId()\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n /**\n * Take ownership of this SessionId in the registry, stopping whatever session\n * held it before. Idempotent - a session reused across reconnects (the\n * RecoveringTcpInitiator pattern) simply re-registers itself.\n */\n private claimSessionId (): void {\n const registry = this.config.sessionRegistry\n if (!registry) return\n const stoppedOld = registry.register(this.sessionId, this)\n if (stoppedOld) {\n this.sessionLogger.info(`session registry stopped previous session for ${this.sessionId.toString()}`)\n }\n this.registered = true\n }\n\n protected override onSessionStopping (): void {\n super.onSessionStopping()\n const registry = this.config.sessionRegistry\n if (!registry || !this.registered) return\n this.registered = false\n this.sessionLogger.info(`session stopping - unregistering from registry: ${this.sessionId.toString()}`)\n registry.unregister(this.sessionId, this)\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)\n })\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (this.wildcardTarget && !this.identityBound) {\n this.onMsgBeforeIdentity(msgType, view)\n return\n }\n if (this.logonVerdictPending) {\n // the application is still deciding whether to accept this peer - hold anything\n // it sends in the meantime rather than acting on it (see awaitLogonVerdict)\n this.sessionLogger.info(`queueing '${msgType}' received while awaiting logon verdict`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n this.dispatchMsg(msgType, view)\n }\n\n /**\n * Message handling for a wildcard acceptor which has not yet learned who it is\n * talking to. The first message must be a Logon; it carries the peer's\n * SenderCompID, which becomes our TargetCompID and hence our SessionId and store.\n *\n * Binding is asynchronous (the store may have to be read from disk) while message\n * delivery is not: the parser emits every message it finds in a TCP segment in one\n * synchronous burst, and a view is only valid for the duration of its own event -\n * AsciiParser recycles the tag index and buffer immediately afterwards. So each\n * message that arrives mid-bind is cloned and queued, then replayed in order.\n */\n private onMsgBeforeIdentity (msgType: string, view: MsgView): void {\n if (this.bindInProgress) {\n this.sessionLogger.info(`queueing '${msgType}' received while binding session identity`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n\n if (msgType !== MsgType.Logon) {\n this.terminate(new Error(`wildcard acceptor expects Logon as the first message, received '${msgType}'`))\n return\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (!peerCompId) {\n this.terminate(new Error('Logon has no SenderCompID - cannot establish session identity'))\n return\n }\n\n this.bindInProgress = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n this.bindIdentity(peerCompId).then(() => {\n this.bindInProgress = false\n this.identityBound = true\n // dispatching the logon can itself open a second gate - an application whose\n // onLogon returns a promise is now deciding - so let resumeRx work out whether\n // it is actually safe to let the socket run again\n this.dispatchMsg(MsgType.Logon, logon)\n this.resumeRx()\n }).catch((e: Error) => {\n this.bindInProgress = false\n this.pendingRx.length = 0\n this.terminate(new Error(`failed to bind session identity for peer '${peerCompId}': ${e.message}`))\n })\n }\n\n /**\n * True while an asynchronous step in the logon handshake is still running and no\n * received message may be acted on: either the identity bind of a wildcard acceptor\n * or an application still deciding the logon verdict.\n */\n private rxGated (): boolean {\n return this.bindInProgress || this.logonVerdictPending\n }\n\n /**\n * Let the socket run again now a gate has opened - but only if no other gate is\n * still shut. Draining can re-gate (a replayed message could start another async\n * step) so the check is repeated after the queue is played out; whichever gate\n * closes last is the one that resumes.\n */\n private resumeRx (): void {\n if (this.rxGated()) return\n this.drainPendingRx()\n if (this.rxGated()) return\n this.transport?.duplex.readable?.resume()\n }\n\n private drainPendingRx (): void {\n while (this.pendingRx.length > 0) {\n if (this.rxGated()) {\n this.sessionLogger.info('suspending replay - logon handshake gated again')\n return\n }\n const queued = this.pendingRx.shift()\n if (!queued) break\n if (this.sessionState.state === SessionState.Stopped) {\n this.sessionLogger.info(`dropping queued '${queued.msgType}' - session stopped during bind`)\n continue\n }\n this.dispatchMsg(queued.msgType, queued.view)\n }\n }\n\n /**\n * Adopt the peer's comp id as our TargetCompID, then build the identity derived\n * state: SessionId, message store, sequence coordinator, registry claim. This is\n * the wildcard equivalent of the work run() does up front for a statically\n * configured session.\n */\n private async bindIdentity (peerCompId: string): Promise<void> {\n const logger = this.sessionLogger\n logger.info(`wildcard acceptor: binding session identity to peer SenderCompID '${peerCompId}'`)\n\n // the description is this session's own clone (see makeSessionScope), and the\n // session message factory holds the same object, so outbound headers pick the\n // new target up immediately\n asMutable(this.config.description).TargetCompID = peerCompId\n\n // every session on a wildcard listener shared one logger name until now, which\n // makes a multi-client server log impossible to follow\n this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`)\n\n this.sessionId = new SessionId(\n this.config.description.BeginString,\n this.config.description.SenderCompId,\n peerCompId\n )\n this.sessionStore = this.storeFactory().create(this.sessionId)\n await this.sessionStore.initialize()\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n this.coordinator.initializeFromStore()\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n logger.info(`session identity bound: ${this.sessionId.toString()} ` +\n `nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n this.claimSessionId()\n }\n\n private dispatchMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)\n })\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n\n const verdict = this.onLogon(view, userName as string, password as string)\n if (typeof verdict === 'boolean') {\n // the common case - finish the handshake in this same event, so an application\n // with a synchronous onLogon sees exactly the timing it always has\n this.completePeerLogon(view, verdict, resetSeqNumFlag)\n return\n }\n this.awaitLogonVerdict(view, verdict, resetSeqNumFlag)\n }\n\n /**\n * onLogon handed back a promise - the application is checking the credentials\n * against something asynchronous. Nothing may be sent or acted on until it\n * answers, so pause the socket and queue whatever the peer says in the meantime.\n *\n * The view has to be cloned: AsciiParser recycles its tag index and buffer as soon\n * as the current event returns, so the original is meaningless by the time the\n * promise settles. Anything already read off it - peerReset here - is carried\n * across as a value rather than read again from the clone.\n */\n private awaitLogonVerdict (view: MsgView, verdict: Promise<boolean>, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info('onLogon returned a promise - awaiting logon verdict')\n this.logonVerdictPending = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n verdict.then((accepted: boolean) => {\n this.logonVerdictPending = false\n if (this.sessionState.state === SessionState.Stopped) {\n logger.info('session stopped while awaiting logon verdict - discarding')\n this.pendingRx.length = 0\n return\n }\n this.completePeerLogon(logon, accepted, peerReset)\n if (!accepted) {\n // completePeerLogon has torn the session down - nothing queued can be acted on\n this.pendingRx.length = 0\n return\n }\n this.resumeRx()\n }).catch((e: Error) => {\n this.logonVerdictPending = false\n this.pendingRx.length = 0\n // a credential check that throws is a refusal, not a reason to let the peer in\n this.rejectLogon(`onLogon failed: ${e.message}`)\n })\n }\n\n /**\n * The application has accepted or refused the peer - finish the handshake either way.\n */\n private completePeerLogon (view: MsgView, accepted: boolean, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info(`peerLogon onLogon returns ${accepted}`)\n if (!accepted) {\n this.rejectLogon('logon rejected by application')\n return\n }\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 && peerReset !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor().catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)\n })\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon()\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 /**\n * The application refused this peer. FIX expects the refusing side to say why and\n * then hang up rather than simply going quiet, so send a Logout carrying the reason\n * before dropping the transport - the order matters, send() discards anything\n * offered once the session has stopped.\n *\n * onReady is never reached and no heartbeat timer starts; the application learns the\n * outcome through onStopped(error).\n */\n private rejectLogon (reason: string): void {\n this.sessionLogger.warning(`refusing peer logon: ${reason}`)\n this.sendLogout(reason)\n this.terminate(new Error(reason))\n }\n\n private sendTestRequest (): void {\n const factory = this.config.factory\n this.setState(SessionState.AwaitingProcessingResponseToTestRequest)\n const tr = factory?.testRequest()\n if (tr) {\n this.send(MsgType.TestRequest, tr)\n }\n }\n\n private sendHeartbeat (testReqId: string): void {\n const factory = this.config.factory\n const hb = factory?.heartbeat(testReqId)\n if (hb) {\n this.send(MsgType.Heartbeat, hb)\n }\n }\n\n private tick (): void {\n if (!this.transport) return\n const sessionState = this.sessionState\n const action: TickAction = sessionState.calcAction(new Date())\n const application: IMsgApplication | null = this.transport.config.description.application ?? null\n const logger = this.sessionLogger\n // Clean up timed-out resend requests\n this.coordinator.tick()\n\n switch (action) {\n case TickAction.Nothing: {\n // all is well\n break\n }\n\n case TickAction.TestRequest: {\n logger.debug(`send test req. state = ${sessionState.toString()}`)\n this.sendTestRequest()\n break\n }\n\n case TickAction.Heartbeat: {\n logger.debug(`send heartbeat. state = ${sessionState.toString()}`)\n this.sendHeartbeat(sessionState.now.toUTCString())\n break\n }\n\n case TickAction.TerminateOnError: {\n if (this.coordinator.incrementTimeoutRecovery(AsciiSession.MaxTimeoutRecoveryAttempts)) {\n // Try to recover — reset timeout state to give session a fresh window.\n // This helps survive sleep/wake scenarios where TCP connection may still be alive.\n logger.info(`timeout recovery attempt ${this.coordinator.timeoutRecoveryAttempts}, resetting timeout state`)\n sessionState.lastTestRequestAt = null\n sessionState.lastReceivedAt = new Date()\n this.setState(SessionState.ActiveNormalSession)\n } else {\n logger.info(sessionState.toString())\n this.terminate(new Error(`${application?.name}: peer not responding`))\n }\n break\n }\n\n case TickAction.Stop: {\n logger.info(sessionState.toString())\n logger.info('stopping')\n this.stop()\n break\n }\n\n default:\n throw new Error('unexpected action')\n }\n }\n}\n"]}
1
+ {"version":3,"file":"ascii-session.js","sourceRoot":"","sources":["../../../src/transport/ascii/ascii-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgView } from '../../buffer'\nimport { MsgTag, MsgType, SessionRejectReason } from '../../types'\nimport { IJsFixConfig } from '../../config'\nimport { FixSession } from '../session/fix-session'\nimport {\n FixMsgAsciiStoreResend, FixMsgMemoryStore, FixMsgStoreRecord,\n IFixMsgStore, IFixMsgStoreRecord,\n IFixSessionStore, IFixSessionStoreFactory,\n MemorySessionStore, MemorySessionStoreFactory, FileSessionStoreFactory, SessionId\n} from '../../store'\nimport { asMutable } from '../session/clone-session-description'\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 /**\n * TargetCompID value which tells an acceptor to take its target from whichever\n * counterparty logs on, rather than from static configuration.\n */\n public static readonly WildcardCompId = '*'\n public heartbeat: boolean = true\n protected store: IFixMsgStore | null = null\n protected resender: FixMsgAsciiStoreResend\n protected coordinator: SessionSequenceCoordinator\n protected sessionStore: IFixSessionStore\n protected sessionId: SessionId\n private registered: boolean = false\n /** acceptor configured with TargetCompID '*' - identity comes from the peer Logon */\n protected readonly wildcardTarget: boolean\n private identityBound: boolean\n private bindInProgress: boolean = false\n private logonVerdictPending: boolean = false\n private readonly pendingRx: Array<{ msgType: string, view: MsgView }> = []\n private readonly clock: DefaultFixClock = new DefaultFixClock()\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 // A wildcard TargetCompID lets one acceptor serve counterparties it was not\n // statically configured for - the peer's SenderCompID becomes our target, and\n // therefore our SessionId and store, once the Logon arrives. An initiator has\n // to know who it is calling, so '*' is meaningless there.\n this.wildcardTarget = config.description.TargetCompID === AsciiSession.WildcardCompId\n if (this.wildcardTarget && this.initiator) {\n throw new Error(`TargetCompID '${AsciiSession.WildcardCompId}' is only valid for acceptors, not initiators`)\n }\n this.identityBound = !this.wildcardTarget\n\n this.sessionId = new SessionId(\n config.description.BeginString,\n config.description.SenderCompId,\n config.description.TargetCompID\n )\n // Until the peer identifies itself there is nothing worth persisting, so a\n // wildcard session starts on a throwaway in-memory store. The real store -\n // keyed on the peer's comp id - is created by bindIdentity.\n this.sessionStore = this.wildcardTarget\n ? new MemorySessionStore(this.sessionId)\n : this.storeFactory().create(this.sessionId)\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n const lastReceivedSeqNum = config.description.LastReceivedSeqNum ?? 0\n this.coordinator.initializeFromConfig(undefined, lastReceivedSeqNum + 1)\n }\n\n private storeFactory (): IFixSessionStoreFactory {\n // Priority: programmatic config > JSON store config > default in-memory\n return this.config.sessionStoreFactory ?? AsciiSession.createStoreFactory(this.config.description.store)\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 if (this.wildcardTarget && !this.identityBound) {\n // Nothing to recover yet - the SessionId is not known until the peer logs on,\n // so store initialisation, sequence sync and registry claim all happen in\n // bindIdentity. Resume and wait for the Logon.\n this.sessionLogger.info('wildcard acceptor: awaiting peer Logon to establish session identity')\n transport.duplex.readable?.resume()\n return await super.run(transport)\n }\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 // Claim this SessionId. A counterparty which reconnected before its previous\n // socket was detected as dead would otherwise leave two live sessions writing\n // to one store - see issue #153.\n this.claimSessionId()\n\n // Resume the stream — super.run() will call subscribe() to hook up the message handler,\n // then the buffered data (including the client's Logon) will be delivered.\n transport.duplex.readable?.resume()\n\n return await super.run(transport)\n }\n\n private checkSeqNo (msgType: string, view: MsgView): boolean {\n switch (msgType) {\n case MsgType.SequenceReset: {\n return true\n }\n\n case MsgType.Logon: {\n // If peer sends ResetSeqNumFlag=Y, accept any sequence number.\n // PeerLogon handles the full sequence reset.\n if (view.getTyped(MsgTag.ResetSeqNumFlag) === true) {\n this.sessionLogger.info('logon with ResetSeqNumFlag=Y, accepting regardless of sequence')\n const seqNo = view.getTyped(MsgTag.MsgSeqNum) as number\n this.sessionState.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n }\n // falls through\n\n default: {\n const state = this.sessionState\n const lastSeq: number = state.lastPeerMsgSeqNum\n const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number\n let ret: boolean = false\n const seqDelta: number = seqNo - lastSeq\n if (seqDelta <= 0) {\n // Check if this is a PossDupFlag=Y message (resend replay) before rejecting.\n // PossDupFlag messages have old sequence numbers and bypass normal checks.\n const possDupFlag = view.getTyped(MsgTag.PossDupFlag) as boolean | undefined\n if (possDupFlag === true) {\n this.sessionLogger.debug(`message '${msgType}' has PossDupFlag=Y, bypassing sequence check`)\n this.coordinator.onMessageReceived(seqNo, true).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // Check if this is a delayed message that fills a pending gap range.\n const pendingRequests = this.coordinator.pendingResendRequests\n const inPendingGapRange = pendingRequests.some(p => seqNo >= p.begin && seqNo <= p.end)\n if (inPendingGapRange) {\n this.sessionLogger.info(`accepting delayed message seq ${seqNo} (in pending gap range)`)\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n return true\n }\n // serious problem ... drop immediately\n this.sessionLogger.warning(`terminate as seqDelta (${seqDelta}) < 0 lastSeq = ${lastSeq} seqNo = ${seqNo}`)\n this.stop()\n } else if (seqDelta > 1) {\n // resend request required as have missed messages.\n const expectedSeq = lastSeq + 1\n\n // We process a Logon beforehand to confirm the connection even we out of sync\n if (msgType === MsgType.Logon) {\n this.peerLogon(view)\n }\n // If the out of sync message is a resend request itself, then we handle it first in order\n // to avoid triggering an endless loop of both sides sending resend requests in response to resend requests.\n if (msgType === MsgType.ResendRequest) {\n this.onResendRequest(view)\n }\n\n // Use coordinator to determine what action to take for the gap\n const action = this.coordinator.onGapDetected(expectedSeq, seqNo)\n this.sessionLogger.info(`gap action: ${action}`)\n\n switch (action.type) {\n case ResendActionType.SendResendRequest: {\n if (action.begin != null && action.end != null) {\n this.sendResendRequest(lastSeq, seqNo)\n this.coordinator.recordResendRequestSent(action.begin, action.end)\n }\n break\n }\n case ResendActionType.Wait: {\n this.sessionLogger.info(`waiting for existing resend request: ${action.reason}`)\n break\n }\n case ResendActionType.SendGapFill: {\n this.sessionLogger.warning(`gap recovery abandoned (storm protection): ${action.reason}`)\n break\n }\n }\n\n // Update sequence state regardless — the gap-triggering message is valid.\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n\n // Logon and ResendRequest were already fully handled above (peerLogon / onResendRequest).\n // Don't return true for them — they must not be dispatched to onSessionMsg again.\n // Application messages (and everything else) should be forwarded normally.\n if (msgType !== MsgType.Logon && msgType !== MsgType.ResendRequest) {\n ret = true\n }\n } else {\n ret = true\n state.lastPeerMsgSeqNum = seqNo\n this.coordinator.onMessageReceived(seqNo, false).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onMessageReceived store persist failed: ${e.message}`)\n })\n }\n\n // Reset timeout recovery on successful message receipt\n if (ret) {\n this.coordinator.resetTimeoutRecovery()\n }\n return ret\n }\n }\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n const okToForward = this.validStateApplicationMsg()\n if (okToForward) {\n this.sessionLogger.info(`ascii forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n } else {\n this.terminate(new Error(`msgType ${msgType} received in state ${this.stateString()}`))\n }\n }\n\n private sendReject (msgType: string, seqNo: number, msg: string, reason: number): void {\n const factory = this.config.factory\n const reject = factory?.reject(msgType, seqNo, msg, reason)\n if (reject) {\n this.sessionLogger.warning(`rejecting with ${JSON.stringify(reject)}`)\n this.send(MsgType.Reject, reject)\n }\n }\n\n protected sendResendRequest (lastSeq: number, receivedSeq: number): void {\n const resend = this.config.factory?.resendRequest(lastSeq + 1, 0)\n if (resend) {\n this.sessionLogger.warning(`received seq ${receivedSeq}, but last known seq is ${lastSeq}. Sending resend request for all messages > ${lastSeq}`)\n this.send(MsgType.ResendRequest, resend)\n }\n }\n\n private checkIntegrity (msgType: string, view: MsgView): boolean {\n const state = this.sessionState\n const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number\n\n const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)\n const computed = view.checksum()\n if (received !== computed) {\n const msg: string = `msgType ${msgType} checksum failed. received = ${received} computed = ${computed}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.ValueIsIncorrect)\n return false\n }\n\n if (view.segment.type === SegmentType.Unknown) {\n const msg: string = `msgType ${msgType} unknown`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidMsgType)\n return false\n }\n\n const invalid = view.invalid()\n if (invalid.length > 0) {\n const msg: string = `msgType ${msgType} invalid tag${invalid.length > 1 ? 's' : ''} ${invalid.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.InvalidTagNumber)\n return false\n }\n\n const undefinedMsg: string | null = view.undefinedForMsg()\n if (undefinedMsg) {\n const msg: string = `msgType ${msgType} ${undefinedMsg}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.TagNotDefinedForThisMessageType)\n return false\n }\n\n const missingRequired = view.missing()\n if (missingRequired.length > 0) {\n const msg: string = `msgType ${msgType} missing required tag${missingRequired.length > 1 ? 's' : ''} ${missingRequired.join(', ')}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.RequiredTagMissing)\n return false\n }\n\n switch (state.state) {\n case SessionState.InitiationLogonReceived:\n case SessionState.InitiationLogonResponse: {\n const targetCompId = view.getString(MsgTag.TargetCompID)\n if (targetCompId !== state.compId) {\n const msg: string = `msgType ${msgType} unexpected TargetCompID ${targetCompId} expecting ${state.compId})`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (peerCompId !== state.peerCompId) {\n const msg: string = `msgType ${msgType} unexpected SenderCompID ${peerCompId} expecting ${state.compId}`\n this.sendReject(msgType, seqNum, msg, SessionRejectReason.CompIDProblem)\n return false\n }\n }\n break\n\n default: {\n break\n }\n }\n\n return true\n }\n\n /**\n * Override to resend stored messages following a sequence reset.\n * @protected\n */\n protected onResendRequest (view: MsgView): void {\n // if no records are in store then send a gap fill for entire sequence\n this.setState(SessionState.HandleResendRequest)\n const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])\n const endSeqNo = requestedEndSeqNo === 0\n ? this.sessionState.lastSentSeqNum()\n : requestedEndSeqNo\n\n this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)\n this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {\n const validRecords = records.filter(rec => rec.obj !== null)\n this.sessionLogger.info(`sending ${validRecords.length}`)\n validRecords.forEach(rec => {\n if (rec.obj) {\n this.send(rec.msgType, rec.obj)\n }\n })\n this.setState(SessionState.ActiveNormalSession)\n }).catch((e: Error) => {\n this.sessionLogger.error(e)\n })\n }\n\n protected override onPrepareForReconnect (): void {\n this.coordinator.prepareForReconnect()\n this.sessionLogger.info('coordinator reset transient state for reconnect')\n }\n\n /**\n * Take ownership of this SessionId in the registry, stopping whatever session\n * held it before. Idempotent - a session reused across reconnects (the\n * RecoveringTcpInitiator pattern) simply re-registers itself.\n */\n private claimSessionId (): void {\n const registry = this.config.sessionRegistry\n if (!registry) return\n const stoppedOld = registry.register(this.sessionId, this)\n if (stoppedOld) {\n this.sessionLogger.info(`session registry stopped previous session for ${this.sessionId.toString()}`)\n }\n this.registered = true\n }\n\n protected override onSessionStopping (): void {\n super.onSessionStopping()\n const registry = this.config.sessionRegistry\n if (!registry || !this.registered) return\n this.registered = false\n this.sessionLogger.info(`session stopping - unregistering from registry: ${this.sessionId.toString()}`)\n registry.unregister(this.sessionId, this)\n }\n\n protected override async onPreLogon (): Promise<void> {\n if (!this.config.description.ResetSeqNumFlag) return\n\n this.sessionLogger.info('initiator has ResetSeqNumFlag=Y, resetting sequences before logon')\n await this.coordinator.resetSession('initiator ResetSeqNumFlag=Y')\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n\n this.sessionLogger.info(`pre-logon reset complete: encoderSeqNum=${transmitter?.msgSeqNum}`)\n }\n\n protected override txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n super.txOnEncoded(msgType, data, hdr)\n // Store the encoded message in the session store for recovery/resend\n const seqNum = hdr?.MsgSeqNum as number | undefined\n if (seqNum != null) {\n const record = new FixMsgStoreRecord(msgType, new Date(), seqNum, undefined, data)\n this.sessionStore.put(record).catch((e: Error) => {\n // Never block sends on store errors\n this.sessionLogger.warning(`failed to store message seq=${seqNum}: ${e.message}`)\n })\n // Update store's sender sequence number (next outgoing seq = seqNum + 1)\n this.sessionStore.setSenderSeqNum(seqNum + 1).catch((e: Error) => {\n this.sessionLogger.warning(`failed to update sender seq: ${e.message}`)\n })\n }\n }\n\n private static readonly MaxLogonRetries = 100\n private static readonly MaxTimeoutRecoveryAttempts = 0\n\n private static createStoreFactory (storeConfig?: { type: string, directory?: string }): IFixSessionStoreFactory {\n if (!storeConfig) return new MemorySessionStoreFactory()\n switch (storeConfig.type?.toLowerCase()) {\n case 'file':\n return new FileSessionStoreFactory(storeConfig.directory ?? 'store')\n default:\n return new MemorySessionStoreFactory()\n }\n }\n\n private handleLogonRejected (text: string | null): void {\n if (!this.coordinator.onLogonRejectedForSequence(AsciiSession.MaxLogonRetries)) {\n this.sessionLogger.warning(`max logon retries (${AsciiSession.MaxLogonRetries}) exceeded, giving up. Text='${text}'`)\n this.setState(SessionState.PeerLogonRejected)\n this.stop()\n return\n }\n\n // The encoder's msgSeqNum is already incremented after each message is sent,\n // so we just need to retry the logon. The next logon will use the next sequence number.\n this.sessionLogger.info(`LOGON_SEQ_RETRY: attempt=${this.coordinator.logonRetryCount}/${AsciiSession.MaxLogonRetries}, reason='${text}'`)\n this.sendLogon()\n }\n\n okForLogon (): boolean {\n const state = this.sessionState.state\n if (this.acceptor) {\n return state === SessionState.WaitingForALogon\n }\n return state === SessionState.InitiationLogonSent\n }\n\n protected onSessionMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n switch (msgType) {\n case MsgType.Logon: {\n // only valid to receive a logon when in LogonSent or WaitingALogon\n // else will drop connection immediately.\n if (this.okForLogon()) {\n this.peerLogon(view)\n } else {\n this.terminate(new Error(`state ${this.stateString()} is illegal for Logon`))\n }\n break\n }\n\n case MsgType.Logout: {\n this.peerLogout(view)\n break\n }\n\n case MsgType.TestRequest: {\n const req: string | null = view.getString(MsgTag.TestReqID)\n if (req) {\n this.sendHeartbeat(req)\n }\n break\n }\n\n case MsgType.Heartbeat: {\n this.sessionState.lastTestRequestAt = null\n this.setState(SessionState.ActiveNormalSession)\n break\n }\n\n case MsgType.ResendRequest: {\n logger.info(`peer sends '${msgType}' resend request.`)\n this.onResendRequest(view)\n break\n }\n\n case MsgType.SequenceReset: {\n const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number\n const gapFillSeq: number = view.getTyped(MsgTag.MsgSeqNum) as number\n logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)\n // expect newSeqNo to be the next message's sequence number.\n this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1\n // Notify coordinator to update expected target and clear pending resend requests\n this.coordinator.onGapFillReceived(gapFillSeq, newSeqNo).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.onGapFillReceived store persist failed: ${e.message}`)\n })\n break\n }\n\n case MsgType.Reject: {\n const refMsgType = view.getString(MsgTag.RefMsgType)\n const text = view.getString(MsgTag.Text)\n const reason = view.getTyped(MsgTag.SessionRejectReason) as number | undefined\n logger.info(`peer rejects RefMsgType='${refMsgType}', reason=${reason}, text='${text}'`)\n\n // Check if this is a logon rejection due to sequence mismatch while we're waiting for logon response.\n // Only retry for ValueIsIncorrect (sequence too low) — structural rejections (RequiredTagMissing etc.)\n // indicate a config problem that retrying won't fix.\n if (refMsgType === MsgType.Logon &&\n this.sessionState.state === SessionState.InitiationLogonSent &&\n reason === SessionRejectReason.ValueIsIncorrect) {\n this.handleLogonRejected(text)\n }\n break\n }\n }\n }\n\n protected onMsg (msgType: string, view: MsgView): void {\n if (this.wildcardTarget && !this.identityBound) {\n this.onMsgBeforeIdentity(msgType, view)\n return\n }\n if (this.logonVerdictPending) {\n // the application is still deciding whether to accept this peer - hold anything\n // it sends in the meantime rather than acting on it (see awaitLogonVerdict)\n this.sessionLogger.info(`queueing '${msgType}' received while awaiting logon verdict`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n this.dispatchMsg(msgType, view)\n }\n\n /**\n * Message handling for a wildcard acceptor which has not yet learned who it is\n * talking to. The first message must be a Logon; it carries the peer's\n * SenderCompID, which becomes our TargetCompID and hence our SessionId and store.\n *\n * Binding is asynchronous (the store may have to be read from disk) while message\n * delivery is not: the parser emits every message it finds in a TCP segment in one\n * synchronous burst, and a view is only valid for the duration of its own event -\n * AsciiParser recycles the tag index and buffer immediately afterwards. So each\n * message that arrives mid-bind is cloned and queued, then replayed in order.\n */\n private onMsgBeforeIdentity (msgType: string, view: MsgView): void {\n if (this.bindInProgress) {\n this.sessionLogger.info(`queueing '${msgType}' received while binding session identity`)\n this.pendingRx.push({ msgType, view: view.clone() })\n return\n }\n\n if (msgType !== MsgType.Logon) {\n this.terminate(new Error(`wildcard acceptor expects Logon as the first message, received '${msgType}'`))\n return\n }\n\n const peerCompId = view.getString(MsgTag.SenderCompID)\n if (!peerCompId) {\n this.terminate(new Error('Logon has no SenderCompID - cannot establish session identity'))\n return\n }\n\n this.bindInProgress = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n this.bindIdentity(peerCompId).then(() => {\n this.bindInProgress = false\n this.identityBound = true\n // dispatching the logon can itself open a second gate - an application whose\n // onLogon returns a promise is now deciding - so let resumeRx work out whether\n // it is actually safe to let the socket run again\n this.dispatchMsg(MsgType.Logon, logon)\n this.resumeRx()\n }).catch((e: Error) => {\n this.bindInProgress = false\n this.pendingRx.length = 0\n this.terminate(new Error(`failed to bind session identity for peer '${peerCompId}': ${e.message}`))\n })\n }\n\n /**\n * True while an asynchronous step in the logon handshake is still running and no\n * received message may be acted on: either the identity bind of a wildcard acceptor\n * or an application still deciding the logon verdict.\n */\n private rxGated (): boolean {\n return this.bindInProgress || this.logonVerdictPending\n }\n\n /**\n * Let the socket run again now a gate has opened - but only if no other gate is\n * still shut. Draining can re-gate (a replayed message could start another async\n * step) so the check is repeated after the queue is played out; whichever gate\n * closes last is the one that resumes.\n */\n private resumeRx (): void {\n if (this.rxGated()) return\n this.drainPendingRx()\n if (this.rxGated()) return\n this.transport?.duplex.readable?.resume()\n }\n\n private drainPendingRx (): void {\n while (this.pendingRx.length > 0) {\n if (this.rxGated()) {\n this.sessionLogger.info('suspending replay - logon handshake gated again')\n return\n }\n const queued = this.pendingRx.shift()\n if (!queued) break\n if (this.sessionState.state === SessionState.Stopped) {\n this.sessionLogger.info(`dropping queued '${queued.msgType}' - session stopped during bind`)\n continue\n }\n this.dispatchMsg(queued.msgType, queued.view)\n }\n }\n\n /**\n * Adopt the peer's comp id as our TargetCompID, then build the identity derived\n * state: SessionId, message store, sequence coordinator, registry claim. This is\n * the wildcard equivalent of the work run() does up front for a statically\n * configured session.\n */\n private async bindIdentity (peerCompId: string): Promise<void> {\n const logger = this.sessionLogger\n logger.info(`wildcard acceptor: binding session identity to peer SenderCompID '${peerCompId}'`)\n\n // the description is this session's own clone (see makeSessionScope), and the\n // session message factory holds the same object, so outbound headers pick the\n // new target up immediately\n asMutable(this.config.description).TargetCompID = peerCompId\n\n // every session on a wildcard listener shared one logger name until now, which\n // makes a multi-client server log impossible to follow\n this.sessionLogger = this.config.logFactory.logger(`${this.me}:${peerCompId}:FixSession`,\n { component: 'FixSession', app: this.me, peer: peerCompId })\n\n this.sessionId = new SessionId(\n this.config.description.BeginString,\n this.config.description.SenderCompId,\n peerCompId\n )\n this.sessionStore = this.storeFactory().create(this.sessionId)\n await this.sessionStore.initialize()\n\n this.coordinator = new SessionSequenceCoordinator(this.sessionStore, this.clock)\n this.coordinator.initializeFromStore()\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = this.coordinator.nextSenderSeqNum\n }\n this.sessionState.lastPeerMsgSeqNum = this.coordinator.lastProcessedPeerSeqNum\n\n logger.info(`session identity bound: ${this.sessionId.toString()} ` +\n `nextSender=${this.coordinator.nextSenderSeqNum}, expectedTarget=${this.coordinator.expectedTargetSeqNum}`)\n\n this.claimSessionId()\n }\n\n private dispatchMsg (msgType: string, view: MsgView): void {\n if (!this.checkSeqNo(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkSeqNo.`)\n return\n }\n\n if (this.checkMsgIntegrity && !this.checkIntegrity(msgType, view)) {\n this.sessionLogger.info(`message '${msgType}' failed checkIntegrity.`)\n switch (msgType) {\n case MsgType.Logon: {\n this.setState(SessionState.PeerLogonRejected)\n this.startTimer()\n break\n }\n }\n return\n }\n\n switch (msgType) {\n case MsgType.Logon:\n case MsgType.Logout:\n case MsgType.TestRequest:\n case MsgType.Reject:\n case MsgType.SequenceReset:\n case MsgType.Heartbeat:\n case MsgType.ResendRequest: {\n this.onSessionMsg(msgType, view)\n break\n }\n\n default: {\n this.checkForwardMsg(msgType, view)\n break\n }\n }\n }\n\n private startTimer (interval: number = 200): void {\n const logger = this.sessionLogger\n logger.info(`start heartbeat timer. interval = ${interval}`)\n this.timer = setInterval(() => {\n this.tick()\n }, interval)\n }\n\n private peerLogon (view: MsgView): void {\n const logger = this.sessionLogger\n const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])\n const resetSeqNumFlag = view.getTyped(MsgTag.ResetSeqNumFlag) as boolean | undefined\n logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, resetSeqNumFlag = ${resetSeqNumFlag}`)\n\n // Handle ResetSeqNumFlag from peer's logon\n if (resetSeqNumFlag === true) {\n const peerSeqNum = (view.getTyped(MsgTag.MsgSeqNum) as number) ?? 1\n const weAlsoReset = this.config.description.ResetSeqNumFlag\n logger.info(`peer sent ResetSeqNumFlag=Y with seqNum=${peerSeqNum}, weAlsoReset=${weAlsoReset}`)\n\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n const savedEncoderSeqNum = weAlsoReset && transmitter ? transmitter.msgSeqNum : null\n\n // Fire-and-forget the async coordinator call (store updates resolve on next microtask)\n // but compute the expected values synchronously since we know the reset outcome\n this.coordinator.handlePeerReset(peerSeqNum, weAlsoReset).catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.handlePeerReset store persist failed: ${e.message}`)\n })\n if (transmitter) {\n transmitter.msgSeqNum = savedEncoderSeqNum ?? 1\n }\n this.sessionState.lastPeerMsgSeqNum = peerSeqNum\n\n // Recreate resender with empty store\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n logger.info(`reset complete: encoderSeqNum=${transmitter?.msgSeqNum}, lastPeerMsgSeqNum=${peerSeqNum}`)\n }\n\n const state = this.sessionState\n state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number\n state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string\n\n const verdict = this.onLogon(view, userName as string, password as string)\n if (typeof verdict === 'boolean') {\n // the common case - finish the handshake in this same event, so an application\n // with a synchronous onLogon sees exactly the timing it always has\n this.completePeerLogon(view, verdict, resetSeqNumFlag)\n return\n }\n this.awaitLogonVerdict(view, verdict, resetSeqNumFlag)\n }\n\n /**\n * onLogon handed back a promise - the application is checking the credentials\n * against something asynchronous. Nothing may be sent or acted on until it\n * answers, so pause the socket and queue whatever the peer says in the meantime.\n *\n * The view has to be cloned: AsciiParser recycles its tag index and buffer as soon\n * as the current event returns, so the original is meaningless by the time the\n * promise settles. Anything already read off it - peerReset here - is carried\n * across as a value rather than read again from the clone.\n */\n private awaitLogonVerdict (view: MsgView, verdict: Promise<boolean>, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info('onLogon returned a promise - awaiting logon verdict')\n this.logonVerdictPending = true\n const logon = view.clone()\n this.transport?.duplex.readable?.pause()\n\n verdict.then((accepted: boolean) => {\n this.logonVerdictPending = false\n if (this.sessionState.state === SessionState.Stopped) {\n logger.info('session stopped while awaiting logon verdict - discarding')\n this.pendingRx.length = 0\n return\n }\n this.completePeerLogon(logon, accepted, peerReset)\n if (!accepted) {\n // completePeerLogon has torn the session down - nothing queued can be acted on\n this.pendingRx.length = 0\n return\n }\n this.resumeRx()\n }).catch((e: Error) => {\n this.logonVerdictPending = false\n this.pendingRx.length = 0\n // a credential check that throws is a refusal, not a reason to let the peer in\n this.rejectLogon(`onLogon failed: ${e.message}`)\n })\n }\n\n /**\n * The application has accepted or refused the peer - finish the handshake either way.\n */\n private completePeerLogon (view: MsgView, accepted: boolean, peerReset: boolean | undefined): void {\n const logger = this.sessionLogger\n logger.info(`peerLogon onLogon returns ${accepted}`)\n if (!accepted) {\n this.rejectLogon('logon rejected by application')\n return\n }\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 && peerReset !== true) {\n logger.info('acceptor sending ResetSeqNumFlag=Y (peer sent N), resetting sequences')\n // Fire-and-forget async coordinator call, set values synchronously\n this.coordinator.resetAsAcceptor().catch((e: Error) => {\n this.sessionLogger.warning(`coordinator.resetAsAcceptor store persist failed: ${e.message}`)\n })\n const transmitter = this.transport?.transmitter as AsciiMsgTransmitter | undefined\n if (transmitter) {\n transmitter.msgSeqNum = 1\n }\n this.sessionState.lastPeerMsgSeqNum = 0\n if (this.store) {\n this.store.clear().catch((e: Error) => {\n this.sessionLogger.warning(`store.clear failed: ${e.message}`)\n })\n this.resender = new FixMsgAsciiStoreResend(this.store, this.config)\n }\n }\n\n this.sendLogon()\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 /**\n * The application refused this peer. FIX expects the refusing side to say why and\n * then hang up rather than simply going quiet, so send a Logout carrying the reason\n * before dropping the transport - the order matters, send() discards anything\n * offered once the session has stopped.\n *\n * onReady is never reached and no heartbeat timer starts; the application learns the\n * outcome through onStopped(error).\n */\n private rejectLogon (reason: string): void {\n this.sessionLogger.warning(`refusing peer logon: ${reason}`)\n this.sendLogout(reason)\n this.terminate(new Error(reason))\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"]}
@@ -34,7 +34,7 @@ let HttpAcceptorListener = class HttpAcceptorListener extends fix_entity_1.FixEn
34
34
  start() {
35
35
  return __awaiter(this, void 0, void 0, function* () {
36
36
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
37
- const logger = this.config.logFactory.logger('acceptor');
37
+ const logger = this.config.logFactory.logger('acceptor', { component: 'HttpAcceptorListener', role: 'acceptor' });
38
38
  const sessionContainer = this.config.sessionContainer;
39
39
  if (!sessionContainer.isRegistered(di_tokens_1.DITokens.FixSession)) {
40
40
  reject(new Error(`application must register a DI token '${di_tokens_1.DITokens.FixSession}' - see src/sample`));