jspurefix 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/appveyor.yml +1 -1
- package/dist/buffer/ascii/ascii-encoder.d.ts +2 -2
- package/dist/buffer/ascii/ascii-encoder.js +1 -1
- package/dist/buffer/ascii/ascii-encoder.js.map +1 -1
- package/dist/buffer/ascii/ascii-parser-state.d.ts +3 -2
- package/dist/buffer/ascii/ascii-parser-state.js +1 -2
- package/dist/buffer/ascii/ascii-parser-state.js.map +1 -1
- package/dist/buffer/ascii/ascii-parser.d.ts +1 -1
- package/dist/buffer/ascii/ascii-parser.js +5 -4
- package/dist/buffer/ascii/ascii-parser.js.map +1 -1
- package/dist/buffer/ascii/ascii-segment-parser.js.map +1 -1
- package/dist/buffer/ascii/ascii-view.d.ts +4 -3
- package/dist/buffer/ascii/ascii-view.js +8 -5
- package/dist/buffer/ascii/ascii-view.js.map +1 -1
- package/dist/buffer/encode-proxy.js +1 -1
- package/dist/buffer/encode-proxy.js.map +1 -1
- package/dist/buffer/fixml/fixml-encoder.d.ts +2 -2
- package/dist/buffer/fixml/fixml-encoder.js +1 -1
- package/dist/buffer/fixml/fixml-encoder.js.map +1 -1
- package/dist/buffer/fixml/fixml-parser.js +2 -2
- package/dist/buffer/fixml/fixml-parser.js.map +1 -1
- package/dist/buffer/fixml/fixml-view.d.ts +3 -2
- package/dist/buffer/fixml/fixml-view.js +5 -4
- package/dist/buffer/fixml/fixml-view.js.map +1 -1
- package/dist/buffer/msg-encoder.d.ts +2 -2
- package/dist/buffer/msg-encoder.js.map +1 -1
- package/dist/buffer/msg-view.d.ts +8 -6
- package/dist/buffer/msg-view.js +10 -8
- package/dist/buffer/msg-view.js.map +1 -1
- package/dist/buffer/segment/segment-description.d.ts +3 -3
- package/dist/buffer/segment/segment-description.js.map +1 -1
- package/dist/buffer/tag/tags.d.ts +2 -5
- package/dist/buffer/tag/tags.js +4 -5
- package/dist/buffer/tag/tags.js.map +1 -1
- package/dist/collections/collection.d.ts +0 -1
- package/dist/collections/collection.js.map +1 -1
- package/dist/collections/index.d.ts +0 -1
- package/dist/collections/index.js +0 -17
- package/dist/collections/index.js.map +1 -1
- package/dist/config/js-fix-config.d.ts +2 -1
- package/dist/config/js-fix-config.js +3 -3
- package/dist/config/js-fix-config.js.map +1 -1
- package/dist/dictionary/compiler/compiler-type.d.ts +3 -3
- package/dist/dictionary/compiler/compiler-type.js.map +1 -1
- package/dist/dictionary/compiler/enum-compiler.js +2 -2
- package/dist/dictionary/compiler/enum-compiler.js.map +1 -1
- package/dist/dictionary/compiler/msg-compiler.d.ts +1 -2
- package/dist/dictionary/compiler/msg-compiler.js +6 -7
- package/dist/dictionary/compiler/msg-compiler.js.map +1 -1
- package/dist/dictionary/contained/contained-component-field.d.ts +1 -1
- package/dist/dictionary/contained/contained-component-field.js.map +1 -1
- package/dist/dictionary/contained/contained-field-set.d.ts +9 -20
- package/dist/dictionary/contained/contained-field-set.js +16 -149
- package/dist/dictionary/contained/contained-field-set.js.map +1 -1
- package/dist/dictionary/contained/contained-group-field.d.ts +1 -1
- package/dist/dictionary/contained/contained-group-field.js.map +1 -1
- package/dist/dictionary/contained/contained-set-builder.d.ts +15 -0
- package/dist/dictionary/contained/contained-set-builder.js +142 -0
- package/dist/dictionary/contained/contained-set-builder.js.map +1 -0
- package/dist/dictionary/contained/contained-set.d.ts +32 -0
- package/dist/{types/FIX.5.0SP2/quickfix/xm_lnon_fix.js → dictionary/contained/contained-set.js} +1 -1
- package/dist/dictionary/contained/contained-set.js.map +1 -0
- package/dist/dictionary/contained/contained-simple-field.d.ts +1 -1
- package/dist/dictionary/contained/contained-simple-field.js.map +1 -1
- package/dist/dictionary/contained/index.d.ts +4 -1
- package/dist/dictionary/contained/index.js +4 -1
- package/dist/dictionary/contained/index.js.map +1 -1
- package/dist/dictionary/definition/category-simple-set.d.ts +1 -2
- package/dist/dictionary/definition/category-simple-set.js +1 -2
- package/dist/dictionary/definition/category-simple-set.js.map +1 -1
- package/dist/dictionary/definition/component-field-definition.d.ts +1 -1
- package/dist/dictionary/definition/component-field-definition.js +2 -2
- package/dist/dictionary/definition/component-field-definition.js.map +1 -1
- package/dist/dictionary/definition/fix-definitions.d.ts +8 -9
- package/dist/dictionary/definition/fix-definitions.js +22 -20
- package/dist/dictionary/definition/fix-definitions.js.map +1 -1
- package/dist/dictionary/definition/group-field-definition.d.ts +1 -1
- package/dist/dictionary/definition/group-field-definition.js +2 -2
- package/dist/dictionary/definition/group-field-definition.js.map +1 -1
- package/dist/dictionary/definition/message-definition.d.ts +1 -1
- package/dist/dictionary/definition/message-definition.js +2 -2
- package/dist/dictionary/definition/message-definition.js.map +1 -1
- package/dist/dictionary/definition/simple-field-definition.d.ts +2 -3
- package/dist/dictionary/definition/simple-field-definition.js +6 -7
- package/dist/dictionary/definition/simple-field-definition.js.map +1 -1
- package/dist/dictionary/parser/fix-repository/repository.js +20 -20
- package/dist/dictionary/parser/fix-repository/repository.js.map +1 -1
- package/dist/dictionary/parser/fixml/components-parser.js +18 -16
- package/dist/dictionary/parser/fixml/components-parser.js.map +1 -1
- package/dist/dictionary/parser/fixml/fields-parser.js +2 -3
- package/dist/dictionary/parser/fixml/fields-parser.js.map +1 -1
- package/dist/dictionary/parser/fixml/include-graph.js +8 -9
- package/dist/dictionary/parser/fixml/include-graph.js.map +1 -1
- package/dist/dictionary/parser/quickfix/field-definition-parser.js.map +1 -1
- package/dist/dictionary/parser/quickfix/message-parser.js +2 -1
- package/dist/dictionary/parser/quickfix/message-parser.js.map +1 -1
- package/dist/dictionary/parser/quickfix/node-parser.js +3 -2
- package/dist/dictionary/parser/quickfix/node-parser.js.map +1 -1
- package/dist/dictionary/parser/quickfix/parse-context.d.ts +3 -3
- package/dist/dictionary/parser/quickfix/parse-context.js.map +1 -1
- package/dist/dictionary/parser/quickfix/parse-progress.d.ts +1 -2
- package/dist/dictionary/parser/quickfix/parse-progress.js +2 -3
- package/dist/dictionary/parser/quickfix/parse-progress.js.map +1 -1
- package/dist/dictionary/parser/quickfix/quick-fix-xml-file-builder.js +4 -5
- package/dist/dictionary/parser/quickfix/quick-fix-xml-file-builder.js.map +1 -1
- package/dist/dictionary/parser/quickfix/quick-fix-xml-file-parser.js +6 -6
- package/dist/dictionary/parser/quickfix/quick-fix-xml-file-parser.js.map +1 -1
- package/dist/dictionary/parser/quickfix/quick-fix-xml-formatter.d.ts +1 -1
- package/dist/dictionary/parser/quickfix/quick-fix-xml-formatter.js.map +1 -1
- package/dist/dictionary/set-reduce.d.ts +2 -2
- package/dist/dictionary/set-reduce.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/jsfix-cmd.js +4 -5
- package/dist/jsfix-cmd.js.map +1 -1
- package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js +7 -8
- package/dist/sample/tcp/recovering-skeleton/respawn-acceptor.js.map +1 -1
- package/dist/sample/tcp/trade-capture/trade-capture-client.js +3 -4
- package/dist/sample/tcp/trade-capture/trade-capture-client.js.map +1 -1
- package/dist/sample/tcp/trade-capture/trade-capture-server.js.map +1 -1
- package/dist/store/fix-msg-ascii-store-resend.d.ts +4 -3
- package/dist/store/fix-msg-ascii-store-resend.js +21 -5
- package/dist/store/fix-msg-ascii-store-resend.js.map +1 -1
- package/dist/store/fix-msg-memory-store.js +3 -4
- package/dist/store/fix-msg-memory-store.js.map +1 -1
- package/dist/store/fix-msg-store-record.js.map +1 -1
- package/dist/test/ascii/ascii-encoder.test.js.map +1 -1
- package/dist/test/ascii/ascii-store-replay.test.js +14 -1
- package/dist/test/ascii/ascii-store-replay.test.js.map +1 -1
- package/dist/test/ascii/fix-log-replay.test.js.map +1 -1
- package/dist/test/ascii/fix-repo-dict.test.js.map +1 -1
- package/dist/test/ascii/qf-50sp0-dict.test.js +7 -7
- package/dist/test/ascii/qf-50sp0-dict.test.js.map +1 -1
- package/dist/test/ascii/qf-50sp2-dict.test.js +5 -2
- package/dist/test/ascii/qf-50sp2-dict.test.js.map +1 -1
- package/dist/test/ascii/session.test.js +64 -15
- package/dist/test/ascii/session.test.js.map +1 -1
- package/dist/test/env/encoder-test.d.ts +3 -3
- package/dist/test/env/encoder-test.js.map +1 -1
- package/dist/test/env/set-constraint-helper.d.ts +4 -4
- package/dist/test/env/set-constraint-helper.js.map +1 -1
- package/dist/transport/ascii/ascii-msg-transmitter.js.map +1 -1
- package/dist/transport/ascii/ascii-session.js +5 -2
- package/dist/transport/ascii/ascii-session.js.map +1 -1
- package/dist/transport/fixml/fixml-session.js.map +1 -1
- package/dist/transport/http/http-acceptor.js +3 -4
- package/dist/transport/http/http-acceptor.js.map +1 -1
- package/dist/transport/http/http-json-sample-adapter.js +3 -4
- package/dist/transport/http/http-json-sample-adapter.js.map +1 -1
- package/dist/transport/session/dynamic-session-manager.d.ts +8 -0
- package/dist/transport/session/dynamic-session-manager.js +15 -0
- package/dist/transport/session/dynamic-session-manager.js.map +1 -0
- package/dist/transport/session/session-description.d.ts +9 -7
- package/dist/transport/session/session-description.js.map +1 -1
- package/dist/util/json-helper.d.ts +2 -2
- package/dist/util/json-helper.js.map +1 -1
- package/dist/util/message-generator.js +1 -1
- package/dist/util/message-generator.js.map +1 -1
- package/package.json +21 -21
- package/src/buffer/ascii/ascii-encoder.ts +7 -7
- package/src/buffer/ascii/ascii-parser-state.ts +4 -4
- package/src/buffer/ascii/ascii-parser.ts +6 -5
- package/src/buffer/ascii/ascii-segment-parser.ts +2 -2
- package/src/buffer/ascii/ascii-view.ts +9 -7
- package/src/buffer/encode-proxy.ts +9 -9
- package/src/buffer/fixml/fixml-encoder.ts +14 -10
- package/src/buffer/fixml/fixml-parser.ts +5 -5
- package/src/buffer/fixml/fixml-view.ts +5 -5
- package/src/buffer/msg-encoder.ts +3 -3
- package/src/buffer/msg-view.ts +18 -18
- package/src/buffer/segment/segment-description.ts +2 -2
- package/src/buffer/tag/tags.ts +4 -6
- package/src/collections/collection.ts +0 -1
- package/src/collections/index.ts +1 -1
- package/src/config/js-fix-config.ts +3 -2
- package/src/dictionary/compiler/compiler-type.ts +8 -2
- package/src/dictionary/compiler/enum-compiler.ts +2 -2
- package/src/dictionary/compiler/msg-compiler.ts +11 -12
- package/src/dictionary/contained/contained-component-field.ts +1 -1
- package/src/dictionary/contained/contained-field-set.ts +21 -176
- package/src/dictionary/contained/contained-group-field.ts +1 -1
- package/src/dictionary/contained/contained-set-builder.ts +164 -0
- package/src/dictionary/contained/contained-set.ts +83 -0
- package/src/dictionary/contained/contained-simple-field.ts +1 -1
- package/src/dictionary/contained/index.ts +4 -1
- package/src/dictionary/definition/category-simple-set.ts +1 -2
- package/src/dictionary/definition/component-field-definition.ts +1 -1
- package/src/dictionary/definition/fix-definitions.ts +28 -26
- package/src/dictionary/definition/group-field-definition.ts +1 -1
- package/src/dictionary/definition/message-definition.ts +6 -6
- package/src/dictionary/definition/simple-field-definition.ts +9 -10
- package/src/dictionary/parser/fix-repository/repository.ts +47 -40
- package/src/dictionary/parser/fixml/components-parser.ts +41 -38
- package/src/dictionary/parser/fixml/fields-parser.ts +3 -4
- package/src/dictionary/parser/fixml/include-graph.ts +13 -14
- package/src/dictionary/parser/quickfix/field-definition-parser.ts +5 -5
- package/src/dictionary/parser/quickfix/message-parser.ts +7 -5
- package/src/dictionary/parser/quickfix/node-parser.ts +13 -6
- package/src/dictionary/parser/quickfix/parse-context.ts +2 -2
- package/src/dictionary/parser/quickfix/parse-progress.ts +2 -3
- package/src/dictionary/parser/quickfix/quick-fix-xml-file-builder.ts +4 -5
- package/src/dictionary/parser/quickfix/quick-fix-xml-file-parser.ts +10 -12
- package/src/dictionary/parser/quickfix/quick-fix-xml-formatter.ts +1 -1
- package/src/dictionary/set-reduce.ts +3 -3
- package/src/index.ts +0 -1
- package/src/jsfix-cmd.ts +5 -6
- package/src/sample/tcp/recovering-skeleton/respawn-acceptor.ts +7 -8
- package/src/sample/tcp/trade-capture/trade-capture-client.ts +4 -5
- package/src/sample/tcp/trade-capture/trade-capture-server.ts +1 -1
- package/src/store/fix-msg-ascii-store-resend.ts +64 -8
- package/src/store/fix-msg-memory-store.ts +3 -4
- package/src/store/fix-msg-store-record.ts +1 -1
- package/src/transport/ascii/ascii-msg-transmitter.ts +6 -6
- package/src/transport/ascii/ascii-session.ts +11 -7
- package/src/transport/fixml/fixml-session.ts +3 -3
- package/src/transport/http/http-acceptor.ts +4 -5
- package/src/transport/http/http-json-sample-adapter.ts +3 -4
- package/src/transport/session/dynamic-session-manager.ts +16 -0
- package/src/transport/session/session-description.ts +10 -7
- package/src/util/json-helper.ts +3 -3
- package/src/util/message-generator.ts +4 -4
- package/dist/collections/dictionary.d.ts +0 -15
- package/dist/collections/dictionary.js +0 -57
- package/dist/collections/dictionary.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/execution_acknowledgement.d.ts +0 -31
- package/dist/types/FIX.5.0SP2/quickfix/execution_acknowledgement.js +0 -3
- package/dist/types/FIX.5.0SP2/quickfix/execution_acknowledgement.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/mass_quote_acknowledgement.d.ts +0 -26
- package/dist/types/FIX.5.0SP2/quickfix/mass_quote_acknowledgement.js +0 -3
- package/dist/types/FIX.5.0SP2/quickfix/mass_quote_acknowledgement.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/set/hop_grp.d.ts +0 -5
- package/dist/types/FIX.5.0SP2/quickfix/set/hop_grp.js +0 -3
- package/dist/types/FIX.5.0SP2/quickfix/set/hop_grp.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/set/msg_type_grp.d.ts +0 -8
- package/dist/types/FIX.5.0SP2/quickfix/set/msg_type_grp.js +0 -3
- package/dist/types/FIX.5.0SP2/quickfix/set/msg_type_grp.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/set/not_affected_orders_grp.d.ts +0 -4
- package/dist/types/FIX.5.0SP2/quickfix/set/not_affected_orders_grp.js +0 -3
- package/dist/types/FIX.5.0SP2/quickfix/set/not_affected_orders_grp.js.map +0 -1
- package/dist/types/FIX.5.0SP2/quickfix/xm_lnon_fix.d.ts +0 -6
- package/dist/types/FIX.5.0SP2/quickfix/xm_lnon_fix.js.map +0 -1
- package/src/collections/dictionary.ts +0 -62
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ContainedComponentField,
|
|
3
|
+
ContainedField,
|
|
4
|
+
ContainedGroupField,
|
|
5
|
+
ContainedSetBuilder,
|
|
6
|
+
ContainedSimpleField
|
|
7
|
+
} from '../../contained'
|
|
2
8
|
import { ComponentFieldDefinition, GroupFieldDefinition, SimpleFieldDefinition } from '../../definition'
|
|
3
9
|
import { ParseContext } from './parse-context'
|
|
4
10
|
import { ISaxNode } from '../../sax-node'
|
|
@@ -17,7 +23,8 @@ export abstract class NodeParser {
|
|
|
17
23
|
protected addto (context: ParseContext, containedField: ContainedField): void {
|
|
18
24
|
if (context.set != null) {
|
|
19
25
|
this.progress.newAdds++
|
|
20
|
-
context.set
|
|
26
|
+
const builder = new ContainedSetBuilder(context.set)
|
|
27
|
+
builder.add(containedField)
|
|
21
28
|
} else {
|
|
22
29
|
this.progress.cacheMisses++
|
|
23
30
|
}
|
|
@@ -34,7 +41,7 @@ export abstract class NodeParser {
|
|
|
34
41
|
throw new Error(`simple field ${node.name} has no parent on which to add.`)
|
|
35
42
|
}
|
|
36
43
|
const fieldName: string = node.attributes.name
|
|
37
|
-
const fieldDefinition: SimpleFieldDefinition |
|
|
44
|
+
const fieldDefinition: SimpleFieldDefinition | undefined = this.progress.definitions.simple.get(fieldName)
|
|
38
45
|
if (!fieldDefinition) {
|
|
39
46
|
throw new Error(`simple field ${fieldName} has no declaration in dictionary.`)
|
|
40
47
|
}
|
|
@@ -60,7 +67,7 @@ export abstract class NodeParser {
|
|
|
60
67
|
if (!parent) {
|
|
61
68
|
throw new Error(`component ${node.name} has no parent on which to add.`)
|
|
62
69
|
}
|
|
63
|
-
const fieldDef: ComponentFieldDefinition |
|
|
70
|
+
const fieldDef: ComponentFieldDefinition | undefined = this.progress.definitions.component.get(componentName)
|
|
64
71
|
if (fieldDef) {
|
|
65
72
|
const containedField: ContainedComponentField = this.makeContainedComponent(fieldDef, parent)
|
|
66
73
|
this.addto(parent, containedField)
|
|
@@ -146,10 +153,10 @@ export abstract class NodeParser {
|
|
|
146
153
|
throw new Error(msg)
|
|
147
154
|
}
|
|
148
155
|
const fullQualifiedName = `${this.fullContextName()}.${groupName}`
|
|
149
|
-
let cached: (GroupFieldDefinition |
|
|
156
|
+
let cached: (GroupFieldDefinition | undefined) = this.progress.groupDefinitionCache.get(fullQualifiedName)
|
|
150
157
|
if (!cached) {
|
|
151
158
|
cached = new GroupFieldDefinition(groupName, groupName, null, noOfField, null)
|
|
152
|
-
this.progress.groupDefinitionCache.
|
|
159
|
+
this.progress.groupDefinitionCache.set(fullQualifiedName, cached)
|
|
153
160
|
} else {
|
|
154
161
|
cached.reset()
|
|
155
162
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IContainedSet } from '../../contained'
|
|
2
2
|
import { ComponentFieldDefinition, GroupFieldDefinition, MessageDefinition } from '../../definition'
|
|
3
3
|
|
|
4
4
|
export class ParseContext {
|
|
5
5
|
public required: boolean
|
|
6
6
|
|
|
7
|
-
constructor (public name: string, public defining: boolean, public set:
|
|
7
|
+
constructor (public name: string, public defining: boolean, public set: IContainedSet | null) {
|
|
8
8
|
this.required = false
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ParseState } from './parse-state'
|
|
2
2
|
import { FixDefinitions, GroupFieldDefinition } from '../../definition'
|
|
3
|
-
import { Dictionary } from '../../../collections'
|
|
4
3
|
|
|
5
4
|
export class ParseProgress {
|
|
6
5
|
public definitions: FixDefinitions
|
|
@@ -13,10 +12,10 @@ export class ParseProgress {
|
|
|
13
12
|
public previousDelta: number = 0
|
|
14
13
|
public componentPasses: number = 0
|
|
15
14
|
public readonly maxIterations: number = 5
|
|
16
|
-
public groupDefinitionCache:
|
|
15
|
+
public groupDefinitionCache: Map<string, GroupFieldDefinition> = new Map<string, GroupFieldDefinition>()
|
|
17
16
|
|
|
18
17
|
public toString (): string {
|
|
19
|
-
return `parseState = ${this.parseState}, numberPasses = ${this.numberPasses}, componentPasses = ${this.componentPasses}, groupCount = ${this.groupDefinitionCache.
|
|
18
|
+
return `parseState = ${this.parseState}, numberPasses = ${this.numberPasses}, componentPasses = ${this.componentPasses}, groupCount = ${this.groupDefinitionCache.size}, cacheMisses = ${this.cacheMisses}, newContexts = ${this.newContexts}, newDefines = ${this.newDefines}, newAdds = ${this.newAdds}, previousDelta = ${this.previousDelta}, delta = ${this.delta()}, changed = ${this.changed()}`
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
public delta (): number {
|
|
@@ -9,13 +9,12 @@ import {
|
|
|
9
9
|
FieldsDispatch
|
|
10
10
|
} from '../../contained'
|
|
11
11
|
import { keys } from 'lodash'
|
|
12
|
-
import { Dictionary } from '../../../collections'
|
|
13
12
|
import { QuickFixXmlFormatter } from './quick-fix-xml-formatter'
|
|
14
13
|
|
|
15
14
|
export class QuickFixXmlFileBuilder {
|
|
16
15
|
private readonly usedTags: INumericKeyed<string> = {}
|
|
17
16
|
private readonly requiredComponents: string[] = []
|
|
18
|
-
private readonly seenComponents:
|
|
17
|
+
private readonly seenComponents: Map<string, boolean> = new Map<string, boolean>()
|
|
19
18
|
private readonly indent: number = 2
|
|
20
19
|
private readonly dispatcher: FieldsDispatch = new FieldsDispatch()
|
|
21
20
|
public readonly elasticBuffer: ElasticBuffer = new ElasticBuffer(10 * 1024)
|
|
@@ -121,7 +120,7 @@ export class QuickFixXmlFileBuilder {
|
|
|
121
120
|
*/
|
|
122
121
|
private writeEnumDefinition (sf: SimpleFieldDefinition, leadingIndent: number): string {
|
|
123
122
|
const eb: ElasticBuffer = new ElasticBuffer(2 * 1024)
|
|
124
|
-
const keys = sf.enums.keys()
|
|
123
|
+
const keys = Array.from(sf.enums.keys())
|
|
125
124
|
keys.sort()
|
|
126
125
|
keys.forEach(k => {
|
|
127
126
|
eb.writeString(QuickFixXmlFormatter.addEnum(sf.enums.get(k), leadingIndent))
|
|
@@ -146,8 +145,8 @@ export class QuickFixXmlFileBuilder {
|
|
|
146
145
|
|
|
147
146
|
private writeComponentField (cf: ContainedComponentField, eb: ElasticBuffer, leadingIndent: number): void {
|
|
148
147
|
eb.writeString(QuickFixXmlFormatter.addComponent(cf, leadingIndent))
|
|
149
|
-
if (!this.seenComponents.
|
|
150
|
-
this.seenComponents.
|
|
148
|
+
if (!this.seenComponents.has(cf.name)) {
|
|
149
|
+
this.seenComponents.set(cf.name, true)
|
|
151
150
|
this.requiredComponents.push(cf.name)
|
|
152
151
|
}
|
|
153
152
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
2
1
|
import { SAXParser } from 'sax'
|
|
3
2
|
import { IDictDoneCb, SAXStream } from '../../dict-primitive'
|
|
4
|
-
import { FixDefinitions } from '../../definition'
|
|
3
|
+
import { FixDefinitions, MessageDefinition } from '../../definition'
|
|
5
4
|
import { FieldDefinitionParser } from './field-definition-parser'
|
|
6
5
|
import { FieldSetParser } from './field-set-parser'
|
|
7
6
|
import { MessageParser } from './message-parser'
|
|
@@ -9,7 +8,7 @@ import { NodeParser } from './node-parser'
|
|
|
9
8
|
import { FixParser } from '../../fix-parser'
|
|
10
9
|
import { GetJsFixLogger } from '../../../config'
|
|
11
10
|
import { promisify } from 'util'
|
|
12
|
-
import { ContainedComponentField } from '../../contained'
|
|
11
|
+
import { ContainedComponentField, ContainedSetBuilder, IContainedSet } from '../../contained'
|
|
13
12
|
import { ISaxNode } from '../../sax-node'
|
|
14
13
|
import { FixDefinitionSource } from '../../fix-definition-source'
|
|
15
14
|
import { VersionUtil } from '../../version-util'
|
|
@@ -33,7 +32,7 @@ export class QuickFixXmlFileParser extends FixParser {
|
|
|
33
32
|
done(e, null)
|
|
34
33
|
})
|
|
35
34
|
|
|
36
|
-
saxStream.on('closetag', (name) => {
|
|
35
|
+
saxStream.on('closetag', (name: string) => {
|
|
37
36
|
if (parser != null) {
|
|
38
37
|
parser.close(saxParser.line, name)
|
|
39
38
|
}
|
|
@@ -49,9 +48,7 @@ export class QuickFixXmlFileParser extends FixParser {
|
|
|
49
48
|
}
|
|
50
49
|
})
|
|
51
50
|
|
|
52
|
-
saxStream.on('opentag', (
|
|
53
|
-
const saxNode: ISaxNode = node as ISaxNode
|
|
54
|
-
|
|
51
|
+
saxStream.on('opentag', (saxNode: ISaxNode) => {
|
|
55
52
|
switch (saxNode.name) {
|
|
56
53
|
case 'fix': {
|
|
57
54
|
switch (progress.parseState) {
|
|
@@ -135,7 +132,7 @@ export class QuickFixXmlFileParser extends FixParser {
|
|
|
135
132
|
switch (progress.parseState) {
|
|
136
133
|
case ParseState.Messages: {
|
|
137
134
|
parser = new FieldSetParser(progress)
|
|
138
|
-
parser.open(saxParser.line,
|
|
135
|
+
parser.open(saxParser.line, saxNode)
|
|
139
136
|
break
|
|
140
137
|
}
|
|
141
138
|
}
|
|
@@ -154,15 +151,16 @@ export class QuickFixXmlFileParser extends FixParser {
|
|
|
154
151
|
|
|
155
152
|
private encloseMessages (): void {
|
|
156
153
|
const messages = this.state.definitions.message
|
|
157
|
-
const keys = messages.keys()
|
|
154
|
+
const keys = Array.from(messages.keys())
|
|
158
155
|
const trailerName = 'StandardTrailer'
|
|
159
156
|
keys.forEach(k => {
|
|
160
|
-
const message = messages.get(k)
|
|
157
|
+
const message: (MessageDefinition | undefined) = messages.get(k)
|
|
158
|
+
const builder = new ContainedSetBuilder(message as IContainedSet)
|
|
161
159
|
const trailer = this.state.definitions.component.get(trailerName)
|
|
162
|
-
if (trailer && !message?.components.
|
|
160
|
+
if (trailer && !message?.components.has(trailerName)) {
|
|
163
161
|
const contained = new ContainedComponentField(trailer, message?.fields?.length ?? 0, true)
|
|
164
162
|
this.state.newAdds++
|
|
165
|
-
|
|
163
|
+
builder?.add(contained)
|
|
166
164
|
}
|
|
167
165
|
})
|
|
168
166
|
}
|
|
@@ -52,7 +52,7 @@ export class QuickFixXmlFormatter {
|
|
|
52
52
|
return `${QuickFixXmlFormatter.whitespace(ws)}</group>${newLine}`
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
public static addEnum (fe: (FieldEnum |
|
|
55
|
+
public static addEnum (fe: (FieldEnum | undefined), ws: number): string {
|
|
56
56
|
return `${QuickFixXmlFormatter.whitespace(ws)}<value enum='${fe?.key}' description='${fe?.description ?? fe?.val}'/>${newLine}`
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ContainedField,
|
|
2
|
+
ContainedField, IContainedSet,
|
|
3
3
|
ContainedGroupField, ContainedSimpleField, ContainedComponentField, ContainedFieldType
|
|
4
4
|
} from './contained'
|
|
5
5
|
import { ITypeDispatcher } from './type-dispatcher'
|
|
@@ -33,8 +33,8 @@ export class SetReduce<T> {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
reduce (def:
|
|
37
|
-
return def.fields.reduce((a:
|
|
36
|
+
reduce (def: IContainedSet, dispatcher: ITypeDispatcher<T>, init: T): T {
|
|
37
|
+
return def.fields.reduce((a: T, field: ContainedField) => {
|
|
38
38
|
this.reduceField(a, field, dispatcher)
|
|
39
39
|
return a
|
|
40
40
|
}, init)
|
package/src/index.ts
CHANGED
package/src/jsfix-cmd.ts
CHANGED
|
@@ -19,7 +19,6 @@ import { AsciiMsgTransmitter } from './transport/ascii/ascii-msg-transmitter'
|
|
|
19
19
|
import { SessionContainer } from './runtime'
|
|
20
20
|
import { DITokens } from './runtime/di-tokens'
|
|
21
21
|
import buildOptions from 'minimist-options'
|
|
22
|
-
import { Dictionary } from './collections'
|
|
23
22
|
import { QuickFixXmlFileBuilder } from './dictionary/parser/quickfix/quick-fix-xml-file-builder'
|
|
24
23
|
|
|
25
24
|
const fs = require('node-fs-extra')
|
|
@@ -202,7 +201,7 @@ export class JsfixCmd {
|
|
|
202
201
|
private sessionDescription: ISessionDescription
|
|
203
202
|
private delimiter: number = AsciiChars.Soh
|
|
204
203
|
private stats: ILooseObject = {}
|
|
205
|
-
private readonly filter:
|
|
204
|
+
private readonly filter: Map<string, boolean> = new Map<string, boolean>()
|
|
206
205
|
private messages: number = 0
|
|
207
206
|
private print: boolean = true
|
|
208
207
|
|
|
@@ -425,7 +424,7 @@ export class JsfixCmd {
|
|
|
425
424
|
}
|
|
426
425
|
|
|
427
426
|
private field (): void {
|
|
428
|
-
let sf: SimpleFieldDefinition |
|
|
427
|
+
let sf: SimpleFieldDefinition | undefined
|
|
429
428
|
const tag: number = parseInt(argv.field, 10)
|
|
430
429
|
const definitions = this.definitions
|
|
431
430
|
if (!isNaN(tag)) {
|
|
@@ -465,7 +464,7 @@ export class JsfixCmd {
|
|
|
465
464
|
|
|
466
465
|
private trim (): string {
|
|
467
466
|
this.setFilter()
|
|
468
|
-
const types = this.filter.
|
|
467
|
+
const types = this.filter.size > 0 ? Array.from(this.filter.keys()) : Array.from(this.definitions.simple.get('MsgType')?.enums.keys() ?? [])
|
|
469
468
|
const qfb = new QuickFixXmlFileBuilder(this.definitions)
|
|
470
469
|
qfb.write(types)
|
|
471
470
|
return qfb.elasticBuffer.toString()
|
|
@@ -524,7 +523,7 @@ export class JsfixCmd {
|
|
|
524
523
|
})
|
|
525
524
|
}
|
|
526
525
|
types.forEach((mt: any) => {
|
|
527
|
-
this.filter.
|
|
526
|
+
this.filter.set(mt, true)
|
|
528
527
|
})
|
|
529
528
|
}
|
|
530
529
|
}
|
|
@@ -555,7 +554,7 @@ export class JsfixCmd {
|
|
|
555
554
|
// the receiver is message parser which is piped from an input stream - file, socket
|
|
556
555
|
ft.receiver.on('msg', (msgType: string, m: AsciiView) => {
|
|
557
556
|
if (filter) {
|
|
558
|
-
if (filter.
|
|
557
|
+
if (filter.has(msgType)) {
|
|
559
558
|
return
|
|
560
559
|
}
|
|
561
560
|
}
|
|
@@ -2,7 +2,6 @@ import { IJsFixConfig, IJsFixLogger } from '../../../config'
|
|
|
2
2
|
import { TcpAcceptorListener } from '../../../transport/tcp'
|
|
3
3
|
import { inject, injectable } from 'tsyringe'
|
|
4
4
|
import { FixEntity, FixSession } from '../../../transport'
|
|
5
|
-
import { Dictionary } from '../../../collections'
|
|
6
5
|
import { MsgView } from '../../../buffer'
|
|
7
6
|
import { MsgTransport } from '../../../transport/factory'
|
|
8
7
|
import { ILooseObject } from '../../../collections/collection'
|
|
@@ -10,7 +9,7 @@ import { ILooseObject } from '../../../collections/collection'
|
|
|
10
9
|
@injectable()
|
|
11
10
|
export class RespawnAcceptor extends FixEntity {
|
|
12
11
|
private readonly logger: IJsFixLogger
|
|
13
|
-
private readonly sessions:
|
|
12
|
+
private readonly sessions: Map<string, FixSession> = new Map<string, FixSession>()
|
|
14
13
|
|
|
15
14
|
constructor (@inject('IJsFixConfig') public readonly config: IJsFixConfig) {
|
|
16
15
|
super(config)
|
|
@@ -28,27 +27,27 @@ export class RespawnAcceptor extends FixEntity {
|
|
|
28
27
|
this.logger.info(`rxOnMsg msgType = ${msgType}`)
|
|
29
28
|
const o: ILooseObject = view.toObject() as ILooseObject
|
|
30
29
|
const key: string = o.StandardHeader.SenderCompID
|
|
31
|
-
if (!this.sessions.
|
|
32
|
-
this.logger.info(`onSession: new session acceptor SenderCompID = ${key} created, count = ${this.sessions.
|
|
33
|
-
this.sessions.
|
|
30
|
+
if (!this.sessions.has(key)) {
|
|
31
|
+
this.logger.info(`onSession: new session acceptor SenderCompID = ${key} created, count = ${this.sessions.size}}`)
|
|
32
|
+
this.sessions.set(key, session)
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
private resetSessionSeqNo (session: FixSession): void {
|
|
38
37
|
const key = this.config.description.TargetCompID
|
|
39
|
-
if (this.sessions.
|
|
38
|
+
if (this.sessions.has(key)) {
|
|
40
39
|
const lastSession = this.sessions.get(key)
|
|
41
40
|
const lastPeerSeqNum = lastSession?.lastPeerSeqNum() ?? 0
|
|
42
41
|
this.logger.info(`resetSessionSeqNo: set lastPeerSeqNum ${lastPeerSeqNum} for key ${key}`)
|
|
43
42
|
session.reset(lastPeerSeqNum)
|
|
44
|
-
this.sessions.
|
|
43
|
+
this.sessions.delete(key)
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
private resetLastSentSeqNo (): void {
|
|
49
48
|
if (!this.resetSeqNo()) {
|
|
50
49
|
const key = this.config.description.TargetCompID
|
|
51
|
-
if (this.sessions.
|
|
50
|
+
if (this.sessions.has(key)) {
|
|
52
51
|
const lastSession = this.sessions.get(key)
|
|
53
52
|
const lastSentSeqNum = lastSession?.lastSentSeqNum() ?? 0
|
|
54
53
|
this.logger.info(`resetLastSentSeqNo: set seqNo ${lastSentSeqNum} for key ${key}`)
|
|
@@ -6,18 +6,17 @@ import {
|
|
|
6
6
|
ITradeCaptureReportRequestAck
|
|
7
7
|
} from '../../../types/FIX4.4/repo'
|
|
8
8
|
import { IJsFixLogger, IJsFixConfig } from '../../../config'
|
|
9
|
-
import { Dictionary } from '../../../collections'
|
|
10
9
|
import { TradeFactory } from './trade-factory'
|
|
11
10
|
|
|
12
11
|
export class TradeCaptureClient extends AsciiSession {
|
|
13
12
|
private readonly logger: IJsFixLogger
|
|
14
13
|
private readonly fixLog: IJsFixLogger
|
|
15
|
-
private readonly reports:
|
|
14
|
+
private readonly reports: Map<string, ITradeCaptureReport>
|
|
16
15
|
|
|
17
16
|
constructor (public readonly config: IJsFixConfig) {
|
|
18
17
|
super(config)
|
|
19
18
|
this.logReceivedMsgs = true
|
|
20
|
-
this.reports = new
|
|
19
|
+
this.reports = new Map<string, ITradeCaptureReport>()
|
|
21
20
|
this.fixLog = config.logFactory.plain(`jsfix.${config?.description?.application?.name}.txt`)
|
|
22
21
|
this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`)
|
|
23
22
|
}
|
|
@@ -28,8 +27,8 @@ export class TradeCaptureClient extends AsciiSession {
|
|
|
28
27
|
case MsgType.TradeCaptureReport: {
|
|
29
28
|
// create an object and cast to the interface
|
|
30
29
|
const tc: ITradeCaptureReport = view.toObject() as ITradeCaptureReport
|
|
31
|
-
this.reports.
|
|
32
|
-
this.logger.info(`[reports: ${this.reports.
|
|
30
|
+
this.reports.set(tc.TradeReportID, tc)
|
|
31
|
+
this.logger.info(`[reports: ${this.reports.size}] received tc ExecID = ${tc.ExecID} TradeReportID = ${tc.TradeReportID} Symbol = ${tc.Instrument.Symbol} ${tc.LastQty} @ ${tc.LastPx}`)
|
|
33
32
|
break
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -32,7 +32,7 @@ export class TradeCaptureServer extends AsciiSession {
|
|
|
32
32
|
|
|
33
33
|
default: {
|
|
34
34
|
const seqNum = view.getTyped(MsgTag.MsgSeqNum)
|
|
35
|
-
const msg = this.config.factory?.reject(msgType, seqNum, `${this.me}: unexpected msg type '${msgType}'`, SessionRejectReason.InvalidMsgType)
|
|
35
|
+
const msg = this.config.factory?.reject(msgType, seqNum as number, `${this.me}: unexpected msg type '${msgType}'`, SessionRejectReason.InvalidMsgType)
|
|
36
36
|
if (msg) {
|
|
37
37
|
this.send(msgType, msg)
|
|
38
38
|
}
|
|
@@ -28,9 +28,15 @@ export class FixMsgAsciiStoreResend {
|
|
|
28
28
|
|
|
29
29
|
private inflateRange (startSeq: number, endSeq: number, input: IFixMsgStoreRecord[]): IFixMsgStoreRecord[] {
|
|
30
30
|
const toResend: IFixMsgStoreRecord[] = []
|
|
31
|
+
// If no records for this given sequence number range, returns a single gap fill
|
|
32
|
+
if (input.length === 0) {
|
|
33
|
+
this.gap(startSeq, endSeq + 1, toResend)
|
|
34
|
+
return toResend
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
let expected = startSeq
|
|
32
38
|
for (let i = 0; i < input.length; ++i) {
|
|
33
|
-
const record = input[i]
|
|
39
|
+
const record = this.prepareRecordForRetransmission(input[i])
|
|
34
40
|
const seqNum = record.seqNum
|
|
35
41
|
const toGap = seqNum - expected
|
|
36
42
|
if (toGap > 0) {
|
|
@@ -48,16 +54,16 @@ export class FixMsgAsciiStoreResend {
|
|
|
48
54
|
return toResend
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
private gap (beginGap: number, newSeq: number, arr: IFixMsgStoreRecord[]): void {
|
|
52
58
|
if (beginGap > 0) {
|
|
53
|
-
arr.push(this.sequenceResetGap(beginGap,
|
|
59
|
+
arr.push(this.sequenceResetGap(beginGap, newSeq))
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
// if records were sent as encoded text then inflate back to object
|
|
58
64
|
// so can be resent or examined
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
private inflate (record: IFixMsgStoreRecord): void {
|
|
61
67
|
if (record.obj) return
|
|
62
68
|
if (!record.encoded) return
|
|
63
69
|
const parser = this.parser
|
|
@@ -71,17 +77,67 @@ export class FixMsgAsciiStoreResend {
|
|
|
71
77
|
parser.parseText(record.encoded)
|
|
72
78
|
}
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
/**
|
|
81
|
+
* A continuous sequence of messages not being retransmitted should be skipped over using a
|
|
82
|
+
* single SequenceReset(35=4) message with GapFillFlag(123) set to “Y” and MsgSeqNum(34) set
|
|
83
|
+
* to the sequence number of the first skipped message and NewSeqNo(36) must always be set
|
|
84
|
+
* to the value of the next sequence number to be expected by the peer immediately following
|
|
85
|
+
* the messages being skipped.
|
|
86
|
+
*/
|
|
87
|
+
private sequenceResetGap (startGap: number, newSeq: number): IFixMsgStoreRecord {
|
|
75
88
|
const factory = this.config.factory
|
|
76
89
|
const gapFill: ISequenceReset = factory?.sequenceReset(newSeq, true) as ISequenceReset
|
|
77
90
|
gapFill.StandardHeader = factory?.header(MsgType.SequenceReset, startGap) as IStandardHeader
|
|
78
91
|
gapFill.StandardHeader.PossDupFlag = true
|
|
79
|
-
|
|
92
|
+
|
|
80
93
|
return new FixMsgStoreRecord(
|
|
81
94
|
MsgType.SequenceReset,
|
|
82
95
|
new Date(),
|
|
83
|
-
|
|
96
|
+
startGap,
|
|
84
97
|
gapFill,
|
|
85
|
-
null
|
|
98
|
+
null,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Prepares the FIX message as response to ResendRequest (2).
|
|
104
|
+
*
|
|
105
|
+
* The FIX session processor retransmitting a message with the PossDupFlag(43) set to "Y" must modify the following fields:
|
|
106
|
+
*
|
|
107
|
+
* SendingTime(52) set to the current sending time
|
|
108
|
+
* OrigSendingTime(122) set to the SendingTime(52) from the original message
|
|
109
|
+
* Recalculate the BodyLength(9)
|
|
110
|
+
* Recalculate the CheckSum(10)
|
|
111
|
+
*
|
|
112
|
+
* If the message is encrypted, SecureDataLen(90) and SecureData(91) may also require re-encryption and re-encoding
|
|
113
|
+
*
|
|
114
|
+
* @see https://www.fixtrading.org/standards/fix-session-layer-online/#message-recovery
|
|
115
|
+
*
|
|
116
|
+
* @param originalRecord the FIX message to be retransmitted as possible duplicate
|
|
117
|
+
* @returns the FIX message ready to be retransmitted
|
|
118
|
+
*/
|
|
119
|
+
private prepareRecordForRetransmission (originalRecord: IFixMsgStoreRecord): IFixMsgStoreRecord {
|
|
120
|
+
const retransmitted = originalRecord.clone() // We don't want to accidently change any fields of the original record
|
|
121
|
+
|
|
122
|
+
const factory = this.config.factory
|
|
123
|
+
if (!retransmitted.obj) {
|
|
124
|
+
retransmitted.obj = {}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Rebuilds header with the updated fields
|
|
128
|
+
const header = factory?.header(
|
|
129
|
+
retransmitted.msgType,
|
|
130
|
+
retransmitted.seqNum,
|
|
131
|
+
new Date(), // SendingTime(52)
|
|
132
|
+
{
|
|
133
|
+
PossDupFlag: true,
|
|
134
|
+
OrigSendingTime: retransmitted.timestamp
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
retransmitted.obj = {
|
|
138
|
+
...retransmitted.obj,
|
|
139
|
+
StandardHeader: header
|
|
140
|
+
}
|
|
141
|
+
return retransmitted
|
|
86
142
|
}
|
|
87
143
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { IFixMsgStore } from './fix-msg-store'
|
|
2
2
|
import { IJsFixConfig, IJsFixLogger } from '../config'
|
|
3
3
|
import { IFixMsgStoreRecord } from './fix-msg-store-record'
|
|
4
|
-
import { Dictionary } from '../collections'
|
|
5
4
|
import { MsgType } from '../types'
|
|
6
5
|
import { IFixMsgStoreState } from './fix-msg-store-state'
|
|
7
6
|
|
|
@@ -9,7 +8,7 @@ export class FixMsgMemoryStore implements IFixMsgStore {
|
|
|
9
8
|
protected readonly logger: IJsFixLogger
|
|
10
9
|
public heartbeat: boolean = true
|
|
11
10
|
private sortedBySeqNum: IFixMsgStoreRecord[] = []
|
|
12
|
-
private readonly excluded:
|
|
11
|
+
private readonly excluded: Map<string, boolean> = new Map<string, boolean>()
|
|
13
12
|
public length: number = 0
|
|
14
13
|
private readonly sessionMessages: string[] = [
|
|
15
14
|
MsgType.Logon,
|
|
@@ -131,7 +130,7 @@ export class FixMsgMemoryStore implements IFixMsgStore {
|
|
|
131
130
|
|
|
132
131
|
public async put (record: IFixMsgStoreRecord): Promise<IFixMsgStoreState> {
|
|
133
132
|
return await new Promise((resolve, reject) => {
|
|
134
|
-
if (this.excluded.
|
|
133
|
+
if (this.excluded.has(record.msgType)) {
|
|
135
134
|
resolve(this.buildState())
|
|
136
135
|
} else {
|
|
137
136
|
const arr = this.sortedBySeqNum
|
|
@@ -154,7 +153,7 @@ export class FixMsgMemoryStore implements IFixMsgStore {
|
|
|
154
153
|
|
|
155
154
|
private excludeRange (exclude: string[]): void {
|
|
156
155
|
exclude.forEach(s => {
|
|
157
|
-
this.excluded.
|
|
156
|
+
this.excluded.set(s, true)
|
|
158
157
|
})
|
|
159
158
|
}
|
|
160
159
|
|
|
@@ -20,7 +20,7 @@ export class FixMsgStoreRecord implements IFixMsgStoreRecord {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
static toMsgStoreRecord (v: MsgView): IFixMsgStoreRecord {
|
|
23
|
-
return new FixMsgStoreRecord(v.getString(MsgTag.MsgType) ?? '', v.getTyped(MsgTag.SendingTime), v.getTyped(MsgTag.MsgSeqNum), v.toObject() as ILooseObject)
|
|
23
|
+
return new FixMsgStoreRecord(v.getString(MsgTag.MsgType) ?? '', v.getTyped(MsgTag.SendingTime) as Date, v.getTyped(MsgTag.MsgSeqNum) as number, v.toObject() as ILooseObject)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
clone (): IFixMsgStoreRecord {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsciiChars, AsciiEncoder, TimeFormatter } from '../../buffer/ascii'
|
|
2
2
|
import { MsgTransmitter } from '../msg-transmitter'
|
|
3
3
|
import { ILooseObject } from '../../collections/collection'
|
|
4
|
-
import {
|
|
4
|
+
import { IContainedSet } from '../../dictionary/contained'
|
|
5
5
|
import { MessageDefinition } from '../../dictionary/definition'
|
|
6
6
|
import { IJsFixConfig } from '../../config'
|
|
7
7
|
import { IStandardHeader } from '../../types/FIX4.4/repo'
|
|
@@ -14,8 +14,8 @@ export class AsciiMsgTransmitter extends MsgTransmitter {
|
|
|
14
14
|
public msgSeqNum: number
|
|
15
15
|
public time: Date
|
|
16
16
|
|
|
17
|
-
private readonly header:
|
|
18
|
-
private readonly trailer:
|
|
17
|
+
private readonly header: IContainedSet | undefined
|
|
18
|
+
private readonly trailer: IContainedSet | undefined
|
|
19
19
|
|
|
20
20
|
constructor (@inject(DITokens.IJsFixConfig) public readonly config: IJsFixConfig) {
|
|
21
21
|
super(config.sessionContainer.resolve<ElasticBuffer>(DITokens.TransmitBuffer), config.definitions, config.description)
|
|
@@ -65,13 +65,13 @@ export class AsciiMsgTransmitter extends MsgTransmitter {
|
|
|
65
65
|
|
|
66
66
|
const buffer = this.buffer
|
|
67
67
|
buffer.reset()
|
|
68
|
-
const msgDef: MessageDefinition |
|
|
68
|
+
const msgDef: MessageDefinition | undefined = this.definitions.message.get(msgType)
|
|
69
69
|
if (!msgDef) {
|
|
70
70
|
this.emit('error', new Error(`ascii transmitter cannot find definition for ${msgType}`))
|
|
71
71
|
return null
|
|
72
72
|
}
|
|
73
|
-
const headerName = this.header?.name ?? 'header'
|
|
74
|
-
const trailerName = this.trailer?.name ?? 'trailer'
|
|
73
|
+
const headerName: string = this.header?.name ?? 'header'
|
|
74
|
+
const trailerName: string = this.trailer?.name ?? 'trailer'
|
|
75
75
|
encoder.encode(hdr, headerName)
|
|
76
76
|
encoder.encode(bodyProps, msgDef.name)
|
|
77
77
|
const lenPos = encoder.bodyLengthPos
|
|
@@ -30,7 +30,7 @@ export abstract class AsciiSession extends FixSession {
|
|
|
30
30
|
default: {
|
|
31
31
|
const state = this.sessionState
|
|
32
32
|
const lastSeq: number = state.lastPeerMsgSeqNum
|
|
33
|
-
const seqNo: number = view.getTyped(MsgTag.MsgSeqNum)
|
|
33
|
+
const seqNo: number = view.getTyped(MsgTag.MsgSeqNum) as number
|
|
34
34
|
let ret: boolean = false
|
|
35
35
|
const seqDelta: number = seqNo - lastSeq
|
|
36
36
|
if (seqDelta <= 0) {
|
|
@@ -89,7 +89,7 @@ export abstract class AsciiSession extends FixSession {
|
|
|
89
89
|
|
|
90
90
|
private checkIntegrity (msgType: string, view: MsgView): boolean {
|
|
91
91
|
const state = this.sessionState
|
|
92
|
-
const seqNum = view.getTyped(MsgTag.MsgSeqNum)
|
|
92
|
+
const seqNum = view.getTyped(MsgTag.MsgSeqNum) as number
|
|
93
93
|
|
|
94
94
|
const received: number = parseInt(view.getString(MsgTag.CheckSum) ?? '', 10)
|
|
95
95
|
const computed = view.checksum()
|
|
@@ -160,7 +160,11 @@ export abstract class AsciiSession extends FixSession {
|
|
|
160
160
|
protected onResendRequest (view: MsgView): void {
|
|
161
161
|
// if no records are in store then send a gap fill for entire sequence
|
|
162
162
|
this.setState(SessionState.HandleResendRequest)
|
|
163
|
-
const [beginSeqNo,
|
|
163
|
+
const [beginSeqNo, requestedEndSeqNo] = view.getTypedTags([MsgTag.BeginSeqNo, MsgTag.EndSeqNo])
|
|
164
|
+
const endSeqNo = requestedEndSeqNo === 0
|
|
165
|
+
? this.sessionState.lastSentSeqNum()
|
|
166
|
+
: requestedEndSeqNo
|
|
167
|
+
|
|
164
168
|
this.sessionLogger.info(`onResendRequest getResendRequest beginSeqNo = ${beginSeqNo}, endSeqNo = ${endSeqNo}`)
|
|
165
169
|
this.resender.getResendRequest(beginSeqNo as number, endSeqNo as number).then((records: IFixMsgStoreRecord[]) => {
|
|
166
170
|
const validRecords = records.filter(rec => rec.obj !== null)
|
|
@@ -171,7 +175,7 @@ export abstract class AsciiSession extends FixSession {
|
|
|
171
175
|
}
|
|
172
176
|
})
|
|
173
177
|
this.setState(SessionState.ActiveNormalSession)
|
|
174
|
-
}).catch(e => {
|
|
178
|
+
}).catch((e: Error) => {
|
|
175
179
|
this.sessionLogger.error(e)
|
|
176
180
|
})
|
|
177
181
|
}
|
|
@@ -225,7 +229,7 @@ export abstract class AsciiSession extends FixSession {
|
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
case MsgType.SequenceReset: {
|
|
228
|
-
const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo)
|
|
232
|
+
const newSeqNo: number = view.getTyped(MsgTag.NewSeqNo) as number
|
|
229
233
|
logger.info(`peer sends '${msgType}' sequence reset. newSeqNo = ${newSeqNo}`)
|
|
230
234
|
// expect newSeqNo to be the next message's sequence number.
|
|
231
235
|
this.sessionState.lastPeerMsgSeqNum = newSeqNo - 1
|
|
@@ -289,8 +293,8 @@ export abstract class AsciiSession extends FixSession {
|
|
|
289
293
|
const [heartBtInt, peerCompId, userName, password] = view.getTypedTags([MsgTag.HeartBtInt, MsgTag.SenderCompID, MsgTag.Username, MsgTag.Password])
|
|
290
294
|
logger.info(`peerLogon Username = ${userName}, heartBtInt = ${heartBtInt}, peerCompId = ${peerCompId}, userName = ${userName}`)
|
|
291
295
|
const state = this.sessionState
|
|
292
|
-
state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt)
|
|
293
|
-
state.peerCompId = view.getTyped(MsgTag.SenderCompID)
|
|
296
|
+
state.peerHeartBeatSecs = view.getTyped(MsgTag.HeartBtInt) as number
|
|
297
|
+
state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string
|
|
294
298
|
const res = this.onLogon(view, userName as string, password as string)
|
|
295
299
|
// currently not using this.
|
|
296
300
|
logger.info(`peerLogon onLogon returns ${res}`)
|
|
@@ -31,7 +31,7 @@ export abstract class FixmlSession extends FixSession {
|
|
|
31
31
|
protected onSessionMsg (msgType: string, view: MsgView): void {
|
|
32
32
|
switch (msgType) {
|
|
33
33
|
case 'UserReq': {
|
|
34
|
-
const reqType: number = view.getTyped('UserReqTyp')
|
|
34
|
+
const reqType: number = view.getTyped('UserReqTyp') as number
|
|
35
35
|
switch (reqType) {
|
|
36
36
|
case UserRequestType.LogOnUser: {
|
|
37
37
|
this.peerLogon(view)
|
|
@@ -47,7 +47,7 @@ export abstract class FixmlSession extends FixSession {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
case 'UserRsp': {
|
|
50
|
-
const userStatus: number = view.getTyped('UserStatus')
|
|
50
|
+
const userStatus: number = view.getTyped('UserStatus') as number
|
|
51
51
|
switch (userStatus) {
|
|
52
52
|
case UserStatus.LoggedIn: {
|
|
53
53
|
this.peerLogon(view)
|
|
@@ -68,7 +68,7 @@ export abstract class FixmlSession extends FixSession {
|
|
|
68
68
|
const logger = this.sessionLogger
|
|
69
69
|
const state = this.sessionState
|
|
70
70
|
state.state = SessionState.InitiationLogonReceived
|
|
71
|
-
state.peerCompId = view.getTyped(MsgTag.SenderCompID)
|
|
71
|
+
state.peerCompId = view.getTyped(MsgTag.SenderCompID) as string
|
|
72
72
|
if (this.acceptor) {
|
|
73
73
|
const reqId: string = view.getString('UserReqID') ?? 'req'
|
|
74
74
|
const o = this?.config?.factory?.logon(reqId, true)
|