@hpcc-js/comms 2.86.1 → 2.87.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.
@@ -22,6 +22,118 @@ function formatNum(num: number | string): string {
22
22
  }
23
23
  return num as string;
24
24
  }
25
+ const DEFINITION_LIST = "DefinitionList";
26
+ const definitionRegex = /([a-zA-Z]:)?(.*[\\\/])(.*)(\((\d+),(\d+)\))/;
27
+
28
+ const extendedProps = ["Avg", "Min", "Max", "Delta", "StdDev"];
29
+ const relatedProps = ["SkewMin", "SkewMax", "NodeMin", "NodeMax"];
30
+ interface PropertyValue {
31
+ Key: string;
32
+ Value: string;
33
+ // Extended properties ---
34
+ Avg: string;
35
+ Min: string;
36
+ Max: string;
37
+ Delta: string;
38
+ StdDev: string;
39
+ // Related properties ---
40
+ SkewMin: string;
41
+ SkewMax: string;
42
+ NodeMin: string;
43
+ NodeMax: string;
44
+ }
45
+
46
+ export interface IScope {
47
+ __parentName?: string;
48
+ __children?: IScope[];
49
+ __formattedProps: { [key: string]: any };
50
+ __groupedProps: { [key: string]: any };
51
+ id: string;
52
+ name: string;
53
+ type: string;
54
+ Kind: string;
55
+ Label: string;
56
+ [key: string]: any;
57
+ }
58
+
59
+ interface SplitKey {
60
+ measure: string;
61
+ ext: string;
62
+ label: string;
63
+ }
64
+
65
+ const metricKeyRegex = /[A-Z][a-z]*/g;
66
+ function _splitLabel(fullLabel: string): SplitKey {
67
+
68
+ // Related properties ---
69
+ for (const relProp of relatedProps) {
70
+ const index = fullLabel.indexOf(relProp);
71
+ if (index === 0) {
72
+ const measure = "";
73
+ const label = fullLabel.slice(index + relProp.length);
74
+ return { measure, ext: relProp, label };
75
+ }
76
+ }
77
+
78
+ // Primary properties ---
79
+ const labelParts = fullLabel.match(metricKeyRegex);
80
+ if (labelParts?.length) {
81
+ const measure = labelParts.shift();
82
+ let label = labelParts.join("");
83
+ for (const ext of extendedProps) {
84
+ const index = label.indexOf(ext);
85
+ if (index === 0) {
86
+ label = label.slice(index + ext.length);
87
+ return { measure, ext, label };
88
+ }
89
+ }
90
+ // Not an aggregate property ---
91
+ return { measure, ext: "", label };
92
+ }
93
+
94
+ // No match found ---
95
+ return { measure: "", ext: "", label: fullLabel };
96
+ }
97
+
98
+ const splitLabelCache: { [key: string]: SplitKey } = {};
99
+ function splitLabel(key: string): SplitKey {
100
+ let retVal = splitLabelCache[key];
101
+ if (!retVal) {
102
+ retVal = _splitLabel(key);
103
+ splitLabelCache[key] = retVal;
104
+ }
105
+ return retVal;
106
+ }
107
+
108
+ function formatValue(item: IScope, key: string): string {
109
+ return item.__formattedProps?.[key] ?? item[key] ?? "";
110
+ }
111
+
112
+ type DedupProperties = { [key: string]: boolean };
113
+
114
+ function formatValues(item: IScope, key: string, dedup: DedupProperties): PropertyValue | null {
115
+ const keyParts = splitLabel(key);
116
+ if (!dedup[keyParts.measure]) {
117
+ dedup[keyParts.label] = true;
118
+
119
+ return {
120
+ Key: `${keyParts.measure}${keyParts.label}`,
121
+ Value: formatValue(item, `${keyParts.measure}${keyParts.label}`),
122
+ // Extended properties ---
123
+ Avg: formatValue(item, `${keyParts.measure}Avg${keyParts.label}`),
124
+ Min: formatValue(item, `${keyParts.measure}Min${keyParts.label}`),
125
+ Max: formatValue(item, `${keyParts.measure}Max${keyParts.label}`),
126
+ Delta: formatValue(item, `${keyParts.measure}Delta${keyParts.label}`),
127
+ StdDev: formatValue(item, `${keyParts.measure}StdDev${keyParts.label}`),
128
+ // Related properties ---
129
+ SkewMin: formatValue(item, `SkewMin${keyParts.label}`),
130
+ SkewMax: formatValue(item, `SkewMax${keyParts.label}`),
131
+ NodeMin: formatValue(item, `NodeMin${keyParts.label}`),
132
+ NodeMax: formatValue(item, `NodeMax${keyParts.label}`)
133
+ };
134
+ }
135
+ return null;
136
+ }
25
137
 
26
138
  const logger = scopedLogger("workunit.ts");
27
139
 
@@ -381,7 +493,7 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
381
493
  abort() {
382
494
  return this.WUAction("Abort");
383
495
  }
384
-
496
+
385
497
  protect() {
386
498
  return this.WUAction("Protect");
387
499
  }
@@ -525,7 +637,7 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
525
637
  return this.WUDetails(request).then(response => response.Scopes.Scope);
526
638
  }
527
639
 
528
- fetchDetailsNormalized(request: Partial<WsWorkunits.WUDetails.Request> = {}): Promise<{ meta: WsWorkunits.WUDetailsMeta.Response, columns: { [id: string]: any }, data: object[] }> {
640
+ fetchDetailsNormalized(request: Partial<WsWorkunits.WUDetails.Request> = {}): Promise<{ meta: WsWorkunits.WUDetailsMeta.Response, columns: { [id: string]: any }, data: IScope[] }> {
529
641
  return Promise.all([this.fetchDetailsMeta(), this.fetchDetailsRaw(request)]).then(promises => {
530
642
  const meta = promises[0];
531
643
  const scopes = promises[1];
@@ -540,7 +652,7 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
540
652
  Measure: "label"
541
653
  }
542
654
  };
543
- const data: object[] = [];
655
+ const data: IScope[] = [];
544
656
  for (const scope of scopes) {
545
657
  const props = {};
546
658
  const formattedProps = {};
@@ -589,16 +701,46 @@ export class Workunit extends StateObject<UWorkunitState, IWorkunitState> implem
589
701
  props[scopeProperty.Name] = scopeProperty.RawValue;
590
702
  }
591
703
  formattedProps[scopeProperty.Name] = formatNum(scopeProperty.Formatted ?? props[scopeProperty.Name]);
592
-
593
704
  }
705
+ // Other properties ---
594
706
  }
595
- data.push({
707
+ const normalizedScope: IScope = {
596
708
  id: scope.Id,
597
709
  name: scope.ScopeName,
598
710
  type: scope.ScopeType,
711
+ Kind: scope["Kind"],
712
+ Label: scope["Label"],
599
713
  __formattedProps: formattedProps,
714
+ __groupedProps: {},
600
715
  ...props
601
- });
716
+ };
717
+ if (normalizedScope[DEFINITION_LIST]) {
718
+ try {
719
+ const definitionList = JSON.parse(normalizedScope[DEFINITION_LIST].split("\\").join("\\\\"));
720
+ normalizedScope[DEFINITION_LIST] = [];
721
+ definitionList.forEach((definition, idx) => {
722
+ const matches = definition.match(definitionRegex);
723
+ if (matches) {
724
+ const filePath = (matches[1] ?? "") + matches[2] + matches[3];
725
+ const line = parseInt(matches[5]);
726
+ const col = parseInt(matches[6]);
727
+ normalizedScope[DEFINITION_LIST].push({ filePath, line, col });
728
+ }
729
+ });
730
+ } catch (e) {
731
+ logger.error(`Unexpected "DefinitionList": ${normalizedScope[DEFINITION_LIST]}`);
732
+ }
733
+ }
734
+ const dedup: DedupProperties = {};
735
+ for (const key in normalizedScope) {
736
+ if (key.indexOf("__") !== 0) {
737
+ const row = formatValues(normalizedScope, key, dedup);
738
+ if (row) {
739
+ normalizedScope.__groupedProps[row.Key] = row;
740
+ }
741
+ }
742
+ }
743
+ data.push(normalizedScope);
602
744
  }
603
745
  return {
604
746
  meta,