@milaboratories/pl-model-middle-layer 1.8.11 → 1.8.13
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/pframe/internal_api/api_factory.d.ts +18 -0
- package/dist/pframe/internal_api/api_factory.d.ts.map +1 -1
- package/dist/pframe/internal_api/api_read.d.ts +28 -1
- package/dist/pframe/internal_api/api_read.d.ts.map +1 -1
- package/dist/pframe/internal_api/http_helpers.d.ts +69 -80
- package/dist/pframe/internal_api/http_helpers.d.ts.map +1 -1
- package/dist/pframe/internal_api/pframe.d.ts +26 -2
- package/dist/pframe/internal_api/pframe.d.ts.map +1 -1
- package/dist/pframe/internal_api/table.d.ts +54 -0
- package/dist/pframe/internal_api/table.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/pframe/internal_api/api_factory.ts +26 -0
- package/src/pframe/internal_api/api_read.ts +37 -1
- package/src/pframe/internal_api/http_helpers.ts +74 -84
- package/src/pframe/internal_api/pframe.ts +29 -2
- package/src/pframe/internal_api/table.ts +65 -0
|
@@ -37,4 +37,22 @@ export interface PFrameFactoryAPIV2 {
|
|
|
37
37
|
* any interactions with disposed PFrame will result in exception */
|
|
38
38
|
dispose(): void;
|
|
39
39
|
}
|
|
40
|
+
/** API exposed by PFrames library allowing to create and provide data for
|
|
41
|
+
* PFrame objects */
|
|
42
|
+
export interface PFrameFactoryAPIV3 extends Disposable {
|
|
43
|
+
/** Associates data source with this PFrame */
|
|
44
|
+
setDataSource(dataSource: PFrameDataSource): void;
|
|
45
|
+
/** Adds PColumn without data info */
|
|
46
|
+
addColumnSpec(columnId: PObjectId, columnSpec: PColumnSpec): void;
|
|
47
|
+
/**
|
|
48
|
+
* Assign data info to the specified PColumn.
|
|
49
|
+
* For parquet data info, schema resolution via network is performed during this call.
|
|
50
|
+
*/
|
|
51
|
+
setColumnData(columnId: PObjectId, dataInfo: DataInfo<PFrameBlobId>, options?: {
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
/** Releases all the data previously added to PFrame using methods above,
|
|
55
|
+
* any interactions with disposed PFrame will result in exception */
|
|
56
|
+
dispose(): void;
|
|
57
|
+
}
|
|
40
58
|
//# sourceMappingURL=api_factory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api_factory.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/api_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,uBAAuB,EACvB,YAAY,EACZ,0BAA0B,EAC1B,WAAW,EACX,SAAS,EACV,MAAM,iCAAiC,CAAC;AAEzC,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAGlC;+EAC+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,gGAAgG;AAChG,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD,qEAAqE;IACrE,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,IACrB,YAAY,GACZ,uBAAuB,CAAC,IAAI,CAAC,GAC7B,yBAAyB,CAAC,IAAI,CAAC,GAC/B,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAEnD;oBACoB;AACpB,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElD,gCAAgC;IAChC,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAElE,gDAAgD;IAChD,aAAa,CACX,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,EAChC,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;wEACoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"api_factory.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/api_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,uBAAuB,EACvB,YAAY,EACZ,0BAA0B,EAC1B,WAAW,EACX,SAAS,EACV,MAAM,iCAAiC,CAAC;AAEzC,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAGlC;+EAC+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,gGAAgG;AAChG,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD,qEAAqE;IACrE,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC/D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,IAAI,IACrB,YAAY,GACZ,uBAAuB,CAAC,IAAI,CAAC,GAC7B,yBAAyB,CAAC,IAAI,CAAC,GAC/B,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAEnD;oBACoB;AACpB,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElD,gCAAgC;IAChC,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAElE,gDAAgD;IAChD,aAAa,CACX,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,EAChC,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;wEACoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;oBACoB;AACpB,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,8CAA8C;IAC9C,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElD,qCAAqC;IACrC,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAElE;;;OAGG;IACH,aAAa,CACX,QAAQ,EAAE,SAAS,EACnB,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,EAChC,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;wEACoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
@@ -2,7 +2,7 @@ import { FindColumnsRequest, FindColumnsResponse } from './find_columns';
|
|
|
2
2
|
import { DeleteColumnFromColumnsRequest, DeleteColumnFromColumnsResponse } from './delete_column';
|
|
3
3
|
import { PColumnInfo, PColumnSpec, PObjectId, UniqueValuesRequest, UniqueValuesResponse } from '@milaboratories/pl-model-common';
|
|
4
4
|
import { CreateTableRequestV3 } from './create_table';
|
|
5
|
-
import { PTableV6 } from './table';
|
|
5
|
+
import { PTableV6, PTableV7 } from './table';
|
|
6
6
|
/** Read interface exposed by PFrames library */
|
|
7
7
|
export interface PFrameReadAPIV8 {
|
|
8
8
|
/**
|
|
@@ -27,4 +27,31 @@ export interface PFrameReadAPIV8 {
|
|
|
27
27
|
signal?: AbortSignal;
|
|
28
28
|
}): Promise<UniqueValuesResponse>;
|
|
29
29
|
}
|
|
30
|
+
/** Read interface exposed by PFrames library */
|
|
31
|
+
export interface PFrameReadAPIV9 {
|
|
32
|
+
/**
|
|
33
|
+
* Finds columns given filtering criteria on column name, annotations etc.
|
|
34
|
+
* and a set of qualified axes specs to find only columns with compatible
|
|
35
|
+
* axes spec.
|
|
36
|
+
*
|
|
37
|
+
* Only column specs are used, this method will work even for columns
|
|
38
|
+
* with no assigned data.
|
|
39
|
+
* */
|
|
40
|
+
findColumns(request: FindColumnsRequest): Promise<FindColumnsResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Construct new axes integration with some entry removed but integration qualificaitons preserved.
|
|
43
|
+
* Removes more then one entry in case the removal will create several disjoint sets of axes.
|
|
44
|
+
*/
|
|
45
|
+
deleteColumn(request: DeleteColumnFromColumnsRequest): Promise<DeleteColumnFromColumnsResponse>;
|
|
46
|
+
/** Retrieve single column spec */
|
|
47
|
+
getColumnSpec(columnId: PObjectId): Promise<PColumnSpec>;
|
|
48
|
+
/** Retrieve information about all columns currently added to the PFrame */
|
|
49
|
+
listColumns(): Promise<PColumnInfo[]>;
|
|
50
|
+
/** Calculates data for the table and returns an object to access it */
|
|
51
|
+
createTable(request: CreateTableRequestV3): PTableV7;
|
|
52
|
+
/** Calculate set of unique values for a specific axis for the filtered set of records */
|
|
53
|
+
getUniqueValues(request: UniqueValuesRequest, ops?: {
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
}): Promise<UniqueValuesResponse>;
|
|
56
|
+
}
|
|
30
57
|
//# sourceMappingURL=api_read.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api_read.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/api_read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAClG,OAAO,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"api_read.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/api_read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAClG,OAAO,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7C,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B;;;;;;;SAOK;IACL,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEvE,mCAAmC;IACnC,YAAY,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAEhG,kCAAkC;IAClC,aAAa,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzD,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEtC,uEAAuE;IACvE,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,QAAQ,CAAC;IAErD,yFAAyF;IACzF,eAAe,CACb,OAAO,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClC;AAED,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC9B;;;;;;;SAOK;IACL,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEvE;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAEhG,kCAAkC;IAClC,aAAa,CAAC,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzD,2EAA2E;IAC3E,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEtC,uEAAuE;IACvE,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,QAAQ,CAAC;IAErD,yFAAyF;IACzF,eAAe,CACb,OAAO,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE;QACJ,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClC"}
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
2
|
import type { RequestListener } from 'node:http';
|
|
3
|
-
import type {
|
|
4
|
-
import type { Branded } from '@milaboratories/pl-model-common';
|
|
5
|
-
/** File statistics */
|
|
6
|
-
export type FileStats = {
|
|
7
|
-
/** File size in bytes */
|
|
8
|
-
size: number;
|
|
9
|
-
/** File modification time if available */
|
|
10
|
-
mtime?: Date;
|
|
11
|
-
};
|
|
3
|
+
import type { Branded, Base64Encoded } from '@milaboratories/pl-model-common';
|
|
12
4
|
/** File range specification */
|
|
13
5
|
export type FileRange = {
|
|
14
6
|
/** Start byte position (inclusive) */
|
|
@@ -24,131 +16,129 @@ export type FileRange = {
|
|
|
24
16
|
*/
|
|
25
17
|
export interface ObjectStore {
|
|
26
18
|
/**
|
|
27
|
-
*
|
|
19
|
+
* @returns file size in bytes or `-1` if file does not exist or permissions do not allow access.
|
|
20
|
+
* @throws if file can become accessible after retry (e.g. on network error)
|
|
28
21
|
*
|
|
29
22
|
* @example
|
|
30
23
|
* ```ts
|
|
31
|
-
* async
|
|
24
|
+
* async getFileSize(filename: string): Promise<number> {
|
|
32
25
|
* const filePath = this.resolve(filename);
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* return false;
|
|
38
|
-
* }
|
|
26
|
+
* return await fs
|
|
27
|
+
* .stat(filePath)
|
|
28
|
+
* .then((stat) => ({ size: stat.isFile() ? stat.size : -1 }))
|
|
29
|
+
* .catch(() => ({ size: -1 }));
|
|
39
30
|
* }
|
|
40
31
|
* ```
|
|
41
32
|
*/
|
|
42
|
-
|
|
33
|
+
getFileSize(filename: string): Promise<number>;
|
|
43
34
|
/**
|
|
44
|
-
*
|
|
35
|
+
* Execute action with readable stream (actions can be concurrency limited by the store).
|
|
36
|
+
* Action resolves when stream is closed by handler @see HttpHelpers.createRequestHandler
|
|
45
37
|
*
|
|
46
|
-
* @
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* try {
|
|
51
|
-
* const stats = await fs.stat(filePath);
|
|
52
|
-
* return {
|
|
53
|
-
* size: stats.size,
|
|
54
|
-
* mtime: stats.mtime
|
|
55
|
-
* };
|
|
56
|
-
* } catch (err: unknown) {
|
|
57
|
-
* throw new Error(
|
|
58
|
-
* `Failed to get file statistics for: ${filename} - ${ensureError(err)}`
|
|
59
|
-
* );
|
|
60
|
-
* }
|
|
61
|
-
* }
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
getFileStats(filename: string): Promise<FileStats>;
|
|
65
|
-
/**
|
|
66
|
-
* Execute action with readable stream.
|
|
67
|
-
* Action resolves when stream is closed eigher by handler
|
|
68
|
-
* @see HttpHelpers.createRequestHandler or the store itself.
|
|
69
|
-
* Returned promise resolves after the action is completed.
|
|
38
|
+
* @param filename - existing file name (for which @see ObjectStore.getFileSize returned non-negative value)
|
|
39
|
+
* @param range - valid range of bytes to read from the file (store may skip validation)
|
|
40
|
+
* @param action - function to execute with the stream, responsible for closing the stream
|
|
41
|
+
* @returns promise that resolves after the action is completed
|
|
70
42
|
*
|
|
71
43
|
* @example
|
|
72
44
|
* ```ts
|
|
73
45
|
* async withReadStream(params: {
|
|
74
46
|
* filename: string;
|
|
75
|
-
* range
|
|
47
|
+
* range: FileRange;
|
|
76
48
|
* action: (stream: Readable) => Promise<void>;
|
|
77
49
|
* }): Promise<void> {
|
|
78
50
|
* const { filename, range, action } = params;
|
|
79
51
|
* const filePath = this.resolve(filename);
|
|
80
52
|
*
|
|
81
|
-
* let stream: Readable;
|
|
82
53
|
* try {
|
|
83
|
-
* stream = createReadStream(filePath, range);
|
|
54
|
+
* const stream = createReadStream(filePath, range);
|
|
55
|
+
* return await action(stream);
|
|
84
56
|
* } catch (err: unknown) {
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* );
|
|
88
|
-
* }
|
|
89
|
-
*
|
|
90
|
-
* try {
|
|
91
|
-
* await action(stream);
|
|
92
|
-
* } finally {
|
|
93
|
-
* if (!stream.destroyed) {
|
|
94
|
-
* stream.destroy();
|
|
95
|
-
* }
|
|
57
|
+
* console.error(`failed to create read stream for ${filename} - ${ensureError(err)}`);
|
|
58
|
+
* throw;
|
|
96
59
|
* }
|
|
97
60
|
* }
|
|
98
61
|
* ```
|
|
99
62
|
*/
|
|
100
63
|
withReadStream(params: {
|
|
101
64
|
filename: string;
|
|
65
|
+
range: FileRange;
|
|
102
66
|
action: (stream: Readable) => Promise<void>;
|
|
103
|
-
range?: FileRange;
|
|
104
67
|
}): Promise<void>;
|
|
105
68
|
}
|
|
106
69
|
/** Object store base URL in format accepted by Apache DataFusion and DuckDB */
|
|
107
70
|
export type ObjectStoreUrl = Branded<string, 'PFrameInternal.ObjectStoreUrl'>;
|
|
71
|
+
/** HTTP(S) request handler creation options */
|
|
72
|
+
export type RequestHandlerOptions = {
|
|
73
|
+
/** Object store to serve files from, @see HttpHelpers.createFsStore */
|
|
74
|
+
store: ObjectStore;
|
|
75
|
+
};
|
|
108
76
|
/** Server configuration options */
|
|
109
77
|
export type HttpServerOptions = {
|
|
110
|
-
/** HTTP request handler function */
|
|
78
|
+
/** HTTP(S) request handler function, @see HttpHelpers.createRequestHandler */
|
|
111
79
|
handler: RequestListener;
|
|
112
|
-
/**
|
|
113
|
-
host?: string;
|
|
114
|
-
/** Port to bind to (defaults to 0 for auto-assignment) */
|
|
80
|
+
/** Port to bind to (@default 0 for auto-assignment) */
|
|
115
81
|
port?: number;
|
|
82
|
+
/** Do not apply authorization middleware to @param handler */
|
|
83
|
+
noAuth?: true;
|
|
84
|
+
/** Downgrade default HTTPS server to plain HTTP, @warning use only for testing */
|
|
85
|
+
http?: true;
|
|
116
86
|
};
|
|
117
|
-
/**
|
|
87
|
+
/**
|
|
88
|
+
* Long unique opaque string for use in Bearer authorization header
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* request.setHeader('Authorization', `Bearer ${authToken}`);
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export type HttpAuthorizationToken = Branded<string, 'PFrameInternal.HttpAuthorizationToken'>;
|
|
96
|
+
/**
|
|
97
|
+
* TLS certificate in PEM format
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```txt
|
|
101
|
+
* -----BEGIN CERTIFICATE-----
|
|
102
|
+
* MIIC2zCCAcOgAwIBAgIJaVW7...
|
|
103
|
+
* ...
|
|
104
|
+
* ...Yf9CRK8fgnukKM7TJ
|
|
105
|
+
* -----END CERTIFICATE-----
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export type PemCertificate = Branded<string, 'PFrameInternal.PemCertificate'>;
|
|
109
|
+
/** HTTP(S) server information and controls, @see HttpHelpers.createHttpServer */
|
|
118
110
|
export interface HttpServer {
|
|
119
|
-
/** Server address info */
|
|
120
|
-
get address():
|
|
111
|
+
/** Server address info formatted as `http{s}://<host>:<port>/` */
|
|
112
|
+
get address(): ObjectStoreUrl;
|
|
113
|
+
/** Authorization token for Bearer scheme, undefined when @see HttpServerOptions.noAuth flag is set */
|
|
114
|
+
get authToken(): HttpAuthorizationToken | undefined;
|
|
115
|
+
/** Base64-encoded CA certificate in PEM format, undefined when @see HttpServerOptions.http flag is set */
|
|
116
|
+
get encodedCaCert(): Base64Encoded<PemCertificate> | undefined;
|
|
121
117
|
/** Promise that resolves when the server is stopped */
|
|
122
118
|
get stopped(): Promise<void>;
|
|
123
|
-
/**
|
|
119
|
+
/** Request server stop, returns the same promise as @see HttpServer.stopped */
|
|
124
120
|
stop(): Promise<void>;
|
|
125
121
|
}
|
|
122
|
+
/** List of HTTP(S) related helper functions exposed by PFrame module */
|
|
126
123
|
export interface HttpHelpers {
|
|
127
124
|
/**
|
|
128
125
|
* Create an object store for serving files from a local directory.
|
|
129
126
|
* Rejects if the provided path does not exist or is not a directory.
|
|
130
|
-
* Intended for testing purposes, you will probably want to implement a different store.
|
|
131
127
|
*/
|
|
132
128
|
createFsStore(rootDir: string): Promise<ObjectStore>;
|
|
133
129
|
/**
|
|
134
130
|
* Create an HTTP request handler for serving files from an object store.
|
|
135
|
-
* Accepts only paths of the form `/<filename>.parquet`, returns
|
|
131
|
+
* Accepts only paths of the form `/<filename>.parquet`, returns 410 otherwise.
|
|
136
132
|
* Assumes that files are immutable (and sets cache headers accordingly).
|
|
137
133
|
*/
|
|
138
|
-
createRequestHandler(
|
|
139
|
-
/**
|
|
140
|
-
* Create an object store URL from the server address info.
|
|
141
|
-
* Result of this function is intended to be passed to PFrames as data source parquet prefix.
|
|
142
|
-
*/
|
|
143
|
-
createObjectStoreUrl(info: AddressInfo): ObjectStoreUrl;
|
|
134
|
+
createRequestHandler(options: RequestHandlerOptions): RequestListener;
|
|
144
135
|
/**
|
|
145
|
-
* Serve HTTP requests using the provided handler on
|
|
146
|
-
*
|
|
136
|
+
* Serve HTTP(S) requests using the provided handler on localhost port.
|
|
137
|
+
* @returns promise that resolves when the server has stopped.
|
|
147
138
|
*
|
|
148
139
|
* @example
|
|
149
140
|
* ```ts
|
|
150
141
|
* const rootDir = '/path/to/directory/with/parquet/files';
|
|
151
|
-
* const port = 3000;
|
|
152
142
|
*
|
|
153
143
|
* let store = await HttpHelpers.createFsStore(rootDir).catch((err: unknown) => {
|
|
154
144
|
* throw new Error(`Failed to create file store for ${rootDir} - ${ensureError(err)}`);
|
|
@@ -156,12 +146,11 @@ export interface HttpHelpers {
|
|
|
156
146
|
*
|
|
157
147
|
* const server = await HttpHelpers.createHttpServer({
|
|
158
148
|
* handler: HttpHelpers.createRequestHandler(store),
|
|
159
|
-
* port,
|
|
160
149
|
* }).catch((err: unknown) => {
|
|
161
|
-
* throw new Error(`Failed to start
|
|
150
|
+
* throw new Error(`Failed to start HTTP server - ${ensureError(err)}`);
|
|
162
151
|
* });
|
|
163
152
|
*
|
|
164
|
-
* const
|
|
153
|
+
* const { address, authToken, base64EncodedCaCert } = server;
|
|
165
154
|
*
|
|
166
155
|
* await server.stop();
|
|
167
156
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http_helpers.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/http_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"http_helpers.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/http_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAE9E,+BAA+B;AAC/B,MAAM,MAAM,SAAS,GAAG;IACtB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,cAAc,CAAC,MAAM,EAAE;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,SAAS,CAAC;QACjB,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7C,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,+EAA+E;AAC/E,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;AAE9E,+CAA+C;AAC/C,MAAM,MAAM,qBAAqB,GAAG;IAClC,uEAAuE;IACvE,KAAK,EAAE,WAAW,CAAC;CAEpB,CAAA;AAED,mCAAmC;AACnC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8EAA8E;IAC9E,OAAO,EAAE,eAAe,CAAC;IACzB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,kFAAkF;IAClF,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,uCAAuC,CAAC,CAAC;AAE9F;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;AAE9E,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACzB,kEAAkE;IAClE,IAAI,OAAO,IAAI,cAAc,CAAC;IAC9B,sGAAsG;IACtG,IAAI,SAAS,IAAI,sBAAsB,GAAG,SAAS,CAAC;IACpD,0GAA0G;IAC1G,IAAI,aAAa,IAAI,aAAa,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAC/D,uDAAuD;IACvD,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,+EAA+E;IAC/E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAErD;;;;OAIG;IACH,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,eAAe,CAAC;IAEtE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACnE"}
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
-
import type { PFrameFactoryAPIV2 } from './api_factory';
|
|
2
|
-
import type { PFrameReadAPIV8 } from './api_read';
|
|
1
|
+
import type { PFrameFactoryAPIV2, PFrameFactoryAPIV3 } from './api_factory';
|
|
2
|
+
import type { PFrameReadAPIV8, PFrameReadAPIV9 } from './api_read';
|
|
3
3
|
export type Logger = (level: 'info' | 'warn' | 'error', message: string) => void;
|
|
4
4
|
export interface PFrameV9 extends PFrameFactoryAPIV2, PFrameReadAPIV8 {
|
|
5
5
|
}
|
|
6
|
+
export interface PFrameV10 extends PFrameFactoryAPIV3, PFrameReadAPIV9 {
|
|
7
|
+
}
|
|
8
|
+
export type PFrameOptions = {
|
|
9
|
+
/** Path to directory where PFrame can create temporary files */
|
|
10
|
+
spillPath: string;
|
|
11
|
+
/** Logger instance, no logging is performed when not provided */
|
|
12
|
+
logger?: Logger;
|
|
13
|
+
};
|
|
14
|
+
/** List of PFrame management functions exposed by PFrame module */
|
|
15
|
+
export interface PFrameFactory {
|
|
16
|
+
/**
|
|
17
|
+
* Create a new PFrame instance.
|
|
18
|
+
* @warning Use concurrency limiting to avoid OOM crashes when multiple instances are simultaneously in use.
|
|
19
|
+
*/
|
|
20
|
+
createPFrame(options: PFrameOptions): PFrameV10;
|
|
21
|
+
/**
|
|
22
|
+
* Dump active allocations from all PFrames instances in pprof format.
|
|
23
|
+
* The result of this function should be saved as `profile.pb.gz`.
|
|
24
|
+
* Use {@link https://pprof.me/} or {@link https://www.speedscope.app/}
|
|
25
|
+
* to view the allocation flamechart.
|
|
26
|
+
* @warning This method will always reject on Windows!
|
|
27
|
+
*/
|
|
28
|
+
pprofDump: () => Promise<Uint8Array>;
|
|
29
|
+
}
|
|
6
30
|
//# sourceMappingURL=pframe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pframe.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/pframe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"pframe.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/pframe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,MAAM,MAAM,GAAG,CACnB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAChC,OAAO,EAAE,MAAM,KACZ,IAAI,CAAC;AAEV,MAAM,WAAW,QAAS,SAAQ,kBAAkB,EAAE,eAAe;CAAG;AAExE,MAAM,WAAW,SAAU,SAAQ,kBAAkB,EAAE,eAAe;CAAG;AAEzE,MAAM,MAAM,aAAa,GAAG;IAC1B,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAA;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;IAEhD;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;CACtC"}
|
|
@@ -53,4 +53,58 @@ export interface PTableV6 {
|
|
|
53
53
|
/** Deallocates all underlying resources */
|
|
54
54
|
dispose(): void;
|
|
55
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Table view returned as a result of create table operation.
|
|
58
|
+
*
|
|
59
|
+
* PTable can be thought as having a composite primary key, consisting of axes,
|
|
60
|
+
* and a set of data columns derived from PColumn values.
|
|
61
|
+
* */
|
|
62
|
+
export interface PTableV7 extends Disposable {
|
|
63
|
+
/**
|
|
64
|
+
* Returns ordered array of table axes specs (primary key "columns" in SQL
|
|
65
|
+
* terms) and data column specs (regular "columns" in SQL terms).
|
|
66
|
+
*
|
|
67
|
+
* Data for a specific table column can be retrieved using unified indexing
|
|
68
|
+
* corresponding to elements in this array.
|
|
69
|
+
*
|
|
70
|
+
* Axes are always listed first.
|
|
71
|
+
* */
|
|
72
|
+
getSpec(): PTableColumnSpec[];
|
|
73
|
+
/** Transforms unified column identifiers into unified indices of columns. */
|
|
74
|
+
getColumnIndices(columnIds: PTableColumnId[]): number[];
|
|
75
|
+
/**
|
|
76
|
+
* Get PTable disk footprint in bytes
|
|
77
|
+
* Warning: This call materializes the join.
|
|
78
|
+
*/
|
|
79
|
+
getFootprint(ops?: {
|
|
80
|
+
withPredecessors?: boolean;
|
|
81
|
+
signal?: AbortSignal;
|
|
82
|
+
}): Promise<number>;
|
|
83
|
+
/**
|
|
84
|
+
* Unified table shape
|
|
85
|
+
* Warning: This call materializes the join.
|
|
86
|
+
*/
|
|
87
|
+
getShape(ops?: {
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
}): Promise<PTableShape>;
|
|
90
|
+
/**
|
|
91
|
+
* Retrieve the data from the table. To retrieve only data required, it can be
|
|
92
|
+
* sliced both horizontally ({@link columnIndices}) and vertically
|
|
93
|
+
* ({@link range}).
|
|
94
|
+
* This call materializes the join.
|
|
95
|
+
*
|
|
96
|
+
* @param columnIndices unified indices of columns to be retrieved
|
|
97
|
+
* @param range optionally limit the range of records to retrieve
|
|
98
|
+
* */
|
|
99
|
+
getData(columnIndices: number[], ops?: {
|
|
100
|
+
range?: TableRange;
|
|
101
|
+
signal?: AbortSignal;
|
|
102
|
+
}): Promise<PTableVector[]>;
|
|
103
|
+
/** Filters the table and returns new PTable instance */
|
|
104
|
+
filter(request: PTableRecordFilter[]): PTableV7;
|
|
105
|
+
/** Sorts the table and returns new PTable instance. */
|
|
106
|
+
sort(request: PTableSorting[]): PTableV7;
|
|
107
|
+
/** Deallocates all underlying resources */
|
|
108
|
+
dispose(): void;
|
|
109
|
+
}
|
|
56
110
|
//# sourceMappingURL=table.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/table.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC;;;;;KAKK;AACL,MAAM,WAAW,QAAQ;IACvB;;;;;;;;SAQK;IACL,OAAO,IAAI,gBAAgB,EAAE,CAAC;IAE9B,6EAA6E;IAC7E,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAExD;;;OAGG;IACH,YAAY,CAAC,GAAG,CAAC,EAAE;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzB;;;;;;;;SAQK;IACL,OAAO,CACL,aAAa,EAAE,MAAM,EAAE,EACvB,GAAG,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE3B,wDAAwD;IACxD,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,QAAQ,CAAC;IAEhD,uDAAuD;IACvD,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;IAEzC,2CAA2C;IAC3C,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/pframe/internal_api/table.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,EACX,MAAM,iCAAiC,CAAC;AAEzC;;;;;KAKK;AACL,MAAM,WAAW,QAAQ;IACvB;;;;;;;;SAQK;IACL,OAAO,IAAI,gBAAgB,EAAE,CAAC;IAE9B,6EAA6E;IAC7E,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAExD;;;OAGG;IACH,YAAY,CAAC,GAAG,CAAC,EAAE;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzB;;;;;;;;SAQK;IACL,OAAO,CACL,aAAa,EAAE,MAAM,EAAE,EACvB,GAAG,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE3B,wDAAwD;IACxD,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,QAAQ,CAAC;IAEhD,uDAAuD;IACvD,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;IAEzC,2CAA2C;IAC3C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;KAKK;AACL,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C;;;;;;;;SAQK;IACL,OAAO,IAAI,gBAAgB,EAAE,CAAC;IAE9B,6EAA6E;IAC7E,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAExD;;;OAGG;IACH,YAAY,CAAC,GAAG,CAAC,EAAE;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzB;;;;;;;;SAQK;IACL,OAAO,CACL,aAAa,EAAE,MAAM,EAAE,EACvB,GAAG,CAAC,EAAE;QACJ,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GACA,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAE3B,wDAAwD;IACxD,MAAM,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,QAAQ,CAAC;IAEhD,uDAAuD;IACvD,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;IAEzC,2CAA2C;IAC3C,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-model-middle-layer",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.13",
|
|
4
4
|
"description": "Common model between middle layer and non-block UI code",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"types": "./dist/index.d.ts",
|
|
6
|
-
"main": "./dist/index.
|
|
7
|
-
"module": "./dist/index.js",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"remeda": "^2.28.0",
|
|
21
21
|
"zod": "~3.23.8",
|
|
22
22
|
"utility-types": "^3.11.0",
|
|
23
|
-
"@milaboratories/pl-model-common": "
|
|
23
|
+
"@milaboratories/pl-model-common": "1.19.13"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"typescript": "~5.6.3",
|
|
27
27
|
"@milaboratories/build-configs": "1.0.8",
|
|
28
|
-
"@milaboratories/ts-
|
|
29
|
-
"@milaboratories/ts-
|
|
28
|
+
"@milaboratories/ts-configs": "1.0.6",
|
|
29
|
+
"@milaboratories/ts-builder": "1.0.5"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"type-check": "ts-builder types --target node",
|
|
@@ -63,3 +63,29 @@ export interface PFrameFactoryAPIV2 {
|
|
|
63
63
|
* any interactions with disposed PFrame will result in exception */
|
|
64
64
|
dispose(): void;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
/** API exposed by PFrames library allowing to create and provide data for
|
|
68
|
+
* PFrame objects */
|
|
69
|
+
export interface PFrameFactoryAPIV3 extends Disposable {
|
|
70
|
+
/** Associates data source with this PFrame */
|
|
71
|
+
setDataSource(dataSource: PFrameDataSource): void;
|
|
72
|
+
|
|
73
|
+
/** Adds PColumn without data info */
|
|
74
|
+
addColumnSpec(columnId: PObjectId, columnSpec: PColumnSpec): void;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Assign data info to the specified PColumn.
|
|
78
|
+
* For parquet data info, schema resolution via network is performed during this call.
|
|
79
|
+
*/
|
|
80
|
+
setColumnData(
|
|
81
|
+
columnId: PObjectId,
|
|
82
|
+
dataInfo: DataInfo<PFrameBlobId>,
|
|
83
|
+
options?: {
|
|
84
|
+
signal?: AbortSignal,
|
|
85
|
+
}
|
|
86
|
+
): Promise<void>;
|
|
87
|
+
|
|
88
|
+
/** Releases all the data previously added to PFrame using methods above,
|
|
89
|
+
* any interactions with disposed PFrame will result in exception */
|
|
90
|
+
dispose(): void;
|
|
91
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
UniqueValuesResponse
|
|
9
9
|
} from '@milaboratories/pl-model-common';
|
|
10
10
|
import { CreateTableRequestV3 } from './create_table';
|
|
11
|
-
import { PTableV6 } from './table';
|
|
11
|
+
import { PTableV6, PTableV7 } from './table';
|
|
12
12
|
|
|
13
13
|
/** Read interface exposed by PFrames library */
|
|
14
14
|
export interface PFrameReadAPIV8 {
|
|
@@ -42,3 +42,39 @@ export interface PFrameReadAPIV8 {
|
|
|
42
42
|
}
|
|
43
43
|
): Promise<UniqueValuesResponse>;
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
/** Read interface exposed by PFrames library */
|
|
47
|
+
export interface PFrameReadAPIV9 {
|
|
48
|
+
/**
|
|
49
|
+
* Finds columns given filtering criteria on column name, annotations etc.
|
|
50
|
+
* and a set of qualified axes specs to find only columns with compatible
|
|
51
|
+
* axes spec.
|
|
52
|
+
*
|
|
53
|
+
* Only column specs are used, this method will work even for columns
|
|
54
|
+
* with no assigned data.
|
|
55
|
+
* */
|
|
56
|
+
findColumns(request: FindColumnsRequest): Promise<FindColumnsResponse>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Construct new axes integration with some entry removed but integration qualificaitons preserved.
|
|
60
|
+
* Removes more then one entry in case the removal will create several disjoint sets of axes.
|
|
61
|
+
*/
|
|
62
|
+
deleteColumn(request: DeleteColumnFromColumnsRequest): Promise<DeleteColumnFromColumnsResponse>;
|
|
63
|
+
|
|
64
|
+
/** Retrieve single column spec */
|
|
65
|
+
getColumnSpec(columnId: PObjectId): Promise<PColumnSpec>;
|
|
66
|
+
|
|
67
|
+
/** Retrieve information about all columns currently added to the PFrame */
|
|
68
|
+
listColumns(): Promise<PColumnInfo[]>;
|
|
69
|
+
|
|
70
|
+
/** Calculates data for the table and returns an object to access it */
|
|
71
|
+
createTable(request: CreateTableRequestV3): PTableV7;
|
|
72
|
+
|
|
73
|
+
/** Calculate set of unique values for a specific axis for the filtered set of records */
|
|
74
|
+
getUniqueValues(
|
|
75
|
+
request: UniqueValuesRequest,
|
|
76
|
+
ops?: {
|
|
77
|
+
signal?: AbortSignal,
|
|
78
|
+
}
|
|
79
|
+
): Promise<UniqueValuesResponse>;
|
|
80
|
+
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
2
|
import type { RequestListener } from 'node:http';
|
|
3
|
-
import type {
|
|
4
|
-
import type { Branded } from '@milaboratories/pl-model-common';
|
|
5
|
-
|
|
6
|
-
/** File statistics */
|
|
7
|
-
export type FileStats = {
|
|
8
|
-
/** File size in bytes */
|
|
9
|
-
size: number;
|
|
10
|
-
/** File modification time if available */
|
|
11
|
-
mtime?: Date;
|
|
12
|
-
};
|
|
3
|
+
import type { Branded, Base64Encoded } from '@milaboratories/pl-model-common';
|
|
13
4
|
|
|
14
5
|
/** File range specification */
|
|
15
6
|
export type FileRange = {
|
|
@@ -27,140 +18,140 @@ export type FileRange = {
|
|
|
27
18
|
*/
|
|
28
19
|
export interface ObjectStore {
|
|
29
20
|
/**
|
|
30
|
-
*
|
|
21
|
+
* @returns file size in bytes or `-1` if file does not exist or permissions do not allow access.
|
|
22
|
+
* @throws if file can become accessible after retry (e.g. on network error)
|
|
31
23
|
*
|
|
32
24
|
* @example
|
|
33
25
|
* ```ts
|
|
34
|
-
* async
|
|
26
|
+
* async getFileSize(filename: string): Promise<number> {
|
|
35
27
|
* const filePath = this.resolve(filename);
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* return false;
|
|
41
|
-
* }
|
|
42
|
-
* }
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
fileExists(filename: string): Promise<boolean>;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Get file statistics
|
|
49
|
-
*
|
|
50
|
-
* @example
|
|
51
|
-
* ```ts
|
|
52
|
-
* async getFileStats(filename: string): Promise<FileStats> {
|
|
53
|
-
* const filePath = this.resolve(filename);
|
|
54
|
-
* try {
|
|
55
|
-
* const stats = await fs.stat(filePath);
|
|
56
|
-
* return {
|
|
57
|
-
* size: stats.size,
|
|
58
|
-
* mtime: stats.mtime
|
|
59
|
-
* };
|
|
60
|
-
* } catch (err: unknown) {
|
|
61
|
-
* throw new Error(
|
|
62
|
-
* `Failed to get file statistics for: ${filename} - ${ensureError(err)}`
|
|
63
|
-
* );
|
|
64
|
-
* }
|
|
28
|
+
* return await fs
|
|
29
|
+
* .stat(filePath)
|
|
30
|
+
* .then((stat) => ({ size: stat.isFile() ? stat.size : -1 }))
|
|
31
|
+
* .catch(() => ({ size: -1 }));
|
|
65
32
|
* }
|
|
66
33
|
* ```
|
|
67
34
|
*/
|
|
68
|
-
|
|
35
|
+
getFileSize(filename: string): Promise<number>;
|
|
69
36
|
|
|
70
37
|
/**
|
|
71
|
-
* Execute action with readable stream.
|
|
72
|
-
* Action resolves when stream is closed
|
|
73
|
-
*
|
|
74
|
-
*
|
|
38
|
+
* Execute action with readable stream (actions can be concurrency limited by the store).
|
|
39
|
+
* Action resolves when stream is closed by handler @see HttpHelpers.createRequestHandler
|
|
40
|
+
*
|
|
41
|
+
* @param filename - existing file name (for which @see ObjectStore.getFileSize returned non-negative value)
|
|
42
|
+
* @param range - valid range of bytes to read from the file (store may skip validation)
|
|
43
|
+
* @param action - function to execute with the stream, responsible for closing the stream
|
|
44
|
+
* @returns promise that resolves after the action is completed
|
|
75
45
|
*
|
|
76
46
|
* @example
|
|
77
47
|
* ```ts
|
|
78
48
|
* async withReadStream(params: {
|
|
79
49
|
* filename: string;
|
|
80
|
-
* range
|
|
50
|
+
* range: FileRange;
|
|
81
51
|
* action: (stream: Readable) => Promise<void>;
|
|
82
52
|
* }): Promise<void> {
|
|
83
53
|
* const { filename, range, action } = params;
|
|
84
54
|
* const filePath = this.resolve(filename);
|
|
85
55
|
*
|
|
86
|
-
* let stream: Readable;
|
|
87
56
|
* try {
|
|
88
|
-
* stream = createReadStream(filePath, range);
|
|
57
|
+
* const stream = createReadStream(filePath, range);
|
|
58
|
+
* return await action(stream);
|
|
89
59
|
* } catch (err: unknown) {
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* );
|
|
93
|
-
* }
|
|
94
|
-
*
|
|
95
|
-
* try {
|
|
96
|
-
* await action(stream);
|
|
97
|
-
* } finally {
|
|
98
|
-
* if (!stream.destroyed) {
|
|
99
|
-
* stream.destroy();
|
|
100
|
-
* }
|
|
60
|
+
* console.error(`failed to create read stream for ${filename} - ${ensureError(err)}`);
|
|
61
|
+
* throw;
|
|
101
62
|
* }
|
|
102
63
|
* }
|
|
103
64
|
* ```
|
|
104
65
|
*/
|
|
105
66
|
withReadStream(params: {
|
|
106
67
|
filename: string;
|
|
68
|
+
range: FileRange;
|
|
107
69
|
action: (stream: Readable) => Promise<void>;
|
|
108
|
-
range?: FileRange;
|
|
109
70
|
}): Promise<void>;
|
|
110
71
|
}
|
|
111
72
|
|
|
112
73
|
/** Object store base URL in format accepted by Apache DataFusion and DuckDB */
|
|
113
74
|
export type ObjectStoreUrl = Branded<string, 'PFrameInternal.ObjectStoreUrl'>;
|
|
114
75
|
|
|
76
|
+
/** HTTP(S) request handler creation options */
|
|
77
|
+
export type RequestHandlerOptions = {
|
|
78
|
+
/** Object store to serve files from, @see HttpHelpers.createFsStore */
|
|
79
|
+
store: ObjectStore;
|
|
80
|
+
/** Here will go caching options... */
|
|
81
|
+
}
|
|
82
|
+
|
|
115
83
|
/** Server configuration options */
|
|
116
84
|
export type HttpServerOptions = {
|
|
117
|
-
/** HTTP request handler function */
|
|
85
|
+
/** HTTP(S) request handler function, @see HttpHelpers.createRequestHandler */
|
|
118
86
|
handler: RequestListener;
|
|
119
|
-
/**
|
|
120
|
-
host?: string;
|
|
121
|
-
/** Port to bind to (defaults to 0 for auto-assignment) */
|
|
87
|
+
/** Port to bind to (@default 0 for auto-assignment) */
|
|
122
88
|
port?: number;
|
|
89
|
+
/** Do not apply authorization middleware to @param handler */
|
|
90
|
+
noAuth?: true;
|
|
91
|
+
/** Downgrade default HTTPS server to plain HTTP, @warning use only for testing */
|
|
92
|
+
http?: true;
|
|
123
93
|
};
|
|
124
94
|
|
|
125
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* Long unique opaque string for use in Bearer authorization header
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* request.setHeader('Authorization', `Bearer ${authToken}`);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export type HttpAuthorizationToken = Branded<string, 'PFrameInternal.HttpAuthorizationToken'>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* TLS certificate in PEM format
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```txt
|
|
110
|
+
* -----BEGIN CERTIFICATE-----
|
|
111
|
+
* MIIC2zCCAcOgAwIBAgIJaVW7...
|
|
112
|
+
* ...
|
|
113
|
+
* ...Yf9CRK8fgnukKM7TJ
|
|
114
|
+
* -----END CERTIFICATE-----
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export type PemCertificate = Branded<string, 'PFrameInternal.PemCertificate'>;
|
|
118
|
+
|
|
119
|
+
/** HTTP(S) server information and controls, @see HttpHelpers.createHttpServer */
|
|
126
120
|
export interface HttpServer {
|
|
127
|
-
/** Server address info */
|
|
128
|
-
get address():
|
|
121
|
+
/** Server address info formatted as `http{s}://<host>:<port>/` */
|
|
122
|
+
get address(): ObjectStoreUrl;
|
|
123
|
+
/** Authorization token for Bearer scheme, undefined when @see HttpServerOptions.noAuth flag is set */
|
|
124
|
+
get authToken(): HttpAuthorizationToken | undefined;
|
|
125
|
+
/** Base64-encoded CA certificate in PEM format, undefined when @see HttpServerOptions.http flag is set */
|
|
126
|
+
get encodedCaCert(): Base64Encoded<PemCertificate> | undefined;
|
|
129
127
|
/** Promise that resolves when the server is stopped */
|
|
130
128
|
get stopped(): Promise<void>;
|
|
131
|
-
/**
|
|
129
|
+
/** Request server stop, returns the same promise as @see HttpServer.stopped */
|
|
132
130
|
stop(): Promise<void>;
|
|
133
131
|
}
|
|
134
132
|
|
|
133
|
+
/** List of HTTP(S) related helper functions exposed by PFrame module */
|
|
135
134
|
export interface HttpHelpers {
|
|
136
135
|
/**
|
|
137
136
|
* Create an object store for serving files from a local directory.
|
|
138
137
|
* Rejects if the provided path does not exist or is not a directory.
|
|
139
|
-
* Intended for testing purposes, you will probably want to implement a different store.
|
|
140
138
|
*/
|
|
141
139
|
createFsStore(rootDir: string): Promise<ObjectStore>;
|
|
142
140
|
|
|
143
141
|
/**
|
|
144
142
|
* Create an HTTP request handler for serving files from an object store.
|
|
145
|
-
* Accepts only paths of the form `/<filename>.parquet`, returns
|
|
143
|
+
* Accepts only paths of the form `/<filename>.parquet`, returns 410 otherwise.
|
|
146
144
|
* Assumes that files are immutable (and sets cache headers accordingly).
|
|
147
145
|
*/
|
|
148
|
-
createRequestHandler(
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Create an object store URL from the server address info.
|
|
152
|
-
* Result of this function is intended to be passed to PFrames as data source parquet prefix.
|
|
153
|
-
*/
|
|
154
|
-
createObjectStoreUrl(info: AddressInfo): ObjectStoreUrl;
|
|
146
|
+
createRequestHandler(options: RequestHandlerOptions): RequestListener;
|
|
155
147
|
|
|
156
148
|
/**
|
|
157
|
-
* Serve HTTP requests using the provided handler on
|
|
158
|
-
*
|
|
149
|
+
* Serve HTTP(S) requests using the provided handler on localhost port.
|
|
150
|
+
* @returns promise that resolves when the server has stopped.
|
|
159
151
|
*
|
|
160
152
|
* @example
|
|
161
153
|
* ```ts
|
|
162
154
|
* const rootDir = '/path/to/directory/with/parquet/files';
|
|
163
|
-
* const port = 3000;
|
|
164
155
|
*
|
|
165
156
|
* let store = await HttpHelpers.createFsStore(rootDir).catch((err: unknown) => {
|
|
166
157
|
* throw new Error(`Failed to create file store for ${rootDir} - ${ensureError(err)}`);
|
|
@@ -168,12 +159,11 @@ export interface HttpHelpers {
|
|
|
168
159
|
*
|
|
169
160
|
* const server = await HttpHelpers.createHttpServer({
|
|
170
161
|
* handler: HttpHelpers.createRequestHandler(store),
|
|
171
|
-
* port,
|
|
172
162
|
* }).catch((err: unknown) => {
|
|
173
|
-
* throw new Error(`Failed to start
|
|
163
|
+
* throw new Error(`Failed to start HTTP server - ${ensureError(err)}`);
|
|
174
164
|
* });
|
|
175
165
|
*
|
|
176
|
-
* const
|
|
166
|
+
* const { address, authToken, base64EncodedCaCert } = server;
|
|
177
167
|
*
|
|
178
168
|
* await server.stop();
|
|
179
169
|
* ```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PFrameFactoryAPIV2 } from './api_factory';
|
|
2
|
-
import type { PFrameReadAPIV8 } from './api_read';
|
|
1
|
+
import type { PFrameFactoryAPIV2, PFrameFactoryAPIV3 } from './api_factory';
|
|
2
|
+
import type { PFrameReadAPIV8, PFrameReadAPIV9 } from './api_read';
|
|
3
3
|
|
|
4
4
|
export type Logger = (
|
|
5
5
|
level: 'info' | 'warn' | 'error',
|
|
@@ -7,3 +7,30 @@ export type Logger = (
|
|
|
7
7
|
) => void;
|
|
8
8
|
|
|
9
9
|
export interface PFrameV9 extends PFrameFactoryAPIV2, PFrameReadAPIV8 {}
|
|
10
|
+
|
|
11
|
+
export interface PFrameV10 extends PFrameFactoryAPIV3, PFrameReadAPIV9 {}
|
|
12
|
+
|
|
13
|
+
export type PFrameOptions = {
|
|
14
|
+
/** Path to directory where PFrame can create temporary files */
|
|
15
|
+
spillPath: string;
|
|
16
|
+
/** Logger instance, no logging is performed when not provided */
|
|
17
|
+
logger?: Logger;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** List of PFrame management functions exposed by PFrame module */
|
|
21
|
+
export interface PFrameFactory {
|
|
22
|
+
/**
|
|
23
|
+
* Create a new PFrame instance.
|
|
24
|
+
* @warning Use concurrency limiting to avoid OOM crashes when multiple instances are simultaneously in use.
|
|
25
|
+
*/
|
|
26
|
+
createPFrame(options: PFrameOptions): PFrameV10;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Dump active allocations from all PFrames instances in pprof format.
|
|
30
|
+
* The result of this function should be saved as `profile.pb.gz`.
|
|
31
|
+
* Use {@link https://pprof.me/} or {@link https://www.speedscope.app/}
|
|
32
|
+
* to view the allocation flamechart.
|
|
33
|
+
* @warning This method will always reject on Windows!
|
|
34
|
+
*/
|
|
35
|
+
pprofDump: () => Promise<Uint8Array>;
|
|
36
|
+
};
|
|
@@ -72,3 +72,68 @@ export interface PTableV6 {
|
|
|
72
72
|
/** Deallocates all underlying resources */
|
|
73
73
|
dispose(): void;
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Table view returned as a result of create table operation.
|
|
78
|
+
*
|
|
79
|
+
* PTable can be thought as having a composite primary key, consisting of axes,
|
|
80
|
+
* and a set of data columns derived from PColumn values.
|
|
81
|
+
* */
|
|
82
|
+
export interface PTableV7 extends Disposable {
|
|
83
|
+
/**
|
|
84
|
+
* Returns ordered array of table axes specs (primary key "columns" in SQL
|
|
85
|
+
* terms) and data column specs (regular "columns" in SQL terms).
|
|
86
|
+
*
|
|
87
|
+
* Data for a specific table column can be retrieved using unified indexing
|
|
88
|
+
* corresponding to elements in this array.
|
|
89
|
+
*
|
|
90
|
+
* Axes are always listed first.
|
|
91
|
+
* */
|
|
92
|
+
getSpec(): PTableColumnSpec[];
|
|
93
|
+
|
|
94
|
+
/** Transforms unified column identifiers into unified indices of columns. */
|
|
95
|
+
getColumnIndices(columnIds: PTableColumnId[]): number[];
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get PTable disk footprint in bytes
|
|
99
|
+
* Warning: This call materializes the join.
|
|
100
|
+
*/
|
|
101
|
+
getFootprint(ops?: {
|
|
102
|
+
withPredecessors?: boolean,
|
|
103
|
+
signal?: AbortSignal,
|
|
104
|
+
}): Promise<number>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Unified table shape
|
|
108
|
+
* Warning: This call materializes the join.
|
|
109
|
+
*/
|
|
110
|
+
getShape(ops?: {
|
|
111
|
+
signal?: AbortSignal,
|
|
112
|
+
}): Promise<PTableShape>;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Retrieve the data from the table. To retrieve only data required, it can be
|
|
116
|
+
* sliced both horizontally ({@link columnIndices}) and vertically
|
|
117
|
+
* ({@link range}).
|
|
118
|
+
* This call materializes the join.
|
|
119
|
+
*
|
|
120
|
+
* @param columnIndices unified indices of columns to be retrieved
|
|
121
|
+
* @param range optionally limit the range of records to retrieve
|
|
122
|
+
* */
|
|
123
|
+
getData(
|
|
124
|
+
columnIndices: number[],
|
|
125
|
+
ops?: {
|
|
126
|
+
range?: TableRange,
|
|
127
|
+
signal?: AbortSignal,
|
|
128
|
+
},
|
|
129
|
+
): Promise<PTableVector[]>;
|
|
130
|
+
|
|
131
|
+
/** Filters the table and returns new PTable instance */
|
|
132
|
+
filter(request: PTableRecordFilter[]): PTableV7;
|
|
133
|
+
|
|
134
|
+
/** Sorts the table and returns new PTable instance. */
|
|
135
|
+
sort(request: PTableSorting[]): PTableV7;
|
|
136
|
+
|
|
137
|
+
/** Deallocates all underlying resources */
|
|
138
|
+
dispose(): void;
|
|
139
|
+
}
|