cx 24.4.3 → 24.4.5

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.
@@ -1,144 +1,144 @@
1
- import { getSelector } from "./getSelector";
2
- import { AggregateFunction } from "./AggregateFunction";
3
- import { Binding } from "./Binding";
4
-
5
- /*
6
- 'column': {
7
- index: 0,
8
- sort: 'asc',
9
- group: true
10
- aggregate: 'count'
11
- }
12
- */
13
-
14
- export class Grouper {
15
- constructor(key, aggregates, dataGetter, nameGetter) {
16
- this.keys = Object.keys(key).map((keyField) => {
17
- let isSimpleField = keyField.indexOf(".") === -1;
18
- let keySetter;
19
- if (isSimpleField) {
20
- // use simple field setter wherever possible
21
- keySetter = function set(result, value) {
22
- result[keyField] = value;
23
- return result;
24
- };
25
- } else {
26
- // for complex paths, use deep setter
27
- let binding = Binding.get(keyField);
28
- keySetter = (result, value) => binding.set(result, value);
29
- }
30
- return {
31
- name: keyField,
32
- keySetter,
33
- value: getSelector(key[keyField]),
34
- };
35
- });
36
- if (nameGetter) this.nameGetter = getSelector(nameGetter);
37
- this.dataGetter = dataGetter || ((x) => x);
38
- this.aggregates =
39
- aggregates &&
40
- transformValues(aggregates, (prop) => {
41
- if (!AggregateFunction[prop.type]) throw new Error(`Unknown aggregate function '${prop.type}'.`);
42
-
43
- return {
44
- value: getSelector(prop.value),
45
- weight: getSelector(prop.weight ?? 1),
46
- type: prop.type,
47
- };
48
- });
49
- this.reset();
50
- }
51
-
52
- reset() {
53
- this.groups = this.initGroup(this.keys.length == 0);
54
- }
55
-
56
- initGroup(leaf) {
57
- if (!leaf) return {};
58
-
59
- return {
60
- records: [],
61
- indexes: [],
62
- aggregates:
63
- this.aggregates &&
64
- transformValues(this.aggregates, (prop) => {
65
- let f = AggregateFunction[prop.type];
66
- return {
67
- processor: f(),
68
- value: prop.value,
69
- weight: prop.weight,
70
- };
71
- }),
72
- };
73
- }
74
-
75
- process(record, index) {
76
- let data = this.dataGetter(record);
77
- let key = this.keys.map((k) => k.value(data));
78
- let g = this.groups;
79
- for (let i = 0; i < key.length; i++) {
80
- let sg = g[key[i]];
81
- if (!sg) {
82
- sg = g[key[i]] = this.initGroup(i + 1 == key.length);
83
- if (this.nameGetter) sg.name = this.nameGetter(data);
84
- }
85
- g = sg;
86
- }
87
-
88
- g.records.push(record);
89
- g.indexes.push(index);
90
-
91
- if (g.aggregates) {
92
- for (let k in g.aggregates)
93
- g.aggregates[k].processor.process(g.aggregates[k].value(data), g.aggregates[k].weight(data));
94
- }
95
- }
96
-
97
- processAll(records, indexes) {
98
- if (indexes) {
99
- for (let i = 0; i < records.length; i++) this.process(records[i], indexes[i]);
100
- } else records.forEach((r, i) => this.process(r, i));
101
- }
102
-
103
- report(g, path, level, results) {
104
- if (level == this.keys.length) {
105
- let key = {};
106
- this.keys.forEach((k, i) => {
107
- key = k.keySetter(key, path[i]);
108
- });
109
- results.push({
110
- key: key,
111
- name: g.name,
112
- records: g.records,
113
- indexes: g.indexes,
114
- aggregates: resolveKeyPaths(transformValues(g.aggregates, (p) => p.processor.getResult())),
115
- });
116
- } else {
117
- Object.keys(g).forEach((k) => this.report(g[k], [...path, k], level + 1, results));
118
- }
119
- }
120
-
121
- getResults() {
122
- let g = this.groups;
123
- let results = [];
124
- this.report(g, [], 0, results);
125
- return results;
126
- }
127
- }
128
-
129
- // transform object values using a function
130
- function transformValues(o, f) {
131
- let res = {};
132
- for (let k in o) res[k] = f(o[k], k);
133
- return res;
134
- }
135
-
136
- // transform keys like 'a.b.c' into nested objects
137
- function resolveKeyPaths(o) {
138
- let res = {};
139
- for (let k in o) {
140
- if (k.indexOf(".") > 0) res = Binding.get(k).set(res, o[k]);
141
- else res[k] = o[k];
142
- }
143
- return res;
144
- }
1
+ import { getSelector } from "./getSelector";
2
+ import { AggregateFunction } from "./AggregateFunction";
3
+ import { Binding } from "./Binding";
4
+
5
+ /*
6
+ 'column': {
7
+ index: 0,
8
+ sort: 'asc',
9
+ group: true
10
+ aggregate: 'count'
11
+ }
12
+ */
13
+
14
+ export class Grouper {
15
+ constructor(key, aggregates, dataGetter, nameGetter) {
16
+ this.keys = Object.keys(key).map((keyField) => {
17
+ let isSimpleField = keyField.indexOf(".") === -1;
18
+ let keySetter;
19
+ if (isSimpleField) {
20
+ // use simple field setter wherever possible
21
+ keySetter = function set(result, value) {
22
+ result[keyField] = value;
23
+ return result;
24
+ };
25
+ } else {
26
+ // for complex paths, use deep setter
27
+ let binding = Binding.get(keyField);
28
+ keySetter = (result, value) => binding.set(result, value);
29
+ }
30
+ return {
31
+ name: keyField,
32
+ keySetter,
33
+ value: getSelector(key[keyField]),
34
+ };
35
+ });
36
+ if (nameGetter) this.nameGetter = getSelector(nameGetter);
37
+ this.dataGetter = dataGetter || ((x) => x);
38
+ this.aggregates =
39
+ aggregates &&
40
+ transformValues(aggregates, (prop) => {
41
+ if (!AggregateFunction[prop.type]) throw new Error(`Unknown aggregate function '${prop.type}'.`);
42
+
43
+ return {
44
+ value: getSelector(prop.value),
45
+ weight: getSelector(prop.weight ?? 1),
46
+ type: prop.type,
47
+ };
48
+ });
49
+ this.reset();
50
+ }
51
+
52
+ reset() {
53
+ this.groups = this.initGroup(this.keys.length == 0);
54
+ }
55
+
56
+ initGroup(leaf) {
57
+ if (!leaf) return {};
58
+
59
+ return {
60
+ records: [],
61
+ indexes: [],
62
+ aggregates:
63
+ this.aggregates &&
64
+ transformValues(this.aggregates, (prop) => {
65
+ let f = AggregateFunction[prop.type];
66
+ return {
67
+ processor: f(),
68
+ value: prop.value,
69
+ weight: prop.weight,
70
+ };
71
+ }),
72
+ };
73
+ }
74
+
75
+ process(record, index) {
76
+ let data = this.dataGetter(record);
77
+ let key = this.keys.map((k) => k.value(data));
78
+ let g = this.groups;
79
+ for (let i = 0; i < key.length; i++) {
80
+ let sg = g[key[i]];
81
+ if (!sg) {
82
+ sg = g[key[i]] = this.initGroup(i + 1 == key.length);
83
+ if (this.nameGetter) sg.name = this.nameGetter(data);
84
+ }
85
+ g = sg;
86
+ }
87
+
88
+ g.records.push(record);
89
+ g.indexes.push(index);
90
+
91
+ if (g.aggregates) {
92
+ for (let k in g.aggregates)
93
+ g.aggregates[k].processor.process(g.aggregates[k].value(data), g.aggregates[k].weight(data));
94
+ }
95
+ }
96
+
97
+ processAll(records, indexes) {
98
+ if (indexes) {
99
+ for (let i = 0; i < records.length; i++) this.process(records[i], indexes[i]);
100
+ } else records.forEach((r, i) => this.process(r, i));
101
+ }
102
+
103
+ report(g, path, level, results) {
104
+ if (level == this.keys.length) {
105
+ let key = {};
106
+ this.keys.forEach((k, i) => {
107
+ key = k.keySetter(key, path[i]);
108
+ });
109
+ results.push({
110
+ key: key,
111
+ name: g.name,
112
+ records: g.records,
113
+ indexes: g.indexes,
114
+ aggregates: resolveKeyPaths(transformValues(g.aggregates, (p) => p.processor.getResult())),
115
+ });
116
+ } else {
117
+ Object.keys(g).forEach((k) => this.report(g[k], [...path, k], level + 1, results));
118
+ }
119
+ }
120
+
121
+ getResults() {
122
+ let g = this.groups;
123
+ let results = [];
124
+ this.report(g, [], 0, results);
125
+ return results;
126
+ }
127
+ }
128
+
129
+ // transform object values using a function
130
+ function transformValues(o, f) {
131
+ let res = {};
132
+ for (let k in o) res[k] = f(o[k], k);
133
+ return res;
134
+ }
135
+
136
+ // transform keys like 'a.b.c' into nested objects
137
+ function resolveKeyPaths(o) {
138
+ let res = {};
139
+ for (let k in o) {
140
+ if (k.indexOf(".") > 0) res = Binding.get(k).set(res, o[k]);
141
+ else res[k] = o[k];
142
+ }
143
+ return res;
144
+ }
@@ -1,57 +1,57 @@
1
- let Grouper = require("./Grouper").Grouper;
2
- import assert from "assert";
3
-
4
- describe("Grouper", function () {
5
- describe("single grouping", function () {
6
- it("should work", function () {
7
- let data = [
8
- { name: "John", age: 12 },
9
- { name: "Jane", age: 12 },
10
- ];
11
-
12
- let grouper = new Grouper({ name: { bind: "name" } });
13
- grouper.processAll(data);
14
-
15
- let results = grouper.getResults();
16
- // console.log(results);
17
- assert.equal(results.length, 2);
18
- });
19
-
20
- it("keys can have nested properties", function () {
21
- let data = [
22
- { name: "John", age: 12 },
23
- { name: "Jane", age: 12 },
24
- ];
25
-
26
- let grouper = new Grouper({ "person.name": { bind: "name" } });
27
- grouper.processAll(data);
28
-
29
- let results = grouper.getResults();
30
- assert.equal(results.length, 2);
31
- assert.equal(results[0].key.person?.name, "John");
32
- assert.equal(results[1].key.person?.name, "Jane");
33
- });
34
- });
35
-
36
- describe("multi grouping", function () {
37
- it("should work", function () {
38
- let data = [
39
- { name: "John", age: 12 },
40
- { name: "John", age: 12 },
41
- { name: "John", age: 13 },
42
- { name: "John", age: 14 },
43
- { name: "Jane", age: 12 },
44
- { name: "Jane", age: 13 },
45
- { name: "Jane", age: 14 },
46
- ];
47
-
48
- let grouper = new Grouper({ name: { bind: "name" }, age: { bind: "age" } });
49
- grouper.processAll(data);
50
-
51
- let results = grouper.getResults();
52
- // console.log(results);
53
- assert.equal(results.length, 6);
54
- assert.equal(results[0].records.length, 2);
55
- });
56
- });
57
- });
1
+ let Grouper = require("./Grouper").Grouper;
2
+ import assert from "assert";
3
+
4
+ describe("Grouper", function () {
5
+ describe("single grouping", function () {
6
+ it("should work", function () {
7
+ let data = [
8
+ { name: "John", age: 12 },
9
+ { name: "Jane", age: 12 },
10
+ ];
11
+
12
+ let grouper = new Grouper({ name: { bind: "name" } });
13
+ grouper.processAll(data);
14
+
15
+ let results = grouper.getResults();
16
+ // console.log(results);
17
+ assert.equal(results.length, 2);
18
+ });
19
+
20
+ it("keys can have nested properties", function () {
21
+ let data = [
22
+ { name: "John", age: 12 },
23
+ { name: "Jane", age: 12 },
24
+ ];
25
+
26
+ let grouper = new Grouper({ "person.name": { bind: "name" } });
27
+ grouper.processAll(data);
28
+
29
+ let results = grouper.getResults();
30
+ assert.equal(results.length, 2);
31
+ assert.equal(results[0].key.person?.name, "John");
32
+ assert.equal(results[1].key.person?.name, "Jane");
33
+ });
34
+ });
35
+
36
+ describe("multi grouping", function () {
37
+ it("should work", function () {
38
+ let data = [
39
+ { name: "John", age: 12 },
40
+ { name: "John", age: 12 },
41
+ { name: "John", age: 13 },
42
+ { name: "John", age: 14 },
43
+ { name: "Jane", age: 12 },
44
+ { name: "Jane", age: 13 },
45
+ { name: "Jane", age: 14 },
46
+ ];
47
+
48
+ let grouper = new Grouper({ name: { bind: "name" }, age: { bind: "age" } });
49
+ grouper.processAll(data);
50
+
51
+ let results = grouper.getResults();
52
+ // console.log(results);
53
+ assert.equal(results.length, 6);
54
+ assert.equal(results[0].records.length, 2);
55
+ });
56
+ });
57
+ });