jspurefix 5.11.0 → 5.11.2

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 (121) 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 +55 -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/connect-error.d.ts +2 -0
  69. package/dist/transport/tcp/connect-error.js +32 -0
  70. package/dist/transport/tcp/connect-error.js.map +1 -0
  71. package/dist/transport/tcp/recovering-tcp-initiator.js +3 -2
  72. package/dist/transport/tcp/recovering-tcp-initiator.js.map +1 -1
  73. package/dist/transport/tcp/tcp-acceptor-listener.js +2 -2
  74. package/dist/transport/tcp/tcp-acceptor-listener.js.map +1 -1
  75. package/dist/transport/tcp/tcp-acceptor.js +2 -2
  76. package/dist/transport/tcp/tcp-acceptor.js.map +1 -1
  77. package/dist/transport/tcp/tcp-initiator-connector.js +2 -2
  78. package/dist/transport/tcp/tcp-initiator-connector.js.map +1 -1
  79. package/dist/transport/tcp/tcp-initiator.js +5 -4
  80. package/dist/transport/tcp/tcp-initiator.js.map +1 -1
  81. package/docs/instrumentation.md +346 -0
  82. package/docs/scattered-components.md +280 -0
  83. package/jsfix.test_client.txt +62 -62
  84. package/jsfix.test_server.txt +72 -72
  85. package/package.json +1 -1
  86. package/src/buffer/fixml/fixml-parser.ts +1 -1
  87. package/src/config/empty-log-factory.ts +2 -2
  88. package/src/config/get-js-fx-logger.ts +2 -2
  89. package/src/config/js-fix-logger-factory.ts +8 -2
  90. package/src/config/js-fix-logger.ts +23 -8
  91. package/src/config/js-fix-winston-log-factory.ts +3 -3
  92. package/src/config/winston-logger.ts +85 -10
  93. package/src/dictionary/fragment-safety.ts +225 -0
  94. package/src/dictionary/index.ts +1 -0
  95. package/src/runtime/make-config.ts +1 -1
  96. package/src/runtime/session-launcher.ts +1 -1
  97. package/src/sample/http/oms/http-client.ts +1 -1
  98. package/src/sample/http/oms/http-server.ts +1 -1
  99. package/src/sample/tcp/qf-md/md-client.ts +1 -1
  100. package/src/sample/tcp/qf-md/md-server.ts +1 -1
  101. package/src/sample/tcp/recovering-skeleton/respawn-acceptor.ts +2 -1
  102. package/src/sample/tcp/recovering-skeleton/skeleton-client.ts +1 -1
  103. package/src/sample/tcp/recovering-skeleton/skeleton-server.ts +1 -1
  104. package/src/sample/tcp/skeleton/skeleton-session.ts +1 -1
  105. package/src/sample/tcp/trade-capture/trade-capture-client.ts +2 -1
  106. package/src/sample/tcp/trade-capture/trade-capture-server.ts +2 -1
  107. package/src/store/fix-msg-memory-store.ts +2 -1
  108. package/src/transport/ascii/ascii-msg-transmitter.ts +2 -1
  109. package/src/transport/ascii/ascii-session.ts +2 -1
  110. package/src/transport/http/http-acceptor-listener.ts +2 -1
  111. package/src/transport/http/http-acceptor.ts +2 -1
  112. package/src/transport/http/http-initiator.ts +2 -1
  113. package/src/transport/http/http-json-sample-adapter.ts +1 -1
  114. package/src/transport/session/fix-session.ts +2 -1
  115. package/src/transport/session/session-registry.ts +1 -1
  116. package/src/transport/tcp/connect-error.ts +56 -0
  117. package/src/transport/tcp/recovering-tcp-initiator.ts +4 -2
  118. package/src/transport/tcp/tcp-acceptor-listener.ts +4 -2
  119. package/src/transport/tcp/tcp-acceptor.ts +2 -1
  120. package/src/transport/tcp/tcp-initiator-connector.ts +4 -2
  121. package/src/transport/tcp/tcp-initiator.ts +9 -5
@@ -1 +1 @@
1
- {"version":3,"file":"http-acceptor-listener.js","sourceRoot":"","sources":["../../../src/transport/http/http-acceptor-listener.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,mDAA8C;AAE9C,uCAA6C;AAC7C,uDAAkD;AAElD,8CAAyC;AAGlC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sBAAS;IACjD,YAA4D,MAAoB;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;IAEhF,CAAC;IAEK,KAAK;;YACT,OAAO,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;gBACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;gBACrG,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACxB,MAAM,QAAQ,GAAgB,IAAI,4BAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBAC3D,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAe,EAAE,EAAE;oBAC3C,MAAM,CAAC,IAAI,CAAC,wCAAwC,oBAAQ,CAAC,UAAU,GAAG,CAAC,CAAA;oBAC3E,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;oBACjF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;oBACxC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACnB,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE;4BAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;4BAC/B,OAAO,CAAC,IAAI,CAAC,CAAA;wBACf,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;;wBACpB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;wBACf,MAAM,CAAC,IAAI,CAAC,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,KAAK,mCAAI,EAAE,CAAC,CAAA;wBAC3B,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBACF,QAAQ,CAAC,MAAM,EAAE,CAAA;YACnB,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AAjCY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,qBAAU,GAAE;IAEG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GADhC,oBAAoB,CAiChC","sourcesContent":["import { IJsFixConfig } from '../../config'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { HttpAcceptor } from './http-acceptor'\nimport { MsgTransport } from '../factory'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixSession } from '../session/fix-session'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class HttpAcceptorListener extends FixEntity {\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n }\n\n async start (): Promise<any> {\n return new Promise<any>(async (resolve, reject) => {\n const logger = this.config.logFactory.logger('acceptor')\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n }\n logger.info('starting.')\n const acceptor: FixAcceptor = new HttpAcceptor(this.config)\n acceptor.on('transport', (t: MsgTransport) => {\n logger.info(`creates new transport using DI token ${DITokens.FixSession}.`)\n const acceptorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.emit('session', acceptorSession, t)\n acceptorSession.run(t).then(() => {\n logger.info('ends')\n acceptor.close(() => {\n logger.info('acceptor closed.')\n resolve(true)\n })\n }).catch((e: Error) => {\n logger.error(e)\n logger.info(e?.stack ?? '')\n reject(e)\n })\n })\n acceptor.listen()\n })\n }\n}\n"]}
1
+ {"version":3,"file":"http-acceptor-listener.js","sourceRoot":"","sources":["../../../src/transport/http/http-acceptor-listener.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAEA,mDAA8C;AAE9C,uCAA6C;AAC7C,uDAAkD;AAElD,8CAAyC;AAGlC,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sBAAS;IACjD,YAA4D,MAAoB;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;IAEhF,CAAC;IAEK,KAAK;;YACT,OAAO,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EACrD,EAAE,SAAS,EAAE,sBAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAA;gBAC1D,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;gBACrG,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBACxB,MAAM,QAAQ,GAAgB,IAAI,4BAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBAC3D,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAe,EAAE,EAAE;oBAC3C,MAAM,CAAC,IAAI,CAAC,wCAAwC,oBAAQ,CAAC,UAAU,GAAG,CAAC,CAAA;oBAC3E,MAAM,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;oBACjF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC,CAAA;oBACxC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACnB,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE;4BAClB,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;4BAC/B,OAAO,CAAC,IAAI,CAAC,CAAA;wBACf,CAAC,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;;wBACpB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;wBACf,MAAM,CAAC,IAAI,CAAC,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,KAAK,mCAAI,EAAE,CAAC,CAAA;wBAC3B,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBACF,QAAQ,CAAC,MAAM,EAAE,CAAA;YACnB,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AAlCY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,qBAAU,GAAE;IAEG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GADhC,oBAAoB,CAkChC","sourcesContent":["import { IJsFixConfig } from '../../config'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { HttpAcceptor } from './http-acceptor'\nimport { MsgTransport } from '../factory'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixSession } from '../session/fix-session'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class HttpAcceptorListener extends FixEntity {\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n }\n\n async start (): Promise<any> {\n return new Promise<any>(async (resolve, reject) => {\n const logger = this.config.logFactory.logger('acceptor',\n { component: 'HttpAcceptorListener', role: 'acceptor' })\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n }\n logger.info('starting.')\n const acceptor: FixAcceptor = new HttpAcceptor(this.config)\n acceptor.on('transport', (t: MsgTransport) => {\n logger.info(`creates new transport using DI token ${DITokens.FixSession}.`)\n const acceptorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.emit('session', acceptorSession, t)\n acceptorSession.run(t).then(() => {\n logger.info('ends')\n acceptor.close(() => {\n logger.info('acceptor closed.')\n resolve(true)\n })\n }).catch((e: Error) => {\n logger.error(e)\n logger.info(e?.stack ?? '')\n reject(e)\n })\n })\n acceptor.listen()\n })\n }\n}\n"]}
@@ -65,13 +65,13 @@ const tsyringe_1 = require("tsyringe");
65
65
  const di_tokens_1 = require("../../runtime/di-tokens");
66
66
  let HttpAcceptor = class HttpAcceptor extends fix_acceptor_1.FixAcceptor {
67
67
  constructor(config) {
68
- var _a, _b, _c, _d;
68
+ var _a, _b, _c, _d, _e, _f;
69
69
  super((_b = (_a = config === null || config === void 0 ? void 0 : config.description) === null || _a === void 0 ? void 0 : _a.application) !== null && _b !== void 0 ? _b : null);
70
70
  this.config = config;
71
71
  this.app = express();
72
72
  this.nextId = 0;
73
73
  this.keys = new Map();
74
- this.logger = config.logFactory.logger(`${(_d = (_c = config === null || config === void 0 ? void 0 : config.description) === null || _c === void 0 ? void 0 : _c.application) === null || _d === void 0 ? void 0 : _d.name}:HttpAcceptor`);
74
+ this.logger = config.logFactory.logger(`${(_d = (_c = config === null || config === void 0 ? void 0 : config.description) === null || _c === void 0 ? void 0 : _c.application) === null || _d === void 0 ? void 0 : _d.name}:HttpAcceptor`, { component: 'HttpAcceptor', app: (_f = (_e = config === null || config === void 0 ? void 0 : config.description) === null || _e === void 0 ? void 0 : _e.application) === null || _f === void 0 ? void 0 : _f.name, role: 'acceptor' });
75
75
  this.logger.info('creating http server');
76
76
  this.router = express.Router();
77
77
  this.router.use(bodyParser.json());
@@ -1 +1 @@
1
- {"version":3,"file":"http-acceptor.js","sourceRoot":"","sources":["../../../src/transport/http/http-acceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgTransport } from '../factory'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { IFixmlRequest } from '../fixml'\nimport { FixDuplex, StringDuplex, StringDuplexTraits } from '../duplex'\n\nimport express = require('express')\nimport * as bodyParser from 'body-parser'\nimport * as http from 'http'\nimport { randomUUID } from 'crypto'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class HttpAcceptor extends FixAcceptor {\n private readonly app: express.Express = express()\n private server: http.Server\n private readonly logger: IJsFixLogger\n private readonly router: express.Router\n private nextId: number = 0\n private readonly keys: Map<string, MsgTransport> = new Map<string, MsgTransport>()\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config?.description?.application ?? null)\n this.logger = config.logFactory.logger(`${config?.description?.application?.name}:HttpAcceptor`)\n this.logger.info('creating http server')\n this.router = express.Router()\n this.router.use(bodyParser.json())\n this.subscribe()\n this.app.use('/', this.router)\n }\n\n public listen (): void {\n const app = this.config.description.application\n const port = app?.http?.port ?? 0\n const logger = this.logger\n logger.info(`start to listen ${port}`)\n this.server = this.app.listen(port, () => {\n logger.info(`app listening at http://localhost:${port}${app?.http?.uri}`)\n })\n this.server.on('error', (err: Error) => {\n logger.error(err)\n this.emit('error', err)\n })\n }\n\n public close (callback?: (err?: Error) => void): void {\n const app = this.config.description.application\n const port = app?.http?.port\n this.logger.info(`close listener on port ${port}`)\n this.server.close(callback)\n }\n\n private saveTransport (tid: number, transport: MsgTransport): string {\n this.transports[tid] = transport\n const keys: string[] = Object.keys(this.transports)\n const a = randomUUID()\n this.keys.set(a, transport)\n this.logger.info(`new transport id = ${tid} token = ${a} created total transports = ${keys.length}`)\n this.emit('transport', transport)\n return a\n }\n\n private harvestTransport (token: string, tid: number): void {\n delete this.transports[tid]\n this.keys.delete(token)\n const keys: string[] = Object.keys(this.transports)\n this.logger.info(`transport ${tid} ends total transports = ${keys.length}`)\n }\n\n private async respond (duplex: FixDuplex, response: express.Response, token: string | null = null): Promise<any> {\n return new Promise<any>((resolve, reject) => {\n response.setHeader('Content-Type', 'application/json')\n const timer = setTimeout(() => {\n const businessReject = '<FIXML><BizMsgRej BizRejRsn=\"4\" Txt=\"no response from application\"/></FIXML>'\n const b = Buffer.from(businessReject, 'utf-8')\n duplex.writable.removeListener('data', transmit)\n response.send(b)\n reject(new Error('no response'))\n }, 5000)\n\n const transmit = (d: Buffer): void => {\n this.logger.info('responding to request')\n clearTimeout(timer)\n if (token) {\n response.setHeader('authorization', token)\n }\n duplex.writable.removeListener('data', transmit)\n response.send(d)\n resolve(true)\n }\n\n duplex.writable.on('data', transmit)\n })\n }\n\n private async logon (req: express.Request, res: express.Response): Promise<void> {\n const body: IFixmlRequest = req.body\n const id = this.nextId++\n this.logger.info(JSON.stringify(body, null, 4))\n // check hand back session key\n const d = new StringDuplex('', StringDuplexTraits.None)\n const transport = new MsgTransport(id, this.config, d)\n const token = this.saveTransport(id, transport)\n this.respond(d, res, token).then(() => {\n this.logger.info('responded to logon')\n }).catch((e: Error) => {\n this.logger.error(e)\n })\n d.readable.push(body.fixml)\n }\n\n private async logout (req: express.Request, res: express.Response): Promise<void> {\n const headers = req.headers\n const body: IFixmlRequest = req.body\n const t: MsgTransport | undefined = this.keys.get(headers?.authorization ?? '')\n if (t) {\n const token = req.headers.authorization\n if (token) {\n this.harvestTransport(token, t.id)\n const d = t.duplex\n this.respond(d, res, token).then(() => {\n this.logger.info('responded to logout')\n t.end()\n }).catch((e: Error) => {\n this.logger.error(e)\n })\n d.readable.push(body.fixml)\n }\n }\n }\n\n private subscribe (): void {\n const router = this.router\n const app = this.config.description.application\n const root = app?.http?.uri\n const authorise = `${root}authorise`\n const query = `${root}query`\n this.logger.info(`uri: authorise ${authorise}, query ${query}`)\n router.post(authorise, async (req: express.Request, res: express.Response) => {\n if (!req.headers.authorization) {\n this.logger.info('logon')\n await this.logon(req, res)\n } else {\n this.logger.info('logout')\n await this.logout(req, res)\n }\n })\n\n router.get(query, async (req: express.Request, res: express.Response) => {\n const headers = req.headers\n const body: IFixmlRequest = req.body\n const t: MsgTransport | null = this.keys.get(headers.authorization ?? '') ?? null\n if (!t) {\n this.logger.info('received request with no token')\n res.send({\n error: 'no key with query'\n })\n } else {\n const d = t.duplex\n this.respond(d, res).then(() => {\n this.logger.info(`responded to ${req.url}`)\n }).catch(e => {\n res.send(e)\n })\n d.readable.push(body.fixml)\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"http-acceptor.js","sourceRoot":"","sources":["../../../src/transport/http/http-acceptor.ts"],"names":[],"mappings":"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","sourcesContent":["import { MsgTransport } from '../factory'\nimport { FixAcceptor } from '../fix-acceptor'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { IFixmlRequest } from '../fixml'\nimport { FixDuplex, StringDuplex, StringDuplexTraits } from '../duplex'\n\nimport express = require('express')\nimport * as bodyParser from 'body-parser'\nimport * as http from 'http'\nimport { randomUUID } from 'crypto'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class HttpAcceptor extends FixAcceptor {\n private readonly app: express.Express = express()\n private server: http.Server\n private readonly logger: IJsFixLogger\n private readonly router: express.Router\n private nextId: number = 0\n private readonly keys: Map<string, MsgTransport> = new Map<string, MsgTransport>()\n\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config?.description?.application ?? null)\n this.logger = config.logFactory.logger(`${config?.description?.application?.name}:HttpAcceptor`,\n { component: 'HttpAcceptor', app: config?.description?.application?.name, role: 'acceptor' })\n this.logger.info('creating http server')\n this.router = express.Router()\n this.router.use(bodyParser.json())\n this.subscribe()\n this.app.use('/', this.router)\n }\n\n public listen (): void {\n const app = this.config.description.application\n const port = app?.http?.port ?? 0\n const logger = this.logger\n logger.info(`start to listen ${port}`)\n this.server = this.app.listen(port, () => {\n logger.info(`app listening at http://localhost:${port}${app?.http?.uri}`)\n })\n this.server.on('error', (err: Error) => {\n logger.error(err)\n this.emit('error', err)\n })\n }\n\n public close (callback?: (err?: Error) => void): void {\n const app = this.config.description.application\n const port = app?.http?.port\n this.logger.info(`close listener on port ${port}`)\n this.server.close(callback)\n }\n\n private saveTransport (tid: number, transport: MsgTransport): string {\n this.transports[tid] = transport\n const keys: string[] = Object.keys(this.transports)\n const a = randomUUID()\n this.keys.set(a, transport)\n this.logger.info(`new transport id = ${tid} token = ${a} created total transports = ${keys.length}`)\n this.emit('transport', transport)\n return a\n }\n\n private harvestTransport (token: string, tid: number): void {\n delete this.transports[tid]\n this.keys.delete(token)\n const keys: string[] = Object.keys(this.transports)\n this.logger.info(`transport ${tid} ends total transports = ${keys.length}`)\n }\n\n private async respond (duplex: FixDuplex, response: express.Response, token: string | null = null): Promise<any> {\n return new Promise<any>((resolve, reject) => {\n response.setHeader('Content-Type', 'application/json')\n const timer = setTimeout(() => {\n const businessReject = '<FIXML><BizMsgRej BizRejRsn=\"4\" Txt=\"no response from application\"/></FIXML>'\n const b = Buffer.from(businessReject, 'utf-8')\n duplex.writable.removeListener('data', transmit)\n response.send(b)\n reject(new Error('no response'))\n }, 5000)\n\n const transmit = (d: Buffer): void => {\n this.logger.info('responding to request')\n clearTimeout(timer)\n if (token) {\n response.setHeader('authorization', token)\n }\n duplex.writable.removeListener('data', transmit)\n response.send(d)\n resolve(true)\n }\n\n duplex.writable.on('data', transmit)\n })\n }\n\n private async logon (req: express.Request, res: express.Response): Promise<void> {\n const body: IFixmlRequest = req.body\n const id = this.nextId++\n this.logger.info(JSON.stringify(body, null, 4))\n // check hand back session key\n const d = new StringDuplex('', StringDuplexTraits.None)\n const transport = new MsgTransport(id, this.config, d)\n const token = this.saveTransport(id, transport)\n this.respond(d, res, token).then(() => {\n this.logger.info('responded to logon')\n }).catch((e: Error) => {\n this.logger.error(e)\n })\n d.readable.push(body.fixml)\n }\n\n private async logout (req: express.Request, res: express.Response): Promise<void> {\n const headers = req.headers\n const body: IFixmlRequest = req.body\n const t: MsgTransport | undefined = this.keys.get(headers?.authorization ?? '')\n if (t) {\n const token = req.headers.authorization\n if (token) {\n this.harvestTransport(token, t.id)\n const d = t.duplex\n this.respond(d, res, token).then(() => {\n this.logger.info('responded to logout')\n t.end()\n }).catch((e: Error) => {\n this.logger.error(e)\n })\n d.readable.push(body.fixml)\n }\n }\n }\n\n private subscribe (): void {\n const router = this.router\n const app = this.config.description.application\n const root = app?.http?.uri\n const authorise = `${root}authorise`\n const query = `${root}query`\n this.logger.info(`uri: authorise ${authorise}, query ${query}`)\n router.post(authorise, async (req: express.Request, res: express.Response) => {\n if (!req.headers.authorization) {\n this.logger.info('logon')\n await this.logon(req, res)\n } else {\n this.logger.info('logout')\n await this.logout(req, res)\n }\n })\n\n router.get(query, async (req: express.Request, res: express.Response) => {\n const headers = req.headers\n const body: IFixmlRequest = req.body\n const t: MsgTransport | null = this.keys.get(headers.authorization ?? '') ?? null\n if (!t) {\n this.logger.info('received request with no token')\n res.send({\n error: 'no key with query'\n })\n } else {\n const d = t.duplex\n this.respond(d, res).then(() => {\n this.logger.info(`responded to ${req.url}`)\n }).catch(e => {\n res.send(e)\n })\n d.readable.push(body.fixml)\n }\n })\n }\n}\n"]}
@@ -31,7 +31,7 @@ let HttpInitiator = class HttpInitiator extends fix_entity_1.FixEntity {
31
31
  constructor(config) {
32
32
  super(config);
33
33
  this.config = config;
34
- this.logger = config.logFactory.logger('initiator');
34
+ this.logger = config.logFactory.logger('initiator', { component: 'HttpInitiator', role: 'initiator' });
35
35
  }
36
36
  start() {
37
37
  return __awaiter(this, void 0, void 0, function* () {
@@ -1 +1 @@
1
- {"version":3,"file":"http-initiator.js","sourceRoot":"","sources":["../../../src/transport/http/http-initiator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAyC;AACzC,sCAAsC;AAEtC,uCAA6C;AAC7C,uDAAkD;AAClD,8CAAyC;AAGlC,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,sBAAS;IAE1C,YAA4D,MAAoB;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;QAE9E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACrD,CAAC;IAEK,KAAK;;YACT,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACxC,CAAC;KAAA;IAGK,OAAO,CAAE,MAAoB;;YACjC,OAAO,MAAM,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;;gBACtD,MAAM,OAAO,GAAG,MAAA,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,0CAAE,WAAW,0CAAE,IAAI,0CAAE,OAAO,CAAA;gBAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC,CAAA;gBACvF,CAAC;gBACD,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;gBACrG,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,oBAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;gBACvE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;gBAClF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;gBAClC,MAAM,kBAAkB,GAAwB,OAAO;oBACrD,CAAC,CAAC,IAAI,sBAAY,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAC;oBACtD,CAAC,CAAC,IAAI,CAAA;gBACR,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAA;gBACrD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;oBAC9C,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACxB,OAAO,CAAC,IAAI,CAAC,CAAA;oBACf,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;wBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;wBACpB,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AA1CY,sCAAa;wBAAb,aAAa;IADzB,IAAA,qBAAU,GAAE;IAGG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GAFhC,aAAa,CA0CzB","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { MsgTransport } from '../factory'\nimport { HttpDuplex } from '../duplex'\nimport { FixSession } from '../session/fix-session'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class HttpInitiator extends FixEntity {\n logger: IJsFixLogger\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n this.logger = config.logFactory.logger('initiator')\n }\n\n async start (): Promise<any> {\n return await this.connect(this.config)\n }\n\n // the adapter will be provided on config\n async connect (config: IJsFixConfig): Promise<any> {\n return await new Promise<any>(async (resolve, reject) => {\n const adapter = config?.description?.application?.http?.adapter\n if (!adapter) {\n reject(new Error('http initiator needs config.description.application.http.adapter'))\n }\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n }\n this.logger.info(`create session with DI Token ${DITokens.FixSession}`)\n const initiatorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.logger.info('connecting ...')\n const initiatorTransport: MsgTransport | null = adapter\n ? new MsgTransport(0, config, new HttpDuplex(adapter))\n : null\n if (!initiatorTransport) {\n reject(new Error('no initiatorTransport for http'))\n } else {\n this.logger.info('... connected, run session')\n initiatorSession.run(initiatorTransport).then(() => {\n this.logger.info('ends')\n resolve(true)\n }).catch((e: Error) => {\n this.logger.error(e)\n reject(e)\n })\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"http-initiator.js","sourceRoot":"","sources":["../../../src/transport/http/http-initiator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAyC;AACzC,sCAAsC;AAEtC,uCAA6C;AAC7C,uDAAkD;AAClD,8CAAyC;AAGlC,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,sBAAS;IAE1C,YAA4D,MAAoB;QAC9E,KAAK,CAAC,MAAM,CAAC,CAAA;QAD6C,WAAM,GAAN,MAAM,CAAc;QAE9E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAChD,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IACtD,CAAC;IAEK,KAAK;;YACT,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACxC,CAAC;KAAA;IAGK,OAAO,CAAE,MAAoB;;YACjC,OAAO,MAAM,IAAI,OAAO,CAAM,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;;gBACtD,MAAM,OAAO,GAAG,MAAA,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,0CAAE,WAAW,0CAAE,IAAI,0CAAE,OAAO,CAAA;gBAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC,CAAA;gBACvF,CAAC;gBACD,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAA;gBACrD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,oBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,oBAAQ,CAAC,UAAU,oBAAoB,CAAC,CAAC,CAAA;gBACrG,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,oBAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;gBACvE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,OAAO,CAAa,oBAAQ,CAAC,UAAU,CAAC,CAAA;gBAClF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;gBAClC,MAAM,kBAAkB,GAAwB,OAAO;oBACrD,CAAC,CAAC,IAAI,sBAAY,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAC;oBACtD,CAAC,CAAC,IAAI,CAAA;gBACR,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAA;gBACrD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;oBAC9C,gBAAgB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;wBACxB,OAAO,CAAC,IAAI,CAAC,CAAA;oBACf,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE;wBACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;wBACpB,MAAM,CAAC,CAAC,CAAC,CAAA;oBACX,CAAC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAA,CAAC,CAAA;QACJ,CAAC;KAAA;CACF,CAAA;AA3CY,sCAAa;wBAAb,aAAa;IADzB,IAAA,qBAAU,GAAE;IAGG,WAAA,IAAA,iBAAM,EAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;;GAFhC,aAAa,CA2CzB","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { MsgTransport } from '../factory'\nimport { HttpDuplex } from '../duplex'\nimport { FixSession } from '../session/fix-session'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\nimport { FixEntity } from '../fix-entity'\n\n@injectable()\nexport class HttpInitiator extends FixEntity {\n logger: IJsFixLogger\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n super(config)\n this.logger = config.logFactory.logger('initiator',\n { component: 'HttpInitiator', role: 'initiator' })\n }\n\n async start (): Promise<any> {\n return await this.connect(this.config)\n }\n\n // the adapter will be provided on config\n async connect (config: IJsFixConfig): Promise<any> {\n return await new Promise<any>(async (resolve, reject) => {\n const adapter = config?.description?.application?.http?.adapter\n if (!adapter) {\n reject(new Error('http initiator needs config.description.application.http.adapter'))\n }\n const sessionContainer = this.config.sessionContainer\n if (!sessionContainer.isRegistered(DITokens.FixSession)) {\n reject(new Error(`application must register a DI token '${DITokens.FixSession}' - see src/sample`))\n }\n this.logger.info(`create session with DI Token ${DITokens.FixSession}`)\n const initiatorSession = sessionContainer.resolve<FixSession>(DITokens.FixSession)\n this.logger.info('connecting ...')\n const initiatorTransport: MsgTransport | null = adapter\n ? new MsgTransport(0, config, new HttpDuplex(adapter))\n : null\n if (!initiatorTransport) {\n reject(new Error('no initiatorTransport for http'))\n } else {\n this.logger.info('... connected, run session')\n initiatorSession.run(initiatorTransport).then(() => {\n this.logger.info('ends')\n resolve(true)\n }).catch((e: Error) => {\n this.logger.error(e)\n reject(e)\n })\n }\n })\n }\n}\n"]}
@@ -23,7 +23,7 @@ let HttpJsonSampleAdapter = class HttpJsonSampleAdapter {
23
23
  this.queue = [];
24
24
  this.token = null;
25
25
  this.routes = new Map();
26
- this.logger = config.logFactory.logger('http.adapter');
26
+ this.logger = config.logFactory.logger('http.adapter', { component: 'HttpJsonSampleAdapter' });
27
27
  const routes = this.routes;
28
28
  const options = (_c = (_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.http) === null || _c === void 0 ? void 0 : _c.options;
29
29
  if (!options) {
@@ -1 +1 @@
1
- {"version":3,"file":"http-json-sample-adapter.js","sourceRoot":"","sources":["../../../src/transport/http/http-json-sample-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { HttpTransaction } from './http-transaction'\nimport { IHttpAdapter } from './http-adapter'\nimport { IHtmlRoute } from './html-route'\nimport { IHtmlOptions } from './html-options'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class HttpJsonSampleAdapter implements IHttpAdapter {\n private readonly logger: IJsFixLogger\n private readonly queue: HttpTransaction[] = []\n private token: string | null = null\n private readonly routes: Map<string, IHtmlRoute> = new Map<string, IHtmlRoute>()\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n this.logger = config.logFactory.logger('http.adapter')\n const routes = this.routes\n const options = config?.description?.application?.http?.options\n if (!options) {\n return\n }\n options.forEach((o: IHtmlRoute) => {\n routes.set(o.name, o)\n })\n this.logger.info(`instance created routes ${routes.size}`)\n }\n\n public getOptions (data: Buffer): IHtmlOptions | null {\n const q = this.queue\n if (q.length === 0) {\n return null\n }\n const next: HttpTransaction | null = q.shift() ?? null\n if (next == null) return null\n const options = next.options\n options.data = {\n fixml: data.toString()\n }\n this.logger.info(`${next.msgType}: ${next.options.method} ${next.options.url} ${data.length}`)\n return options\n }\n\n endMessage (m: any): Buffer {\n // grab token if not yet received\n if (!this.token) {\n const headers = m.headers\n this.token = headers.authorization\n this.logger.info(`receive token ${this.token}`)\n }\n return m.data\n }\n\n beginMessage (msgType: string): void {\n // build options based on type\n const routes = this.routes\n const route = routes.get(msgType) ?? routes.get('default')\n const options = {\n method: route?.value.method,\n url: route?.value.url,\n json: route?.value.json,\n resolveWithFullResponse: route?.value.resolveWithFullResponse,\n headers: route?.value.headers\n } as IHtmlOptions\n const headers = options.headers\n if (headers) {\n if (this.token) {\n headers.authorization = this.token\n } else if (msgType === 'UserReq') {\n delete headers.authorization\n }\n }\n this.queue.push(new HttpTransaction(msgType, options))\n }\n}\n"]}
1
+ {"version":3,"file":"http-json-sample-adapter.js","sourceRoot":"","sources":["../../../src/transport/http/http-json-sample-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { HttpTransaction } from './http-transaction'\nimport { IHttpAdapter } from './http-adapter'\nimport { IHtmlRoute } from './html-route'\nimport { IHtmlOptions } from './html-options'\nimport { inject, injectable } from 'tsyringe'\nimport { DITokens } from '../../runtime/di-tokens'\n\n@injectable()\nexport class HttpJsonSampleAdapter implements IHttpAdapter {\n private readonly logger: IJsFixLogger\n private readonly queue: HttpTransaction[] = []\n private token: string | null = null\n private readonly routes: Map<string, IHtmlRoute> = new Map<string, IHtmlRoute>()\n constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {\n this.logger = config.logFactory.logger('http.adapter', { component: 'HttpJsonSampleAdapter' })\n const routes = this.routes\n const options = config?.description?.application?.http?.options\n if (!options) {\n return\n }\n options.forEach((o: IHtmlRoute) => {\n routes.set(o.name, o)\n })\n this.logger.info(`instance created routes ${routes.size}`)\n }\n\n public getOptions (data: Buffer): IHtmlOptions | null {\n const q = this.queue\n if (q.length === 0) {\n return null\n }\n const next: HttpTransaction | null = q.shift() ?? null\n if (next == null) return null\n const options = next.options\n options.data = {\n fixml: data.toString()\n }\n this.logger.info(`${next.msgType}: ${next.options.method} ${next.options.url} ${data.length}`)\n return options\n }\n\n endMessage (m: any): Buffer {\n // grab token if not yet received\n if (!this.token) {\n const headers = m.headers\n this.token = headers.authorization\n this.logger.info(`receive token ${this.token}`)\n }\n return m.data\n }\n\n beginMessage (msgType: string): void {\n // build options based on type\n const routes = this.routes\n const route = routes.get(msgType) ?? routes.get('default')\n const options = {\n method: route?.value.method,\n url: route?.value.url,\n json: route?.value.json,\n resolveWithFullResponse: route?.value.resolveWithFullResponse,\n headers: route?.value.headers\n } as IHtmlOptions\n const headers = options.headers\n if (headers) {\n if (this.token) {\n headers.authorization = this.token\n } else if (msgType === 'UserReq') {\n delete headers.authorization\n }\n }\n this.queue.push(new HttpTransaction(msgType, options))\n }\n}\n"]}
@@ -50,7 +50,7 @@ const session_state_1 = require("./session-state");
50
50
  const segment_type_1 = require("../../buffer/segment/segment-type");
51
51
  class FixSession extends events.EventEmitter {
52
52
  constructor(config) {
53
- var _a, _b, _c;
53
+ var _a, _b, _c, _d;
54
54
  super();
55
55
  this.config = config;
56
56
  this.logReceivedMsgs = false;
@@ -65,8 +65,8 @@ class FixSession extends events.EventEmitter {
65
65
  heartBeat: config.description.HeartBtInt,
66
66
  lastPeerMsgSeqNum: config.description.LastReceivedSeqNum
67
67
  });
68
- this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`);
69
- this.initiator = ((_c = description === null || description === void 0 ? void 0 : description.application) === null || _c === void 0 ? void 0 : _c.type) === 'initiator';
68
+ this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`, { component: 'FixSession', app: this.me, role: (_c = description === null || description === void 0 ? void 0 : description.application) === null || _c === void 0 ? void 0 : _c.type });
69
+ this.initiator = ((_d = description === null || description === void 0 ? void 0 : description.application) === null || _d === void 0 ? void 0 : _d.type) === 'initiator';
70
70
  this.acceptor = !this.initiator;
71
71
  this.checkMsgIntegrity = this.acceptor;
72
72
  this.sessionState.compId = description.SenderCompId;
@@ -1 +1 @@
1
- {"version":3,"file":"fix-session.js","sourceRoot":"","sources":["../../../src/transport/session/fix-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElasticBuffer, MsgView } from '../../buffer'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSessionState } from './fix-session-state'\nimport { MsgTransport } from '../factory'\nimport { MsgTag } from '../../types'\nimport { ILooseObject } from '../../collections/collection'\nimport { SendCallback } from '../send-callback'\n\nimport * as events from 'events'\nimport { SessionState } from './session-state'\nimport { SegmentType } from '../../buffer/segment/segment-type'\n\n/**\n * The set of listeners this session attached to one specific transport.\n *\n * The handlers must be kept as stable references - `EventEmitter.removeListener`\n * matches on identity, so subscribing with a fresh closure and unsubscribing with\n * a method reference silently leaves the listener attached (issue #153). Holding\n * the transport alongside the handlers also lets `unsubscribe` detach from the\n * transport it actually subscribed to, even when `this.transport` has already\n * moved on to a newer connection.\n */\ninterface ITransportSubscription {\n readonly transport: MsgTransport\n readonly rxOnMsg: (msgType: string, view: MsgView) => void\n readonly rxOnError: (e: Error) => void\n readonly rxOnDone: () => void\n readonly rxOnEnd: () => void\n readonly rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => void\n readonly txOnError: (e: Error) => void\n readonly txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => void\n}\n\nexport abstract class FixSession extends events.EventEmitter {\n public logReceivedMsgs: boolean = false\n protected timer: NodeJS.Timeout | null = null\n protected transport: MsgTransport | null = null\n private subscription: ITransportSubscription | null = null\n public manageSession: boolean = true\n public checkMsgIntegrity: boolean = false\n protected readonly me: string\n protected readonly initiator: boolean\n protected readonly acceptor: boolean\n protected readonly sessionState: FixSessionState\n /**\n * Not readonly: a wildcard acceptor does not know which counterparty it is\n * serving until the Logon arrives, and every session on that listener would\n * otherwise log under the same name. Rebound once the identity is known.\n */\n protected sessionLogger: IJsFixLogger\n protected requestLogoutType: string\n protected respondLogoutType: string\n protected requestLogonType: string\n\n protected constructor (public readonly config: IJsFixConfig) {\n super()\n const description = config.description\n this.me = description?.application?.name ?? 'me'\n this.sessionState = new FixSessionState(\n {\n heartBeat: config.description.HeartBtInt,\n lastPeerMsgSeqNum: config.description.LastReceivedSeqNum\n })\n this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`)\n this.initiator = description?.application?.type === 'initiator'\n this.acceptor = !this.initiator\n this.checkMsgIntegrity = this.acceptor\n this.sessionState.compId = description.SenderCompId\n }\n\n stateStr (theState: SessionState): string {\n return SessionState[theState]\n }\n\n assignState (newState: SessionState): void {\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n const logger = this.sessionLogger\n const msg = `current state ${currentStateStr} (${currentState}) moves to ${SessionState[newState]} (${newState})`\n logger.info(msg)\n this.sessionState.state = newState\n }\n\n public setState (state: SessionState): void {\n const logger = this.sessionLogger\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n if (state === currentState) return\n switch (currentState) {\n case SessionState.ConfirmingLogout:\n case SessionState.Stopped:\n if (state !== SessionState.NetworkConnectionEstablished) {\n logger.info(`ignoring request to change state as now already in ${currentStateStr}`)\n } else {\n this.assignState(state)\n }\n break\n\n default: {\n this.assignState(state)\n }\n }\n }\n\n public getState (): SessionState {\n return this.sessionState.state\n }\n\n public lastSentSeqNum (): number {\n return this.sessionState.lastSentSeqNum()\n }\n\n public lastPeerSeqNum (): number {\n return this.sessionState.lastPeerMsgSeqNum\n }\n\n public sendLogon (): void {\n const lo = this.config.factory?.logon()\n if (lo) {\n this.send(this.requestLogonType, lo)\n }\n }\n\n private async waitPromise (): Promise<number> {\n const logger = this.sessionLogger\n if (this.initiator) {\n // Hook for subclasses to reset sequences when ResetSeqNumFlag=Y is configured —\n // must run after the store is loaded, before sendLogon stamps a seq num.\n await this.onPreLogon()\n }\n return await new Promise<any>((resolve, reject) => {\n if (this.initiator) {\n logger.debug(`initiator sending logon state = ${this.stateString()}`)\n this.sendLogon()\n this.setState(SessionState.InitiationLogonSent)\n } else {\n logger.debug(`acceptor waits for logon state = ${this.stateString()}`)\n this.setState(SessionState.WaitingForALogon)\n }\n\n // Use named handlers and detach BOTH when the promise settles. Only one of\n // 'error'/'done' fires per run; without removing the sibling the unfired\n // listener would leak on every reconnect (issue #146). `once` alone is not\n // enough for the same reason — the sibling never fires, so never self-detaches.\n const cleanup = (): void => {\n this.removeListener('error', onError)\n this.removeListener('done', onDone)\n }\n const onError = (e: Error): void => {\n cleanup()\n // read the logger now, not the one captured when the run started - a\n // wildcard acceptor rebinds it once it knows which peer it is serving\n this.sessionLogger.error(e)\n reject(e)\n }\n const onDone = (): void => {\n cleanup()\n resolve(this.transport?.id)\n }\n\n this.on('error', onError)\n this.on('done', onDone)\n })\n }\n\n public async run (transport: MsgTransport): Promise<number> {\n const logger = this.sessionLogger\n if (this.transport) {\n logger.info(`reset from previous transport. state ${this.stateString()}`)\n this.reset()\n }\n this.transport = transport\n this.subscribe()\n return await this.waitPromise()\n }\n\n protected expectedEndState (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Stopped:\n case SessionState.ConfirmingLogout:\n return true\n\n default:\n return false\n }\n }\n\n protected rxOnEnd (): void {\n const logger = this.sessionLogger\n logger.info(`rx end received sessionState = [${this.sessionState.toString()}]`)\n const expectedState = this.expectedEndState()\n if (expectedState) {\n logger.info(`rx receives end state = ${this.stateString()} - stop session`)\n this.stop()\n } else {\n this.setState(SessionState.DetectBrokenNetworkConnection)\n const e = new Error(`unexpected state - transport failed? = ${this.stateString()}`)\n logger.info(`rx error ${e.message}`)\n this.terminate(e)\n }\n }\n\n protected rxOnMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n if (this.logReceivedMsgs) {\n const name = view.segment.type !== SegmentType.Unknown ? view?.segment?.set?.name : 'unknown'\n logger.info(`${msgType}: ${name}`)\n logger.info(`${view.toString()}`)\n }\n this.sessionState.lastReceivedAt = new Date()\n if (this.manageSession) {\n this.onMsg(msgType, view)\n } else {\n this.checkForwardMsg(msgType, view)\n }\n }\n\n protected rxOnDone (): void {\n const logger = this.sessionLogger\n logger.info('rx done received')\n this.done()\n }\n\n protected rxOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`rx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected rxOnDecoded (msgType: string, data: ElasticBuffer, ptr: number): void {\n const logger = this.sessionLogger\n logger.debug(`rx: [${msgType}] ${ptr} bytes`)\n this.onDecoded(msgType, data.toString(ptr))\n }\n\n protected txOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`tx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n const logger = this.sessionLogger\n this.sessionState.lastHeader = hdr\n logger.debug(`tx: [${msgType}] ${data.length} bytes seqNo = ${this.lastSentSeqNum()}`)\n this.onEncoded(msgType, data)\n }\n\n /**\n * true when the event which has just fired came from the transport this session\n * is currently running. A half open socket can keep emitting long after the peer\n * has reconnected on a fresh connection - those events must not be allowed to drive\n * the live session (issue #153).\n */\n private isCurrentTransport (transport: MsgTransport, event: string): boolean {\n if (this.subscription?.transport === transport && this.transport === transport) {\n return true\n }\n const current = this.transport?.id ?? 'none'\n this.sessionLogger.warning(`ignoring '${event}' from stale transport ${transport.id} - current transport is ${current}`)\n return false\n }\n\n protected unsubscribe (): void {\n const logger = this.sessionLogger\n const subscription = this.subscription\n if (!subscription) {\n logger.debug('unsubscribe called with no active subscription')\n return\n }\n const transport = subscription.transport\n logger.info(`unsubscribe transport ${transport.id} sessionState = [${this.sessionState.toString()}]`)\n const rx = transport.receiver\n const tx = transport.transmitter\n\n rx?.removeListener('msg', subscription.rxOnMsg)\n rx?.removeListener('error', subscription.rxOnError)\n rx?.removeListener('done', subscription.rxOnDone)\n rx?.removeListener('end', subscription.rxOnEnd)\n rx?.removeListener('decoded', subscription.rxOnDecoded)\n tx?.removeListener('error', subscription.txOnError)\n tx?.removeListener('encoded', subscription.txOnEncoded)\n this.subscription = null\n logger.debug(`unsubscribe complete - rx listeners now ${rx?.listenerCount('msg') ?? 0} msg, ${rx?.listenerCount('end') ?? 0} end`)\n }\n\n protected subscribe (): void {\n const transport = this.transport\n if (!transport) {\n this.sessionLogger.warning('subscribe called with no transport')\n return\n }\n // detach from any previous transport before attaching to this one\n if (this.subscription) {\n this.unsubscribe()\n }\n const inst = this\n const subscription: ITransportSubscription = {\n transport,\n rxOnMsg: (msgType: string, view: MsgView) => {\n if (inst.isCurrentTransport(transport, 'msg')) inst.rxOnMsg(msgType, view)\n },\n rxOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'error')) inst.rxOnError(e)\n },\n rxOnDone: () => {\n if (inst.isCurrentTransport(transport, 'done')) inst.rxOnDone()\n },\n rxOnEnd: () => {\n if (inst.isCurrentTransport(transport, 'end')) inst.rxOnEnd()\n },\n rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => {\n if (inst.isCurrentTransport(transport, 'decoded')) inst.rxOnDecoded(msgType, data, ptr)\n },\n txOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'tx error')) inst.txOnError(e)\n },\n txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => {\n if (inst.isCurrentTransport(transport, 'encoded')) inst.txOnEncoded(msgType, data, hdr)\n }\n }\n const rx = transport.receiver\n const tx = transport.transmitter\n rx?.on('msg', subscription.rxOnMsg)\n rx?.on('error', subscription.rxOnError)\n rx?.on('done', subscription.rxOnDone)\n rx?.on('end', subscription.rxOnEnd)\n rx?.on('decoded', subscription.rxOnDecoded)\n tx?.on('error', subscription.txOnError)\n tx?.on('encoded', subscription.txOnEncoded)\n this.subscription = subscription\n this.sessionLogger.info(`subscribed to transport ${transport.id}`)\n }\n\n protected validStateApplicationMsg (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Idle:\n case SessionState.InitiateConnection:\n case SessionState.InitiationLogonSent:\n case SessionState.WaitingForALogon:\n case SessionState.HandleResendRequest:\n case SessionState.AwaitingProcessingResponseToTestRequest:\n case SessionState.AwaitingProcessingResponseToResendRequest:\n return false\n default:\n return true\n }\n }\n\n protected stateString (): string {\n return SessionState[this.sessionState.state]\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n this.sessionLogger.info(`forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n }\n\n private stopTimer (): void {\n if (this.timer) {\n this.sessionLogger.info('stopTimer')\n clearInterval(this.timer)\n this.timer = null\n }\n }\n\n protected terminate (error: Error): void {\n if (this.sessionState.state === SessionState.Stopped) return\n this.sessionLogger.error(error)\n this.stopTimer()\n this.unsubscribe()\n if (this.transport) {\n this.sessionLogger.info(`terminate: kill transport ${this.transport.id}`)\n this.transport.end()\n }\n this.transport = null\n this.setState(SessionState.Stopped)\n this.onSessionStopping()\n this.emit('error', error)\n this.onStopped(error)\n }\n\n protected peerLogout (view: MsgView): void {\n const msg = view.getString(MsgTag.Text)\n const state = this.sessionState.state\n switch (state) {\n case SessionState.WaitingLogoutConfirm: {\n this.sessionLogger.info(`peer confirms logout Text = '${msg}'`)\n this.stop()\n break\n }\n\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.setState(SessionState.ConfirmingLogout)\n this.sessionLogger.info(`peer initiates logout Text = '${msg}'`)\n this.sessionLogout()\n }\n }\n }\n\n /**\n * @param callback optional, invoked once the message has been encoded and handed to\n * the transport, or as soon as that fails. Without it a send is fire and forget:\n * nothing tells the caller which sequence number the message went out under, and a\n * message dropped because the session is down, or refused by the encoder, goes\n * unanswered. See https://github.com/TimelordUK/jspurefix/issues/86\n */\n protected send (msgType: string, obj: ILooseObject, callback: SendCallback | null = null): void {\n const state = this.sessionState.state\n switch (state) {\n case SessionState.Stopped: {\n const msg = `can't send in state ${this.stateString()}`\n this.sessionLogger.warning(msg)\n // the message is dropped either way - but a caller that asked to be told is\n // now told, instead of watching for a log line\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n\n default: {\n this.sessionState.LastSentAt = new Date()\n const transmitter = this.transport?.transmitter\n if (!transmitter) {\n const msg = `no transport to send ${msgType} on`\n this.sessionLogger.warning(msg)\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n transmitter.send(msgType, obj, callback)\n break\n }\n }\n }\n\n protected sendLogout (msg: string): void {\n const factory = this.config.factory\n this.sessionLogger.info(`sending logout with ${msg}`)\n const lo = factory?.logout(this.requestLogoutType, msg)\n if (lo) {\n this.send(this.requestLogoutType, lo)\n }\n }\n\n protected sessionLogout (): void {\n const sessionState = this.sessionState\n if (sessionState.logoutSentAt) {\n return\n }\n\n switch (sessionState.state) {\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonResponse:\n case SessionState.InitiationLogonReceived: {\n // this instance initiates logout\n this.setState(SessionState.WaitingLogoutConfirm)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} initiate logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n case SessionState.ConfirmingLogout: {\n // this instance responds to log out\n this.setState(SessionState.ConfirmingLogout)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} confirming logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n default: {\n this.sessionLogger.info(`sessionLogout ignored as in state ${sessionState.state}`)\n }\n }\n }\n\n public done (): void {\n switch (this.sessionState.state) {\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.sessionLogout()\n break\n }\n\n case SessionState.Stopped:\n this.sessionLogger.info('done. session is now stopped')\n break\n\n default: {\n this.stop()\n break\n }\n }\n this.sessionLogger.info(`done. check logout sequence state ${this.stateString()}`)\n }\n\n public reset (resetSeqNum?: number | null): void {\n this.stopTimer()\n // unsubscribe from old transport before clearing reference\n this.unsubscribe()\n // reset parser to clear any partial message state from dropped connection\n const receiver: any = this.transport?.receiver\n if (receiver?.reset) {\n receiver.reset()\n }\n this.transport = null\n const resetFlag = this.config.description.ResetSeqNumFlag\n const seqNum = resetFlag ? 0 : resetSeqNum ?? this.sessionState.lastPeerMsgSeqNum\n this.sessionState.reset(seqNum) // from header def ... eventually\n this.onPrepareForReconnect()\n this.setState(SessionState.NetworkConnectionEstablished)\n }\n\n protected onPrepareForReconnect (): void {\n // Override in subclass to reset coordinator/transient state\n }\n\n /**\n * Called once as the session moves to Stopped, before the application is informed\n * via onStopped. Override to release session scoped resources - the ascii session\n * uses this to remove itself from the session registry. Mirrors cspurefix\n * FixSession.OnSessionStopping.\n */\n protected onSessionStopping (): void {\n // Default no-op\n }\n\n /**\n * Called for initiators after the store is loaded but before the Logon is sent.\n * Override to reset sequences/store when ResetSeqNumFlag=Y so the Logon goes out\n * with MsgSeqNum=1 instead of the recovered sender seq num.\n */\n protected async onPreLogon (): Promise<void> {\n // Default no-op\n }\n\n /**\n * Stop this session on behalf of an external caller - typically the session registry\n * when a new connection for the same SessionId replaces this one, but equally an\n * application which has decided the peer is gone. Mirrors cspurefix\n * FixSession.RequestStop.\n * @param reason recorded in the session log and carried on the emitted error\n */\n public requestStop (reason: string): void {\n this.sessionLogger.info(`requestStop: ${reason}`)\n this.stop(new Error(reason))\n }\n\n protected stop (error: Error | null = null): void {\n if (this.sessionState.state === SessionState.Stopped) {\n return\n }\n this.stopTimer()\n this.unsubscribe()\n this.sessionLogger.info(`stop: kill transport ${this.transport?.id ?? 'none'}`)\n this.onSessionStopping()\n this.transport?.end()\n if (error) {\n this.sessionLogger.info(`stop: emit error ${error.message}`)\n this.emit('error', error)\n } else {\n this.emit('done')\n }\n\n this.setState(SessionState.Stopped)\n this.onStopped(error ?? undefined)\n this.transport = null\n }\n\n /**\n * dispatches a message into the subclass that inherits from FixSession. The view contains\n * the parsed message which has utility methods such as toObject(). The Ascii session provides\n * an implementation to handle admin level messages such as logon, hearbeat and resest request.\n * Any application messges are dispatched via onApplicationMsg where the application can action\n * the message.\n * @param msgType the string based msg type the view represents\n * @param view container for all parsed fields representing the received message.\n * @protected\n */\n protected abstract onMsg (msgType: string, view: MsgView): void\n /**\n * the parsed txt recieved from the peer application. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all received\n * messages.\n * @param msgType the string based msg type the view represents\n * @param txt the received message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onDecoded (msgType: string, txt: string): void\n /**\n * the formatted txt sent to the peer application as an outbound message. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all transmitted\n * messages. use msgType for example to persist only trade capture messages to database\n * @param msgType the msg type representing the message.\n * @param txt the sent message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onEncoded (msgType: string, txt: string): void\n /**\n * typically all session level messages are handled by AsciiSession and these are\n * application level such as MarketDataRefresh. This will represent the applications main\n * work functiono where responses can be sent back to the peer. If manageSession has been set false\n * (not recommended) all messages are sent to this function\n * @param msgType the msg type representing the message.\n * @param view a wrapper containing the parsed message received.\n * @protected\n */\n protected abstract onApplicationMsg (msgType: string, view: MsgView): void\n /**\n * at this point the application is ready to send messages - peer login has been achieved\n * and the session can be considered ready to use. In the case of an initiator the application\n * may at this point send for security definitions or send market data subscriptions\n * @param view the login message causing session to be ready\n * @protected\n */\n protected abstract onReady (view: MsgView): void\n\n /**\n * Inform application this session has now ended - either from logout or connection dropped\n * @param error if session has been terminated via an error it is provided\n * @protected\n */\n protected abstract onStopped (error?: Error): void\n /**\n * Inform the application of a peer login attempt and ask it to accept or reject.\n *\n * Return true to let the session continue. Return false to refuse the peer: a\n * Logout carrying a Text reason is sent and the transport is dropped, so onReady\n * is never reached and no heartbeat is started.\n *\n * The verdict may be returned as a promise, for applications that must check the\n * credentials against an async source such as an http api or a database. While\n * that promise is pending the transport is paused and any message the peer sends\n * is queued, then replayed in order once the verdict arrives.\n *\n * @param view the login message\n * @param user extracted user from message\n * @param password extracted password from the message.\n * @protected\n */\n protected abstract onLogon (view: MsgView, user: string, password: string): boolean | Promise<boolean>\n}\n"]}
1
+ {"version":3,"file":"fix-session.js","sourceRoot":"","sources":["../../../src/transport/session/fix-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElasticBuffer, MsgView } from '../../buffer'\nimport { IJsFixConfig, IJsFixLogger } from '../../config'\nimport { FixSessionState } from './fix-session-state'\nimport { MsgTransport } from '../factory'\nimport { MsgTag } from '../../types'\nimport { ILooseObject } from '../../collections/collection'\nimport { SendCallback } from '../send-callback'\n\nimport * as events from 'events'\nimport { SessionState } from './session-state'\nimport { SegmentType } from '../../buffer/segment/segment-type'\n\n/**\n * The set of listeners this session attached to one specific transport.\n *\n * The handlers must be kept as stable references - `EventEmitter.removeListener`\n * matches on identity, so subscribing with a fresh closure and unsubscribing with\n * a method reference silently leaves the listener attached (issue #153). Holding\n * the transport alongside the handlers also lets `unsubscribe` detach from the\n * transport it actually subscribed to, even when `this.transport` has already\n * moved on to a newer connection.\n */\ninterface ITransportSubscription {\n readonly transport: MsgTransport\n readonly rxOnMsg: (msgType: string, view: MsgView) => void\n readonly rxOnError: (e: Error) => void\n readonly rxOnDone: () => void\n readonly rxOnEnd: () => void\n readonly rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => void\n readonly txOnError: (e: Error) => void\n readonly txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => void\n}\n\nexport abstract class FixSession extends events.EventEmitter {\n public logReceivedMsgs: boolean = false\n protected timer: NodeJS.Timeout | null = null\n protected transport: MsgTransport | null = null\n private subscription: ITransportSubscription | null = null\n public manageSession: boolean = true\n public checkMsgIntegrity: boolean = false\n protected readonly me: string\n protected readonly initiator: boolean\n protected readonly acceptor: boolean\n protected readonly sessionState: FixSessionState\n /**\n * Not readonly: a wildcard acceptor does not know which counterparty it is\n * serving until the Logon arrives, and every session on that listener would\n * otherwise log under the same name. Rebound once the identity is known.\n */\n protected sessionLogger: IJsFixLogger\n protected requestLogoutType: string\n protected respondLogoutType: string\n protected requestLogonType: string\n\n protected constructor (public readonly config: IJsFixConfig) {\n super()\n const description = config.description\n this.me = description?.application?.name ?? 'me'\n this.sessionState = new FixSessionState(\n {\n heartBeat: config.description.HeartBtInt,\n lastPeerMsgSeqNum: config.description.LastReceivedSeqNum\n })\n this.sessionLogger = config.logFactory.logger(`${this.me}:FixSession`,\n { component: 'FixSession', app: this.me, role: description?.application?.type })\n this.initiator = description?.application?.type === 'initiator'\n this.acceptor = !this.initiator\n this.checkMsgIntegrity = this.acceptor\n this.sessionState.compId = description.SenderCompId\n }\n\n stateStr (theState: SessionState): string {\n return SessionState[theState]\n }\n\n assignState (newState: SessionState): void {\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n const logger = this.sessionLogger\n const msg = `current state ${currentStateStr} (${currentState}) moves to ${SessionState[newState]} (${newState})`\n logger.info(msg)\n this.sessionState.state = newState\n }\n\n public setState (state: SessionState): void {\n const logger = this.sessionLogger\n const currentState = this.sessionState.state\n const currentStateStr = this.stateStr(currentState)\n if (state === currentState) return\n switch (currentState) {\n case SessionState.ConfirmingLogout:\n case SessionState.Stopped:\n if (state !== SessionState.NetworkConnectionEstablished) {\n logger.info(`ignoring request to change state as now already in ${currentStateStr}`)\n } else {\n this.assignState(state)\n }\n break\n\n default: {\n this.assignState(state)\n }\n }\n }\n\n public getState (): SessionState {\n return this.sessionState.state\n }\n\n public lastSentSeqNum (): number {\n return this.sessionState.lastSentSeqNum()\n }\n\n public lastPeerSeqNum (): number {\n return this.sessionState.lastPeerMsgSeqNum\n }\n\n public sendLogon (): void {\n const lo = this.config.factory?.logon()\n if (lo) {\n this.send(this.requestLogonType, lo)\n }\n }\n\n private async waitPromise (): Promise<number> {\n const logger = this.sessionLogger\n if (this.initiator) {\n // Hook for subclasses to reset sequences when ResetSeqNumFlag=Y is configured —\n // must run after the store is loaded, before sendLogon stamps a seq num.\n await this.onPreLogon()\n }\n return await new Promise<any>((resolve, reject) => {\n if (this.initiator) {\n logger.debug(`initiator sending logon state = ${this.stateString()}`)\n this.sendLogon()\n this.setState(SessionState.InitiationLogonSent)\n } else {\n logger.debug(`acceptor waits for logon state = ${this.stateString()}`)\n this.setState(SessionState.WaitingForALogon)\n }\n\n // Use named handlers and detach BOTH when the promise settles. Only one of\n // 'error'/'done' fires per run; without removing the sibling the unfired\n // listener would leak on every reconnect (issue #146). `once` alone is not\n // enough for the same reason — the sibling never fires, so never self-detaches.\n const cleanup = (): void => {\n this.removeListener('error', onError)\n this.removeListener('done', onDone)\n }\n const onError = (e: Error): void => {\n cleanup()\n // read the logger now, not the one captured when the run started - a\n // wildcard acceptor rebinds it once it knows which peer it is serving\n this.sessionLogger.error(e)\n reject(e)\n }\n const onDone = (): void => {\n cleanup()\n resolve(this.transport?.id)\n }\n\n this.on('error', onError)\n this.on('done', onDone)\n })\n }\n\n public async run (transport: MsgTransport): Promise<number> {\n const logger = this.sessionLogger\n if (this.transport) {\n logger.info(`reset from previous transport. state ${this.stateString()}`)\n this.reset()\n }\n this.transport = transport\n this.subscribe()\n return await this.waitPromise()\n }\n\n protected expectedEndState (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Stopped:\n case SessionState.ConfirmingLogout:\n return true\n\n default:\n return false\n }\n }\n\n protected rxOnEnd (): void {\n const logger = this.sessionLogger\n logger.info(`rx end received sessionState = [${this.sessionState.toString()}]`)\n const expectedState = this.expectedEndState()\n if (expectedState) {\n logger.info(`rx receives end state = ${this.stateString()} - stop session`)\n this.stop()\n } else {\n this.setState(SessionState.DetectBrokenNetworkConnection)\n const e = new Error(`unexpected state - transport failed? = ${this.stateString()}`)\n logger.info(`rx error ${e.message}`)\n this.terminate(e)\n }\n }\n\n protected rxOnMsg (msgType: string, view: MsgView): void {\n const logger = this.sessionLogger\n\n if (this.logReceivedMsgs) {\n const name = view.segment.type !== SegmentType.Unknown ? view?.segment?.set?.name : 'unknown'\n logger.info(`${msgType}: ${name}`)\n logger.info(`${view.toString()}`)\n }\n this.sessionState.lastReceivedAt = new Date()\n if (this.manageSession) {\n this.onMsg(msgType, view)\n } else {\n this.checkForwardMsg(msgType, view)\n }\n }\n\n protected rxOnDone (): void {\n const logger = this.sessionLogger\n logger.info('rx done received')\n this.done()\n }\n\n protected rxOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`rx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected rxOnDecoded (msgType: string, data: ElasticBuffer, ptr: number): void {\n const logger = this.sessionLogger\n logger.debug(`rx: [${msgType}] ${ptr} bytes`)\n this.onDecoded(msgType, data.toString(ptr))\n }\n\n protected txOnError (e: Error): void {\n const logger = this.sessionLogger\n logger.warning(`tx error event: ${e.message} ${JSON.stringify(e)}`)\n this.terminate(e)\n }\n\n protected txOnEncoded (msgType: string, data: string, hdr: ILooseObject): void {\n const logger = this.sessionLogger\n this.sessionState.lastHeader = hdr\n logger.debug(`tx: [${msgType}] ${data.length} bytes seqNo = ${this.lastSentSeqNum()}`)\n this.onEncoded(msgType, data)\n }\n\n /**\n * true when the event which has just fired came from the transport this session\n * is currently running. A half open socket can keep emitting long after the peer\n * has reconnected on a fresh connection - those events must not be allowed to drive\n * the live session (issue #153).\n */\n private isCurrentTransport (transport: MsgTransport, event: string): boolean {\n if (this.subscription?.transport === transport && this.transport === transport) {\n return true\n }\n const current = this.transport?.id ?? 'none'\n this.sessionLogger.warning(`ignoring '${event}' from stale transport ${transport.id} - current transport is ${current}`)\n return false\n }\n\n protected unsubscribe (): void {\n const logger = this.sessionLogger\n const subscription = this.subscription\n if (!subscription) {\n logger.debug('unsubscribe called with no active subscription')\n return\n }\n const transport = subscription.transport\n logger.info(`unsubscribe transport ${transport.id} sessionState = [${this.sessionState.toString()}]`)\n const rx = transport.receiver\n const tx = transport.transmitter\n\n rx?.removeListener('msg', subscription.rxOnMsg)\n rx?.removeListener('error', subscription.rxOnError)\n rx?.removeListener('done', subscription.rxOnDone)\n rx?.removeListener('end', subscription.rxOnEnd)\n rx?.removeListener('decoded', subscription.rxOnDecoded)\n tx?.removeListener('error', subscription.txOnError)\n tx?.removeListener('encoded', subscription.txOnEncoded)\n this.subscription = null\n logger.debug(`unsubscribe complete - rx listeners now ${rx?.listenerCount('msg') ?? 0} msg, ${rx?.listenerCount('end') ?? 0} end`)\n }\n\n protected subscribe (): void {\n const transport = this.transport\n if (!transport) {\n this.sessionLogger.warning('subscribe called with no transport')\n return\n }\n // detach from any previous transport before attaching to this one\n if (this.subscription) {\n this.unsubscribe()\n }\n const inst = this\n const subscription: ITransportSubscription = {\n transport,\n rxOnMsg: (msgType: string, view: MsgView) => {\n if (inst.isCurrentTransport(transport, 'msg')) inst.rxOnMsg(msgType, view)\n },\n rxOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'error')) inst.rxOnError(e)\n },\n rxOnDone: () => {\n if (inst.isCurrentTransport(transport, 'done')) inst.rxOnDone()\n },\n rxOnEnd: () => {\n if (inst.isCurrentTransport(transport, 'end')) inst.rxOnEnd()\n },\n rxOnDecoded: (msgType: string, data: ElasticBuffer, ptr: number) => {\n if (inst.isCurrentTransport(transport, 'decoded')) inst.rxOnDecoded(msgType, data, ptr)\n },\n txOnError: (e: Error) => {\n if (inst.isCurrentTransport(transport, 'tx error')) inst.txOnError(e)\n },\n txOnEncoded: (msgType: string, data: string, hdr: ILooseObject) => {\n if (inst.isCurrentTransport(transport, 'encoded')) inst.txOnEncoded(msgType, data, hdr)\n }\n }\n const rx = transport.receiver\n const tx = transport.transmitter\n rx?.on('msg', subscription.rxOnMsg)\n rx?.on('error', subscription.rxOnError)\n rx?.on('done', subscription.rxOnDone)\n rx?.on('end', subscription.rxOnEnd)\n rx?.on('decoded', subscription.rxOnDecoded)\n tx?.on('error', subscription.txOnError)\n tx?.on('encoded', subscription.txOnEncoded)\n this.subscription = subscription\n this.sessionLogger.info(`subscribed to transport ${transport.id}`)\n }\n\n protected validStateApplicationMsg (): boolean {\n switch (this.sessionState.state) {\n case SessionState.Idle:\n case SessionState.InitiateConnection:\n case SessionState.InitiationLogonSent:\n case SessionState.WaitingForALogon:\n case SessionState.HandleResendRequest:\n case SessionState.AwaitingProcessingResponseToTestRequest:\n case SessionState.AwaitingProcessingResponseToResendRequest:\n return false\n default:\n return true\n }\n }\n\n protected stateString (): string {\n return SessionState[this.sessionState.state]\n }\n\n protected checkForwardMsg (msgType: string, view: MsgView): void {\n this.sessionLogger.info(`forwarding msgType = '${msgType}' to application`)\n this.setState(SessionState.ActiveNormalSession)\n this.onApplicationMsg(msgType, view)\n }\n\n private stopTimer (): void {\n if (this.timer) {\n this.sessionLogger.info('stopTimer')\n clearInterval(this.timer)\n this.timer = null\n }\n }\n\n protected terminate (error: Error): void {\n if (this.sessionState.state === SessionState.Stopped) return\n this.sessionLogger.error(error)\n this.stopTimer()\n this.unsubscribe()\n if (this.transport) {\n this.sessionLogger.info(`terminate: kill transport ${this.transport.id}`)\n this.transport.end()\n }\n this.transport = null\n this.setState(SessionState.Stopped)\n this.onSessionStopping()\n this.emit('error', error)\n this.onStopped(error)\n }\n\n protected peerLogout (view: MsgView): void {\n const msg = view.getString(MsgTag.Text)\n const state = this.sessionState.state\n switch (state) {\n case SessionState.WaitingLogoutConfirm: {\n this.sessionLogger.info(`peer confirms logout Text = '${msg}'`)\n this.stop()\n break\n }\n\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.setState(SessionState.ConfirmingLogout)\n this.sessionLogger.info(`peer initiates logout Text = '${msg}'`)\n this.sessionLogout()\n }\n }\n }\n\n /**\n * @param callback optional, invoked once the message has been encoded and handed to\n * the transport, or as soon as that fails. Without it a send is fire and forget:\n * nothing tells the caller which sequence number the message went out under, and a\n * message dropped because the session is down, or refused by the encoder, goes\n * unanswered. See https://github.com/TimelordUK/jspurefix/issues/86\n */\n protected send (msgType: string, obj: ILooseObject, callback: SendCallback | null = null): void {\n const state = this.sessionState.state\n switch (state) {\n case SessionState.Stopped: {\n const msg = `can't send in state ${this.stateString()}`\n this.sessionLogger.warning(msg)\n // the message is dropped either way - but a caller that asked to be told is\n // now told, instead of watching for a log line\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n\n default: {\n this.sessionState.LastSentAt = new Date()\n const transmitter = this.transport?.transmitter\n if (!transmitter) {\n const msg = `no transport to send ${msgType} on`\n this.sessionLogger.warning(msg)\n callback?.(new Error(msg), { msgType, header: null, encoded: null })\n break\n }\n transmitter.send(msgType, obj, callback)\n break\n }\n }\n }\n\n protected sendLogout (msg: string): void {\n const factory = this.config.factory\n this.sessionLogger.info(`sending logout with ${msg}`)\n const lo = factory?.logout(this.requestLogoutType, msg)\n if (lo) {\n this.send(this.requestLogoutType, lo)\n }\n }\n\n protected sessionLogout (): void {\n const sessionState = this.sessionState\n if (sessionState.logoutSentAt) {\n return\n }\n\n switch (sessionState.state) {\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonResponse:\n case SessionState.InitiationLogonReceived: {\n // this instance initiates logout\n this.setState(SessionState.WaitingLogoutConfirm)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} initiate logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n case SessionState.ConfirmingLogout: {\n // this instance responds to log out\n this.setState(SessionState.ConfirmingLogout)\n sessionState.logoutSentAt = new Date()\n const msg = `${this.me} confirming logout`\n this.sessionLogger.info(msg)\n this.sendLogout(msg)\n break\n }\n\n default: {\n this.sessionLogger.info(`sessionLogout ignored as in state ${sessionState.state}`)\n }\n }\n }\n\n public done (): void {\n switch (this.sessionState.state) {\n case SessionState.InitiationLogonResponse:\n case SessionState.ActiveNormalSession:\n case SessionState.InitiationLogonReceived: {\n this.sessionLogout()\n break\n }\n\n case SessionState.Stopped:\n this.sessionLogger.info('done. session is now stopped')\n break\n\n default: {\n this.stop()\n break\n }\n }\n this.sessionLogger.info(`done. check logout sequence state ${this.stateString()}`)\n }\n\n public reset (resetSeqNum?: number | null): void {\n this.stopTimer()\n // unsubscribe from old transport before clearing reference\n this.unsubscribe()\n // reset parser to clear any partial message state from dropped connection\n const receiver: any = this.transport?.receiver\n if (receiver?.reset) {\n receiver.reset()\n }\n this.transport = null\n const resetFlag = this.config.description.ResetSeqNumFlag\n const seqNum = resetFlag ? 0 : resetSeqNum ?? this.sessionState.lastPeerMsgSeqNum\n this.sessionState.reset(seqNum) // from header def ... eventually\n this.onPrepareForReconnect()\n this.setState(SessionState.NetworkConnectionEstablished)\n }\n\n protected onPrepareForReconnect (): void {\n // Override in subclass to reset coordinator/transient state\n }\n\n /**\n * Called once as the session moves to Stopped, before the application is informed\n * via onStopped. Override to release session scoped resources - the ascii session\n * uses this to remove itself from the session registry. Mirrors cspurefix\n * FixSession.OnSessionStopping.\n */\n protected onSessionStopping (): void {\n // Default no-op\n }\n\n /**\n * Called for initiators after the store is loaded but before the Logon is sent.\n * Override to reset sequences/store when ResetSeqNumFlag=Y so the Logon goes out\n * with MsgSeqNum=1 instead of the recovered sender seq num.\n */\n protected async onPreLogon (): Promise<void> {\n // Default no-op\n }\n\n /**\n * Stop this session on behalf of an external caller - typically the session registry\n * when a new connection for the same SessionId replaces this one, but equally an\n * application which has decided the peer is gone. Mirrors cspurefix\n * FixSession.RequestStop.\n * @param reason recorded in the session log and carried on the emitted error\n */\n public requestStop (reason: string): void {\n this.sessionLogger.info(`requestStop: ${reason}`)\n this.stop(new Error(reason))\n }\n\n protected stop (error: Error | null = null): void {\n if (this.sessionState.state === SessionState.Stopped) {\n return\n }\n this.stopTimer()\n this.unsubscribe()\n this.sessionLogger.info(`stop: kill transport ${this.transport?.id ?? 'none'}`)\n this.onSessionStopping()\n this.transport?.end()\n if (error) {\n this.sessionLogger.info(`stop: emit error ${error.message}`)\n this.emit('error', error)\n } else {\n this.emit('done')\n }\n\n this.setState(SessionState.Stopped)\n this.onStopped(error ?? undefined)\n this.transport = null\n }\n\n /**\n * dispatches a message into the subclass that inherits from FixSession. The view contains\n * the parsed message which has utility methods such as toObject(). The Ascii session provides\n * an implementation to handle admin level messages such as logon, hearbeat and resest request.\n * Any application messges are dispatched via onApplicationMsg where the application can action\n * the message.\n * @param msgType the string based msg type the view represents\n * @param view container for all parsed fields representing the received message.\n * @protected\n */\n protected abstract onMsg (msgType: string, view: MsgView): void\n /**\n * the parsed txt recieved from the peer application. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all received\n * messages.\n * @param msgType the string based msg type the view represents\n * @param txt the received message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onDecoded (msgType: string, txt: string): void\n /**\n * the formatted txt sent to the peer application as an outbound message. Given the applicaton is\n * responible for maintaining the fix log, this can be used to persist all transmitted\n * messages. use msgType for example to persist only trade capture messages to database\n * @param msgType the msg type representing the message.\n * @param txt the sent message where for Ascii, the wire SOH delimeter is replaced\n * with that specified in the config e.g. '|'\n * @protected\n */\n protected abstract onEncoded (msgType: string, txt: string): void\n /**\n * typically all session level messages are handled by AsciiSession and these are\n * application level such as MarketDataRefresh. This will represent the applications main\n * work functiono where responses can be sent back to the peer. If manageSession has been set false\n * (not recommended) all messages are sent to this function\n * @param msgType the msg type representing the message.\n * @param view a wrapper containing the parsed message received.\n * @protected\n */\n protected abstract onApplicationMsg (msgType: string, view: MsgView): void\n /**\n * at this point the application is ready to send messages - peer login has been achieved\n * and the session can be considered ready to use. In the case of an initiator the application\n * may at this point send for security definitions or send market data subscriptions\n * @param view the login message causing session to be ready\n * @protected\n */\n protected abstract onReady (view: MsgView): void\n\n /**\n * Inform application this session has now ended - either from logout or connection dropped\n * @param error if session has been terminated via an error it is provided\n * @protected\n */\n protected abstract onStopped (error?: Error): void\n /**\n * Inform the application of a peer login attempt and ask it to accept or reject.\n *\n * Return true to let the session continue. Return false to refuse the peer: a\n * Logout carrying a Text reason is sent and the transport is dropped, so onReady\n * is never reached and no heartbeat is started.\n *\n * The verdict may be returned as a promise, for applications that must check the\n * credentials against an async source such as an http api or a database. While\n * that promise is pending the transport is paused and any message the peer sends\n * is queued, then replayed in order once the verdict arrives.\n *\n * @param view the login message\n * @param user extracted user from message\n * @param password extracted password from the message.\n * @protected\n */\n protected abstract onLogon (view: MsgView, user: string, password: string): boolean | Promise<boolean>\n}\n"]}
@@ -6,7 +6,7 @@ class SessionRegistry {
6
6
  constructor(logFactory) {
7
7
  var _a;
8
8
  this.sessions = new Map();
9
- this.logger = (_a = logFactory === null || logFactory === void 0 ? void 0 : logFactory.logger('SessionRegistry')) !== null && _a !== void 0 ? _a : null;
9
+ this.logger = (_a = logFactory === null || logFactory === void 0 ? void 0 : logFactory.logger('SessionRegistry', { component: 'SessionRegistry' })) !== null && _a !== void 0 ? _a : null;
10
10
  }
11
11
  get count() {
12
12
  return this.sessions.size;
@@ -1 +1 @@
1
- {"version":3,"file":"session-registry.js","sourceRoot":"","sources":["../../../src/transport/session/session-registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { SessionId } from '../../store/session-id'\nimport { IJsFixLogger } from '../../config/js-fix-logger'\nimport { JsFixLoggerFactory } from '../../config/js-fix-logger-factory'\n\n/**\n * The registry only ever needs to ask a session to stop, so it is typed against\n * that capability rather than against FixSession. IJsFixConfig carries a registry,\n * and FixSession is constructed from IJsFixConfig - depending on the concrete class\n * here would close an import cycle.\n */\nexport interface IStoppableSession {\n requestStop: (reason: string) => void\n}\n\n/**\n * Tracks the live session for each SessionId served by an acceptor.\n *\n * FIX allows exactly one active session per (BeginString, SenderCompID,\n * TargetCompID). A counterparty whose socket has gone half open - no FIN, no RST,\n * so node never raises 'end' - will happily open a second connection and log on\n * again. Without a registry the acceptor then runs two sessions for one CompID\n * pair, both writing to the same message store and both stamping sequence numbers,\n * which corrupts the store and produces sequence errors the peer cannot recover\n * from. See https://github.com/TimelordUK/jspurefix/issues/153.\n *\n * Ported from cspurefix PureFix.Transport/Session/SessionRegistry.cs.\n */\nexport interface ISessionRegistry {\n /**\n * Claim this SessionId for the given session. Any *different* session already\n * holding it is stopped first, because its transport is by definition stale.\n * @returns true when an existing session was stopped\n */\n register: (sessionId: SessionId, session: IStoppableSession) => boolean\n /**\n * Release this SessionId. A no-op unless the registered session is this exact\n * instance - a session which has already been replaced must not evict its\n * successor on the way out.\n */\n unregister: (sessionId: SessionId, session: IStoppableSession) => void\n /** number of live sessions */\n readonly count: number\n /** the SessionId keys currently held, for logging and diagnostics */\n keys: () => string[]\n get: (sessionId: SessionId) => IStoppableSession | null\n}\n\nexport const REPLACED_BY_NEW_CONNECTION =\n 'replaced by new connection - stopping old session with stale transport'\n\nexport class SessionRegistry implements ISessionRegistry {\n private readonly sessions = new Map<string, IStoppableSession>()\n private readonly logger: IJsFixLogger | null\n\n constructor (logFactory?: JsFixLoggerFactory) {\n this.logger = logFactory?.logger('SessionRegistry') ?? null\n }\n\n public get count (): number {\n return this.sessions.size\n }\n\n public keys (): string[] {\n return Array.from(this.sessions.keys())\n }\n\n public get (sessionId: SessionId): IStoppableSession | null {\n return this.sessions.get(sessionId.toString()) ?? null\n }\n\n public register (sessionId: SessionId, session: IStoppableSession): boolean {\n const key = sessionId.toString()\n const logger = this.logger\n logger?.info(`register called for SessionId=${key}, activeSessions=${this.sessions.size}`)\n\n const existing = this.sessions.get(key)\n let stoppedOld = false\n\n if (existing && existing !== session) {\n logger?.info(`FOUND EXISTING SESSION for ${key} - this is a reconnection scenario`)\n logger?.info('stopping old session to prevent stale transport writes')\n this.sessions.set(key, session)\n // stop after re-pointing the map so the old session's unregister (which runs\n // synchronously inside requestStop) sees it is no longer the holder\n existing.requestStop(REPLACED_BY_NEW_CONNECTION)\n stoppedOld = true\n logger?.info('old session stopped, new session registered')\n } else if (existing === session) {\n logger?.debug(`same session instance already registered for ${key}`)\n } else {\n logger?.info(`no existing session found - registering new session: ${key}`)\n this.sessions.set(key, session)\n }\n\n logger?.info(`register complete for ${key}: stoppedOldSession=${stoppedOld}, totalActiveSessions=${this.sessions.size}`)\n return stoppedOld\n }\n\n public unregister (sessionId: SessionId, session: IStoppableSession): void {\n const key = sessionId.toString()\n const logger = this.logger\n logger?.info(`unregister called for SessionId=${key}`)\n\n if (this.sessions.get(key) === session) {\n this.sessions.delete(key)\n logger?.info(`successfully unregistered session: ${key}, remainingActiveSessions=${this.sessions.size}`)\n } else {\n // expected when a new connection has already taken this SessionId over\n logger?.info(`session NOT unregistered (already replaced by new connection or not found): ${key}`)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"session-registry.js","sourceRoot":"","sources":["../../../src/transport/session/session-registry.ts"],"names":[],"mappings":";;;AA+Ca,QAAA,0BAA0B,GACrC,wEAAwE,CAAA;AAE1E,MAAa,eAAe;IAI1B,YAAa,UAA+B;;QAH3B,aAAQ,GAAG,IAAI,GAAG,EAA6B,CAAA;QAI9D,IAAI,CAAC,MAAM,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,mCAAI,IAAI,CAAA;IAC/F,CAAC;IAED,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3B,CAAC;IAEM,IAAI;QACT,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IACzC,CAAC;IAEM,GAAG,CAAE,SAAoB;;QAC9B,OAAO,MAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,mCAAI,IAAI,CAAA;IACxD,CAAC;IAEM,QAAQ,CAAE,SAAoB,EAAE,OAA0B;QAC/D,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAA;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,iCAAiC,GAAG,oBAAoB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;QAE1F,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,UAAU,GAAG,KAAK,CAAA;QAEtB,IAAI,QAAQ,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,8BAA8B,GAAG,oCAAoC,CAAC,CAAA;YACnF,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,wDAAwD,CAAC,CAAA;YACtE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAG/B,QAAQ,CAAC,WAAW,CAAC,kCAA0B,CAAC,CAAA;YAChD,UAAU,GAAG,IAAI,CAAA;YACjB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,6CAA6C,CAAC,CAAA;QAC7D,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,CAAC,gDAAgD,GAAG,EAAE,CAAC,CAAA;QACtE,CAAC;aAAM,CAAC;YACN,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,wDAAwD,GAAG,EAAE,CAAC,CAAA;YAC3E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QACjC,CAAC;QAED,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,yBAAyB,GAAG,uBAAuB,UAAU,yBAAyB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;QACxH,OAAO,UAAU,CAAA;IACnB,CAAC;IAEM,UAAU,CAAE,SAAoB,EAAE,OAA0B;QACjE,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAA;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAA;QAEtD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,sCAAsC,GAAG,6BAA6B,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1G,CAAC;aAAM,CAAC;YAEN,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,+EAA+E,GAAG,EAAE,CAAC,CAAA;QACpG,CAAC;IACH,CAAC;CACF;AA7DD,0CA6DC","sourcesContent":["import { SessionId } from '../../store/session-id'\nimport { IJsFixLogger } from '../../config/js-fix-logger'\nimport { JsFixLoggerFactory } from '../../config/js-fix-logger-factory'\n\n/**\n * The registry only ever needs to ask a session to stop, so it is typed against\n * that capability rather than against FixSession. IJsFixConfig carries a registry,\n * and FixSession is constructed from IJsFixConfig - depending on the concrete class\n * here would close an import cycle.\n */\nexport interface IStoppableSession {\n requestStop: (reason: string) => void\n}\n\n/**\n * Tracks the live session for each SessionId served by an acceptor.\n *\n * FIX allows exactly one active session per (BeginString, SenderCompID,\n * TargetCompID). A counterparty whose socket has gone half open - no FIN, no RST,\n * so node never raises 'end' - will happily open a second connection and log on\n * again. Without a registry the acceptor then runs two sessions for one CompID\n * pair, both writing to the same message store and both stamping sequence numbers,\n * which corrupts the store and produces sequence errors the peer cannot recover\n * from. See https://github.com/TimelordUK/jspurefix/issues/153.\n *\n * Ported from cspurefix PureFix.Transport/Session/SessionRegistry.cs.\n */\nexport interface ISessionRegistry {\n /**\n * Claim this SessionId for the given session. Any *different* session already\n * holding it is stopped first, because its transport is by definition stale.\n * @returns true when an existing session was stopped\n */\n register: (sessionId: SessionId, session: IStoppableSession) => boolean\n /**\n * Release this SessionId. A no-op unless the registered session is this exact\n * instance - a session which has already been replaced must not evict its\n * successor on the way out.\n */\n unregister: (sessionId: SessionId, session: IStoppableSession) => void\n /** number of live sessions */\n readonly count: number\n /** the SessionId keys currently held, for logging and diagnostics */\n keys: () => string[]\n get: (sessionId: SessionId) => IStoppableSession | null\n}\n\nexport const REPLACED_BY_NEW_CONNECTION =\n 'replaced by new connection - stopping old session with stale transport'\n\nexport class SessionRegistry implements ISessionRegistry {\n private readonly sessions = new Map<string, IStoppableSession>()\n private readonly logger: IJsFixLogger | null\n\n constructor (logFactory?: JsFixLoggerFactory) {\n this.logger = logFactory?.logger('SessionRegistry', { component: 'SessionRegistry' }) ?? null\n }\n\n public get count (): number {\n return this.sessions.size\n }\n\n public keys (): string[] {\n return Array.from(this.sessions.keys())\n }\n\n public get (sessionId: SessionId): IStoppableSession | null {\n return this.sessions.get(sessionId.toString()) ?? null\n }\n\n public register (sessionId: SessionId, session: IStoppableSession): boolean {\n const key = sessionId.toString()\n const logger = this.logger\n logger?.info(`register called for SessionId=${key}, activeSessions=${this.sessions.size}`)\n\n const existing = this.sessions.get(key)\n let stoppedOld = false\n\n if (existing && existing !== session) {\n logger?.info(`FOUND EXISTING SESSION for ${key} - this is a reconnection scenario`)\n logger?.info('stopping old session to prevent stale transport writes')\n this.sessions.set(key, session)\n // stop after re-pointing the map so the old session's unregister (which runs\n // synchronously inside requestStop) sees it is no longer the holder\n existing.requestStop(REPLACED_BY_NEW_CONNECTION)\n stoppedOld = true\n logger?.info('old session stopped, new session registered')\n } else if (existing === session) {\n logger?.debug(`same session instance already registered for ${key}`)\n } else {\n logger?.info(`no existing session found - registering new session: ${key}`)\n this.sessions.set(key, session)\n }\n\n logger?.info(`register complete for ${key}: stoppedOldSession=${stoppedOld}, totalActiveSessions=${this.sessions.size}`)\n return stoppedOld\n }\n\n public unregister (sessionId: SessionId, session: IStoppableSession): void {\n const key = sessionId.toString()\n const logger = this.logger\n logger?.info(`unregister called for SessionId=${key}`)\n\n if (this.sessions.get(key) === session) {\n this.sessions.delete(key)\n logger?.info(`successfully unregistered session: ${key}, remainingActiveSessions=${this.sessions.size}`)\n } else {\n // expected when a new connection has already taken this SessionId over\n logger?.info(`session NOT unregistered (already replaced by new connection or not found): ${key}`)\n }\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function describeConnectError(e: unknown): string;
2
+ export declare function withConnectReason(e: Error): Error;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeConnectError = describeConnectError;
4
+ exports.withConnectReason = withConnectReason;
5
+ function describeConnectError(e) {
6
+ if (e == null)
7
+ return 'unknown error';
8
+ const described = detail(e);
9
+ return described.length > 0 ? described : String(e);
10
+ }
11
+ function detail(e) {
12
+ if (e == null)
13
+ return '';
14
+ const err = e;
15
+ if (Array.isArray(err.errors) && err.errors.length > 0) {
16
+ const unique = Array.from(new Set(err.errors.map(detail).filter(m => m.length > 0)));
17
+ if (unique.length > 0)
18
+ return unique.join('; ');
19
+ }
20
+ if (err.message)
21
+ return err.message;
22
+ if (err.code)
23
+ return err.code;
24
+ return '';
25
+ }
26
+ function withConnectReason(e) {
27
+ if (!e.message) {
28
+ e.message = describeConnectError(e);
29
+ }
30
+ return e;
31
+ }
32
+ //# sourceMappingURL=connect-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-error.js","sourceRoot":"","sources":["../../../src/transport/tcp/connect-error.ts"],"names":[],"mappings":";;AAaA,oDAIC;AAiCD,8CAKC;AA1CD,SAAgB,oBAAoB,CAAE,CAAU;IAC9C,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,eAAe,CAAA;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC;AASD,SAAS,MAAM,CAAE,CAAU;IACzB,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAExB,MAAM,GAAG,GAAG,CAA4D,CAAA;IAExE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAGvD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACpF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjD,CAAC;IAED,IAAI,GAAG,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,OAAO,CAAA;IACnC,IAAI,GAAG,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC,IAAI,CAAA;IAC7B,OAAO,EAAE,CAAA;AACX,CAAC;AASD,SAAgB,iBAAiB,CAAE,CAAQ;IACzC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACf,CAAC,CAAC,OAAO,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * A readable reason for a failed connection.\n *\n * Node raises an AggregateError when the host resolved to more than one address and\n * every attempt failed. That is not an edge case: 'localhost' is both ::1 and\n * 127.0.0.1 on any modern machine, so it is what an ordinary refused connection looks\n * like. Its own message is empty and the detail sits in errors[], so reporting\n * e.message alone said nothing at all about the commonest failure there is - an\n * application catching a rejected connect saw an Error with no message.\n *\n * Falls back to the code (ECONNREFUSED, ENOTFOUND, ETIMEDOUT) when there is no\n * message anywhere, which is still enough to act on.\n */\nexport function describeConnectError (e: unknown): string {\n if (e == null) return 'unknown error'\n const described = detail(e)\n return described.length > 0 ? described : String(e)\n}\n\n/**\n * The reason, or '' when this error carries none.\n *\n * Kept separate from the public function so a nested error with nothing to say\n * contributes nothing, rather than a stringified 'Error' that would then look like a\n * reason and stop the aggregate falling back to its own code.\n */\nfunction detail (e: unknown): string {\n if (e == null) return ''\n\n const err = e as { message?: string, code?: string, errors?: unknown[] }\n\n if (Array.isArray(err.errors) && err.errors.length > 0) {\n // every address usually fails the same way - say it once rather than repeating\n // 'connect ECONNREFUSED' for each family\n const unique = Array.from(new Set(err.errors.map(detail).filter(m => m.length > 0)))\n if (unique.length > 0) return unique.join('; ')\n }\n\n if (err.message) return err.message\n if (err.code) return err.code\n return ''\n}\n\n/**\n * Give an error a message when it has none, keeping the object itself.\n *\n * Deliberately not a wrapper: `code` and `errors` are what a caller switches on, and\n * building a fresh Error to hold the text would throw both away. Returns the same\n * error so it can be used inline.\n */\nexport function withConnectReason (e: Error): Error {\n if (!e.message) {\n e.message = describeConnectError(e)\n }\n return e\n}\n"]}
@@ -28,6 +28,7 @@ const session_state_1 = require("../session/session-state");
28
28
  const tsyringe_1 = require("tsyringe");
29
29
  const di_tokens_1 = require("../../runtime/di-tokens");
30
30
  const fix_entity_1 = require("../fix-entity");
31
+ const connect_error_1 = require("./connect-error");
31
32
  let RecoveringTcpInitiator = RecoveringTcpInitiator_1 = class RecoveringTcpInitiator extends fix_entity_1.FixEntity {
32
33
  constructor(jsFixConfig) {
33
34
  var _a, _b, _c, _d, _e, _f, _g;
@@ -40,7 +41,7 @@ let RecoveringTcpInitiator = RecoveringTcpInitiator_1 = class RecoveringTcpIniti
40
41
  this.connectTimeoutSecs = RecoveringTcpInitiator_1.DefaultConnectTimeoutSecs;
41
42
  this.application = (_a = this.jsFixConfig.description.application) !== null && _a !== void 0 ? _a : null;
42
43
  const name = (_c = (_b = this.application) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'na';
43
- this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`);
44
+ this.logger = jsFixConfig.logFactory.logger(`${name}:RecoveringTcpInitiator`, { component: 'RecoveringTcpInitiator', app: name, role: 'initiator' });
44
45
  if (!this.application) {
45
46
  throw new Error('no application in session description.');
46
47
  }
@@ -140,7 +141,7 @@ let RecoveringTcpInitiator = RecoveringTcpInitiator_1 = class RecoveringTcpIniti
140
141
  this.connect(this.connectTimeoutSecs).then(t => {
141
142
  this.logger.info(`new transport ${t.id}`);
142
143
  }).catch((e) => {
143
- this.logger.info(`failed to re-connect ${e.message} - backoff for ${this.backoffFailConnectSecs}`);
144
+ this.logger.info(`failed to re-connect: ${(0, connect_error_1.describeConnectError)(e)} - backoff for ${this.backoffFailConnectSecs}`);
144
145
  this.th = setTimeout(() => {
145
146
  this.logger.info('returning to recover()');
146
147
  setImmediate(() => {