jspurefix 5.11.3 → 5.11.4

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 (100) hide show
  1. package/.gitattributes +4 -0
  2. package/dist/buffer/index.d.ts +6 -0
  3. package/dist/buffer/index.js +6 -0
  4. package/dist/buffer/index.js.map +1 -1
  5. package/dist/collections/index.d.ts +1 -0
  6. package/dist/collections/index.js +16 -0
  7. package/dist/collections/index.js.map +1 -1
  8. package/dist/dictionary/contained/index.d.ts +3 -0
  9. package/dist/dictionary/contained/index.js +3 -0
  10. package/dist/dictionary/contained/index.js.map +1 -1
  11. package/dist/dictionary/index.d.ts +5 -0
  12. package/dist/dictionary/index.js +5 -0
  13. package/dist/dictionary/index.js.map +1 -1
  14. package/dist/generator/applicability.d.ts +3 -0
  15. package/dist/generator/applicability.js +48 -0
  16. package/dist/generator/applicability.js.map +1 -0
  17. package/dist/generator/case-builder.d.ts +34 -0
  18. package/dist/generator/case-builder.js +111 -0
  19. package/dist/generator/case-builder.js.map +1 -0
  20. package/dist/generator/corpus-store.d.ts +43 -0
  21. package/dist/generator/corpus-store.js +115 -0
  22. package/dist/generator/corpus-store.js.map +1 -0
  23. package/dist/generator/index.d.ts +12 -0
  24. package/dist/generator/index.js +29 -0
  25. package/dist/generator/index.js.map +1 -0
  26. package/dist/generator/instrument-universe.d.ts +54 -0
  27. package/dist/generator/instrument-universe.js +286 -0
  28. package/dist/generator/instrument-universe.js.map +1 -0
  29. package/dist/generator/layout.d.ts +46 -0
  30. package/dist/generator/layout.js +208 -0
  31. package/dist/generator/layout.js.map +1 -0
  32. package/dist/generator/market-context.d.ts +64 -0
  33. package/dist/generator/market-context.js +119 -0
  34. package/dist/generator/market-context.js.map +1 -0
  35. package/dist/generator/outcome.d.ts +16 -0
  36. package/dist/generator/outcome.js +71 -0
  37. package/dist/generator/outcome.js.map +1 -0
  38. package/dist/generator/realistic-generator.d.ts +53 -0
  39. package/dist/generator/realistic-generator.js +275 -0
  40. package/dist/generator/realistic-generator.js.map +1 -0
  41. package/dist/generator/rng.d.ts +12 -0
  42. package/dist/generator/rng.js +60 -0
  43. package/dist/generator/rng.js.map +1 -0
  44. package/dist/generator/scatter.d.ts +50 -0
  45. package/dist/generator/scatter.js +285 -0
  46. package/dist/generator/scatter.js.map +1 -0
  47. package/dist/generator/scenarios.d.ts +13 -0
  48. package/dist/generator/scenarios.js +139 -0
  49. package/dist/generator/scenarios.js.map +1 -0
  50. package/dist/generator/value-conventions.d.ts +15 -0
  51. package/dist/generator/value-conventions.js +217 -0
  52. package/dist/generator/value-conventions.js.map +1 -0
  53. package/dist/index.d.ts +6 -0
  54. package/dist/index.js +4 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/jsfix-cmd.d.ts +5 -0
  57. package/dist/jsfix-cmd.js +161 -0
  58. package/dist/jsfix-cmd.js.map +1 -1
  59. package/dist/store/fix-msg-ascii-store-resend.js +2 -2
  60. package/dist/store/fix-msg-ascii-store-resend.js.map +1 -1
  61. package/dist/store/fix-msg-store-record.d.ts +1 -1
  62. package/dist/store/fix-msg-store-record.js.map +1 -1
  63. package/dist/store/index.d.ts +1 -0
  64. package/dist/store/index.js +1 -0
  65. package/dist/store/index.js.map +1 -1
  66. package/dist/transport/index.d.ts +7 -0
  67. package/dist/transport/index.js +7 -0
  68. package/dist/transport/index.js.map +1 -1
  69. package/dist/transport/session/index.d.ts +1 -0
  70. package/dist/transport/session/index.js +1 -0
  71. package/dist/transport/session/index.js.map +1 -1
  72. package/docs/generated-cases.md +237 -0
  73. package/docs/scattered-components.md +60 -5
  74. package/jsfix.test_client.txt +62 -62
  75. package/jsfix.test_server.txt +72 -72
  76. package/package.json +5 -2
  77. package/src/buffer/index.ts +6 -0
  78. package/src/collections/index.ts +1 -1
  79. package/src/dictionary/contained/index.ts +3 -0
  80. package/src/dictionary/index.ts +5 -0
  81. package/src/generator/applicability.ts +87 -0
  82. package/src/generator/case-builder.ts +167 -0
  83. package/src/generator/corpus-store.ts +166 -0
  84. package/src/generator/index.ts +12 -0
  85. package/src/generator/instrument-universe.ts +347 -0
  86. package/src/generator/layout.ts +279 -0
  87. package/src/generator/market-context.ts +207 -0
  88. package/src/generator/outcome.ts +102 -0
  89. package/src/generator/realistic-generator.ts +404 -0
  90. package/src/generator/rng.ts +92 -0
  91. package/src/generator/scatter.ts +432 -0
  92. package/src/generator/scenarios.ts +167 -0
  93. package/src/generator/value-conventions.ts +295 -0
  94. package/src/index.ts +12 -0
  95. package/src/jsfix-cmd.ts +204 -0
  96. package/src/store/fix-msg-ascii-store-resend.ts +2 -1
  97. package/src/store/fix-msg-store-record.ts +4 -1
  98. package/src/store/index.ts +1 -0
  99. package/src/transport/index.ts +10 -0
  100. package/src/transport/session/index.ts +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realistic-generator.js","sourceRoot":"","sources":["../../src/generator/realistic-generator.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILooseObject } from '../collections/collection'\nimport {\n ContainedComponentField,\n ContainedFieldType,\n ContainedGroupField,\n ContainedSimpleField,\n IContainedSet\n} from '../dictionary/contained'\nimport { FixDefinitions, MessageDefinition } from '../dictionary/definition'\nimport { TagType } from '../buffer/tag/tag-type'\nimport { Rng } from './rng'\nimport { MarketContext } from './market-context'\nimport { IFieldContext, ValueConventions } from './value-conventions'\nimport { AssetClass, IInstrumentSpec, InstrumentUniverse } from './instrument-universe'\nimport { fieldApplies, setApplies } from './applicability'\n\n/**\n * Builds an object for a message type that a counterparty might plausibly have sent.\n *\n * The difference from `MessageGenerator` is what gets left out. The old generator asked\n * \"should this tag be present\" of every tag independently at one probability, which at\n * any useful density produces every field in the dictionary and a message no human can\n * read. Here optional fields are tiered - a field the generator understands is likely,\n * an ordinary one is occasional, an exotic one is rare - so the shape of the output\n * resembles the shape of real traffic even before the values are looked at.\n *\n * Two structural guarantees the encoder depends on are maintained by construction:\n *\n * - every instance of a repeating group carries the group delimiter, propagated down\n * through whatever nested component happens to own it;\n * - a component that ends up with no fields at all is dropped rather than emitted\n * empty.\n */\n\nexport interface IGeneratorOptions {\n /** same seed, same message, byte for byte */\n readonly seed?: number\n /**\n * multiplier on the optional field probabilities. 0 gives required fields only;\n * 1 is the natural rate; above 1 fattens the message toward the old behaviour.\n */\n readonly density?: number\n readonly asOf?: Date\n readonly instrument?: string | IInstrumentSpec\n readonly assetClass?: AssetClass\n /** optional components below this depth are not populated; required ones still are */\n readonly maxDepth?: number\n /** upper bound on instances of any one group */\n readonly maxGroupInstances?: number\n /**\n * dotted paths or bare names that must appear, e.g. `Instrument` or\n * `TrdCapRptSideGrp.Parties`. Used by the scatter planner to guarantee the shape it\n * is about to take apart.\n */\n readonly include?: readonly string[]\n readonly exclude?: readonly string[]\n readonly senderCompId?: string\n readonly targetCompId?: string\n}\n\nexport interface IGeneratedMessage {\n readonly msgType: string\n readonly name: string\n readonly object: ILooseObject\n readonly market: MarketContext\n readonly definition: MessageDefinition\n}\n\ninterface IWalkState {\n readonly path: readonly string[]\n readonly depth: number\n readonly instance: number\n /** tags that must be emitted somewhere below here, whatever the dice say */\n readonly mustInclude: readonly number[]\n}\n\n/**\n * Components a message of any kind is very likely to carry. Without this the tiering\n * treats `Instrument` as no more probable than any other optional component, and a\n * market data refresh comes out describing the price of nothing at all.\n */\nconst coreSets = /^(Instrument|InstrumentLeg|UnderlyingInstrument|OrderQtyData|Parties|NestedParties[0-9]?|InstrmtLegGrp|TrdInstrmtLegGrp|InstrmtMDReqGrp|MDIncGrp|MDFullGrp)$/\n\n/** a set that names legs, as opposed to a field that merely starts with Leg */\nconst legSet = /Leg(s|Grp|$|[A-Z])|InstrmtLeg/\n/** UndInstrmtGrp and UnderlyingInstrument both, since the abbreviation is not uniform */\nconst underlyingSet = /Und(erlying|Instrmt)/\n\nexport class RealisticGenerator {\n private readonly rng: Rng\n private readonly density: number\n private readonly maxDepth: number\n private readonly maxGroupInstances: number\n private readonly forced: Set<string>\n private readonly forcedTags: number[]\n private readonly suppressed: Set<string>\n private assetClass: AssetClass = AssetClass.Equity\n\n constructor (\n public readonly definitions: FixDefinitions,\n public readonly options: IGeneratorOptions = {}) {\n this.rng = new Rng(options.seed ?? 0x5eed)\n this.density = options.density ?? 1.0\n this.maxDepth = options.maxDepth ?? 6\n this.maxGroupInstances = options.maxGroupInstances ?? 2\n // an entry that is all digits is a tag, which is the portable way to name a field:\n // repository dictionaries call a group TrdInstrmtLegGrp and QuickFIX calls it NoLegs,\n // but both agree that it is 555\n const include = options.include ?? []\n this.forcedTags = include.filter(s => /^[0-9]+$/.test(s)).map(s => parseInt(s, 10))\n this.forced = new Set<string>(include.filter(s => !/^[0-9]+$/.test(s)))\n this.suppressed = new Set<string>(options.exclude ?? [])\n }\n\n public generate (msgType: string): IGeneratedMessage {\n const definition = this.definitions.message.get(msgType)\n if (!definition) {\n throw new Error(`definitions do not contain type ${msgType}`)\n }\n const instrument = this.resolveInstrument()\n const market = new MarketContext({\n rng: this.rng,\n instrument,\n assetClass: this.options.assetClass,\n asOf: this.options.asOf,\n senderCompId: this.options.senderCompId,\n targetCompId: this.options.targetCompId\n })\n const conventions = new ValueConventions(market)\n this.assetClass = market.instrument.assetClass\n const state: IWalkState = { path: [], depth: 0, instance: 0, mustInclude: this.forcedTags }\n const object = this.build(definition, market, conventions, state) ?? {}\n return {\n msgType: definition.msgType ?? msgType,\n name: definition.name,\n object,\n market,\n definition\n }\n }\n\n private resolveInstrument (): IInstrumentSpec | undefined {\n const wanted = this.options.instrument\n if (!wanted) return undefined\n if (typeof wanted !== 'string') return wanted\n const found = InstrumentUniverse.byName(wanted)\n if (!found) {\n throw new Error(`no instrument named ${wanted} - try one of ${InstrumentUniverse.all.map(i => i.symbol).join(', ')}`)\n }\n return found\n }\n\n private build (\n set: IContainedSet,\n market: MarketContext,\n conventions: ValueConventions,\n state: IWalkState): ILooseObject | null {\n const o: ILooseObject = {}\n const fields = set.fields\n for (let i = 0; i < fields.length; ++i) {\n const field = fields[i]\n switch (field.type) {\n case ContainedFieldType.Simple:\n this.simple(o, set, field as ContainedSimpleField, i, conventions, state)\n break\n case ContainedFieldType.Component:\n this.component(o, field as ContainedComponentField, market, conventions, state)\n break\n case ContainedFieldType.Group:\n this.group(o, field as ContainedGroupField, market, conventions, state)\n break\n default:\n break\n }\n }\n return Object.keys(o).length > 0 ? o : null\n }\n\n private simple (\n o: ILooseObject,\n set: IContainedSet,\n sf: ContainedSimpleField,\n index: number,\n conventions: ValueConventions,\n state: IWalkState): void {\n const definition = sf.definition\n // the encoder writes a Length from the RawData that follows it, so supplying one\n // here would only give it the chance to disagree\n if (definition.tagType === TagType.Length && RealisticGenerator.rawFollows(set, index)) {\n return\n }\n const dotted = RealisticGenerator.dot(state.path, sf.name)\n if (this.suppressed.has(dotted) || this.suppressed.has(sf.name)) return\n const must = state.mustInclude.includes(definition.tag)\n if (!must && !sf.required && !this.isForced(dotted, sf.name)) {\n if (!fieldApplies(sf.name, this.assetClass)) return\n if (!this.rng.bool(this.probability(sf))) return\n }\n const fieldContext: IFieldContext = { path: state.path, instance: state.instance }\n const value = conventions.value(definition, fieldContext)\n if (value != null && value !== '') {\n o[sf.name] = value\n }\n }\n\n private component (\n o: ILooseObject,\n cf: ContainedComponentField,\n market: MarketContext,\n conventions: ValueConventions,\n state: IWalkState): void {\n const name = cf.name\n if (name === 'StandardHeader' || name === 'StandardTrailer') return\n const dotted = RealisticGenerator.dot(state.path, name)\n if (this.suppressed.has(dotted) || this.suppressed.has(name)) return\n\n const definition = cf.definition\n const carries = RealisticGenerator.carriesAny(definition, state.mustInclude)\n if (!cf.required && !carries && !this.isForced(dotted, name)) {\n if (state.depth >= this.maxDepth) return\n if (!setApplies(name, this.assetClass)) return\n if (!this.rng.bool(this.componentProbability(name, state.depth))) return\n }\n const restore = this.enter(name, market, state.instance)\n const child = this.build(definition, market, conventions, {\n path: [...state.path, name],\n depth: state.depth + 1,\n instance: state.instance,\n // only the tags this component can actually reach travel further down\n mustInclude: state.mustInclude.filter(t => definition.containedTag[t])\n })\n restore()\n if (child) {\n o[name] = child\n }\n }\n\n private group (\n o: ILooseObject,\n gf: ContainedGroupField,\n market: MarketContext,\n conventions: ValueConventions,\n state: IWalkState): void {\n const name = gf.name\n const dotted = RealisticGenerator.dot(state.path, name)\n if (this.suppressed.has(dotted) || this.suppressed.has(name)) return\n\n const definition = gf.definition\n const carries = RealisticGenerator.carriesAny(definition, state.mustInclude)\n if (!gf.required && !carries && !this.isForced(dotted, name)) {\n if (state.depth >= this.maxDepth) return\n if (!setApplies(name, this.assetClass)) return\n if (!this.rng.bool(this.groupProbability(name, state.depth))) return\n }\n\n const isLegs = legSet.test(name) || legSet.test(definition.name)\n const legs = market.instrument.legs\n // a strategy has exactly the legs it has, so the group size is not a dice roll\n const count = isLegs && legs && legs.length > 0\n ? legs.length\n : this.instances(state.depth)\n\n // every instance has to open with the group delimiter or the encoder rejects it,\n // and the delimiter may be owned by a component nested inside the instance body\n const delimiter = definition.firstSimple?.definition.tag\n const inherited = state.mustInclude.filter(t => definition.containedTag[t])\n const must = delimiter ? [delimiter, ...inherited] : inherited\n\n const instances: ILooseObject[] = []\n for (let i = 0; i < count; ++i) {\n const restore = this.enter(name, market, i)\n const instance = this.build(definition, market, conventions, {\n path: [...state.path, name],\n depth: state.depth + 1,\n instance: i,\n mustInclude: must\n })\n restore()\n // an instance whose only content is a nested group carries no delimiter, and the\n // encoder rejects the whole group for it. This happens where `firstSimple` cannot\n // name a delimiter to force - a group whose body opens with another group - so the\n // guarantee above is not always enough and the shape has to be checked for.\n if (instance && RealisticGenerator.hasOwnSimple(instance, definition)) {\n instances.push(instance)\n }\n }\n\n if (instances.length > 0) {\n o[name] = instances\n }\n }\n\n /**\n * Descending into a set that names legs or underlyings moves the market context onto\n * that leg or underlying, so `LegPrice` inside the second leg resolves against the\n * second contract without the value layer knowing where it is. Returns the undo, so\n * the context is restored however the walk below it turns out.\n *\n * Both a group and the component inside it are checked, because dictionaries disagree\n * about which one carries the name - `UndInstrmtGrp` wrapping `UnderlyingInstrument`\n * in the repository rendering, a bare `NoUnderlyings` in QuickFIX.\n */\n private enter (name: string, market: MarketContext, instance: number): () => void {\n const wasLeg = market.leg\n const wasUnderlying = market.underlying\n const legs = market.instrument.legs\n if (legSet.test(name) && legs && legs.length > 0) {\n market.leg = legs[instance % legs.length]\n } else if (underlyingSet.test(name)) {\n market.underlying = market.underlying ?? InstrumentUniverse.choose(\n this.rng,\n market.instrument.assetClass === AssetClass.Spread ? AssetClass.Future : AssetClass.Equity)\n } else {\n return () => {}\n }\n return () => {\n market.leg = wasLeg\n market.underlying = wasUnderlying\n }\n }\n\n /**\n * How likely an optional simple field is to appear. A field the value layer knows by\n * tag is one a real message of this type probably carries; a low numbered tag is\n * everyday FIX; everything else is somebody else's extension and should be rare.\n */\n private probability (sf: ContainedSimpleField): number {\n const tag = sf.definition.tag\n let base: number\n if (ValueConventions.knows(tag)) {\n base = 0.75\n } else if (tag < 500) {\n base = 0.3\n } else {\n base = 0.08\n }\n return Math.min(1, base * this.density)\n }\n\n private componentProbability (name: string, depth: number): number {\n if (coreSets.test(name)) return Math.min(1, 0.9 * Math.max(0.5, this.density))\n return Math.min(1, (0.45 / (depth + 1)) * this.density)\n }\n\n private groupProbability (name: string, depth: number): number {\n if (coreSets.test(name)) return Math.min(1, 0.8 * Math.max(0.5, this.density))\n return Math.min(1, (0.35 / (depth + 1)) * this.density)\n }\n\n private instances (depth: number): number {\n const cap = Math.max(1, this.maxGroupInstances - depth + 1)\n return this.rng.int(1, Math.min(this.maxGroupInstances, cap))\n }\n\n private isForced (dotted: string, name: string): boolean {\n if (this.forced.has(dotted) || this.forced.has(name)) return true\n // forcing a path forces everything above it\n for (const f of this.forced) {\n if (f.startsWith(`${dotted}.`)) return true\n }\n return false\n }\n\n /**\n * whether this object emits at least one simple field at its own level - through\n * nested components, which the encoder counts as the same level, but not through a\n * group, which is framed separately and cannot serve as a delimiter\n */\n private static hasOwnSimple (o: ILooseObject, set: IContainedSet): boolean {\n for (const field of set.fields) {\n switch (field.type) {\n case ContainedFieldType.Simple:\n if (o[field.name] != null && o[field.name] !== '') return true\n break\n case ContainedFieldType.Component: {\n const cf = field as ContainedComponentField\n const child = o[cf.name]\n if (child && RealisticGenerator.hasOwnSimple(child as ILooseObject, cf.definition)) return true\n break\n }\n default:\n break\n }\n }\n return false\n }\n\n private static carriesAny (set: IContainedSet, tags: readonly number[]): boolean {\n for (const t of tags) {\n if (set.containedTag[t]) return true\n }\n return false\n }\n\n private static rawFollows (set: IContainedSet, index: number): boolean {\n const next = set.fields[index + 1]\n if (!next || next.type !== ContainedFieldType.Simple) return false\n return (next as ContainedSimpleField).definition.tagType === TagType.RawData\n }\n\n private static dot (path: readonly string[], name: string): string {\n return path.length > 0 ? `${path.join('.')}.${name}` : name\n }\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export declare class Rng {
2
+ private state;
3
+ constructor(seed?: number);
4
+ next(): number;
5
+ int(min: number, max: number): number;
6
+ bool(probability?: number): boolean;
7
+ pick<T>(from: readonly T[]): T;
8
+ frontBiased(count: number, bias?: number): number;
9
+ around(centre: number, spreadPct: number, tick: number): number;
10
+ private static decimals;
11
+ shuffled<T>(from: readonly T[]): T[];
12
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Rng = void 0;
4
+ class Rng {
5
+ constructor(seed = 0x5eed) {
6
+ this.state = (seed >>> 0) || 0x9e3779b9;
7
+ }
8
+ next() {
9
+ this.state = (this.state + 0x6d2b79f5) >>> 0;
10
+ let t = this.state;
11
+ t = Math.imul(t ^ (t >>> 15), t | 1);
12
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
13
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
14
+ }
15
+ int(min, max) {
16
+ if (max < min)
17
+ return min;
18
+ return min + Math.floor(this.next() * (max - min + 1));
19
+ }
20
+ bool(probability = 0.5) {
21
+ return this.next() < probability;
22
+ }
23
+ pick(from) {
24
+ return from[this.int(0, from.length - 1)];
25
+ }
26
+ frontBiased(count, bias = 3) {
27
+ if (count <= 1)
28
+ return 0;
29
+ return Math.min(count - 1, Math.floor(Math.pow(this.next(), bias) * count));
30
+ }
31
+ around(centre, spreadPct, tick) {
32
+ const move = centre * spreadPct * (this.next() * 2 - 1);
33
+ const raw = centre + move;
34
+ const snapped = Math.round(raw / tick) * tick;
35
+ const dp = Rng.decimals(tick);
36
+ return Number(snapped.toFixed(dp));
37
+ }
38
+ static decimals(tick) {
39
+ const s = tick.toString();
40
+ const dot = s.indexOf('.');
41
+ if (dot < 0)
42
+ return 0;
43
+ const exp = s.indexOf('e');
44
+ if (exp > 0)
45
+ return Math.min(10, parseInt(s.substring(exp + 2), 10));
46
+ return Math.min(10, s.length - dot - 1);
47
+ }
48
+ shuffled(from) {
49
+ const a = from.slice();
50
+ for (let i = a.length - 1; i > 0; --i) {
51
+ const j = this.int(0, i);
52
+ const t = a[i];
53
+ a[i] = a[j];
54
+ a[j] = t;
55
+ }
56
+ return a;
57
+ }
58
+ }
59
+ exports.Rng = Rng;
60
+ //# sourceMappingURL=rng.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/generator/rng.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A small deterministic generator, so a corpus written today reproduces byte for byte\n * tomorrow. `Math.random` is fine for a benchmark that only wants volume; it is no use\n * at all for a fixture someone has to debug, where \"run it again and get the same\n * message\" is the whole point.\n *\n * mulberry32 - 32 bits of state, uniform enough for choosing fields and prices, and\n * short enough to port to cspurefix unchanged.\n */\nexport class Rng {\n private state: number\n\n constructor (seed: number = 0x5eed) {\n // 0 is a fixed point of the mixer, so fold it away rather than silently degenerate\n this.state = (seed >>> 0) || 0x9e3779b9\n }\n\n /**\n * uniform in [0, 1)\n */\n public next (): number {\n this.state = (this.state + 0x6d2b79f5) >>> 0\n let t = this.state\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n /**\n * uniform integer in [min, max] inclusive\n */\n public int (min: number, max: number): number {\n if (max < min) return min\n return min + Math.floor(this.next() * (max - min + 1))\n }\n\n public bool (probability: number = 0.5): boolean {\n return this.next() < probability\n }\n\n public pick<T> (from: readonly T[]): T {\n return from[this.int(0, from.length - 1)]\n }\n\n /**\n * an index into `count` items, biased toward the front. `bias` of 1 is uniform;\n * higher values pull harder toward 0.\n *\n * used for enumerated fields, where the dictionary lists values roughly in order of\n * how ordinary they are - Side 1 and 2 before the twenty exotic ones - so a uniform\n * pick produces a message no counterparty would ever send.\n */\n public frontBiased (count: number, bias: number = 3): number {\n if (count <= 1) return 0\n return Math.min(count - 1, Math.floor(Math.pow(this.next(), bias) * count))\n }\n\n /**\n * a value near `centre`, within +/- `spreadPct`, snapped to `tick`\n */\n public around (centre: number, spreadPct: number, tick: number): number {\n const move = centre * spreadPct * (this.next() * 2 - 1)\n const raw = centre + move\n const snapped = Math.round(raw / tick) * tick\n // ticks are decimal fractions, so re-round to kill the binary residue\n const dp = Rng.decimals(tick)\n return Number(snapped.toFixed(dp))\n }\n\n private static decimals (tick: number): number {\n const s = tick.toString()\n const dot = s.indexOf('.')\n if (dot < 0) return 0\n const exp = s.indexOf('e')\n if (exp > 0) return Math.min(10, parseInt(s.substring(exp + 2), 10))\n return Math.min(10, s.length - dot - 1)\n }\n\n /**\n * shuffle a copy, Fisher-Yates from the seeded stream\n */\n public shuffled<T> (from: readonly T[]): T[] {\n const a = from.slice()\n for (let i = a.length - 1; i > 0; --i) {\n const j = this.int(0, i)\n const t = a[i]\n a[i] = a[j]\n a[j] = t\n }\n return a\n }\n}\n"]}
@@ -0,0 +1,50 @@
1
+ import { ILayout, LayoutNode } from './layout';
2
+ import { Rng } from './rng';
3
+ export declare enum Containment {
4
+ Root = "root",
5
+ Within = "within",
6
+ Deeper = "deeper"
7
+ }
8
+ export interface IScatterSite {
9
+ readonly level: string;
10
+ readonly component: string;
11
+ readonly containment: Containment;
12
+ readonly structureDepth: number;
13
+ readonly fragments: number;
14
+ readonly tags: number[];
15
+ readonly contendedTags: number[];
16
+ }
17
+ interface ISiteRef {
18
+ readonly level: LayoutNode;
19
+ readonly component: LayoutNode;
20
+ readonly containment: Containment;
21
+ readonly structureDepth: number;
22
+ }
23
+ export interface IScatterPlan {
24
+ readonly depth: number;
25
+ readonly sites: readonly IScatterSite[];
26
+ }
27
+ export interface IScatterResult {
28
+ readonly wire: string;
29
+ readonly plan: IScatterPlan;
30
+ readonly order: readonly number[];
31
+ }
32
+ export declare class Scatterer {
33
+ private readonly layout;
34
+ private readonly rng;
35
+ private readonly fragments;
36
+ constructor(layout: ILayout, rng: Rng, fragments?: number);
37
+ plan(depth: number): ISiteRef[];
38
+ scatter(depth: number, delimiter: string): IScatterResult;
39
+ private static contended;
40
+ private static runs;
41
+ private findChain;
42
+ private static candidates;
43
+ private findInside;
44
+ private units;
45
+ private orderLevel;
46
+ private arrange;
47
+ private static weave;
48
+ private static split;
49
+ }
50
+ export {};
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Scatterer = exports.Containment = void 0;
4
+ const layout_1 = require("./layout");
5
+ const fragment_safety_1 = require("../dictionary/fragment-safety");
6
+ var Containment;
7
+ (function (Containment) {
8
+ Containment["Root"] = "root";
9
+ Containment["Within"] = "within";
10
+ Containment["Deeper"] = "deeper";
11
+ })(Containment || (exports.Containment = Containment = {}));
12
+ class Scatterer {
13
+ constructor(layout, rng, fragments = 2) {
14
+ this.layout = layout;
15
+ this.rng = rng;
16
+ this.fragments = fragments;
17
+ }
18
+ plan(depth) {
19
+ for (let want = depth; want >= 1; --want) {
20
+ const chain = this.findChain(this.layout.root, want, Containment.Root);
21
+ if (chain)
22
+ return chain;
23
+ }
24
+ return [];
25
+ }
26
+ scatter(depth, delimiter) {
27
+ const sites = this.plan(depth);
28
+ const chains = new Map();
29
+ for (const site of sites) {
30
+ const existing = chains.get(site.level);
31
+ if (existing) {
32
+ existing.push(site.component);
33
+ }
34
+ else {
35
+ chains.set(site.level, [site.component]);
36
+ }
37
+ }
38
+ const order = this.orderLevel(this.layout.root, chains);
39
+ const { tokens, bodyStart, bodyEnd } = this.layout;
40
+ const head = [];
41
+ for (let i = 0; i < bodyStart; ++i)
42
+ head.push(i);
43
+ const tail = [];
44
+ for (let i = bodyEnd; i < tokens.length; ++i)
45
+ tail.push(i);
46
+ const full = [...head, ...order, ...tail];
47
+ const position = new Map();
48
+ full.forEach((tokenIndex, at) => position.set(tokenIndex, at));
49
+ return {
50
+ wire: (0, layout_1.assemble)(tokens, full, delimiter),
51
+ order,
52
+ plan: {
53
+ depth: sites.length,
54
+ sites: sites.map(site => ({
55
+ level: site.level.path,
56
+ component: site.component.path,
57
+ containment: site.containment,
58
+ structureDepth: site.structureDepth,
59
+ contendedTags: Scatterer.contended(site),
60
+ fragments: Scatterer.runs(site.component.canonical().map(t => { var _a; return (_a = position.get(t)) !== null && _a !== void 0 ? _a : -1; })),
61
+ tags: site.component.canonical()
62
+ .map(t => { var _a; return ({ t, at: (_a = position.get(t)) !== null && _a !== void 0 ? _a : -1 }); })
63
+ .sort((a, b) => a.at - b.at)
64
+ .map(x => tokens[x.t].tag)
65
+ }))
66
+ }
67
+ };
68
+ }
69
+ static contended(site) {
70
+ const set = site.level.set;
71
+ if (!set)
72
+ return [];
73
+ const name = site.component.name;
74
+ const path = site.level.path;
75
+ const out = [];
76
+ for (const f of fragment_safety_1.FragmentSafety.analyseSet(set, path)) {
77
+ if (f.code !== fragment_safety_1.FragmentSafetyCode.SiblingTagCollision)
78
+ continue;
79
+ if (f.path !== path)
80
+ continue;
81
+ if (!f.owners.includes(name))
82
+ continue;
83
+ out.push(f.tag);
84
+ }
85
+ return out;
86
+ }
87
+ static runs(positions) {
88
+ const sorted = positions.slice().sort((a, b) => a - b);
89
+ let count = sorted.length > 0 ? 1 : 0;
90
+ for (let i = 1; i < sorted.length; ++i) {
91
+ if (sorted[i] !== sorted[i - 1] + 1)
92
+ count++;
93
+ }
94
+ return count;
95
+ }
96
+ findChain(level, depth, containment, structureDepth = 0) {
97
+ if (depth <= 0)
98
+ return [];
99
+ const units = this.units(level);
100
+ for (const candidate of Scatterer.candidates(level, units)) {
101
+ const site = { level, component: candidate, containment, structureDepth };
102
+ if (depth === 1)
103
+ return [site];
104
+ const inner = this.findInside(level, candidate, units, depth - 1, structureDepth);
105
+ if (inner)
106
+ return [site, ...inner];
107
+ }
108
+ for (const u of units) {
109
+ if (u.node.kind !== layout_1.LayoutKind.Group)
110
+ continue;
111
+ for (const instance of u.node.children) {
112
+ const chain = this.findChain(instance, depth, Containment.Deeper, structureDepth + 1);
113
+ if (chain)
114
+ return chain;
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ static candidates(level, units) {
120
+ var _a;
121
+ const owned = new Map();
122
+ for (const u of units) {
123
+ for (const owner of u.owners) {
124
+ owned.set(owner, ((_a = owned.get(owner)) !== null && _a !== void 0 ? _a : 0) + 1);
125
+ }
126
+ }
127
+ const out = [];
128
+ for (const [node, count] of owned) {
129
+ if (count < 2)
130
+ continue;
131
+ if (count >= units.length)
132
+ continue;
133
+ out.push(node);
134
+ }
135
+ out.sort((a, b) => { var _a, _b; return ((_a = owned.get(b)) !== null && _a !== void 0 ? _a : 0) - ((_b = owned.get(a)) !== null && _b !== void 0 ? _b : 0); });
136
+ if (level.kind === layout_1.LayoutKind.Instance && units.length <= 2) {
137
+ return [];
138
+ }
139
+ return out;
140
+ }
141
+ findInside(level, outer, units, depth, structureDepth) {
142
+ var _a;
143
+ const inside = units.filter(u => u.owners.includes(outer));
144
+ const nested = new Map();
145
+ for (const u of inside) {
146
+ const at = u.owners.indexOf(outer);
147
+ for (let i = at + 1; i < u.owners.length; ++i) {
148
+ const n = u.owners[i];
149
+ nested.set(n, ((_a = nested.get(n)) !== null && _a !== void 0 ? _a : 0) + 1);
150
+ }
151
+ }
152
+ const ordered = Array.from(nested.entries())
153
+ .filter(([, count]) => count >= 2 && count < inside.length)
154
+ .sort((a, b) => b[1] - a[1]);
155
+ for (const [node] of ordered) {
156
+ const site = { level, component: node, containment: Containment.Within, structureDepth };
157
+ if (depth === 1)
158
+ return [site];
159
+ const deeper = this.findInside(level, node, units, depth - 1, structureDepth);
160
+ if (deeper)
161
+ return [site, ...deeper];
162
+ }
163
+ const carried = units.filter(u => u.node.kind === layout_1.LayoutKind.Group && u.owners.includes(outer));
164
+ const siblings = units.filter(u => u.node.kind === layout_1.LayoutKind.Group && !u.owners.includes(outer));
165
+ for (const [group, containment] of [
166
+ ...carried.map(u => [u.node, Containment.Within]),
167
+ ...siblings.map(u => [u.node, Containment.Deeper])
168
+ ]) {
169
+ for (const instance of group.children) {
170
+ const chain = this.findChain(instance, depth, containment, structureDepth + 1);
171
+ if (chain && chain.length === depth)
172
+ return chain;
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ units(level, chains) {
178
+ const out = [];
179
+ const visit = (node, owners) => {
180
+ for (const child of node.children) {
181
+ switch (child.kind) {
182
+ case layout_1.LayoutKind.Field: {
183
+ const tokens = [child.tokenIndex];
184
+ if (child.extraTokenIndex >= 0)
185
+ tokens.push(child.extraTokenIndex);
186
+ out.push({ tokens, owners: owners.slice(), node: child });
187
+ break;
188
+ }
189
+ case layout_1.LayoutKind.Component:
190
+ visit(child, [...owners, child]);
191
+ break;
192
+ case layout_1.LayoutKind.Group: {
193
+ const tokens = [child.tokenIndex];
194
+ for (const instance of child.children) {
195
+ for (const t of chains ? this.orderLevel(instance, chains) : instance.canonical()) {
196
+ tokens.push(t);
197
+ }
198
+ }
199
+ out.push({ tokens, owners: owners.slice(), node: child });
200
+ break;
201
+ }
202
+ default:
203
+ break;
204
+ }
205
+ }
206
+ };
207
+ visit(level, []);
208
+ return out;
209
+ }
210
+ orderLevel(level, chains) {
211
+ var _a;
212
+ const units = this.units(level, chains);
213
+ const chain = (_a = chains.get(level)) !== null && _a !== void 0 ? _a : [];
214
+ let arranged;
215
+ if (level.kind === layout_1.LayoutKind.Instance && units.length > 0) {
216
+ const pinned = units[0];
217
+ const rest = units.slice(1);
218
+ const target = chain.length > 0 ? chain[0] : null;
219
+ if (target && pinned.owners.includes(target)) {
220
+ arranged = [pinned, ...this.arrange(rest, chain, true)];
221
+ }
222
+ else {
223
+ arranged = [pinned, ...this.arrange(rest, chain, false)];
224
+ }
225
+ }
226
+ else {
227
+ arranged = this.arrange(units, chain, false);
228
+ }
229
+ const out = [];
230
+ for (const u of arranged) {
231
+ for (const t of u.tokens)
232
+ out.push(t);
233
+ }
234
+ return out;
235
+ }
236
+ arrange(units, chain, restFirst) {
237
+ if (chain.length === 0 || units.length === 0)
238
+ return units;
239
+ const target = chain[0];
240
+ const inTarget = units.filter(u => u.owners.includes(target));
241
+ const rest = units.filter(u => !u.owners.includes(target));
242
+ if (inTarget.length === 0 || rest.length === 0)
243
+ return units;
244
+ const ordered = chain.length > 1 ? this.arrange(inTarget, chain.slice(1), false) : inTarget;
245
+ return restFirst
246
+ ? Scatterer.weave(rest, ordered, this.fragments, this.rng)
247
+ : Scatterer.weave(ordered, rest, this.fragments, this.rng);
248
+ }
249
+ static weave(target, filler, fragments, rng) {
250
+ const f = Math.min(fragments, target.length, filler.length + 1);
251
+ if (f < 2)
252
+ return [...target, ...filler];
253
+ const targetRuns = Scatterer.split(target, f, rng);
254
+ const fillerRuns = Scatterer.split(filler, f - 1, rng);
255
+ const out = [];
256
+ for (let i = 0; i < f; ++i) {
257
+ out.push(...targetRuns[i]);
258
+ if (i < f - 1)
259
+ out.push(...fillerRuns[i]);
260
+ }
261
+ return out;
262
+ }
263
+ static split(units, parts, rng) {
264
+ if (parts <= 1)
265
+ return [units];
266
+ const cuts = new Set();
267
+ let guard = 0;
268
+ while (cuts.size < parts - 1 && guard++ < 100) {
269
+ cuts.add(rng.int(1, units.length - 1));
270
+ }
271
+ const sorted = Array.from(cuts).sort((a, b) => a - b);
272
+ const out = [];
273
+ let from = 0;
274
+ for (const cut of sorted) {
275
+ out.push(units.slice(from, cut));
276
+ from = cut;
277
+ }
278
+ out.push(units.slice(from));
279
+ while (out.length < parts)
280
+ out.push([]);
281
+ return out;
282
+ }
283
+ }
284
+ exports.Scatterer = Scatterer;
285
+ //# sourceMappingURL=scatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter.js","sourceRoot":"","sources":["../../src/generator/scatter.ts"],"names":[],"mappings":"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","sourcesContent":["import { ILayout, LayoutKind, LayoutNode, assemble } from './layout'\nimport { FragmentSafety, FragmentSafetyCode } from '../dictionary/fragment-safety'\nimport { Rng } from './rng'\n\n/**\n * Taking a well formed message apart in a way the specification still permits.\n *\n * Two facts from `docs/scattered-components.md` are the whole basis of this:\n *\n * Contiguity is only forced where framing exists, and framing only exists where it is\n * needed.\n *\n * A repeating group is the sole self describing construct in tag value FIX, so a group\n * run - its `NoXXX` and every instance - is atomic and moves as one block. Everywhere\n * else a component's extent is a convention of the dictionary with no wire\n * representation, so its tags may legally be interleaved with its siblings.\n *\n * And, within one group instance, the delimiter must come first. That is the only other\n * ordering the wire actually constrains, and it is honoured by pinning.\n *\n * Because the result is a permutation of the body's tokens, the encoded length and the\n * sum of the bytes are both unchanged - so `BodyLength` and `CheckSum` stay correct\n * without being recomputed. A scattered message differs from its canonical twin only in\n * the order of the fields, which is precisely the claim under test.\n *\n * ## Depth\n *\n * A *site* is one component made non-adjacent within its level. `--russian-doll n` asks\n * for n sites, each one level further into the message than the last:\n *\n * 1 Instrument scattered in the message body - the shape the shipped repair handles\n * 2 and again inside a group instance, one level down the structure stack\n * 3 and again inside a group instance of that instance\n *\n * A site one level down is preferred where it genuinely sits *within* the site above -\n * a component of the scattered component, or a group carried by it - because that is the\n * russian doll the design note describes. Where the dictionary offers no such shape, and\n * standard FIX 4.4 very often does not, the planner settles for a site at the same\n * structure depth reached through a sibling group instead, and says which it found. Both\n * are past what the engine handles: detection is populated only at structure depth 1, so\n * a component scattered inside any group instance goes unnoticed however it was reached.\n *\n * The planner degrades rather than failing. A message that cannot express three levels\n * yields two and a note, because which shapes a dictionary can express is a finding in\n * itself.\n */\n\nexport enum Containment {\n /** the message body */\n Root = 'root',\n /** genuinely inside the site above it - a nested component, or a group it carries */\n Within = 'within',\n /** the same structure depth, but reached through a sibling group */\n Deeper = 'deeper'\n}\n\nexport interface IScatterSite {\n /** dotted path of the level the site sits in - the message body or a group instance */\n readonly level: string\n /** dotted path of the component made non-adjacent */\n readonly component: string\n /** how this site relates to the one above it */\n readonly containment: Containment\n /**\n * how many group instance bodies enclose the site. 0 is the message body, which is\n * the only depth today's detection is populated at, so anything above 0 is past what\n * the engine notices.\n */\n readonly structureDepth: number\n /** how many runs the component was broken into */\n readonly fragments: number\n /** tags belonging to the component, in the order they now appear */\n readonly tags: number[]\n /**\n * tags of this component that a *sibling* at the same level also claims. Phase 0 of\n * the design note found 57 of these in the QuickFIX FIX50SP2 dictionary, all of them\n * `Currency(15)` declared both inside `Instrument` and beside it. No repair\n * attributing by tag identity can tell which one a scattered tag belonged to, so a\n * case with a non-empty list here is testing something unanswerable rather than\n * something broken.\n */\n readonly contendedTags: number[]\n}\n\ninterface ISiteRef {\n readonly level: LayoutNode\n readonly component: LayoutNode\n readonly containment: Containment\n readonly structureDepth: number\n}\n\nexport interface IScatterPlan {\n readonly depth: number\n readonly sites: readonly IScatterSite[]\n}\n\nexport interface IScatterResult {\n readonly wire: string\n readonly plan: IScatterPlan\n /** body token order, for a caller that wants to show the move */\n readonly order: readonly number[]\n}\n\ninterface IUnit {\n /** tokens in the order they should now appear; a group run carries its whole subtree */\n readonly tokens: number[]\n /** component nodes of this level enclosing the unit, outermost first */\n readonly owners: readonly LayoutNode[]\n readonly node: LayoutNode\n}\n\n/** a level, and the chain of components to scatter within it, outermost first */\ntype LevelChains = Map<LayoutNode, LayoutNode[]>\n\nexport class Scatterer {\n constructor (\n private readonly layout: ILayout,\n private readonly rng: Rng,\n private readonly fragments: number = 2) {\n }\n\n /**\n * the deepest chain of scatter sites this message can support, up to `depth`.\n *\n * Returns fewer sites than asked for rather than failing: which shapes a dictionary\n * can actually express is a finding in its own right, and a caller that wanted three\n * levels is better served by two and a note than by an exception.\n */\n public plan (depth: number): ISiteRef[] {\n for (let want = depth; want >= 1; --want) {\n const chain = this.findChain(this.layout.root, want, Containment.Root)\n if (chain) return chain\n }\n return []\n }\n\n public scatter (depth: number, delimiter: string): IScatterResult {\n const sites = this.plan(depth)\n const chains: LevelChains = new Map<LayoutNode, LayoutNode[]>()\n for (const site of sites) {\n const existing = chains.get(site.level)\n if (existing) {\n existing.push(site.component)\n } else {\n chains.set(site.level, [site.component])\n }\n }\n const order = this.orderLevel(this.layout.root, chains)\n const { tokens, bodyStart, bodyEnd } = this.layout\n const head: number[] = []\n for (let i = 0; i < bodyStart; ++i) head.push(i)\n const tail: number[] = []\n for (let i = bodyEnd; i < tokens.length; ++i) tail.push(i)\n const full = [...head, ...order, ...tail]\n const position = new Map<number, number>()\n full.forEach((tokenIndex, at) => position.set(tokenIndex, at))\n return {\n wire: assemble(tokens, full, delimiter),\n order,\n plan: {\n depth: sites.length,\n sites: sites.map(site => ({\n level: site.level.path,\n component: site.component.path,\n containment: site.containment,\n structureDepth: site.structureDepth,\n contendedTags: Scatterer.contended(site),\n fragments: Scatterer.runs(site.component.canonical().map(t => position.get(t) ?? -1)),\n tags: site.component.canonical()\n .map(t => ({ t, at: position.get(t) ?? -1 }))\n .sort((a, b) => a.at - b.at)\n .map(x => tokens[x.t].tag)\n }))\n }\n }\n }\n\n /**\n * tags of the scattered component that a sibling of it, at the same level, also claims\n */\n private static contended (site: ISiteRef): number[] {\n const set = site.level.set\n if (!set) return []\n const name = site.component.name\n const path = site.level.path\n const out: number[] = []\n for (const f of FragmentSafety.analyseSet(set, path)) {\n if (f.code !== FragmentSafetyCode.SiblingTagCollision) continue\n if (f.path !== path) continue\n if (!f.owners.includes(name)) continue\n out.push(f.tag)\n }\n return out\n }\n\n /**\n * how many separate runs these positions form once sorted - one if the component is\n * still contiguous, which is how a plan reports that it failed to achieve anything\n */\n private static runs (positions: number[]): number {\n const sorted = positions.slice().sort((a, b) => a - b)\n let count = sorted.length > 0 ? 1 : 0\n for (let i = 1; i < sorted.length; ++i) {\n if (sorted[i] !== sorted[i - 1] + 1) count++\n }\n return count\n }\n\n // ---------------------------------------------------------------- planning\n\n /**\n * a chain of sites, each one level further into the message than the last\n */\n private findChain (\n level: LayoutNode,\n depth: number,\n containment: Containment,\n structureDepth: number = 0): ISiteRef[] | null {\n if (depth <= 0) return []\n const units = this.units(level)\n for (const candidate of Scatterer.candidates(level, units)) {\n const site: ISiteRef = { level, component: candidate, containment, structureDepth }\n if (depth === 1) return [site]\n const inner = this.findInside(level, candidate, units, depth - 1, structureDepth)\n if (inner) return [site, ...inner]\n }\n // Nothing scatterable at this level. A market data refresh is the ordinary case:\n // its body is a handful of loose fields and one group, so every component it has\n // lives inside an entry. Descend rather than report the message unscatterable.\n for (const u of units) {\n if (u.node.kind !== LayoutKind.Group) continue\n for (const instance of u.node.children) {\n const chain = this.findChain(instance, depth, Containment.Deeper, structureDepth + 1)\n if (chain) return chain\n }\n }\n return null\n }\n\n /**\n * components of this level worth scattering: at least two units of their own, and at\n * least one unit of the level left over to put between them\n */\n private static candidates (level: LayoutNode, units: readonly IUnit[]): LayoutNode[] {\n const owned = new Map<LayoutNode, number>()\n for (const u of units) {\n for (const owner of u.owners) {\n owned.set(owner, (owned.get(owner) ?? 0) + 1)\n }\n }\n const out: LayoutNode[] = []\n for (const [node, count] of owned) {\n if (count < 2) continue\n if (count >= units.length) continue\n out.push(node)\n }\n // widest first, so the plan uses the component with the most room to be broken up\n out.sort((a, b) => (owned.get(b) ?? 0) - (owned.get(a) ?? 0))\n if (level.kind === LayoutKind.Instance && units.length <= 2) {\n // the delimiter is pinned, so a level of two units has nothing spare to interleave\n return []\n }\n return out\n }\n\n /**\n * the next site down. Preference order is the containment order of the design note:\n * a component nested inside this one, then a group this component carries, then - only\n * because standard FIX rarely offers either - any group at this level.\n */\n private findInside (\n level: LayoutNode,\n outer: LayoutNode,\n units: readonly IUnit[],\n depth: number,\n structureDepth: number): ISiteRef[] | null {\n const inside = units.filter(u => u.owners.includes(outer))\n\n // a component of the scattered component, scattered among its parent's own tags\n const nested = new Map<LayoutNode, number>()\n for (const u of inside) {\n const at = u.owners.indexOf(outer)\n for (let i = at + 1; i < u.owners.length; ++i) {\n const n = u.owners[i]\n nested.set(n, (nested.get(n) ?? 0) + 1)\n }\n }\n const ordered = Array.from(nested.entries())\n .filter(([, count]) => count >= 2 && count < inside.length)\n .sort((a, b) => b[1] - a[1])\n for (const [node] of ordered) {\n const site: ISiteRef = { level, component: node, containment: Containment.Within, structureDepth }\n if (depth === 1) return [site]\n const deeper = this.findInside(level, node, units, depth - 1, structureDepth)\n if (deeper) return [site, ...deeper]\n }\n\n // a group instance is a level of its own; one carried by the scattered component is\n // genuinely within it, one carried by a sibling only reaches the same structure depth\n const carried = units.filter(u => u.node.kind === LayoutKind.Group && u.owners.includes(outer))\n const siblings = units.filter(u => u.node.kind === LayoutKind.Group && !u.owners.includes(outer))\n for (const [group, containment] of [\n ...carried.map(u => [u.node, Containment.Within] as [LayoutNode, Containment]),\n ...siblings.map(u => [u.node, Containment.Deeper] as [LayoutNode, Containment])\n ]) {\n for (const instance of group.children) {\n const chain = this.findChain(instance, depth, containment, structureDepth + 1)\n if (chain && chain.length === depth) return chain\n }\n }\n return null\n }\n\n // ---------------------------------------------------------------- ordering\n\n /**\n * the units of one level: every field is a unit, a component contributes its fields to\n * the enclosing level rather than a unit of its own, and a whole group run is a single\n * atomic unit because the wire frames it\n */\n private units (level: LayoutNode, chains?: LevelChains): IUnit[] {\n const out: IUnit[] = []\n const visit = (node: LayoutNode, owners: LayoutNode[]): void => {\n for (const child of node.children) {\n switch (child.kind) {\n case LayoutKind.Field: {\n const tokens = [child.tokenIndex]\n if (child.extraTokenIndex >= 0) tokens.push(child.extraTokenIndex)\n out.push({ tokens, owners: owners.slice(), node: child })\n break\n }\n case LayoutKind.Component:\n visit(child, [...owners, child])\n break\n case LayoutKind.Group: {\n const tokens = [child.tokenIndex]\n for (const instance of child.children) {\n // an instance is a level, so it may carry a scatter site of its own\n for (const t of chains ? this.orderLevel(instance, chains) : instance.canonical()) {\n tokens.push(t)\n }\n }\n out.push({ tokens, owners: owners.slice(), node: child })\n break\n }\n default:\n break\n }\n }\n }\n visit(level, [])\n return out\n }\n\n private orderLevel (level: LayoutNode, chains: LevelChains): number[] {\n const units = this.units(level, chains)\n const chain = chains.get(level) ?? []\n let arranged: IUnit[]\n if (level.kind === LayoutKind.Instance && units.length > 0) {\n // the group delimiter has to stay at the front of the instance\n const pinned = units[0]\n const rest = units.slice(1)\n const target = chain.length > 0 ? chain[0] : null\n if (target && pinned.owners.includes(target)) {\n // the pinned unit already belongs to the component being scattered, so putting\n // the other units of the level next is enough to break its run\n arranged = [pinned, ...this.arrange(rest, chain, true)]\n } else {\n arranged = [pinned, ...this.arrange(rest, chain, false)]\n }\n } else {\n arranged = this.arrange(units, chain, false)\n }\n const out: number[] = []\n for (const u of arranged) {\n for (const t of u.tokens) out.push(t)\n }\n return out\n }\n\n /**\n * @param restFirst put the untargeted units before the targeted ones, used when the\n * pinned delimiter already belongs to the target\n */\n private arrange (units: IUnit[], chain: readonly LayoutNode[], restFirst: boolean): IUnit[] {\n if (chain.length === 0 || units.length === 0) return units\n const target = chain[0]\n const inTarget = units.filter(u => u.owners.includes(target))\n const rest = units.filter(u => !u.owners.includes(target))\n if (inTarget.length === 0 || rest.length === 0) return units\n // deeper sites in the same level are scattered within the target's own units first\n const ordered = chain.length > 1 ? this.arrange(inTarget, chain.slice(1), false) : inTarget\n return restFirst\n ? Scatterer.weave(rest, ordered, this.fragments, this.rng)\n : Scatterer.weave(ordered, rest, this.fragments, this.rng)\n }\n\n /**\n * break `target` into runs and put pieces of `filler` between them\n */\n private static weave (target: IUnit[], filler: IUnit[], fragments: number, rng: Rng): IUnit[] {\n const f = Math.min(fragments, target.length, filler.length + 1)\n if (f < 2) return [...target, ...filler]\n const targetRuns = Scatterer.split(target, f, rng)\n const fillerRuns = Scatterer.split(filler, f - 1, rng)\n const out: IUnit[] = []\n for (let i = 0; i < f; ++i) {\n out.push(...targetRuns[i])\n if (i < f - 1) out.push(...fillerRuns[i])\n }\n return out\n }\n\n private static split (units: IUnit[], parts: number, rng: Rng): IUnit[][] {\n if (parts <= 1) return [units]\n const cuts = new Set<number>()\n let guard = 0\n while (cuts.size < parts - 1 && guard++ < 100) {\n cuts.add(rng.int(1, units.length - 1))\n }\n const sorted = Array.from(cuts).sort((a, b) => a - b)\n const out: IUnit[][] = []\n let from = 0\n for (const cut of sorted) {\n out.push(units.slice(from, cut))\n from = cut\n }\n out.push(units.slice(from))\n while (out.length < parts) out.push([])\n return out\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { IGeneratorOptions } from './realistic-generator';
2
+ export interface IScenario {
3
+ readonly name: string;
4
+ readonly description: string;
5
+ readonly msgType: string;
6
+ readonly options: IGeneratorOptions;
7
+ }
8
+ export declare const Scenarios: {
9
+ all: readonly IScenario[];
10
+ get(name: string): IScenario | undefined;
11
+ names(): string[];
12
+ describe(): string;
13
+ };