@milaboratories/pl-model-common 1.3.9

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.
@@ -0,0 +1,79 @@
1
+ /** Handle of logs. This handle should be passed
2
+ * to the driver for retrieving logs. */
3
+ export type AnyLogHandle = LiveLogHandle | ReadyLogHandle;
4
+
5
+ /** Handle of the live logs of a program.
6
+ * The resource that represents a log can be deleted,
7
+ * in this case the handle should be refreshed. */
8
+ export type LiveLogHandle = `log+live://log/${string}`;
9
+
10
+ /** Handle of the ready logs of a program. */
11
+ export type ReadyLogHandle = `log+ready://log/${string}`;
12
+
13
+ /** Driver to retrieve logs given log handle */
14
+ export interface LogsDriver {
15
+ lastLines(
16
+ /** A handle that was issued previously. */
17
+ handle: AnyLogHandle,
18
+
19
+ /** Allows client to limit total data sent from server. */
20
+ lineCount: number,
21
+
22
+ /** Makes streamer to perform seek operation to given offset before sending the contents.
23
+ * Client can just use the <new_offset> value of the last response from server to continue streaming after reconnection.
24
+ * If undefined, then starts from the end. */
25
+ offsetBytes?: number,
26
+
27
+ /** Is substring for line search pattern.
28
+ * This option makes controller to send to the client only lines, that
29
+ * have given substring. */
30
+ searchStr?: string
31
+ ): Promise<StreamingApiResponse>;
32
+
33
+ readText(
34
+ /** A handle that was issued previously. */
35
+ handle: AnyLogHandle,
36
+
37
+ /** Allows client to limit total data sent from server. */
38
+ lineCount: number,
39
+
40
+ /** Makes streamer to perform seek operation to given offset before sending the contents.
41
+ * Client can just use the <new_offset> value of the last response from server to continue streaming after reconnection.
42
+ * If undefined of 0, then starts from the beginning. */
43
+ offsetBytes?: number,
44
+
45
+ /** Is substring for line search pattern.
46
+ * This option makes controller to send to the client only lines, that
47
+ * have given substring. */
48
+ searchStr?: string
49
+ ): Promise<StreamingApiResponse>;
50
+ }
51
+
52
+ /** Response of the driver.
53
+ * The caller should give a handle to retrieve it.
54
+ * It can be OK or outdated, in which case the handle
55
+ * should be issued again. */
56
+ export type StreamingApiResponse =
57
+ | StreamingApiResponseOk
58
+ | StreamingApiResponseHandleOutdated;
59
+
60
+ export type StreamingApiResponseOk = {
61
+ /** The handle don't have to be updated,
62
+ * the response is OK. */
63
+ shouldUpdateHandle: false;
64
+
65
+ /** Whether the log can still grow or it's in a final state. */
66
+ live: boolean;
67
+
68
+ /** Data of the response, in bytes. */
69
+ data: Uint8Array;
70
+ /** Current size of the file. It can grow if it's still live. */
71
+ size: number;
72
+ /** Offset in bytes from the beginning of a file. */
73
+ newOffset: number;
74
+ };
75
+
76
+ /** The handle should be issued again, this one is done. */
77
+ export type StreamingApiResponseHandleOutdated = {
78
+ shouldUpdateHandle: true;
79
+ };
@@ -0,0 +1,80 @@
1
+ import { assertNever } from '../util';
2
+
3
+ const uploadPrefix = 'upload://upload/';
4
+ const indexPrefix = 'index://index/';
5
+
6
+ export type ImportFileHandleUpload = `upload://upload/${string}`;
7
+ export type ImportFileHandleIndex = `index://index/${string}`;
8
+
9
+ export type ImportFileHandle = ImportFileHandleUpload | ImportFileHandleIndex;
10
+
11
+ export function isImportFileHandleUpload(
12
+ handle: ImportFileHandle
13
+ ): handle is ImportFileHandleUpload {
14
+ return handle.startsWith(uploadPrefix);
15
+ }
16
+
17
+ export function isImportFileHandleIndex(
18
+ handle: ImportFileHandle
19
+ ): handle is ImportFileHandleIndex {
20
+ return handle.startsWith(indexPrefix);
21
+ }
22
+
23
+ /** Results in upload */
24
+ export type StorageHandleLocal = `local://${string}`;
25
+
26
+ /** Results in index */
27
+ export type StorageHandleRemote = `remote://${string}`;
28
+
29
+ export type StorageHandle = StorageHandleLocal | StorageHandleRemote;
30
+
31
+ export type StorageEntry = {
32
+ name: string;
33
+ handle: StorageHandle;
34
+ initialFullPath: string;
35
+
36
+ // TODO
37
+ // pathStartsWithDisk
38
+ };
39
+
40
+ export type ListFilesResult = {
41
+ parent?: string;
42
+ entries: LsEntry[];
43
+ };
44
+
45
+ export type LsEntry =
46
+ | {
47
+ type: 'dir';
48
+ name: string;
49
+ fullPath: string;
50
+ }
51
+ | {
52
+ type: 'file';
53
+ name: string;
54
+ fullPath: string;
55
+
56
+ /** This handle should be set to args... */
57
+ handle: ImportFileHandle;
58
+ };
59
+
60
+ export interface LsDriver {
61
+ /** remote and local storages */
62
+ getStorageList(): Promise<StorageEntry[]>;
63
+
64
+ listFiles(storage: StorageHandle, fullPath: string): Promise<ListFilesResult>;
65
+ }
66
+
67
+ /** Gets a file path from an import handle. */
68
+ export function getFilePathFromHandle(handle: ImportFileHandle): string {
69
+ if (isImportFileHandleIndex(handle)) {
70
+ const trimmed = handle.slice(indexPrefix.length);
71
+ const data = JSON.parse(decodeURIComponent(trimmed));
72
+ return data.path;
73
+ } else if (isImportFileHandleUpload(handle)) {
74
+ const trimmed = handle.slice(uploadPrefix.length);
75
+ const data = JSON.parse(decodeURIComponent(trimmed));
76
+ return data.localPath;
77
+ }
78
+
79
+ assertNever(handle);
80
+ }
@@ -0,0 +1,19 @@
1
+ import { ValueType } from './spec';
2
+
3
+ /** Allows to search multiple columns in different contexts. */
4
+ export interface ColumnFilter {
5
+ /** Match any of the types listed here. If undefined, will be ignored during
6
+ * matching. */
7
+ readonly type?: ValueType[];
8
+
9
+ /** Match any of the names listed here. If undefined, will be ignored during
10
+ * matching. */
11
+ readonly name?: string[];
12
+
13
+ /** Match requires all the annotations listed here to have corresponding values. */
14
+ readonly annotationValue?: Record<string, string>;
15
+
16
+ /** Match requires all the annotations listed here to match corresponding regex
17
+ * pattern. */
18
+ readonly annotationPattern?: Record<string, string>;
19
+ }
@@ -0,0 +1,67 @@
1
+ import { ValueType } from './spec';
2
+
3
+ export const PValueIntNA = -2147483648;
4
+ export const PValueLongNA = -9007199254740991n;
5
+ export const PValueFloatNA = NaN;
6
+ export const PValueDoubleNA = NaN;
7
+ export const PValueStringNA = null;
8
+ export const PValueBytesNA = null;
9
+
10
+ export type PValueInt = number;
11
+ export type PValueLong = number; // use bigint only if extra integer precision is needed
12
+ export type PValueFloat = number;
13
+ export type PValueDouble = number;
14
+ export type PValueString = string | null;
15
+ export type PValueBytes = Uint8Array | null;
16
+
17
+ export type PVectorDataInt = Int32Array;
18
+ export type PVectorDataLong = BigInt64Array;
19
+ export type PVectorDataFloat = Float32Array;
20
+ export type PVectorDataDouble = Float64Array;
21
+ export type PVectorDataString = PValueString[];
22
+ export type PVectorDataBytes = PValueBytes[];
23
+
24
+ export type PVectorData =
25
+ | PVectorDataInt
26
+ | PVectorDataLong
27
+ | PVectorDataFloat
28
+ | PVectorDataDouble
29
+ | PVectorDataString
30
+ | PVectorDataBytes;
31
+
32
+ /** Table column data in comparison to the data stored in a separate PColumn
33
+ * may have some of the values "absent", i.e. as a result of missing record in
34
+ * outer join operation. This information is encoded in {@link absent} field. */
35
+ export interface PTableVector {
36
+ /** Stored data type */
37
+ readonly type: ValueType;
38
+
39
+ /** Values for present positions, absent positions have NA values */
40
+ readonly data: PVectorData;
41
+
42
+ /**
43
+ * Encoded bit array marking some elements of this vector as absent,
44
+ *
45
+ * Encoding described here:
46
+ * https://gist.github.com/vadimpiven/45f8279d84f47b9857df845126694c39
47
+ * */
48
+ readonly absent: Uint8Array;
49
+ }
50
+
51
+ /** Used in requests to partially retrieve table's data */
52
+ export type TableRange = {
53
+ /** Index of the first record to retrieve */
54
+ readonly offset: number;
55
+
56
+ /** Block length */
57
+ readonly length: number;
58
+ };
59
+
60
+ /** Unified information about table shape */
61
+ export type PTableShape = {
62
+ /** Number of unified table columns, including all axes and PColumn values */
63
+ columns: number;
64
+
65
+ /** Number of rows */
66
+ rows: number;
67
+ };
@@ -0,0 +1,110 @@
1
+ import { Branded } from '../../branding';
2
+ import { PTable } from './table';
3
+ import { PFrame } from './pframe';
4
+ import { AddParameterToAllMethods } from './type_util';
5
+ import { PTableShape, PTableVector, TableRange } from './data';
6
+ import { FindColumnsRequest, FindColumnsResponse } from './find_columns';
7
+ import { PObjectId } from '../../pool';
8
+ import { PColumnIdAndSpec, PColumnSpec } from './spec';
9
+ import {
10
+ CalculateTableDataRequest,
11
+ CalculateTableDataResponse
12
+ } from './table_calculate';
13
+ import { UniqueValuesRequest, UniqueValuesResponse } from './unique_values';
14
+ import { PTableColumnSpec } from './table_common';
15
+
16
+ /** PFrame handle */
17
+ export type PFrameHandle = Branded<string, 'PFrame'>;
18
+
19
+ /** PFrame handle */
20
+ export type PTableHandle = Branded<string, 'PTable'>;
21
+
22
+ /** Allows to access main data layer features of platforma */
23
+ export interface PFrameDriver {
24
+ //
25
+ // PFrame methods
26
+ //
27
+
28
+ /**
29
+ * Finds columns given filtering criteria on column name, annotations etc.
30
+ * and a set of axes ids to find only columns with compatible specs.
31
+ * */
32
+ findColumns(
33
+ handle: PFrameHandle,
34
+ request: FindColumnsRequest
35
+ ): Promise<FindColumnsResponse>;
36
+
37
+ /** Retrieve single column spec */
38
+ getColumnSpec(
39
+ handle: PFrameHandle,
40
+ columnId: PObjectId
41
+ ): Promise<PColumnSpec>;
42
+
43
+ /** Retrieve information about all columns currently added to the PFrame */
44
+ listColumns(handle: PFrameHandle): Promise<PColumnIdAndSpec[]>;
45
+
46
+ /** Calculates data for the table and returns complete data representation of it */
47
+ calculateTableData(
48
+ handle: PFrameHandle,
49
+ request: CalculateTableDataRequest<PObjectId>
50
+ ): Promise<CalculateTableDataResponse>;
51
+
52
+ /** Calculate set of unique values for a specific axis for the filtered set of records */
53
+ getUniqueValues(
54
+ handle: PFrameHandle,
55
+ request: UniqueValuesRequest
56
+ ): Promise<UniqueValuesResponse>;
57
+
58
+ //
59
+ // PTable methods
60
+ //
61
+
62
+ /** Unified table shape */
63
+ getShape(handle: PTableHandle): Promise<PTableShape>;
64
+
65
+ /**
66
+ * Returns ordered array of table axes specs (primary key "columns" in SQL
67
+ * terms) and data column specs (regular "columns" in SQL terms).
68
+ *
69
+ * Data for a specific table column can be retrieved using unified indexing
70
+ * corresponding to elements in this array.
71
+ *
72
+ * Axes are always listed first.
73
+ * */
74
+ getSpec(handle: PTableHandle): Promise<PTableColumnSpec[]>;
75
+
76
+ /**
77
+ * Retrieve the data from the table. To retrieve only data required, it can be
78
+ * sliced both horizontally ({@link columnIndices}) and vertically
79
+ * ({@link range}).
80
+ *
81
+ * @param columnIndices unified indices of columns to be retrieved
82
+ * @param range optionally limit the range of records to retrieve
83
+ * */
84
+ getData(
85
+ handle: PTableHandle,
86
+ columnIndices: number[],
87
+ range?: TableRange | undefined
88
+ ): Promise<PTableVector[]>;
89
+ }
90
+
91
+ //
92
+ // The following keeps the PFrame driver from above to be in sync with
93
+ // PFrame and PTable interfaces.
94
+ //
95
+
96
+ type ExpectedPFrameDriverTypeF = AddParameterToAllMethods<
97
+ PFrame,
98
+ [handle: PFrameHandle]
99
+ >;
100
+ type ExpectedPFrameDriverTypeT = AddParameterToAllMethods<
101
+ PTable,
102
+ [handle: PTableHandle]
103
+ >;
104
+ type ExpectedPFrameDriverType = ExpectedPFrameDriverTypeF &
105
+ ExpectedPFrameDriverTypeT;
106
+
107
+ type TypeEqualityGuard<A, B> = Exclude<A, B> | Exclude<B, A>;
108
+ function assert<T extends never>() {}
109
+
110
+ assert<TypeEqualityGuard<PFrameDriver, ExpectedPFrameDriverType>>();
@@ -0,0 +1,30 @@
1
+ import { ColumnFilter } from './column_filter';
2
+ import { AxisId, PColumnIdAndSpec } from './spec';
3
+
4
+ /**
5
+ * Request to search among existing columns in the PFrame. Two filtering
6
+ * criteria can be used: (1) column ашдеук, to search for columns with
7
+ * specific properties like name, annotations and domains, and (2) being
8
+ * compatible with the given list of axis ids.
9
+ * */
10
+ export interface FindColumnsRequest {
11
+ /** Basic column filter */
12
+ readonly columnFilter: ColumnFilter;
13
+
14
+ /** Will only search for columns compatible with these list of axis ids */
15
+ readonly compatibleWith: AxisId[];
16
+
17
+ /**
18
+ * Defines what level of compatibility with provided list of axis ids is required.
19
+ *
20
+ * If true will search only for such columns which axes completely maps onto the
21
+ * axes listed in the {@link compatibleWith} list.
22
+ * */
23
+ readonly strictlyCompatible: boolean;
24
+ }
25
+
26
+ /** Response for {@link FindColumnsRequest} */
27
+ export interface FindColumnsResponse {
28
+ /** Array of column ids found using request criteria. */
29
+ readonly hits: PColumnIdAndSpec[];
30
+ }
@@ -0,0 +1,11 @@
1
+ export * from './column_filter';
2
+ export * from './data';
3
+ export * from './find_columns';
4
+ export * from './pframe';
5
+ export * from './spec';
6
+ export * from './table';
7
+ export * from './table_calculate';
8
+ export * from './table_common';
9
+ export * from './unique_values';
10
+
11
+ export * from './driver';
@@ -0,0 +1,34 @@
1
+ import { PObjectId } from '../../pool';
2
+ import { FindColumnsRequest, FindColumnsResponse } from './find_columns';
3
+ import { PColumn, PColumnIdAndSpec, PColumnSpec } from './spec';
4
+ import {
5
+ CalculateTableDataRequest,
6
+ CalculateTableDataResponse
7
+ } from './table_calculate';
8
+ import { UniqueValuesRequest, UniqueValuesResponse } from './unique_values';
9
+
10
+ /** Read interface exposed by PFrames library */
11
+ export interface PFrame {
12
+ /**
13
+ * Finds columns given filtering criteria on column name, annotations etc.
14
+ * and a set of axes ids to find only columns with compatible specs.
15
+ * */
16
+ findColumns(request: FindColumnsRequest): Promise<FindColumnsResponse>;
17
+
18
+ /** Retrieve single column spec */
19
+ getColumnSpec(columnId: PObjectId): Promise<PColumnSpec>;
20
+
21
+ /** Retrieve information about all columns currently added to the PFrame */
22
+ listColumns(): Promise<PColumnIdAndSpec[]>;
23
+
24
+ /** Calculates data for the table and returns complete data representation of it */
25
+ calculateTableData(
26
+ request: CalculateTableDataRequest<PObjectId>
27
+ ): Promise<CalculateTableDataResponse>;
28
+
29
+ /** Calculate set of unique values for a specific axis for the filtered set of records */
30
+ getUniqueValues(request: UniqueValuesRequest): Promise<UniqueValuesResponse>;
31
+ }
32
+
33
+ /** Information required to instantiate a PFrame. */
34
+ export type PFrameDef<Data> = PColumn<Data>[];
@@ -0,0 +1,139 @@
1
+ import { PObject, PObjectId, PObjectSpec } from '../../pool';
2
+
3
+ /** PFrame columns and axes within them may store one of these types. */
4
+ export type ValueType =
5
+ | 'Int'
6
+ | 'Long'
7
+ | 'Float'
8
+ | 'Double'
9
+ | 'String'
10
+ | 'Bytes';
11
+
12
+ /**
13
+ * Specification of an individual axis.
14
+ *
15
+ * Each axis is a part of a composite key that addresses data inside the PColumn.
16
+ *
17
+ * Each record inside a PColumn is addressed by a unique tuple of values set for
18
+ * all the axes specified in the column spec.
19
+ * */
20
+ export interface AxisSpec {
21
+ /** Type of the axis value. Should not use non-key types like float or double. */
22
+ readonly type: ValueType;
23
+
24
+ /** Name of the axis */
25
+ readonly name: string;
26
+
27
+ /** Adds auxiliary information to the axis name, type and parents to form a
28
+ * unique identifier */
29
+ readonly domain?: Record<string, string>;
30
+
31
+ /** Any additional information attached to the axis that does not affect its
32
+ * identifier */
33
+ readonly annotations?: Record<string, string>;
34
+
35
+ /**
36
+ * Parent axes provide contextual grouping for the axis in question, establishing
37
+ * a hierarchy where the current axis is dependent on one or more axes for its
38
+ * full definition and meaning. For instance, in a data structure where each
39
+ * "container" axis may contain multiple "item" axes, the `item` axis would
40
+ * list the index of the `container` axis in this field to denote its dependency.
41
+ *
42
+ * This means that the identity or significance of the `item` axis is only
43
+ * interpretable when combined with its parent `container` axis. An `item` axis
44
+ * index by itself may be non-unique and only gains uniqueness within the context
45
+ * of its parent `container`. Therefore, the `parentAxes` field is essential for
46
+ * mapping these relationships and ensuring data coherence across nested or
47
+ * multi-level data models.
48
+ *
49
+ * A list of zero-based indices of parent axes in the overall axes specification
50
+ * from the column spec. Each index corresponds to the position of a parent axis
51
+ * in the list that defines the structure of the data model.
52
+ */
53
+ readonly parentAxes?: number[];
54
+ }
55
+
56
+ /** Common type representing spec for all the axes in a column */
57
+ export type AxesSpec = AxisSpec[];
58
+
59
+ /**
60
+ * Full column specification including all axes specs and specs of the column
61
+ * itself.
62
+ *
63
+ * A PColumn in its essence represents a mapping from a fixed size, explicitly
64
+ * typed tuple to an explicitly typed value.
65
+ *
66
+ * (axis1Value1, axis2Value1, ...) -> columnValue
67
+ *
68
+ * Each element in tuple correspond to the axis having the same index in axesSpec.
69
+ * */
70
+ export interface PColumnSpec extends PObjectSpec {
71
+ /** Defines specific type of BObject, the most generic type of unit of
72
+ * information in Platforma Project. */
73
+ readonly kind: 'PColumn';
74
+
75
+ /** Type of column values */
76
+ readonly valueType: ValueType;
77
+
78
+ /** Column name */
79
+ readonly name: string;
80
+
81
+ /** Adds auxiliary information to the axis name, type and parents to form a
82
+ * unique identifier */
83
+ readonly domain?: Record<string, string>;
84
+
85
+ /** Any additional information attached to the column that does not affect its
86
+ * identifier */
87
+ readonly annotations?: Record<string, string>;
88
+
89
+ /** A list of zero-based indices of parent axes from the {@link axesSpec} array. */
90
+ readonly parentAxes?: number[];
91
+
92
+ /** Axes specifications */
93
+ readonly axesSpec: AxesSpec;
94
+ }
95
+
96
+ export interface PColumn<Data> extends PObject<Data> {
97
+ /** PColumn spec, allowing it to be found among other PObjects */
98
+ readonly spec: PColumnSpec;
99
+ }
100
+
101
+ /** Columns in a PFrame also have internal identifier, this object represents
102
+ * combination of specs and such id */
103
+ export interface PColumnIdAndSpec {
104
+ /** Internal column id within the PFrame */
105
+ readonly columnId: PObjectId;
106
+
107
+ /** Column spec */
108
+ readonly spec: PColumnSpec;
109
+ }
110
+
111
+ /** Information returned by {@link PFrame.listColumns} method */
112
+ export interface PColumnInfo extends PColumnIdAndSpec {
113
+ /** True if data was associated with this PColumn */
114
+ readonly hasData: boolean;
115
+ }
116
+
117
+ export interface AxisId {
118
+ /** Type of the axis or column value. For an axis should not use non-key
119
+ * types like float or double. */
120
+ readonly type: ValueType;
121
+
122
+ /** Name of the axis or column */
123
+ readonly name: string;
124
+
125
+ /** Adds auxiliary information to the axis or column name and type to form a
126
+ * unique identifier */
127
+ readonly domain?: Record<string, string>;
128
+ }
129
+
130
+ /** Array of axis ids */
131
+ export type AxesId = AxisId[];
132
+
133
+ /** Extracts axes ids from axes spec array from column spec */
134
+ export function getAxesId(spec: AxesSpec): AxesId {
135
+ return spec.map((s) => {
136
+ const { type, name, domain } = s;
137
+ return { type, name, domain };
138
+ });
139
+ }
@@ -0,0 +1,31 @@
1
+ import { PTableColumnSpec } from './table_common';
2
+ import { PTableShape, PTableVector, TableRange } from './data';
3
+
4
+ /**
5
+ * Table view.
6
+ * */
7
+ export interface PTable {
8
+ /** Unified table shape */
9
+ getShape(): Promise<PTableShape>;
10
+
11
+ /**
12
+ * Returns ordered array of table axes specs (primary key "columns" in SQL
13
+ * terms) and data column specs (regular "columns" in SQL terms).
14
+ *
15
+ * Data for a specific table column can be retrieved using unified indexing
16
+ * corresponding to elements in this array.
17
+ *
18
+ * Axes are always listed first.
19
+ * */
20
+ getSpec(): Promise<PTableColumnSpec[]>;
21
+
22
+ /**
23
+ * Retrieve the data from the table. To retrieve only data required, it can be
24
+ * sliced both horizontally ({@link columnIndices}) and vertically
25
+ * ({@link range}).
26
+ *
27
+ * @param columnIndices unified indices of columns to be retrieved
28
+ * @param range optionally limit the range of records to retrieve
29
+ * */
30
+ getData(columnIndices: number[], range?: TableRange): Promise<PTableVector[]>;
31
+ }