@platforma-sdk/model 1.53.15 → 1.54.7
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/dist/annotations/converter.cjs +8 -32
- package/dist/annotations/converter.cjs.map +1 -1
- package/dist/annotations/converter.d.ts.map +1 -1
- package/dist/annotations/converter.js +7 -31
- package/dist/annotations/converter.js.map +1 -1
- package/dist/block_model.cjs +1 -0
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts.map +1 -1
- package/dist/block_model.js +1 -0
- package/dist/block_model.js.map +1 -1
- package/dist/builder.cjs +1 -0
- package/dist/builder.cjs.map +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +1 -0
- package/dist/builder.js.map +1 -1
- package/dist/components/PlDataTable/index.d.ts +5 -0
- package/dist/components/PlDataTable/index.d.ts.map +1 -0
- package/dist/components/PlDataTable/labels.cjs +91 -0
- package/dist/components/PlDataTable/labels.cjs.map +1 -0
- package/dist/components/PlDataTable/labels.d.ts +7 -0
- package/dist/components/PlDataTable/labels.d.ts.map +1 -0
- package/dist/components/PlDataTable/labels.js +88 -0
- package/dist/components/PlDataTable/labels.js.map +1 -0
- package/dist/components/PlDataTable/state-migration.cjs +162 -0
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -0
- package/dist/components/PlDataTable/state-migration.d.ts +94 -0
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -0
- package/dist/components/PlDataTable/state-migration.js +158 -0
- package/dist/components/PlDataTable/state-migration.js.map +1 -0
- package/dist/components/PlDataTable/table.cjs +188 -0
- package/dist/components/PlDataTable/table.cjs.map +1 -0
- package/dist/components/PlDataTable/table.d.ts +26 -0
- package/dist/components/PlDataTable/table.d.ts.map +1 -0
- package/dist/components/PlDataTable/table.js +184 -0
- package/dist/components/PlDataTable/table.js.map +1 -0
- package/dist/components/PlDataTable/v4.d.ts +157 -0
- package/dist/components/PlDataTable/v4.d.ts.map +1 -0
- package/dist/components/PlDataTable/v5.d.ts +113 -0
- package/dist/components/PlDataTable/v5.d.ts.map +1 -0
- package/dist/filters/converters/filterEmpty.cjs +49 -0
- package/dist/filters/converters/filterEmpty.cjs.map +1 -0
- package/dist/filters/converters/filterEmpty.d.ts +4 -0
- package/dist/filters/converters/filterEmpty.d.ts.map +1 -0
- package/dist/filters/converters/filterEmpty.js +46 -0
- package/dist/filters/converters/filterEmpty.js.map +1 -0
- package/dist/filters/converters/filterToQuery.cjs +244 -0
- package/dist/filters/converters/filterToQuery.cjs.map +1 -0
- package/dist/filters/converters/filterToQuery.d.ts +4 -0
- package/dist/filters/converters/filterToQuery.d.ts.map +1 -0
- package/dist/filters/converters/filterToQuery.js +242 -0
- package/dist/filters/converters/filterToQuery.js.map +1 -0
- package/dist/filters/{converter.cjs → converters/filterUiToExpressionImpl.cjs} +3 -2
- package/dist/filters/converters/filterUiToExpressionImpl.cjs.map +1 -0
- package/dist/filters/{converter.d.ts → converters/filterUiToExpressionImpl.d.ts} +2 -2
- package/dist/filters/converters/filterUiToExpressionImpl.d.ts.map +1 -0
- package/dist/filters/{converter.js → converters/filterUiToExpressionImpl.js} +3 -2
- package/dist/filters/converters/filterUiToExpressionImpl.js.map +1 -0
- package/dist/filters/converters/index.d.ts +3 -0
- package/dist/filters/converters/index.d.ts.map +1 -0
- package/dist/filters/distill.cjs +46 -0
- package/dist/filters/distill.cjs.map +1 -0
- package/dist/filters/distill.d.ts +6 -0
- package/dist/filters/distill.d.ts.map +1 -0
- package/dist/filters/distill.js +44 -0
- package/dist/filters/distill.js.map +1 -0
- package/dist/filters/index.d.ts +2 -1
- package/dist/filters/index.d.ts.map +1 -1
- package/dist/filters/types.d.ts +1 -117
- package/dist/filters/types.d.ts.map +1 -1
- package/dist/index.cjs +17 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/package.json.cjs +1 -1
- package/dist/package.json.js +1 -1
- package/dist/pframe_utils/columns.cjs +2 -0
- package/dist/pframe_utils/columns.cjs.map +1 -1
- package/dist/pframe_utils/columns.js +2 -0
- package/dist/pframe_utils/columns.js.map +1 -1
- package/dist/pframe_utils/index.cjs +2 -0
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.js +2 -0
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/pframe_utils/querySpec.d.ts +2 -0
- package/dist/pframe_utils/querySpec.d.ts.map +1 -0
- package/dist/render/api.cjs +7 -0
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +3 -2
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +8 -1
- package/dist/render/api.js.map +1 -1
- package/dist/render/future.d.ts +1 -1
- package/dist/render/index.d.ts +2 -1
- package/dist/render/index.d.ts.map +1 -1
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +4 -1
- package/dist/render/internal.d.ts.map +1 -1
- package/dist/render/internal.js.map +1 -1
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts +1 -1
- package/dist/render/util/column_collection.d.ts.map +1 -1
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +1 -1
- package/dist/render/util/pcolumn_data.d.ts.map +1 -1
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/package.json +8 -6
- package/src/annotations/converter.ts +12 -40
- package/src/block_model.ts +1 -0
- package/src/builder.ts +1 -0
- package/src/components/PlDataTable/index.ts +22 -0
- package/src/components/PlDataTable/labels.ts +101 -0
- package/src/components/PlDataTable/state-migration.ts +285 -0
- package/src/components/PlDataTable/table.ts +279 -0
- package/src/components/PlDataTable/v4.ts +193 -0
- package/src/components/PlDataTable/v5.ts +140 -0
- package/src/filters/converters/filterEmpty.test.ts +125 -0
- package/src/filters/converters/filterEmpty.ts +57 -0
- package/src/filters/converters/filterToQuery.test.ts +417 -0
- package/src/filters/converters/filterToQuery.ts +258 -0
- package/src/filters/{converter.test.ts → converters/filterUiToExpressionImpl.test.ts} +2 -2
- package/src/filters/{converter.ts → converters/filterUiToExpressionImpl.ts} +3 -2
- package/src/filters/converters/index.ts +2 -0
- package/src/filters/distill.ts +59 -0
- package/src/filters/index.ts +2 -1
- package/src/filters/types.ts +8 -48
- package/src/pframe_utils/querySpec.ts +1 -0
- package/src/render/api.ts +13 -6
- package/src/render/index.ts +2 -1
- package/src/render/internal.ts +11 -0
- package/src/render/util/column_collection.ts +1 -1
- package/src/render/util/pcolumn_data.ts +1 -1
- package/dist/components/PlDataTable.cjs +0 -307
- package/dist/components/PlDataTable.cjs.map +0 -1
- package/dist/components/PlDataTable.d.ts +0 -366
- package/dist/components/PlDataTable.d.ts.map +0 -1
- package/dist/components/PlDataTable.js +0 -297
- package/dist/components/PlDataTable.js.map +0 -1
- package/dist/filters/converter.cjs.map +0 -1
- package/dist/filters/converter.d.ts.map +0 -1
- package/dist/filters/converter.js.map +0 -1
- package/src/components/PlDataTable.ts +0 -794
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { assertNever } from "@milaboratories/pl-model-common";
|
|
2
|
+
import type {
|
|
3
|
+
FilterSpec,
|
|
4
|
+
FilterSpecLeaf,
|
|
5
|
+
PTableColumnId,
|
|
6
|
+
SingleAxisSelector,
|
|
7
|
+
SpecQueryExpression,
|
|
8
|
+
} from "@milaboratories/pl-model-common";
|
|
9
|
+
|
|
10
|
+
/** Parses a CanonicalizedJson<PTableColumnId> string into a SpecQueryExpression reference. */
|
|
11
|
+
function resolveColumnRef(columnStr: string): SpecQueryExpression {
|
|
12
|
+
const parsed = JSON.parse(columnStr) as PTableColumnId;
|
|
13
|
+
if (parsed.type === "axis") {
|
|
14
|
+
return { type: "axisRef", value: parsed.id as SingleAxisSelector };
|
|
15
|
+
}
|
|
16
|
+
return { type: "columnRef", value: parsed.id };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Converts a FilterSpec tree into a SpecQueryExpression. */
|
|
20
|
+
export function filterSpecToSpecQueryExpr(
|
|
21
|
+
filter: FilterSpec<FilterSpecLeaf<string>>,
|
|
22
|
+
): SpecQueryExpression {
|
|
23
|
+
switch (filter.type) {
|
|
24
|
+
case "and":
|
|
25
|
+
case "or": {
|
|
26
|
+
const inputs = filter.filters
|
|
27
|
+
.filter((f) => f.type !== undefined)
|
|
28
|
+
.map(filterSpecToSpecQueryExpr);
|
|
29
|
+
if (inputs.length === 0) {
|
|
30
|
+
throw new Error(`${filter.type.toUpperCase()} filter requires at least one operand`);
|
|
31
|
+
}
|
|
32
|
+
return { type: filter.type, input: inputs };
|
|
33
|
+
}
|
|
34
|
+
case "not":
|
|
35
|
+
return { type: "not", input: filterSpecToSpecQueryExpr(filter.filter) };
|
|
36
|
+
|
|
37
|
+
case "patternEquals":
|
|
38
|
+
return {
|
|
39
|
+
type: "stringEquals",
|
|
40
|
+
input: resolveColumnRef(filter.column),
|
|
41
|
+
value: filter.value,
|
|
42
|
+
caseInsensitive: false,
|
|
43
|
+
};
|
|
44
|
+
case "patternNotEquals":
|
|
45
|
+
return {
|
|
46
|
+
type: "not",
|
|
47
|
+
input: {
|
|
48
|
+
type: "stringEquals",
|
|
49
|
+
input: resolveColumnRef(filter.column),
|
|
50
|
+
value: filter.value,
|
|
51
|
+
caseInsensitive: false,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
case "patternContainSubsequence":
|
|
55
|
+
return {
|
|
56
|
+
type: "stringContains",
|
|
57
|
+
input: resolveColumnRef(filter.column),
|
|
58
|
+
value: filter.value,
|
|
59
|
+
caseInsensitive: false,
|
|
60
|
+
};
|
|
61
|
+
case "patternNotContainSubsequence":
|
|
62
|
+
return {
|
|
63
|
+
type: "not",
|
|
64
|
+
input: {
|
|
65
|
+
type: "stringContains",
|
|
66
|
+
input: resolveColumnRef(filter.column),
|
|
67
|
+
value: filter.value,
|
|
68
|
+
caseInsensitive: false,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
case "patternMatchesRegularExpression":
|
|
72
|
+
return {
|
|
73
|
+
type: "stringRegex",
|
|
74
|
+
input: resolveColumnRef(filter.column),
|
|
75
|
+
value: filter.value,
|
|
76
|
+
};
|
|
77
|
+
case "patternFuzzyContainSubsequence":
|
|
78
|
+
return {
|
|
79
|
+
type: "stringContainsFuzzy",
|
|
80
|
+
input: resolveColumnRef(filter.column),
|
|
81
|
+
value: filter.value,
|
|
82
|
+
maxEdits: filter.maxEdits ?? 1,
|
|
83
|
+
caseInsensitive: false,
|
|
84
|
+
substitutionsOnly: filter.substitutionsOnly ?? false,
|
|
85
|
+
wildcard: filter.wildcard ?? null,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
case "equal":
|
|
89
|
+
return {
|
|
90
|
+
type: "numericComparison",
|
|
91
|
+
operand: "eq",
|
|
92
|
+
left: resolveColumnRef(filter.column),
|
|
93
|
+
right: { type: "constant", value: filter.x },
|
|
94
|
+
};
|
|
95
|
+
case "notEqual":
|
|
96
|
+
return {
|
|
97
|
+
type: "numericComparison",
|
|
98
|
+
operand: "ne",
|
|
99
|
+
left: resolveColumnRef(filter.column),
|
|
100
|
+
right: { type: "constant", value: filter.x },
|
|
101
|
+
};
|
|
102
|
+
case "lessThan":
|
|
103
|
+
return {
|
|
104
|
+
type: "numericComparison",
|
|
105
|
+
operand: "lt",
|
|
106
|
+
left: resolveColumnRef(filter.column),
|
|
107
|
+
right: { type: "constant", value: filter.x },
|
|
108
|
+
};
|
|
109
|
+
case "greaterThan":
|
|
110
|
+
return {
|
|
111
|
+
type: "numericComparison",
|
|
112
|
+
operand: "gt",
|
|
113
|
+
left: resolveColumnRef(filter.column),
|
|
114
|
+
right: { type: "constant", value: filter.x },
|
|
115
|
+
};
|
|
116
|
+
case "lessThanOrEqual":
|
|
117
|
+
return {
|
|
118
|
+
type: "numericComparison",
|
|
119
|
+
operand: "le",
|
|
120
|
+
left: resolveColumnRef(filter.column),
|
|
121
|
+
right: { type: "constant", value: filter.x },
|
|
122
|
+
};
|
|
123
|
+
case "greaterThanOrEqual":
|
|
124
|
+
return {
|
|
125
|
+
type: "numericComparison",
|
|
126
|
+
operand: "ge",
|
|
127
|
+
left: resolveColumnRef(filter.column),
|
|
128
|
+
right: { type: "constant", value: filter.x },
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
case "equalToColumn":
|
|
132
|
+
return {
|
|
133
|
+
type: "numericComparison",
|
|
134
|
+
operand: "eq",
|
|
135
|
+
left: resolveColumnRef(filter.column),
|
|
136
|
+
right: resolveColumnRef(filter.rhs),
|
|
137
|
+
};
|
|
138
|
+
case "lessThanColumn": {
|
|
139
|
+
const left = resolveColumnRef(filter.column);
|
|
140
|
+
const right = resolveColumnRef(filter.rhs);
|
|
141
|
+
if (filter.minDiff !== undefined && filter.minDiff !== 0) {
|
|
142
|
+
return {
|
|
143
|
+
type: "numericComparison",
|
|
144
|
+
operand: "lt",
|
|
145
|
+
left: {
|
|
146
|
+
type: "numericBinary",
|
|
147
|
+
operand: "add",
|
|
148
|
+
left,
|
|
149
|
+
right: { type: "constant", value: filter.minDiff },
|
|
150
|
+
},
|
|
151
|
+
right,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return { type: "numericComparison", operand: "lt", left, right };
|
|
155
|
+
}
|
|
156
|
+
case "greaterThanColumn": {
|
|
157
|
+
const left = resolveColumnRef(filter.column);
|
|
158
|
+
const right = resolveColumnRef(filter.rhs);
|
|
159
|
+
if (filter.minDiff !== undefined && filter.minDiff !== 0) {
|
|
160
|
+
return {
|
|
161
|
+
type: "numericComparison",
|
|
162
|
+
operand: "gt",
|
|
163
|
+
left: {
|
|
164
|
+
type: "numericBinary",
|
|
165
|
+
operand: "add",
|
|
166
|
+
left,
|
|
167
|
+
right: { type: "constant", value: filter.minDiff },
|
|
168
|
+
},
|
|
169
|
+
right,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return { type: "numericComparison", operand: "gt", left, right };
|
|
173
|
+
}
|
|
174
|
+
case "lessThanColumnOrEqual": {
|
|
175
|
+
const left = resolveColumnRef(filter.column);
|
|
176
|
+
const right = resolveColumnRef(filter.rhs);
|
|
177
|
+
if (filter.minDiff !== undefined && filter.minDiff !== 0) {
|
|
178
|
+
return {
|
|
179
|
+
type: "numericComparison",
|
|
180
|
+
operand: "le",
|
|
181
|
+
left: {
|
|
182
|
+
type: "numericBinary",
|
|
183
|
+
operand: "add",
|
|
184
|
+
left,
|
|
185
|
+
right: { type: "constant", value: filter.minDiff },
|
|
186
|
+
},
|
|
187
|
+
right,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return { type: "numericComparison", operand: "le", left, right };
|
|
191
|
+
}
|
|
192
|
+
case "greaterThanColumnOrEqual": {
|
|
193
|
+
const left = resolveColumnRef(filter.column);
|
|
194
|
+
const right = resolveColumnRef(filter.rhs);
|
|
195
|
+
if (filter.minDiff !== undefined && filter.minDiff !== 0) {
|
|
196
|
+
return {
|
|
197
|
+
type: "numericComparison",
|
|
198
|
+
operand: "ge",
|
|
199
|
+
left: {
|
|
200
|
+
type: "numericBinary",
|
|
201
|
+
operand: "add",
|
|
202
|
+
left,
|
|
203
|
+
right: { type: "constant", value: filter.minDiff },
|
|
204
|
+
},
|
|
205
|
+
right,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return { type: "numericComparison", operand: "ge", left, right };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
case "inSet":
|
|
212
|
+
return {
|
|
213
|
+
type: "isIn",
|
|
214
|
+
input: resolveColumnRef(filter.column),
|
|
215
|
+
set: filter.value,
|
|
216
|
+
};
|
|
217
|
+
case "notInSet":
|
|
218
|
+
return {
|
|
219
|
+
type: "not",
|
|
220
|
+
input: {
|
|
221
|
+
type: "isIn",
|
|
222
|
+
input: resolveColumnRef(filter.column),
|
|
223
|
+
set: filter.value,
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
case "isNA":
|
|
228
|
+
return {
|
|
229
|
+
type: "isNull",
|
|
230
|
+
input: resolveColumnRef(filter.column),
|
|
231
|
+
};
|
|
232
|
+
case "isNotNA":
|
|
233
|
+
return {
|
|
234
|
+
type: "not",
|
|
235
|
+
input: {
|
|
236
|
+
type: "isNull",
|
|
237
|
+
input: resolveColumnRef(filter.column),
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
case "ifNa":
|
|
242
|
+
return {
|
|
243
|
+
type: "ifNull",
|
|
244
|
+
input: resolveColumnRef(filter.column),
|
|
245
|
+
replacement: { type: "constant", value: filter.replacement },
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
case "topN":
|
|
249
|
+
case "bottomN":
|
|
250
|
+
throw new Error(`Filter type "${filter.type}" is not supported in query expressions`);
|
|
251
|
+
|
|
252
|
+
case undefined:
|
|
253
|
+
throw new Error("Filter type is undefined");
|
|
254
|
+
|
|
255
|
+
default:
|
|
256
|
+
assertNever(filter);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { SUniversalPColumnId } from "@milaboratories/pl-model-common";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { convertFilterUiToExpressions } from "./
|
|
4
|
-
import { FilterSpec } from "
|
|
3
|
+
import { convertFilterUiToExpressions } from "./filterUiToExpressionImpl";
|
|
4
|
+
import { FilterSpec } from "../types";
|
|
5
5
|
|
|
6
6
|
describe("convertFilterUiToExpressions", () => {
|
|
7
7
|
it('should compile "or" filter to ptabler expression', () => {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type Expression,
|
|
9
9
|
type ExpressionImpl,
|
|
10
10
|
} from "@milaboratories/ptabler-expression-js";
|
|
11
|
-
import type { FilterSpec } from "../
|
|
11
|
+
import type { FilterSpec } from "../types";
|
|
12
12
|
|
|
13
13
|
export function convertFilterUiToExpressionImpl(value: FilterSpec): ExpressionImpl {
|
|
14
14
|
if (value.type === "or") {
|
|
@@ -127,7 +127,8 @@ export function convertFilterUiToExpressionImpl(value: FilterSpec): ExpressionIm
|
|
|
127
127
|
value.type === "patternMatchesRegularExpression" ||
|
|
128
128
|
value.type === "patternFuzzyContainSubsequence" ||
|
|
129
129
|
value.type === "inSet" ||
|
|
130
|
-
value.type === "notInSet"
|
|
130
|
+
value.type === "notInSet" ||
|
|
131
|
+
value.type === "ifNa"
|
|
131
132
|
) {
|
|
132
133
|
throw new Error("Not implemented filter type: " + value.type);
|
|
133
134
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DistributiveKeys, UnionToTuples } from "@milaboratories/helpers";
|
|
2
|
+
import {
|
|
3
|
+
type FilterSpec,
|
|
4
|
+
type FilterSpecLeaf,
|
|
5
|
+
type PTableFilters,
|
|
6
|
+
} from "@milaboratories/pl-model-common";
|
|
7
|
+
|
|
8
|
+
/** All possible field names that can appear in any FilterSpecLeaf variant. */
|
|
9
|
+
type FilterSpecLeafKey = DistributiveKeys<FilterSpecLeaf<string>>;
|
|
10
|
+
|
|
11
|
+
/** Compile-time check: every key in the tuple is a valid leaf key (via satisfies). */
|
|
12
|
+
const KNOWN_LEAF_KEYS_TUPLE: UnionToTuples<FilterSpecLeafKey> = [
|
|
13
|
+
"n",
|
|
14
|
+
"x",
|
|
15
|
+
"rhs",
|
|
16
|
+
"type",
|
|
17
|
+
"value",
|
|
18
|
+
"column",
|
|
19
|
+
"minDiff",
|
|
20
|
+
"maxEdits",
|
|
21
|
+
"wildcard",
|
|
22
|
+
"replacement",
|
|
23
|
+
"substitutionsOnly",
|
|
24
|
+
];
|
|
25
|
+
const KNOWN_LEAF_KEYS: Set<FilterSpecLeafKey> = new Set(KNOWN_LEAF_KEYS_TUPLE);
|
|
26
|
+
|
|
27
|
+
type UnknownFilterNode = FilterSpec<
|
|
28
|
+
FilterSpecLeaf<string>,
|
|
29
|
+
Record<string, unknown>,
|
|
30
|
+
Record<string, unknown>
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
function distillLeaf(node: Record<string, unknown>): FilterSpecLeaf<string> {
|
|
34
|
+
const result: Record<string, unknown> = {};
|
|
35
|
+
for (const [key, value] of Object.entries(node)) {
|
|
36
|
+
if (KNOWN_LEAF_KEYS.has(key as FilterSpecLeafKey)) {
|
|
37
|
+
result[key] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result as FilterSpecLeaf<string>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function distillNode(node: UnknownFilterNode): FilterSpec<FilterSpecLeaf<string>> {
|
|
44
|
+
switch (node.type) {
|
|
45
|
+
case "and":
|
|
46
|
+
case "or":
|
|
47
|
+
return { type: node.type, filters: node.filters.map(distillNode) };
|
|
48
|
+
case "not":
|
|
49
|
+
return { type: "not", filter: distillNode(node.filter) };
|
|
50
|
+
default:
|
|
51
|
+
return distillLeaf(node as Record<string, unknown>);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Strips all non-FilterSpec metadata from the filter tree (whitelist approach). */
|
|
56
|
+
export function distillFilter(filter: UnknownFilterNode | null | undefined): PTableFilters {
|
|
57
|
+
if (filter == null) return null;
|
|
58
|
+
return distillNode(filter);
|
|
59
|
+
}
|
package/src/filters/index.ts
CHANGED
package/src/filters/types.ts
CHANGED
|
@@ -8,51 +8,11 @@ export type SimplifiedUniversalPColumnEntry = {
|
|
|
8
8
|
obj: SimplifiedPColumnSpec;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export type
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| { type: "isNA"; column: T }
|
|
20
|
-
| { type: "isNotNA"; column: T }
|
|
21
|
-
| { type: "patternEquals"; column: T; value: string }
|
|
22
|
-
| { type: "patternNotEquals"; column: T; value: string }
|
|
23
|
-
| { type: "patternContainSubsequence"; column: T; value: string }
|
|
24
|
-
| { type: "patternNotContainSubsequence"; column: T; value: string }
|
|
25
|
-
| { type: "patternMatchesRegularExpression"; column: T; value: string }
|
|
26
|
-
| {
|
|
27
|
-
type: "patternFuzzyContainSubsequence";
|
|
28
|
-
column: T;
|
|
29
|
-
value: string;
|
|
30
|
-
maxEdits?: number;
|
|
31
|
-
substitutionsOnly?: boolean;
|
|
32
|
-
wildcard?: string;
|
|
33
|
-
}
|
|
34
|
-
| { type: "inSet"; column: T; value: string[] }
|
|
35
|
-
| { type: "notInSet"; column: T; value: string[] }
|
|
36
|
-
| { type: "topN"; column: T; n: number }
|
|
37
|
-
| { type: "bottomN"; column: T; n: number }
|
|
38
|
-
| { type: "equal"; column: T; x: number }
|
|
39
|
-
| { type: "notEqual"; column: T; x: number }
|
|
40
|
-
| { type: "lessThan"; column: T; x: number }
|
|
41
|
-
| { type: "greaterThan"; column: T; x: number }
|
|
42
|
-
| { type: "lessThanOrEqual"; column: T; x: number }
|
|
43
|
-
| { type: "greaterThanOrEqual"; column: T; x: number }
|
|
44
|
-
| { type: "equalToColumn"; column: T; rhs: T }
|
|
45
|
-
| { type: "lessThanColumn"; column: T; rhs: T; minDiff?: number }
|
|
46
|
-
| { type: "greaterThanColumn"; column: T; rhs: T; minDiff?: number }
|
|
47
|
-
| { type: "lessThanColumnOrEqual"; column: T; rhs: T; minDiff?: number }
|
|
48
|
-
| { type: "greaterThanColumnOrEqual"; column: T; rhs: T; minDiff?: number };
|
|
49
|
-
|
|
50
|
-
export type FilterSpec<
|
|
51
|
-
Leaf extends FilterSpecLeaf<unknown> = FilterSpecLeaf<SUniversalPColumnId>,
|
|
52
|
-
CommonNode = {},
|
|
53
|
-
CommonLeaf = CommonNode,
|
|
54
|
-
> = FilterSpecNode<Leaf, CommonNode, CommonLeaf>;
|
|
55
|
-
|
|
56
|
-
export type FilterSpecType = Exclude<FilterSpec, { type: undefined }>["type"];
|
|
57
|
-
|
|
58
|
-
export type FilterSpecOfType<T extends FilterSpecType> = Extract<FilterSpec, { type: T }>;
|
|
11
|
+
export type {
|
|
12
|
+
FilterSpecNode,
|
|
13
|
+
FilterSpecLeaf,
|
|
14
|
+
FilterSpec,
|
|
15
|
+
FilterSpecType,
|
|
16
|
+
FilterSpecOfType,
|
|
17
|
+
PTableFilters,
|
|
18
|
+
} from "@milaboratories/pl-model-common";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { collectQueryColumns, isBooleanExpression } from "@milaboratories/pl-model-common";
|
package/src/render/api.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
PObjectSpec,
|
|
17
17
|
PSpecPredicate,
|
|
18
18
|
PTableDef,
|
|
19
|
+
PTableDefV2,
|
|
19
20
|
PTableHandle,
|
|
20
21
|
PTableRecordFilter,
|
|
21
22
|
PTableSorting,
|
|
@@ -36,6 +37,7 @@ import {
|
|
|
36
37
|
mapDataInfo,
|
|
37
38
|
mapPObjectData,
|
|
38
39
|
mapPTableDef,
|
|
40
|
+
mapPTableDefV2,
|
|
39
41
|
mapValueInVOE,
|
|
40
42
|
PColumnName,
|
|
41
43
|
readAnnotation,
|
|
@@ -58,12 +60,9 @@ import type { LabelDerivationOps } from "./util/label";
|
|
|
58
60
|
import { deriveLabels } from "./util/label";
|
|
59
61
|
import type { APColumnSelectorWithSplit } from "./util/split_selectors";
|
|
60
62
|
import { patchInSetFilters } from "./util/pframe_upgraders";
|
|
61
|
-
import { allPColumnsReady } from "./util";
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
| TreeEntry
|
|
65
|
-
| DataInfo<TreeEntry>
|
|
66
|
-
| PColumnValues;
|
|
63
|
+
import { allPColumnsReady } from "./util/pcolumn_data";
|
|
64
|
+
import type { PColumnDataUniversal } from "./internal";
|
|
65
|
+
import { collectQueryColumns } from "@milaboratories/pl-model-common";
|
|
67
66
|
|
|
68
67
|
/**
|
|
69
68
|
* Helper function to match domain objects
|
|
@@ -682,6 +681,13 @@ export abstract class RenderCtxBase<Args, Data> {
|
|
|
682
681
|
return this.ctx.createPTable(mapPTableDef(rawDef, (po) => transformPColumnData(po)));
|
|
683
682
|
}
|
|
684
683
|
|
|
684
|
+
public createPTableV2(def: PTableDefV2<PColumn<PColumnDataUniversal>>): PTableHandle | undefined {
|
|
685
|
+
const columns = collectQueryColumns(def.query);
|
|
686
|
+
this.verifyInlineAndExplicitColumnsSupport(columns);
|
|
687
|
+
if (!allPColumnsReady(columns)) return undefined;
|
|
688
|
+
return this.ctx.createPTableV2(mapPTableDefV2(def, (po) => transformPColumnData(po)));
|
|
689
|
+
}
|
|
690
|
+
|
|
685
691
|
/** @deprecated scheduled for removal from SDK */
|
|
686
692
|
public getBlockLabel(blockId: string): string {
|
|
687
693
|
return this.ctx.getBlockLabel(blockId);
|
|
@@ -721,6 +727,7 @@ export class RenderCtx<Args, Data> extends RenderCtxBase<Args, Data> {
|
|
|
721
727
|
/** Render context for legacy v1/v2 blocks - provides backward compatibility */
|
|
722
728
|
export class RenderCtxLegacy<Args, UiState> extends RenderCtxBase<Args, UiState> {
|
|
723
729
|
private _argsCache?: { v: Args };
|
|
730
|
+
|
|
724
731
|
public get args(): Args {
|
|
725
732
|
if (this._argsCache === undefined) {
|
|
726
733
|
const raw = this.ctx.args;
|
package/src/render/index.ts
CHANGED
|
@@ -2,5 +2,6 @@ export * from "./api";
|
|
|
2
2
|
export * from "./traversal_ops";
|
|
3
3
|
export * from "./accessor";
|
|
4
4
|
export * from "./util";
|
|
5
|
-
export { type ExtractFutureRefType } from "./future";
|
|
6
5
|
export { FutureRef } from "./future";
|
|
6
|
+
export type { PColumnDataUniversal } from "./internal";
|
|
7
|
+
export type { ExtractFutureRefType } from "./future";
|
package/src/render/internal.ts
CHANGED
|
@@ -13,12 +13,14 @@ import type {
|
|
|
13
13
|
PObjectSpec,
|
|
14
14
|
PSpecPredicate,
|
|
15
15
|
PTableDef,
|
|
16
|
+
PTableDefV2,
|
|
16
17
|
PTableHandle,
|
|
17
18
|
ResultCollection,
|
|
18
19
|
ValueOrError,
|
|
19
20
|
DataInfo,
|
|
20
21
|
RangeBytes,
|
|
21
22
|
} from "@milaboratories/pl-model-common";
|
|
23
|
+
import type { TreeNodeAccessor } from "./accessor";
|
|
22
24
|
|
|
23
25
|
export const StagingAccessorName = "staging";
|
|
24
26
|
export const MainAccessorName = "main";
|
|
@@ -26,6 +28,11 @@ export const MainAccessorName = "main";
|
|
|
26
28
|
export type AccessorHandle = Branded<string, "AccessorHandle">;
|
|
27
29
|
export type FutureHandle = Branded<string, "FutureHandle">;
|
|
28
30
|
|
|
31
|
+
export type PColumnDataUniversal<TreeEntry = TreeNodeAccessor> =
|
|
32
|
+
| TreeEntry
|
|
33
|
+
| DataInfo<TreeEntry>
|
|
34
|
+
| PColumnValues;
|
|
35
|
+
|
|
29
36
|
export interface GlobalCfgRenderCtxMethods<AHandle = AccessorHandle, FHandle = FutureHandle> {
|
|
30
37
|
//
|
|
31
38
|
// Root accessor creation
|
|
@@ -146,6 +153,10 @@ export interface GlobalCfgRenderCtxMethods<AHandle = AccessorHandle, FHandle = F
|
|
|
146
153
|
|
|
147
154
|
createPTable(def: PTableDef<PColumn<AHandle | PColumnValues | DataInfo<AHandle>>>): PTableHandle;
|
|
148
155
|
|
|
156
|
+
createPTableV2(
|
|
157
|
+
def: PTableDefV2<PColumn<AHandle | PColumnValues | DataInfo<AHandle>>>,
|
|
158
|
+
): PTableHandle;
|
|
159
|
+
|
|
149
160
|
//
|
|
150
161
|
// Computable
|
|
151
162
|
//
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
import canonicalize from "canonicalize";
|
|
34
34
|
import type { Optional } from "utility-types";
|
|
35
35
|
import type { TreeNodeAccessor } from "../accessor";
|
|
36
|
-
import type { PColumnDataUniversal } from "../
|
|
36
|
+
import type { PColumnDataUniversal } from "../internal";
|
|
37
37
|
import { filterDataInfoEntries } from "./axis_filtering";
|
|
38
38
|
import type { LabelDerivationOps, TraceEntry } from "./label";
|
|
39
39
|
import { deriveLabels } from "./label";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
type PColumnKey,
|
|
17
17
|
} from "@milaboratories/pl-model-common";
|
|
18
18
|
import { TreeNodeAccessor } from "../accessor";
|
|
19
|
-
import type { PColumnDataUniversal } from "../
|
|
19
|
+
import type { PColumnDataUniversal } from "../internal";
|
|
20
20
|
|
|
21
21
|
const PCD_PREFIX = "PColumnData/";
|
|
22
22
|
|