@milaboratories/pl-model-common 1.19.0 → 1.19.2
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/drivers/pframe/data_info.d.ts +51 -0
- package/dist/drivers/pframe/data_info.d.ts.map +1 -1
- package/dist/drivers/pframe/data_types.d.ts +86 -82
- package/dist/drivers/pframe/data_types.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/anchored.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/filtered_column.d.ts +4 -3
- package/dist/drivers/pframe/spec/filtered_column.d.ts.map +1 -1
- package/dist/drivers/pframe/spec/spec.d.ts +7 -1
- package/dist/drivers/pframe/spec/spec.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +474 -546
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/drivers/pframe/data_info.ts +64 -0
- package/src/drivers/pframe/data_types.ts +278 -244
- package/src/drivers/pframe/spec/anchored.ts +2 -3
- package/src/drivers/pframe/spec/filtered_column.ts +5 -3
- package/src/drivers/pframe/spec/spec.ts +14 -1
package/package.json
CHANGED
|
@@ -85,6 +85,70 @@ export type BinaryPartitionedDataInfo<Blob> = {
|
|
|
85
85
|
parts: Record<string, BinaryChunk<Blob>>;
|
|
86
86
|
};
|
|
87
87
|
|
|
88
|
+
type ParquetPartitionInfoMappingAxis = {
|
|
89
|
+
/** Data type (matches PColumn axis types) */
|
|
90
|
+
type: 'Int' | 'Long' | 'String';
|
|
91
|
+
|
|
92
|
+
/** Field name in the Parquet file */
|
|
93
|
+
id: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
type ParquetPartitionInfoMappingColumn = {
|
|
97
|
+
/** Data type (matches PColumn value type) */
|
|
98
|
+
type: 'Int' | 'Long' | 'Float' | 'Double' | 'String';
|
|
99
|
+
|
|
100
|
+
/** Field name in the Parquet file */
|
|
101
|
+
id: string;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
type ParquetPartitionInfoMapping = {
|
|
105
|
+
/** Axes mappings - Parquet file is sorted by these fields in this order */
|
|
106
|
+
axes: ParquetPartitionInfoMappingAxis[];
|
|
107
|
+
|
|
108
|
+
/** Column mapping */
|
|
109
|
+
column: ParquetPartitionInfoMappingColumn;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
type ParquetPartitionInfoData<Blob> = {
|
|
113
|
+
/** Parquet file (PTable) containing column data */
|
|
114
|
+
data: Blob;
|
|
115
|
+
|
|
116
|
+
/** Content hash calculated for the specific axes and data this partition represents */
|
|
117
|
+
dataDigest?: string;
|
|
118
|
+
|
|
119
|
+
/** Pre-computed statistics for optimization without blob download */
|
|
120
|
+
stats?: {
|
|
121
|
+
/** Number of rows in the column */
|
|
122
|
+
numberOfRows?: number;
|
|
123
|
+
/** Byte size information for storage optimization and query planning */
|
|
124
|
+
numberOfBytes?: {
|
|
125
|
+
/** Byte sizes for each axis column in the same order as axes mapping */
|
|
126
|
+
axes: number[];
|
|
127
|
+
/** Byte size for the data column */
|
|
128
|
+
column: number;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export type ParquetChunk<Blob> = {
|
|
134
|
+
/** Mapping of column names to their data */
|
|
135
|
+
mapping: ParquetPartitionInfoMapping;
|
|
136
|
+
|
|
137
|
+
/** Data for this partition */
|
|
138
|
+
data: ParquetPartitionInfoData<Blob>;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export type ParquetPartitionedDataInfo<Blob> = {
|
|
142
|
+
/** Identifier for this data format ('ParquetPartitioned') */
|
|
143
|
+
type: 'ParquetPartitioned';
|
|
144
|
+
|
|
145
|
+
/** Number of leading axes used for partitioning */
|
|
146
|
+
partitionKeyLength: number;
|
|
147
|
+
|
|
148
|
+
/** Map of stringified partition keys to parquet files */
|
|
149
|
+
parts: Record<string, ParquetChunk<Blob>>;
|
|
150
|
+
};
|
|
151
|
+
|
|
88
152
|
/**
|
|
89
153
|
* Union type representing all possible data storage formats for PColumn data.
|
|
90
154
|
* The specific format used depends on data size, access patterns, and performance requirements.
|
|
@@ -1,277 +1,180 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Branded } from '../../branding';
|
|
2
|
+
import {
|
|
3
|
+
type ValueType,
|
|
4
|
+
type ValueTypeBytes,
|
|
5
|
+
} from './spec/spec';
|
|
2
6
|
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
export type PVectorDataInt = Int32Array;
|
|
8
|
+
export type PVectorDataLong = BigInt64Array;
|
|
9
|
+
export type PVectorDataFloat = Float32Array;
|
|
10
|
+
export type PVectorDataDouble = Float64Array;
|
|
11
|
+
export type PVectorDataString = (null | string)[];
|
|
12
|
+
export type PVectorDataBytes = (null | Uint8Array)[];
|
|
13
|
+
export type PVectorDataTyped<DataType extends ValueType> =
|
|
14
|
+
DataType extends 'Int' ? PVectorDataInt :
|
|
15
|
+
DataType extends 'Long' ? PVectorDataLong :
|
|
16
|
+
DataType extends 'Float' ? PVectorDataFloat :
|
|
17
|
+
DataType extends 'Double' ? PVectorDataDouble :
|
|
18
|
+
DataType extends 'String' ? PVectorDataString :
|
|
19
|
+
DataType extends 'Bytes' ? PVectorDataBytes :
|
|
20
|
+
never;
|
|
21
|
+
export type PVectorData = PVectorDataTyped<ValueType>;
|
|
22
|
+
|
|
23
|
+
export type PTableVectorTyped<DataType extends ValueType> = {
|
|
24
|
+
/** Stored data type */
|
|
25
|
+
readonly type: DataType;
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export type NotNAPValueFloat = number;
|
|
20
|
-
export type NotNAPValueDouble = number;
|
|
21
|
-
export type NotNAPValueString = string;
|
|
27
|
+
/** Values for present positions, absent positions have NA values */
|
|
28
|
+
readonly data: PVectorDataTyped<DataType>;
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Encoded bit array marking some elements of this vector as NA,
|
|
32
|
+
* call {@link bitSet} to read the data.
|
|
33
|
+
* In old desktop versions NA values are encoded as magic values in data array.
|
|
34
|
+
* */
|
|
35
|
+
readonly isNA?: Uint8Array;
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Encoded bit array marking some elements of this vector as absent,
|
|
39
|
+
* call {@link bitSet} to read the data.
|
|
40
|
+
* */
|
|
41
|
+
readonly absent: Uint8Array;
|
|
42
|
+
};
|
|
43
|
+
/** Table column data in comparison to the data stored in a separate PColumn
|
|
44
|
+
* may have some of the values "absent", i.e. as a result of missing record in
|
|
45
|
+
* outer join operation. This information is encoded in {@link absent} field. */
|
|
46
|
+
export type PTableVector = PTableVectorTyped<ValueType>;
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
case 'Long':
|
|
39
|
-
return value === Number(PValueLongNA) || value === PValueLongNA;
|
|
40
|
-
case 'Float':
|
|
41
|
-
return Number.isNaN(value);
|
|
42
|
-
case 'Double':
|
|
43
|
-
return Number.isNaN(value);
|
|
44
|
-
case 'String':
|
|
45
|
-
return value === PValueStringNA;
|
|
46
|
-
case 'Bytes':
|
|
47
|
-
return value === PValueBytesNA;
|
|
48
|
-
default:
|
|
49
|
-
throw Error(`unsupported data type: ${valueType satisfies never}`);
|
|
50
|
-
}
|
|
48
|
+
function isBitSet(bitVector: Uint8Array, offset: number): boolean {
|
|
49
|
+
const chunkIndex = Math.floor(offset / 8);
|
|
50
|
+
const mask = 1 << (7 - (offset % 8));
|
|
51
|
+
return (bitVector[chunkIndex] & mask) > 0;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
export function ensureNotNAPValue(value: bigint): bigint;
|
|
56
|
-
export function ensureNotNAPValue(value: unknown): NotNAPValue;
|
|
57
|
-
export function ensureNotNAPValue(value: unknown): NotNAPValue {
|
|
58
|
-
if (!isNotNAPValue(value)) throw new Error(`Expected not-NA PValue, got ${value}`);
|
|
59
|
-
return value;
|
|
54
|
+
function isValueAbsent(vector: PTableVector, row: number): boolean {
|
|
55
|
+
return isBitSet(vector.absent, row);
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
export function isNotNAPValue(value: unknown, valueType: 'Float'): value is number;
|
|
65
|
-
export function isNotNAPValue(value: unknown, valueType: 'Double'): value is number;
|
|
66
|
-
export function isNotNAPValue(value: unknown, valueType: 'String'): value is string;
|
|
67
|
-
export function isNotNAPValue(value: unknown, valueType: ValueType): value is NotNAPValue;
|
|
68
|
-
export function isNotNAPValue(value: unknown): value is NotNAPValue;
|
|
69
|
-
export function isNotNAPValue(value: unknown, valueType?: ValueType): boolean {
|
|
70
|
-
if (!valueType)
|
|
71
|
-
return (
|
|
72
|
-
typeof value === 'string'
|
|
73
|
-
|| (typeof value === 'number' && isFinite(value))
|
|
74
|
-
|| typeof value === 'bigint'
|
|
75
|
-
);
|
|
76
|
-
if (isValueNA(value, valueType)) return false;
|
|
77
|
-
switch (valueType) {
|
|
78
|
-
case 'Int':
|
|
79
|
-
return typeof value === 'number';
|
|
80
|
-
case 'Long':
|
|
81
|
-
return typeof value === 'number' || typeof value === 'bigint';
|
|
82
|
-
case 'Float':
|
|
83
|
-
return typeof value === 'number';
|
|
84
|
-
case 'Double':
|
|
85
|
-
return typeof value === 'number';
|
|
86
|
-
case 'String':
|
|
87
|
-
return typeof value === 'string';
|
|
88
|
-
case 'Bytes':
|
|
89
|
-
throw Error(`Bytes not yet supported`);
|
|
90
|
-
default:
|
|
91
|
-
throw Error(`unsupported data type: ${valueType satisfies never}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
58
|
+
function isValueNA(vector: PTableVector, row: number): boolean {
|
|
59
|
+
if (vector.isNA) return isBitSet(vector.isNA, row);
|
|
94
60
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
export function isPValue(value: unknown, valueType: 'Double'): value is PValueDouble;
|
|
99
|
-
export function isPValue(value: unknown, valueType: 'String'): value is PValueString;
|
|
100
|
-
export function isPValue(value: unknown, valueType: ValueType): value is PValue;
|
|
101
|
-
export function isPValue(value: unknown): value is PValue;
|
|
102
|
-
export function isPValue(value: unknown, valueType?: ValueType): boolean {
|
|
103
|
-
if (!valueType)
|
|
104
|
-
return (
|
|
105
|
-
value === null
|
|
106
|
-
|| typeof value === 'string'
|
|
107
|
-
|| typeof value === 'number'
|
|
108
|
-
|| typeof value === 'bigint'
|
|
109
|
-
);
|
|
110
|
-
if (isValueNA(value, valueType)) return true;
|
|
61
|
+
// Check for legacy magic values to support old desktop versions
|
|
62
|
+
const valueType = vector.type;
|
|
63
|
+
const value = vector.data[row];
|
|
111
64
|
switch (valueType) {
|
|
112
65
|
case 'Int':
|
|
113
|
-
return
|
|
66
|
+
return (value as PVectorDataInt[number]) === -2147483648;
|
|
114
67
|
case 'Long':
|
|
115
|
-
return
|
|
68
|
+
return (value as PVectorDataLong[number]) === -9007199254740991n;
|
|
116
69
|
case 'Float':
|
|
117
|
-
return
|
|
70
|
+
return Number.isNaN((value as PVectorDataFloat[number]));
|
|
118
71
|
case 'Double':
|
|
119
|
-
return
|
|
72
|
+
return Number.isNaN((value as PVectorDataDouble[number]));
|
|
120
73
|
case 'String':
|
|
121
|
-
return
|
|
74
|
+
return (value as PVectorDataString[number]) === null;
|
|
122
75
|
case 'Bytes':
|
|
123
|
-
|
|
76
|
+
return (value as PVectorDataBytes[number]) === null;
|
|
124
77
|
default:
|
|
125
78
|
throw Error(`unsupported data type: ${valueType satisfies never}`);
|
|
126
79
|
}
|
|
127
80
|
}
|
|
128
81
|
|
|
129
|
-
export
|
|
130
|
-
export type
|
|
82
|
+
export const PTableAbsent = { type: 'absent' } as const;
|
|
83
|
+
export type PTableAbsent = typeof PTableAbsent;
|
|
131
84
|
|
|
132
|
-
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
* PValue representation.
|
|
136
|
-
*/
|
|
137
|
-
export function toJsonSafePValue(value: PValue): PValueJsonSafe {
|
|
138
|
-
if (value === null || typeof value === 'string' || typeof value === 'number') return value;
|
|
139
|
-
if (typeof value === 'bigint') return { bigint: value.toString() };
|
|
140
|
-
throw new Error(`Type ${typeof value} (value ${value}) not yet supported.`);
|
|
85
|
+
/** Type guard for absent value */
|
|
86
|
+
export function isPTableAbsent(value: unknown): value is PTableAbsent {
|
|
87
|
+
return typeof value === 'object' && value !== null && 'type' in value && value.type === 'absent';
|
|
141
88
|
}
|
|
142
89
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
* safely cast any unknown value to actual runtime PValue representation.
|
|
146
|
-
*/
|
|
147
|
-
export function safeConvertToPValue(value: unknown, checkType?: ValueType): PValue {
|
|
148
|
-
if (
|
|
149
|
-
value === null
|
|
150
|
-
|| typeof value === 'string'
|
|
151
|
-
|| typeof value === 'number'
|
|
152
|
-
|| typeof value === 'bigint'
|
|
153
|
-
) {
|
|
154
|
-
if (checkType && !isValueNA(value, checkType) && !isPValue(value, checkType))
|
|
155
|
-
throw new Error(`Unexpected value type, got ${typeof value}, expected ${checkType}`);
|
|
156
|
-
return value;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (
|
|
160
|
-
typeof value === 'object'
|
|
161
|
-
&& value !== null
|
|
162
|
-
&& 'bigint' in value
|
|
163
|
-
&& typeof value.bigint === 'string'
|
|
164
|
-
) {
|
|
165
|
-
if (checkType && checkType !== 'Long')
|
|
166
|
-
throw new Error(`Unexpected value type, got serialized bigint, expected ${checkType}`);
|
|
167
|
-
|
|
168
|
-
return BigInt(value.bigint);
|
|
169
|
-
}
|
|
90
|
+
export const PTableNA = null;
|
|
91
|
+
export type PTableNA = typeof PTableNA;
|
|
170
92
|
|
|
171
|
-
|
|
93
|
+
/** Type guard for NA value */
|
|
94
|
+
export function isPTableNA(value: unknown): value is PTableNA {
|
|
95
|
+
return value === PTableNA;
|
|
172
96
|
}
|
|
173
97
|
|
|
174
|
-
export
|
|
175
|
-
|
|
176
|
-
export
|
|
177
|
-
export
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
98
|
+
export type ValueTypeSupported = Exclude<ValueType, ValueTypeBytes>;
|
|
99
|
+
|
|
100
|
+
export type PTableValueInt = number;
|
|
101
|
+
export type PTableValueLong = number;
|
|
102
|
+
export type PTableValueFloat = number;
|
|
103
|
+
export type PTableValueDouble = number;
|
|
104
|
+
export type PTableValueString = string;
|
|
105
|
+
export type PTableValueData<DataType extends ValueTypeSupported> =
|
|
106
|
+
DataType extends 'Int' ? PTableValueInt :
|
|
107
|
+
DataType extends 'Long' ? PTableValueLong :
|
|
108
|
+
DataType extends 'Float' ? PTableValueFloat :
|
|
109
|
+
DataType extends 'Double' ? PTableValueDouble :
|
|
110
|
+
DataType extends 'String' ? PTableValueString :
|
|
111
|
+
never;
|
|
112
|
+
export type PTableValueDataBranded<DataType extends ValueTypeSupported> = Branded<PTableValueData<DataType>, DataType>;
|
|
113
|
+
export type PTableValue<
|
|
114
|
+
Absent = PTableAbsent,
|
|
115
|
+
NA = PTableNA,
|
|
116
|
+
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
117
|
+
> = Absent | NA | PTableValueData<DataType>;
|
|
118
|
+
export type PTableValueBranded<
|
|
119
|
+
Absent = PTableAbsent,
|
|
120
|
+
NA = PTableNA,
|
|
121
|
+
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
122
|
+
> = Absent | NA | PTableValueDataBranded<DataType>;
|
|
123
|
+
|
|
124
|
+
export type PTableValueAxis<
|
|
125
|
+
Absent = PTableAbsent,
|
|
126
|
+
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
127
|
+
> = PTableValue<Absent, never, DataType>;
|
|
128
|
+
|
|
129
|
+
export function isPTableValueAxis<Absent, NA, DataType extends ValueTypeSupported>(
|
|
130
|
+
value: PTableValue<Absent, NA, DataType>,
|
|
131
|
+
isNA: (value: PTableValue<Absent, NA, DataType>) => value is NA,
|
|
132
|
+
): value is PTableValueAxis<Absent, DataType>;
|
|
133
|
+
export function isPTableValueAxis<Absent, DataType extends ValueTypeSupported>(
|
|
134
|
+
value: PTableValue<Absent, PTableNA, DataType>,
|
|
135
|
+
): value is PTableValueAxis<Absent, DataType>;
|
|
136
|
+
export function isPTableValueAxis<
|
|
137
|
+
Absent = PTableAbsent,
|
|
138
|
+
NA = PTableNA,
|
|
139
|
+
DataType extends ValueTypeSupported = ValueTypeSupported,
|
|
140
|
+
>(
|
|
141
|
+
value: PTableValue<Absent, NA, DataType>,
|
|
142
|
+
isNA?: (value: PTableValue<Absent, NA, DataType>) => value is NA,
|
|
143
|
+
): value is PTableValueAxis<Absent, DataType> {
|
|
144
|
+
return !(isNA ? isNA(value) : isPTableNA(value));
|
|
181
145
|
}
|
|
182
146
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
// @TODO add range check
|
|
200
|
-
return Number(value);
|
|
147
|
+
function pTableValueImpl<
|
|
148
|
+
FillAbsent = PTableAbsent,
|
|
149
|
+
FillNA = PTableNA,
|
|
150
|
+
DataType extends ValueType = ValueTypeSupported,
|
|
151
|
+
>(
|
|
152
|
+
column: PTableVectorTyped<ValueType>,
|
|
153
|
+
row: number,
|
|
154
|
+
options?: {
|
|
155
|
+
absent?: FillAbsent;
|
|
156
|
+
na?: FillNA;
|
|
157
|
+
dataType?: DataType;
|
|
158
|
+
},
|
|
159
|
+
) {
|
|
160
|
+
const valueType: ValueType = column.type;
|
|
161
|
+
if (valueType === 'Bytes') {
|
|
162
|
+
throw Error('Bytes not yet supported');
|
|
201
163
|
}
|
|
202
|
-
throw new Error(`Unexpected value type: ${typeof value}`);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export type PVectorDataInt = Int32Array;
|
|
206
|
-
export type PVectorDataLong = BigInt64Array;
|
|
207
|
-
export type PVectorDataFloat = Float32Array;
|
|
208
|
-
export type PVectorDataDouble = Float64Array;
|
|
209
|
-
export type PVectorDataString = PValueString[];
|
|
210
|
-
export type PVectorDataBytes = PValueBytes[];
|
|
211
|
-
|
|
212
|
-
export type PVectorData =
|
|
213
|
-
| PVectorDataInt
|
|
214
|
-
| PVectorDataLong
|
|
215
|
-
| PVectorDataFloat
|
|
216
|
-
| PVectorDataDouble
|
|
217
|
-
| PVectorDataString
|
|
218
|
-
| PVectorDataBytes;
|
|
219
|
-
|
|
220
|
-
/** Table column data in comparison to the data stored in a separate PColumn
|
|
221
|
-
* may have some of the values "absent", i.e. as a result of missing record in
|
|
222
|
-
* outer join operation. This information is encoded in {@link absent} field. */
|
|
223
|
-
export interface PTableVector {
|
|
224
|
-
/** Stored data type */
|
|
225
|
-
readonly type: ValueType;
|
|
226
164
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Encoded bit array marking some elements of this vector as absent,
|
|
232
|
-
* call {@link isValueAbsent} to read the data.
|
|
233
|
-
* */
|
|
234
|
-
readonly absent: Uint8Array;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/** Used to read bit array with value absence information */
|
|
238
|
-
export function isValueAbsent(absent: Uint8Array, index: number): boolean {
|
|
239
|
-
const chunkIndex = Math.floor(index / 8);
|
|
240
|
-
const mask = 1 << (7 - (index % 8));
|
|
241
|
-
return (absent[chunkIndex] & mask) > 0;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export const PTableAbsent = { type: 'absent' } as const;
|
|
245
|
-
export type PTableAbsent = typeof PTableAbsent;
|
|
246
|
-
export const PTableNA = null;
|
|
247
|
-
export type PTableNA = typeof PTableNA;
|
|
248
|
-
|
|
249
|
-
/** Decoded PTable value */
|
|
250
|
-
export type PTableValue = PTableAbsent | PTableNA | number | string;
|
|
251
|
-
|
|
252
|
-
/** Type guard for absent PValue */
|
|
253
|
-
export function isPTableAbsent(value: PTableValue): value is PTableAbsent {
|
|
254
|
-
return typeof value === 'object' && value !== null && value.type === 'absent';
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export type AbsentAndNAFill = {
|
|
258
|
-
na?: PTableValue;
|
|
259
|
-
absent?: PTableValue;
|
|
260
|
-
};
|
|
165
|
+
if (options && 'dataType' in options && options.dataType !== undefined && options.dataType !== valueType) {
|
|
166
|
+
throw Error(`expected column of type ${options.dataType}, got ${valueType}`);
|
|
167
|
+
}
|
|
261
168
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
row: number,
|
|
266
|
-
fill: AbsentAndNAFill = {},
|
|
267
|
-
): PTableValue {
|
|
268
|
-
if (isValueAbsent(column.absent, row))
|
|
269
|
-
return fill.absent === undefined ? PTableAbsent : fill.absent;
|
|
169
|
+
if (isValueAbsent(column, row)) {
|
|
170
|
+
return options?.absent !== undefined ? options.absent : PTableAbsent;
|
|
171
|
+
}
|
|
270
172
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
173
|
+
if (isValueNA(column, row)) {
|
|
174
|
+
return options?.na !== undefined ? options.na : PTableNA;
|
|
175
|
+
}
|
|
274
176
|
|
|
177
|
+
const value = column.data[row]!;
|
|
275
178
|
switch (valueType) {
|
|
276
179
|
case 'Int':
|
|
277
180
|
return value as PVectorDataInt[number];
|
|
@@ -282,12 +185,143 @@ export function pTableValue(
|
|
|
282
185
|
case 'Double':
|
|
283
186
|
return value as PVectorDataDouble[number];
|
|
284
187
|
case 'String':
|
|
285
|
-
return value as PVectorDataString[number]
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
188
|
+
return (value as PVectorDataString[number])!;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Read PTableValue from PTable column at specified row */
|
|
193
|
+
export function pTableValue<DataType extends ValueType>(
|
|
194
|
+
column: PTableVectorTyped<DataType>,
|
|
195
|
+
row: number,
|
|
196
|
+
): DataType extends ValueTypeSupported ? PTableValue<PTableAbsent, PTableNA, DataType> : never;
|
|
197
|
+
export function pTableValue<FillAbsent, DataType extends ValueType>(
|
|
198
|
+
column: PTableVectorTyped<DataType>,
|
|
199
|
+
row: number,
|
|
200
|
+
options: {
|
|
201
|
+
absent: FillAbsent;
|
|
202
|
+
}
|
|
203
|
+
): DataType extends ValueTypeSupported ? PTableValue<FillAbsent, PTableNA, DataType> : never;
|
|
204
|
+
export function pTableValue<FillNA, DataType extends ValueType>(
|
|
205
|
+
column: PTableVectorTyped<DataType>,
|
|
206
|
+
row: number,
|
|
207
|
+
options: {
|
|
208
|
+
na: FillNA;
|
|
209
|
+
}
|
|
210
|
+
): DataType extends ValueTypeSupported ? PTableValue<PTableAbsent, FillNA, DataType> : never;
|
|
211
|
+
export function pTableValue<FillNA, FillAbsent, DataType extends ValueType>(
|
|
212
|
+
column: PTableVectorTyped<DataType>,
|
|
213
|
+
row: number,
|
|
214
|
+
options: {
|
|
215
|
+
absent: FillAbsent;
|
|
216
|
+
na: FillNA;
|
|
217
|
+
}
|
|
218
|
+
): DataType extends ValueTypeSupported ? PTableValue<FillAbsent, FillNA, DataType> : never;
|
|
219
|
+
export function pTableValue<FillAbsent, DataType extends ValueTypeSupported>(
|
|
220
|
+
column: PTableVectorTyped<ValueType>,
|
|
221
|
+
row: number,
|
|
222
|
+
options: {
|
|
223
|
+
absent: FillAbsent;
|
|
224
|
+
dataType: DataType;
|
|
225
|
+
}
|
|
226
|
+
): PTableValue<FillAbsent, PTableNA>;
|
|
227
|
+
export function pTableValue<FillNA, DataType extends ValueTypeSupported>(
|
|
228
|
+
column: PTableVectorTyped<ValueType>,
|
|
229
|
+
row: number,
|
|
230
|
+
options: {
|
|
231
|
+
na: FillNA;
|
|
232
|
+
dataType: DataType;
|
|
233
|
+
}
|
|
234
|
+
): PTableValue<PTableAbsent, FillNA, DataType>;
|
|
235
|
+
export function pTableValue<FillNA, FillAbsent, DataType extends ValueTypeSupported>(
|
|
236
|
+
column: PTableVectorTyped<ValueType>,
|
|
237
|
+
row: number,
|
|
238
|
+
options: {
|
|
239
|
+
absent: FillAbsent;
|
|
240
|
+
na: FillNA;
|
|
241
|
+
dataType: DataType;
|
|
242
|
+
}
|
|
243
|
+
): PTableValue<FillAbsent, FillNA, DataType>;
|
|
244
|
+
export function pTableValue<
|
|
245
|
+
FillAbsent = PTableAbsent,
|
|
246
|
+
FillNA = PTableNA,
|
|
247
|
+
DataType extends ValueType = ValueTypeSupported,
|
|
248
|
+
>(
|
|
249
|
+
column: PTableVectorTyped<ValueType>,
|
|
250
|
+
row: number,
|
|
251
|
+
options?: {
|
|
252
|
+
absent?: FillAbsent;
|
|
253
|
+
na?: FillNA;
|
|
254
|
+
dataType?: DataType;
|
|
255
|
+
},
|
|
256
|
+
) {
|
|
257
|
+
return pTableValueImpl(column, row, options);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function pTableValueBranded<DataType extends ValueType>(
|
|
261
|
+
column: PTableVectorTyped<DataType>,
|
|
262
|
+
row: number,
|
|
263
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<PTableAbsent, PTableNA, DataType> : never;
|
|
264
|
+
export function pTableValueBranded<FillAbsent, DataType extends ValueType>(
|
|
265
|
+
column: PTableVectorTyped<DataType>,
|
|
266
|
+
row: number,
|
|
267
|
+
options: {
|
|
268
|
+
absent: FillAbsent;
|
|
269
|
+
}
|
|
270
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<FillAbsent, PTableNA, DataType> : never;
|
|
271
|
+
export function pTableValueBranded<FillNA, DataType extends ValueType>(
|
|
272
|
+
column: PTableVectorTyped<DataType>,
|
|
273
|
+
row: number,
|
|
274
|
+
options: {
|
|
275
|
+
na: FillNA;
|
|
276
|
+
}
|
|
277
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<PTableAbsent, FillNA, DataType> : never;
|
|
278
|
+
export function pTableValueBranded<FillNA, FillAbsent, DataType extends ValueType>(
|
|
279
|
+
column: PTableVectorTyped<DataType>,
|
|
280
|
+
row: number,
|
|
281
|
+
options: {
|
|
282
|
+
absent: FillAbsent;
|
|
283
|
+
na: FillNA;
|
|
290
284
|
}
|
|
285
|
+
): DataType extends ValueTypeSupported ? PTableValueBranded<FillAbsent, FillNA, DataType> : never;
|
|
286
|
+
export function pTableValueBranded<FillAbsent, DataType extends ValueTypeSupported>(
|
|
287
|
+
column: PTableVectorTyped<ValueType>,
|
|
288
|
+
row: number,
|
|
289
|
+
options: {
|
|
290
|
+
absent: FillAbsent;
|
|
291
|
+
dataType: DataType;
|
|
292
|
+
}
|
|
293
|
+
): PTableValueBranded<FillAbsent, PTableNA>;
|
|
294
|
+
export function pTableValueBranded<FillNA, DataType extends ValueTypeSupported>(
|
|
295
|
+
column: PTableVectorTyped<ValueType>,
|
|
296
|
+
row: number,
|
|
297
|
+
options: {
|
|
298
|
+
na: FillNA;
|
|
299
|
+
dataType: DataType;
|
|
300
|
+
}
|
|
301
|
+
): PTableValueBranded<PTableAbsent, FillNA, DataType>;
|
|
302
|
+
export function pTableValueBranded<FillNA, FillAbsent, DataType extends ValueTypeSupported>(
|
|
303
|
+
column: PTableVectorTyped<ValueType>,
|
|
304
|
+
row: number,
|
|
305
|
+
options: {
|
|
306
|
+
absent: FillAbsent;
|
|
307
|
+
na: FillNA;
|
|
308
|
+
dataType: DataType;
|
|
309
|
+
}
|
|
310
|
+
): PTableValueBranded<FillAbsent, FillNA, DataType>;
|
|
311
|
+
export function pTableValueBranded<
|
|
312
|
+
FillAbsent = PTableAbsent,
|
|
313
|
+
FillNA = PTableNA,
|
|
314
|
+
DataType extends ValueType = ValueTypeSupported,
|
|
315
|
+
>(
|
|
316
|
+
column: PTableVectorTyped<ValueType>,
|
|
317
|
+
row: number,
|
|
318
|
+
options?: {
|
|
319
|
+
absent?: FillAbsent;
|
|
320
|
+
na?: FillNA;
|
|
321
|
+
dataType?: DataType;
|
|
322
|
+
},
|
|
323
|
+
) {
|
|
324
|
+
return pTableValueImpl(column, row, options);
|
|
291
325
|
}
|
|
292
326
|
|
|
293
327
|
/** Used in requests to partially retrieve table's data */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import canonicalize from 'canonicalize';
|
|
2
|
-
import type {
|
|
3
|
-
import type { AxisFilter } from './filtered_column';
|
|
2
|
+
import type { AxisFilter, AxisFilterValue } from './filtered_column';
|
|
4
3
|
import type { SUniversalPColumnId, UniversalPColumnId } from './ids';
|
|
5
4
|
import { stringifyColumnId } from './ids';
|
|
6
5
|
import type { AAxisSelector, AnchorAxisRef, AnchorAxisRefByIdx, AnchoredPColumnId, AnchoredPColumnSelector, AxisSelector, PColumnSelector } from './selectors';
|
|
@@ -131,7 +130,7 @@ export class AnchoredIdDeriver {
|
|
|
131
130
|
}
|
|
132
131
|
|
|
133
132
|
// Process axis filters and create a sliced column ID
|
|
134
|
-
const resolvedFilters: [number,
|
|
133
|
+
const resolvedFilters: [number, AxisFilterValue][] = [];
|
|
135
134
|
|
|
136
135
|
for (const filter of axisFilters) {
|
|
137
136
|
const [axisIdOrIndex, value] = filter;
|