@milaboratories/pl-model-common 1.29.0 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bmodel/block_config.d.ts +1 -0
- package/dist/bmodel/code.d.ts +1 -0
- package/dist/driver_kit.d.ts +1 -1
- package/dist/drivers/index.d.ts +7 -7
- package/dist/drivers/index.js +2 -2
- package/dist/drivers/pframe/data_types.cjs +0 -15
- package/dist/drivers/pframe/data_types.cjs.map +1 -1
- package/dist/drivers/pframe/data_types.d.ts +14 -60
- package/dist/drivers/pframe/data_types.js +1 -13
- package/dist/drivers/pframe/data_types.js.map +1 -1
- package/dist/drivers/pframe/driver.cjs.map +1 -1
- package/dist/drivers/pframe/driver.d.ts +13 -5
- package/dist/drivers/pframe/driver.js.map +1 -1
- package/dist/drivers/pframe/index.d.ts +6 -6
- package/dist/drivers/pframe/index.js +2 -2
- package/dist/drivers/pframe/pframe.d.ts +2 -2
- package/dist/drivers/pframe/query/query_common.d.ts +2 -2
- package/dist/drivers/pframe/query/query_data.d.ts +1 -1
- package/dist/drivers/pframe/query/query_spec.d.ts +2 -2
- package/dist/drivers/pframe/spec/ids.d.ts +2 -2
- package/dist/drivers/pframe/spec/index.d.ts +1 -1
- package/dist/drivers/pframe/spec/index.js +1 -1
- package/dist/drivers/pframe/spec/selectors.d.ts +1 -1
- package/dist/drivers/pframe/spec/spec.cjs +14 -1
- package/dist/drivers/pframe/spec/spec.cjs.map +1 -1
- package/dist/drivers/pframe/spec/spec.d.ts +7 -1
- package/dist/drivers/pframe/spec/spec.js +14 -2
- package/dist/drivers/pframe/spec/spec.js.map +1 -1
- package/dist/drivers/pframe/spec_driver.d.ts +36 -6
- package/dist/drivers/pframe/table_calculate.cjs.map +1 -1
- package/dist/drivers/pframe/table_calculate.d.ts +5 -6
- package/dist/drivers/pframe/table_calculate.js.map +1 -1
- package/dist/drivers/pframe/table_common.d.ts +1 -1
- package/dist/drivers/pframe/unique_values.d.ts +2 -2
- package/dist/errors.cjs +48 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +25 -1
- package/dist/errors.js +37 -1
- package/dist/errors.js.map +1 -1
- package/dist/flags/block_flags.cjs.map +1 -1
- package/dist/flags/block_flags.d.ts +4 -1
- package/dist/flags/block_flags.js.map +1 -1
- package/dist/flags/flag_utils.d.ts +1 -1
- package/dist/flags/index.d.ts +3 -0
- package/dist/index.cjs +38 -3
- package/dist/index.d.ts +31 -22
- package/dist/index.js +12 -4
- package/dist/pool/query.d.ts +1 -1
- package/dist/pool_entry.cjs +30 -0
- package/dist/pool_entry.cjs.map +1 -0
- package/dist/pool_entry.d.ts +30 -0
- package/dist/pool_entry.js +29 -0
- package/dist/pool_entry.js.map +1 -0
- package/dist/services/index.cjs +6 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.js +6 -0
- package/dist/services/service_capabilities.cjs +51 -0
- package/dist/services/service_capabilities.cjs.map +1 -0
- package/dist/services/service_capabilities.d.ts +33 -0
- package/dist/services/service_capabilities.js +46 -0
- package/dist/services/service_capabilities.js.map +1 -0
- package/dist/services/service_declarations.cjs +17 -0
- package/dist/services/service_declarations.cjs.map +1 -0
- package/dist/services/service_declarations.d.ts +16 -0
- package/dist/services/service_declarations.js +17 -0
- package/dist/services/service_declarations.js.map +1 -0
- package/dist/services/service_injector_factory.cjs +19 -0
- package/dist/services/service_injector_factory.cjs.map +1 -0
- package/dist/services/service_injector_factory.d.ts +8 -0
- package/dist/services/service_injector_factory.js +18 -0
- package/dist/services/service_injector_factory.js.map +1 -0
- package/dist/services/service_injectors.cjs +48 -0
- package/dist/services/service_injectors.cjs.map +1 -0
- package/dist/services/service_injectors.d.ts +23 -0
- package/dist/services/service_injectors.js +46 -0
- package/dist/services/service_injectors.js.map +1 -0
- package/dist/services/service_registry.cjs +52 -0
- package/dist/services/service_registry.cjs.map +1 -0
- package/dist/services/service_registry.d.ts +25 -0
- package/dist/services/service_registry.js +51 -0
- package/dist/services/service_registry.js.map +1 -0
- package/dist/services/service_types.cjs +30 -0
- package/dist/services/service_types.cjs.map +1 -0
- package/dist/services/service_types.d.ts +45 -0
- package/dist/services/service_types.js +28 -0
- package/dist/services/service_types.js.map +1 -0
- package/package.json +4 -4
- package/src/drivers/pframe/data_types.ts +18 -140
- package/src/drivers/pframe/driver.ts +11 -1
- package/src/drivers/pframe/spec/spec.ts +16 -2
- package/src/drivers/pframe/spec_driver.ts +37 -5
- package/src/drivers/pframe/table_calculate.ts +3 -4
- package/src/errors.ts +53 -0
- package/src/flags/block_flags.ts +5 -2
- package/src/index.ts +2 -0
- package/src/pool_entry.ts +42 -0
- package/src/services/index.ts +5 -0
- package/src/services/service_capabilities.test.ts +119 -0
- package/src/services/service_capabilities.ts +64 -0
- package/src/services/service_declarations.ts +25 -0
- package/src/services/service_injector_factory.ts +27 -0
- package/src/services/service_injectors.ts +79 -0
- package/src/services/service_registry.test.ts +69 -0
- package/src/services/service_registry.ts +94 -0
- package/src/services/service_types.ts +114 -0
|
@@ -26,7 +26,7 @@ export type PTableVectorTyped<DataType extends ValueType> = {
|
|
|
26
26
|
/** Stored data type */
|
|
27
27
|
readonly type: DataType;
|
|
28
28
|
|
|
29
|
-
/** Values for present positions
|
|
29
|
+
/** Values for present positions */
|
|
30
30
|
readonly data: PVectorDataTyped<DataType>;
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -36,15 +36,10 @@ export type PTableVectorTyped<DataType extends ValueType> = {
|
|
|
36
36
|
* */
|
|
37
37
|
readonly isNA?: Uint8Array;
|
|
38
38
|
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
* call {@link bitSet} to read the data.
|
|
42
|
-
* */
|
|
43
|
-
readonly absent: Uint8Array;
|
|
39
|
+
/** @deprecated Always empty. Kept for backwards compatibility with old blocks. */
|
|
40
|
+
readonly absent?: Uint8Array;
|
|
44
41
|
};
|
|
45
|
-
/** Table column data
|
|
46
|
-
* may have some of the values "absent", i.e. as a result of missing record in
|
|
47
|
-
* outer join operation. This information is encoded in {@link absent} field. */
|
|
42
|
+
/** Table column data */
|
|
48
43
|
export type PTableVector = PTableVectorTyped<ValueType>;
|
|
49
44
|
|
|
50
45
|
function isBitSet(bitVector: Uint8Array, offset: number): boolean {
|
|
@@ -53,10 +48,6 @@ function isBitSet(bitVector: Uint8Array, offset: number): boolean {
|
|
|
53
48
|
return (bitVector[chunkIndex] & mask) > 0;
|
|
54
49
|
}
|
|
55
50
|
|
|
56
|
-
function isValueAbsent(vector: PTableVector, row: number): boolean {
|
|
57
|
-
return isBitSet(vector.absent, row);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
51
|
function isValueNA(vector: PTableVector, row: number): boolean {
|
|
61
52
|
if (vector.isNA) return isBitSet(vector.isNA, row);
|
|
62
53
|
|
|
@@ -81,14 +72,6 @@ function isValueNA(vector: PTableVector, row: number): boolean {
|
|
|
81
72
|
}
|
|
82
73
|
}
|
|
83
74
|
|
|
84
|
-
export const PTableAbsent = { type: "absent" } as const;
|
|
85
|
-
export type PTableAbsent = typeof PTableAbsent;
|
|
86
|
-
|
|
87
|
-
/** Type guard for absent value */
|
|
88
|
-
export function isPTableAbsent(value: unknown): value is PTableAbsent {
|
|
89
|
-
return typeof value === "object" && value !== null && "type" in value && value.type === "absent";
|
|
90
|
-
}
|
|
91
|
-
|
|
92
75
|
export const PTableNA = null;
|
|
93
76
|
export type PTableNA = typeof PTableNA;
|
|
94
77
|
|
|
@@ -120,49 +103,21 @@ export type PTableValueDataBranded<DataType extends ValueTypeSupported> = Brande
|
|
|
120
103
|
PTableValueData<DataType>,
|
|
121
104
|
DataType
|
|
122
105
|
>;
|
|
123
|
-
export type PTableValue<
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
127
|
-
> = Absent | NA | PTableValueData<DataType>;
|
|
106
|
+
export type PTableValue<NA = PTableNA, DataType extends ValueTypeSupported = ValueTypeSupported> =
|
|
107
|
+
| NA
|
|
108
|
+
| PTableValueData<DataType>;
|
|
128
109
|
export type PTableValueBranded<
|
|
129
|
-
Absent = PTableAbsent,
|
|
130
110
|
NA = PTableNA,
|
|
131
111
|
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
132
|
-
> =
|
|
133
|
-
|
|
134
|
-
export type PTableValueAxis<
|
|
135
|
-
Absent = PTableAbsent,
|
|
136
|
-
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
137
|
-
> = PTableValue<Absent, never, DataType>;
|
|
112
|
+
> = NA | PTableValueDataBranded<DataType>;
|
|
138
113
|
|
|
139
|
-
export
|
|
140
|
-
|
|
141
|
-
isNA: (value: PTableValue<Absent, NA, DataType>) => value is NA,
|
|
142
|
-
): value is PTableValueAxis<Absent, DataType>;
|
|
143
|
-
export function isPTableValueAxis<Absent, DataType extends ValueTypeSupported>(
|
|
144
|
-
value: PTableValue<Absent, PTableNA, DataType>,
|
|
145
|
-
): value is PTableValueAxis<Absent, DataType>;
|
|
146
|
-
export function isPTableValueAxis<
|
|
147
|
-
Absent = PTableAbsent,
|
|
148
|
-
NA = PTableNA,
|
|
149
|
-
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
150
|
-
>(
|
|
151
|
-
value: PTableValue<Absent, NA, DataType>,
|
|
152
|
-
isNA?: (value: PTableValue<Absent, NA, DataType>) => value is NA,
|
|
153
|
-
): value is PTableValueAxis<Absent, DataType> {
|
|
154
|
-
return !(isNA ? isNA(value) : isPTableNA(value));
|
|
155
|
-
}
|
|
114
|
+
export type PTableValueAxis<DataType extends ValueTypeSupported = ValueTypeSupported> =
|
|
115
|
+
PTableValueData<DataType>;
|
|
156
116
|
|
|
157
|
-
function pTableValueImpl<
|
|
158
|
-
FillAbsent = PTableAbsent,
|
|
159
|
-
FillNA = PTableNA,
|
|
160
|
-
DataType extends ValueType = ValueTypeSupported,
|
|
161
|
-
>(
|
|
117
|
+
function pTableValueImpl<FillNA = PTableNA, DataType extends ValueType = ValueTypeSupported>(
|
|
162
118
|
column: PTableVectorTyped<ValueType>,
|
|
163
119
|
row: number,
|
|
164
120
|
options?: {
|
|
165
|
-
absent?: FillAbsent;
|
|
166
121
|
na?: FillNA;
|
|
167
122
|
dataType?: DataType;
|
|
168
123
|
},
|
|
@@ -181,10 +136,6 @@ function pTableValueImpl<
|
|
|
181
136
|
throw Error(`expected column of type ${options.dataType}, got ${valueType}`);
|
|
182
137
|
}
|
|
183
138
|
|
|
184
|
-
if (isValueAbsent(column, row)) {
|
|
185
|
-
return options?.absent !== undefined ? options.absent : PTableAbsent;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
139
|
if (isValueNA(column, row)) {
|
|
189
140
|
return options?.na !== undefined ? options.na : PTableNA;
|
|
190
141
|
}
|
|
@@ -208,37 +159,14 @@ function pTableValueImpl<
|
|
|
208
159
|
export function pTableValue<DataType extends ValueType>(
|
|
209
160
|
column: PTableVectorTyped<DataType>,
|
|
210
161
|
row: number,
|
|
211
|
-
): DataType extends ValueTypeSupported ? PTableValue<
|
|
212
|
-
export function pTableValue<FillAbsent, DataType extends ValueType>(
|
|
213
|
-
column: PTableVectorTyped<DataType>,
|
|
214
|
-
row: number,
|
|
215
|
-
options: {
|
|
216
|
-
absent: FillAbsent;
|
|
217
|
-
},
|
|
218
|
-
): DataType extends ValueTypeSupported ? PTableValue<FillAbsent, PTableNA, DataType> : never;
|
|
162
|
+
): DataType extends ValueTypeSupported ? PTableValue<PTableNA, DataType> : never;
|
|
219
163
|
export function pTableValue<FillNA, DataType extends ValueType>(
|
|
220
164
|
column: PTableVectorTyped<DataType>,
|
|
221
165
|
row: number,
|
|
222
166
|
options: {
|
|
223
167
|
na: FillNA;
|
|
224
168
|
},
|
|
225
|
-
): DataType extends ValueTypeSupported ? PTableValue<
|
|
226
|
-
export function pTableValue<FillNA, FillAbsent, DataType extends ValueType>(
|
|
227
|
-
column: PTableVectorTyped<DataType>,
|
|
228
|
-
row: number,
|
|
229
|
-
options: {
|
|
230
|
-
absent: FillAbsent;
|
|
231
|
-
na: FillNA;
|
|
232
|
-
},
|
|
233
|
-
): DataType extends ValueTypeSupported ? PTableValue<FillAbsent, FillNA, DataType> : never;
|
|
234
|
-
export function pTableValue<FillAbsent, DataType extends ValueTypeSupported>(
|
|
235
|
-
column: PTableVectorTyped<ValueType>,
|
|
236
|
-
row: number,
|
|
237
|
-
options: {
|
|
238
|
-
absent: FillAbsent;
|
|
239
|
-
dataType: DataType;
|
|
240
|
-
},
|
|
241
|
-
): PTableValue<FillAbsent, PTableNA>;
|
|
169
|
+
): DataType extends ValueTypeSupported ? PTableValue<FillNA, DataType> : never;
|
|
242
170
|
export function pTableValue<FillNA, DataType extends ValueTypeSupported>(
|
|
243
171
|
column: PTableVectorTyped<ValueType>,
|
|
244
172
|
row: number,
|
|
@@ -246,25 +174,11 @@ export function pTableValue<FillNA, DataType extends ValueTypeSupported>(
|
|
|
246
174
|
na: FillNA;
|
|
247
175
|
dataType: DataType;
|
|
248
176
|
},
|
|
249
|
-
): PTableValue<
|
|
250
|
-
export function pTableValue<FillNA
|
|
251
|
-
column: PTableVectorTyped<ValueType>,
|
|
252
|
-
row: number,
|
|
253
|
-
options: {
|
|
254
|
-
absent: FillAbsent;
|
|
255
|
-
na: FillNA;
|
|
256
|
-
dataType: DataType;
|
|
257
|
-
},
|
|
258
|
-
): PTableValue<FillAbsent, FillNA, DataType>;
|
|
259
|
-
export function pTableValue<
|
|
260
|
-
FillAbsent = PTableAbsent,
|
|
261
|
-
FillNA = PTableNA,
|
|
262
|
-
DataType extends ValueType = ValueTypeSupported,
|
|
263
|
-
>(
|
|
177
|
+
): PTableValue<FillNA, DataType>;
|
|
178
|
+
export function pTableValue<FillNA = PTableNA, DataType extends ValueType = ValueTypeSupported>(
|
|
264
179
|
column: PTableVectorTyped<ValueType>,
|
|
265
180
|
row: number,
|
|
266
181
|
options?: {
|
|
267
|
-
absent?: FillAbsent;
|
|
268
182
|
na?: FillNA;
|
|
269
183
|
dataType?: DataType;
|
|
270
184
|
},
|
|
@@ -275,39 +189,14 @@ export function pTableValue<
|
|
|
275
189
|
export function pTableValueBranded<DataType extends ValueType>(
|
|
276
190
|
column: PTableVectorTyped<DataType>,
|
|
277
191
|
row: number,
|
|
278
|
-
): DataType extends ValueTypeSupported
|
|
279
|
-
? PTableValueBranded<PTableAbsent, PTableNA, DataType>
|
|
280
|
-
: never;
|
|
281
|
-
export function pTableValueBranded<FillAbsent, DataType extends ValueType>(
|
|
282
|
-
column: PTableVectorTyped<DataType>,
|
|
283
|
-
row: number,
|
|
284
|
-
options: {
|
|
285
|
-
absent: FillAbsent;
|
|
286
|
-
},
|
|
287
|
-
): DataType extends ValueTypeSupported ? PTableValueBranded<FillAbsent, PTableNA, DataType> : never;
|
|
192
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<PTableNA, DataType> : never;
|
|
288
193
|
export function pTableValueBranded<FillNA, DataType extends ValueType>(
|
|
289
194
|
column: PTableVectorTyped<DataType>,
|
|
290
195
|
row: number,
|
|
291
196
|
options: {
|
|
292
197
|
na: FillNA;
|
|
293
198
|
},
|
|
294
|
-
): DataType extends ValueTypeSupported ? PTableValueBranded<
|
|
295
|
-
export function pTableValueBranded<FillNA, FillAbsent, DataType extends ValueType>(
|
|
296
|
-
column: PTableVectorTyped<DataType>,
|
|
297
|
-
row: number,
|
|
298
|
-
options: {
|
|
299
|
-
absent: FillAbsent;
|
|
300
|
-
na: FillNA;
|
|
301
|
-
},
|
|
302
|
-
): DataType extends ValueTypeSupported ? PTableValueBranded<FillAbsent, FillNA, DataType> : never;
|
|
303
|
-
export function pTableValueBranded<FillAbsent, DataType extends ValueTypeSupported>(
|
|
304
|
-
column: PTableVectorTyped<ValueType>,
|
|
305
|
-
row: number,
|
|
306
|
-
options: {
|
|
307
|
-
absent: FillAbsent;
|
|
308
|
-
dataType: DataType;
|
|
309
|
-
},
|
|
310
|
-
): PTableValueBranded<FillAbsent, PTableNA>;
|
|
199
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<FillNA, DataType> : never;
|
|
311
200
|
export function pTableValueBranded<FillNA, DataType extends ValueTypeSupported>(
|
|
312
201
|
column: PTableVectorTyped<ValueType>,
|
|
313
202
|
row: number,
|
|
@@ -315,25 +204,14 @@ export function pTableValueBranded<FillNA, DataType extends ValueTypeSupported>(
|
|
|
315
204
|
na: FillNA;
|
|
316
205
|
dataType: DataType;
|
|
317
206
|
},
|
|
318
|
-
): PTableValueBranded<
|
|
319
|
-
export function pTableValueBranded<FillNA, FillAbsent, DataType extends ValueTypeSupported>(
|
|
320
|
-
column: PTableVectorTyped<ValueType>,
|
|
321
|
-
row: number,
|
|
322
|
-
options: {
|
|
323
|
-
absent: FillAbsent;
|
|
324
|
-
na: FillNA;
|
|
325
|
-
dataType: DataType;
|
|
326
|
-
},
|
|
327
|
-
): PTableValueBranded<FillAbsent, FillNA, DataType>;
|
|
207
|
+
): PTableValueBranded<FillNA, DataType>;
|
|
328
208
|
export function pTableValueBranded<
|
|
329
|
-
FillAbsent = PTableAbsent,
|
|
330
209
|
FillNA = PTableNA,
|
|
331
210
|
DataType extends ValueType = ValueTypeSupported,
|
|
332
211
|
>(
|
|
333
212
|
column: PTableVectorTyped<ValueType>,
|
|
334
213
|
row: number,
|
|
335
214
|
options?: {
|
|
336
|
-
absent?: FillAbsent;
|
|
337
215
|
na?: FillNA;
|
|
338
216
|
dataType?: DataType;
|
|
339
217
|
},
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Branded } from "../../branding";
|
|
2
2
|
import type { PTable } from "./table";
|
|
3
|
-
import type { PFrame } from "./pframe";
|
|
3
|
+
import type { PFrame, PFrameDef } from "./pframe";
|
|
4
|
+
import type { PColumn } from "./spec/spec";
|
|
5
|
+
import type { PColumnValues, DataInfo } from "./data_info";
|
|
6
|
+
import type { PTableDef, PTableDefV2 } from "./table_calculate";
|
|
4
7
|
import type { AddParameterToAllMethods } from "./type_util";
|
|
5
8
|
import type { PTableShape, PTableVector, TableRange } from "./data_types";
|
|
6
9
|
import type { FindColumnsRequest, FindColumnsResponse } from "./find_columns";
|
|
@@ -16,6 +19,13 @@ export type PFrameHandle = Branded<string, "PFrame">;
|
|
|
16
19
|
/** PFrame handle */
|
|
17
20
|
export type PTableHandle = Branded<string, "PTable">;
|
|
18
21
|
|
|
22
|
+
/** Model-side PFrame service — creates frames/tables from column definitions. */
|
|
23
|
+
export interface PFrameModelDriver<Col = PColumn<string | PColumnValues | DataInfo<string>>> {
|
|
24
|
+
createPFrame(def: PFrameDef<Col>): PFrameHandle;
|
|
25
|
+
createPTable(def: PTableDef<Col>): PTableHandle;
|
|
26
|
+
createPTableV2(def: PTableDefV2<Col>): PTableHandle;
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
/** Allows to access main data layer features of platforma */
|
|
20
30
|
export interface PFrameDriver {
|
|
21
31
|
//
|
|
@@ -508,8 +508,6 @@ export function getNormalizedAxesList(axes: AxisSpec[]): AxisSpecNormalized[] {
|
|
|
508
508
|
modifiedAxis.parentAxesSpec = parents.some((p) => p === undefined)
|
|
509
509
|
? []
|
|
510
510
|
: (parents as AxisSpecNormalized[]);
|
|
511
|
-
|
|
512
|
-
delete modifiedAxis.annotations?.[Annotation.Parents];
|
|
513
511
|
}
|
|
514
512
|
});
|
|
515
513
|
|
|
@@ -543,6 +541,22 @@ export function getDenormalizedAxesList(axesSpec: AxisSpecNormalized[]): AxisSpe
|
|
|
543
541
|
});
|
|
544
542
|
}
|
|
545
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Resolve annotation-based parents (`pl7.app/parents`) to numeric `parentAxes`
|
|
546
|
+
* on a column spec. Returns the spec unchanged if all axes already use numeric
|
|
547
|
+
* indices or have no parent annotations.
|
|
548
|
+
*/
|
|
549
|
+
export function resolveAnnotationParents(spec: PColumnSpec): PColumnSpec {
|
|
550
|
+
const hasAnnotationParents = spec.axesSpec.some(
|
|
551
|
+
(axis) => !!readAnnotationJson(axis, Annotation.Parents),
|
|
552
|
+
);
|
|
553
|
+
if (!hasAnnotationParents) return spec;
|
|
554
|
+
|
|
555
|
+
const normalized = getNormalizedAxesList(spec.axesSpec);
|
|
556
|
+
const denormalized = getDenormalizedAxesList(normalized);
|
|
557
|
+
return { ...spec, axesSpec: denormalized };
|
|
558
|
+
}
|
|
559
|
+
|
|
546
560
|
/** Common type representing spec for all the axes in a column */
|
|
547
561
|
export type AxesSpec = AxisSpec[];
|
|
548
562
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Branded } from "@milaboratories/helpers";
|
|
2
|
+
import type { PoolEntry } from "../../pool_entry";
|
|
2
3
|
import type {
|
|
3
4
|
AxisSpec,
|
|
4
5
|
AxesSpec,
|
|
@@ -10,6 +11,7 @@ import type {
|
|
|
10
11
|
ColumnValueType,
|
|
11
12
|
} from "./spec";
|
|
12
13
|
import type { PTableColumnId, PTableColumnSpec } from "./table_common";
|
|
14
|
+
import { DataQuery, SpecQuery } from "./query";
|
|
13
15
|
|
|
14
16
|
/** Matches a string value either exactly or by regex pattern */
|
|
15
17
|
export type StringMatcher =
|
|
@@ -144,6 +146,33 @@ export interface DiscoverColumnsResponse {
|
|
|
144
146
|
hits: DiscoverColumnsResponseHit[];
|
|
145
147
|
}
|
|
146
148
|
|
|
149
|
+
/** Request for deleting an entry from a given axes integration */
|
|
150
|
+
export interface DeleteColumnRequest {
|
|
151
|
+
/** Already integrated axes with qualifications */
|
|
152
|
+
axes: ColumnAxesWithQualifications[];
|
|
153
|
+
/** Zero based index of the entry to be deleted */
|
|
154
|
+
delete: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Response from delete column */
|
|
158
|
+
export interface DeleteColumnResponse {
|
|
159
|
+
axes: ColumnAxesWithQualifications[];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Response from evaluating a query against a PFrame. */
|
|
163
|
+
export type EvaluateQueryResponse = {
|
|
164
|
+
/**
|
|
165
|
+
* The table specification describing the structure of the query result,
|
|
166
|
+
* including all axes and columns that will be present in the output.
|
|
167
|
+
*/
|
|
168
|
+
tableSpec: PTableColumnSpec[];
|
|
169
|
+
/**
|
|
170
|
+
* The data layer query representation with numeric indices,
|
|
171
|
+
* suitable for execution by the data processing engine.
|
|
172
|
+
*/
|
|
173
|
+
dataQuery: DataQuery;
|
|
174
|
+
};
|
|
175
|
+
|
|
147
176
|
/** Handle to a spec-only PFrame (no data, synchronous operations). */
|
|
148
177
|
export type SpecFrameHandle = Branded<string, "SpecFrameHandle">;
|
|
149
178
|
|
|
@@ -155,17 +184,20 @@ export type SpecFrameHandle = Branded<string, "SpecFrameHandle">;
|
|
|
155
184
|
* because the underlying WASM PFrame computes results immediately.
|
|
156
185
|
*/
|
|
157
186
|
export interface PFrameSpecDriver {
|
|
158
|
-
/** Create a spec-only PFrame from column specs. Returns a handle. */
|
|
159
|
-
createSpecFrame(specs: Record<string, PColumnSpec>): SpecFrameHandle
|
|
187
|
+
/** Create a spec-only PFrame from column specs. Returns a pool entry with handle and unref. */
|
|
188
|
+
createSpecFrame(specs: Record<string, PColumnSpec>): PoolEntry<SpecFrameHandle>;
|
|
160
189
|
|
|
161
190
|
/** Discover columns compatible with given axes integration. */
|
|
162
|
-
|
|
191
|
+
discoverColumns(
|
|
163
192
|
handle: SpecFrameHandle,
|
|
164
193
|
request: DiscoverColumnsRequest,
|
|
165
194
|
): DiscoverColumnsResponse;
|
|
166
195
|
|
|
167
|
-
/**
|
|
168
|
-
|
|
196
|
+
/** Delete an entry from a given axes integration */
|
|
197
|
+
deleteColumn(handle: SpecFrameHandle, request: DeleteColumnRequest): DeleteColumnResponse;
|
|
198
|
+
|
|
199
|
+
/** Evaluates a query specification against this PFrame */
|
|
200
|
+
evaluateQuery(handle: SpecFrameHandle, request: SpecQuery): EvaluateQueryResponse;
|
|
169
201
|
|
|
170
202
|
/** Expand index-based parentAxes in AxesSpec to resolved AxisId parents in AxesId. */
|
|
171
203
|
expandAxes(spec: AxesSpec): AxesId;
|
|
@@ -85,8 +85,7 @@ export interface InnerJoin<Col> {
|
|
|
85
85
|
/**
|
|
86
86
|
* Defines a join request tree node that will output all records present at
|
|
87
87
|
* least in one of the child nodes ({@link entries}), values for those PColumns
|
|
88
|
-
* that
|
|
89
|
-
* see {@link PTableVector.absent}.
|
|
88
|
+
* that lack corresponding combinations of axis values will be null.
|
|
90
89
|
* */
|
|
91
90
|
export interface FullJoin<Col> {
|
|
92
91
|
/** Node type discriminator */
|
|
@@ -100,8 +99,8 @@ export interface FullJoin<Col> {
|
|
|
100
99
|
* Defines a join request tree node that will output all records present in
|
|
101
100
|
* {@link primary} child node, and records from the {@link secondary} nodes will
|
|
102
101
|
* be added to the output only if present, values for those PColumns from the
|
|
103
|
-
* {@link secondary} list, that
|
|
104
|
-
* will be
|
|
102
|
+
* {@link secondary} list, that lack corresponding combinations of axis values
|
|
103
|
+
* will be null.
|
|
105
104
|
*
|
|
106
105
|
* This node can be thought as a chain of SQL LEFT JOIN operations starting from
|
|
107
106
|
* the {@link primary} node and adding {@link secondary} nodes one by one.
|
package/src/errors.ts
CHANGED
|
@@ -28,6 +28,59 @@ export function isAggregateError(error: unknown): error is AggregateError {
|
|
|
28
28
|
return error instanceof Error && error.name === "AggregateError";
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export class ServiceError extends Error {
|
|
32
|
+
name = "ServiceError";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isServiceError(error: unknown): error is ServiceError {
|
|
36
|
+
return (
|
|
37
|
+
error instanceof Error &&
|
|
38
|
+
(error.name === "ServiceError" || error.name.startsWith("ServiceError."))
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class ServiceInvalidIdError extends ServiceError {
|
|
43
|
+
name = "ServiceError.InvalidId";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function isServiceInvalidIdError(error: unknown): error is ServiceInvalidIdError {
|
|
47
|
+
return error instanceof Error && error.name === "ServiceError.InvalidId";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class ServiceAlreadyRegisteredError extends ServiceError {
|
|
51
|
+
name = "ServiceError.AlreadyRegistered";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isServiceAlreadyRegisteredError(
|
|
55
|
+
error: unknown,
|
|
56
|
+
): error is ServiceAlreadyRegisteredError {
|
|
57
|
+
return error instanceof Error && error.name === "ServiceError.AlreadyRegistered";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class ServiceInjectionError extends ServiceError {
|
|
61
|
+
name = "ServiceError.Injection";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function isServiceInjectionError(error: unknown): error is ServiceInjectionError {
|
|
65
|
+
return error instanceof Error && error.name === "ServiceError.Injection";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class ServiceNotRegisteredError extends ServiceError {
|
|
69
|
+
name = "ServiceError.NotRegistered";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function isServiceNotRegisteredError(error: unknown): error is ServiceNotRegisteredError {
|
|
73
|
+
return error instanceof Error && error.name === "ServiceError.NotRegistered";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export class ServiceMethodNotFoundError extends ServiceError {
|
|
77
|
+
name = "ServiceError.MethodNotFound";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function isServiceMethodNotFoundError(error: unknown): error is ServiceMethodNotFoundError {
|
|
81
|
+
return error instanceof Error && error.name === "ServiceError.MethodNotFound";
|
|
82
|
+
}
|
|
83
|
+
|
|
31
84
|
export class PFrameError extends Error {
|
|
32
85
|
name = "PFrameError";
|
|
33
86
|
}
|
package/src/flags/block_flags.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ServiceRequireFlags } from "../services";
|
|
1
2
|
import type { ArrayTypeUnion, Assert, Is, IsSubtypeOf } from "./type_utils";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -20,7 +21,7 @@ export type BlockCodeKnownFeatureFlags = {
|
|
|
20
21
|
readonly requiresModelAPIVersion?: number;
|
|
21
22
|
readonly requiresUIAPIVersion?: number;
|
|
22
23
|
readonly requiresCreatePTable?: number;
|
|
23
|
-
};
|
|
24
|
+
} & ServiceRequireFlags;
|
|
24
25
|
|
|
25
26
|
export const AllSupportsFeatureFlags = ["supportsLazyState", "supportsPframeQueryRanking"] as const;
|
|
26
27
|
|
|
@@ -42,9 +43,11 @@ type _KnownFlagsAreValidFlags = Assert<
|
|
|
42
43
|
|
|
43
44
|
// This check ensures that all keys in BlockConfigV3FeatureFlags are covered in the arrays above.
|
|
44
45
|
// It will produce a compile-time error if there's a mismatch.
|
|
46
|
+
// Adding a service to Services automatically satisfies this assertion via ServiceRequireFlags.
|
|
45
47
|
type _AllFlagsAreCovered = Assert<
|
|
46
48
|
Is<
|
|
47
49
|
keyof BlockCodeKnownFeatureFlags,
|
|
48
|
-
ArrayTypeUnion<typeof AllRequiresFeatureFlags, typeof AllSupportsFeatureFlags>
|
|
50
|
+
| ArrayTypeUnion<typeof AllRequiresFeatureFlags, typeof AllSupportsFeatureFlags>
|
|
51
|
+
| keyof ServiceRequireFlags
|
|
49
52
|
>
|
|
50
53
|
>;
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface PoolEntry<K extends string = string, R extends {} = {}> extends Disposable {
|
|
2
|
+
/** Resource key, calculated using provided `calculateParamsKey` function */
|
|
3
|
+
readonly key: K;
|
|
4
|
+
|
|
5
|
+
/** Resource itself created by `createNewResource` function */
|
|
6
|
+
readonly resource: R;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Release the reference. Idempotent.
|
|
10
|
+
* Same as `[Symbol.dispose]()` — provided as a named function
|
|
11
|
+
* for use in callbacks (e.g. `addOnDestroy(entry.unref)`).
|
|
12
|
+
*/
|
|
13
|
+
readonly unref: () => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Wraps a PoolEntry for use with `using`. Auto-calls `unref()` at end of scope
|
|
18
|
+
* unless `keep()` is called to transfer ownership to the caller.
|
|
19
|
+
*/
|
|
20
|
+
export class PoolEntryGuard<K extends string = string, R extends {} = {}> implements Disposable {
|
|
21
|
+
private kept = false;
|
|
22
|
+
|
|
23
|
+
constructor(readonly entry: PoolEntry<K, R>) {}
|
|
24
|
+
|
|
25
|
+
get key(): K {
|
|
26
|
+
return this.entry.key;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get resource(): R {
|
|
30
|
+
return this.entry.resource;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Disarm the guard — caller takes ownership of the entry. */
|
|
34
|
+
keep(): PoolEntry<K, R> {
|
|
35
|
+
this.kept = true;
|
|
36
|
+
return this.entry;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[Symbol.dispose](): void {
|
|
40
|
+
if (!this.kept) this.entry.unref();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
SERVICE_CAPABILITY_FLAGS,
|
|
4
|
+
registerServiceCapabilities,
|
|
5
|
+
resolveRequiredServices,
|
|
6
|
+
getMethodNames,
|
|
7
|
+
isKnownServiceName,
|
|
8
|
+
} from "./service_capabilities";
|
|
9
|
+
import { Services } from "./service_declarations";
|
|
10
|
+
|
|
11
|
+
describe("SERVICE_CAPABILITY_FLAGS", () => {
|
|
12
|
+
it("should have one flag per service", () => {
|
|
13
|
+
expect(SERVICE_CAPABILITY_FLAGS).toHaveLength(Object.keys(Services).length);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should derive requires* flag names from Services keys", () => {
|
|
17
|
+
for (const key of Object.keys(Services)) {
|
|
18
|
+
expect(SERVICE_CAPABILITY_FLAGS).toContain(`requires${key}`);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("registerServiceCapabilities", () => {
|
|
24
|
+
it("should call register once per service with (flag, true)", () => {
|
|
25
|
+
const register = vi.fn();
|
|
26
|
+
registerServiceCapabilities(register);
|
|
27
|
+
expect(register).toHaveBeenCalledTimes(Object.keys(Services).length);
|
|
28
|
+
for (const call of register.mock.calls) {
|
|
29
|
+
expect(call[0]).toMatch(/^requires[A-Z]/);
|
|
30
|
+
expect(call[1]).toBe(true);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("resolveRequiredServices", () => {
|
|
36
|
+
it("should return empty array for undefined flags", () => {
|
|
37
|
+
expect(resolveRequiredServices(undefined)).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should return empty array for flags without requires*", () => {
|
|
41
|
+
expect(resolveRequiredServices({ supportsLazyState: true })).toEqual([]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should return empty array when requires* is false", () => {
|
|
45
|
+
expect(resolveRequiredServices({ requiresPFrameSpec: false })).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("should resolve a single required service", () => {
|
|
49
|
+
const result = resolveRequiredServices({ requiresPFrameSpec: true });
|
|
50
|
+
expect(result).toEqual([Services.PFrameSpec]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should resolve multiple required services", () => {
|
|
54
|
+
const result = resolveRequiredServices({
|
|
55
|
+
requiresPFrameSpec: true,
|
|
56
|
+
requiresPFrame: true,
|
|
57
|
+
});
|
|
58
|
+
expect(result).toContain(Services.PFrameSpec);
|
|
59
|
+
expect(result).toContain(Services.PFrame);
|
|
60
|
+
expect(result).toHaveLength(2);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should ignore non-boolean requires* values", () => {
|
|
64
|
+
const result = resolveRequiredServices({
|
|
65
|
+
requiresPFrameSpec: true,
|
|
66
|
+
requiresModelAPIVersion: 2,
|
|
67
|
+
});
|
|
68
|
+
expect(result).toEqual([Services.PFrameSpec]);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("isKnownServiceName", () => {
|
|
73
|
+
it("should return true for registered service names", () => {
|
|
74
|
+
for (const id of Object.values(Services)) {
|
|
75
|
+
expect(isKnownServiceName(id as string)).toBe(true);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should return false for unknown names", () => {
|
|
80
|
+
expect(isKnownServiceName("nonexistent")).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe("getMethodNames", () => {
|
|
85
|
+
it("should return own method names", () => {
|
|
86
|
+
const obj = {
|
|
87
|
+
foo() {},
|
|
88
|
+
bar() {},
|
|
89
|
+
baz: 42,
|
|
90
|
+
};
|
|
91
|
+
const names = getMethodNames(obj as any);
|
|
92
|
+
expect(names).toContain("foo");
|
|
93
|
+
expect(names).toContain("bar");
|
|
94
|
+
expect(names).not.toContain("baz");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("should include prototype methods", () => {
|
|
98
|
+
class Base {
|
|
99
|
+
baseMethod() {}
|
|
100
|
+
}
|
|
101
|
+
class Child extends Base {
|
|
102
|
+
childMethod() {}
|
|
103
|
+
}
|
|
104
|
+
const names = getMethodNames(new Child() as any);
|
|
105
|
+
expect(names).toContain("baseMethod");
|
|
106
|
+
expect(names).toContain("childMethod");
|
|
107
|
+
expect(names).not.toContain("constructor");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should not include getters", () => {
|
|
111
|
+
const obj = Object.create(null, {
|
|
112
|
+
method: { value: () => {}, enumerable: true },
|
|
113
|
+
getter: { get: () => 42, enumerable: true },
|
|
114
|
+
});
|
|
115
|
+
const names = getMethodNames(obj);
|
|
116
|
+
expect(names).toContain("method");
|
|
117
|
+
expect(names).not.toContain("getter");
|
|
118
|
+
});
|
|
119
|
+
});
|