@milaboratories/pf-driver 1.0.41 → 1.0.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pf-driver",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "PFrameDriver implementation abstracted from Middle Layer",
5
5
  "keywords": [],
6
6
  "license": "UNLICENSED",
@@ -20,22 +20,22 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@milaboratories/pframes-rs-node": "1.0.109",
23
+ "@milaboratories/pframes-rs-node": "1.1.2",
24
+ "@milaboratories/pframes-rs-wasm": "0.1.0",
24
25
  "es-toolkit": "^1.39.10",
25
26
  "lru-cache": "^11.2.2",
26
- "@milaboratories/pl-model-middle-layer": "1.11.6",
27
27
  "@milaboratories/ts-helpers": "1.7.2",
28
- "@platforma-sdk/model": "1.53.14"
28
+ "@platforma-sdk/model": "1.53.15",
29
+ "@milaboratories/pl-model-middle-layer": "1.11.7"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/node": "~24.5.2",
32
33
  "@vitest/coverage-istanbul": "^4.0.16",
33
- "tsconfig-paths": "^4.2.0",
34
34
  "typescript": "~5.6.3",
35
35
  "vitest": "^4.0.16",
36
- "@milaboratories/build-configs": "1.4.2",
37
- "@milaboratories/ts-builder": "1.2.6",
38
- "@milaboratories/ts-configs": "1.2.1"
36
+ "@milaboratories/build-configs": "1.4.3",
37
+ "@milaboratories/ts-configs": "1.2.1",
38
+ "@milaboratories/ts-builder": "1.2.8"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=22.19.0"
@@ -39,6 +39,9 @@ export interface AbstractInternalPFrameDriver<PColumnData> extends PFrameDriver,
39
39
  /** Create a new PTable */
40
40
  createPTable(def: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle>;
41
41
 
42
+ /** Create a new PTable by new Pframe-rs api */
43
+ createPTableV2(def: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle>;
44
+
42
45
  /** Calculates data for the table and returns complete data representation of it */
43
46
  calculateTableData(
44
47
  handle: PFrameHandle,
@@ -142,3 +142,50 @@ test.for([{ testCase: "01_json" }, { testCase: "02_binary" }, { testCase: "03_pa
142
142
  expect(result).toEqual(expected);
143
143
  },
144
144
  );
145
+
146
+ test.skip("createTableV2 support", async ({ expect }) => {
147
+ await using driver = await createPFrameDriverDouble({});
148
+
149
+ const columnId = "column1" as PObjectId;
150
+ const columnSpec = {
151
+ kind: "PColumn" as const,
152
+ axesSpec: [
153
+ {
154
+ name: "axis1",
155
+ type: "String" as const,
156
+ },
157
+ ],
158
+ name: "column1",
159
+ valueType: "Int" as const,
160
+ };
161
+
162
+ using pTable = driver.createPTableV2({
163
+ src: {
164
+ type: "column",
165
+ column: {
166
+ id: columnId,
167
+ spec: columnSpec,
168
+ data: [
169
+ { key: ["a"], val: 10 },
170
+ { key: ["b"], val: 20 },
171
+ ],
172
+ },
173
+ },
174
+ partitionFilters: [],
175
+ filters: [],
176
+ sorting: [],
177
+ });
178
+
179
+ const uiDriver: PFrameDriver = driver;
180
+ const shape = await uiDriver.getShape(pTable.key);
181
+ expect(shape.rows).toBe(2);
182
+ expect(shape.columns).toBe(2); // 1 axis + 1 value column
183
+
184
+ const data = await uiDriver.getData(pTable.key, [0, 1]);
185
+ // axis column
186
+ expect(data[0].type).toBe("String");
187
+ expect([...data[0].data]).toEqual(["a", "b"]);
188
+ // value column
189
+ expect(data[1].type).toBe("Int");
190
+ expect([...data[1].data]).toEqual([10, 20]);
191
+ });
@@ -125,6 +125,7 @@ export type InternalPFrameDriverDouble = AbstractInternalPFrameDriver<
125
125
  PFrameInternal.DataInfo<FileName> | PColumnValues
126
126
  >;
127
127
 
128
+ // It's mock for testing purposes, not a real test!
128
129
  export async function createPFrameDriverDouble({
129
130
  dataFolder = tmpdir() as FolderPath,
130
131
  logger = () => {},
@@ -57,6 +57,7 @@ import {
57
57
  PTableCachePlainOpsDefaults,
58
58
  type PTableCachePlainOps,
59
59
  } from "./ptable_cache_plain";
60
+ // import { createPFrame as createSpecFrame } from "@milaboratories/pframes-rs-wasm";
60
61
 
61
62
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
62
63
  export interface LocalBlobProvider<
@@ -181,8 +182,11 @@ export class AbstractPFrameDriver<
181
182
  this.logger,
182
183
  ),
183
184
  );
184
-
185
- const pTableEntry = this.pTableDefs.acquire({ def: sortedDef, pFrameHandle: pFrameEntry.key });
185
+ const pTableEntry = this.pTableDefs.acquire({
186
+ type: "v1",
187
+ def: sortedDef,
188
+ pFrameHandle: pFrameEntry.key,
189
+ });
186
190
  if (logPFrames()) {
187
191
  this.logger(
188
192
  "info",
@@ -202,6 +206,52 @@ export class AbstractPFrameDriver<
202
206
  };
203
207
  }
204
208
 
209
+ public createPTableV2(_rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {
210
+ throw new Error("createPTableV2 is not implemented yet");
211
+ // const columns = extractAllColumns(rawDef.src);
212
+ // const pFrameEntry = this.createPFrame(columns);
213
+
214
+ // const columnsMap = columns.reduce(
215
+ // (acc, col) => ((acc[col.id] = col.spec), acc),
216
+ // {} as Record<string, PColumnSpec>,
217
+ // );
218
+ // const sortedDef = sortPTableDef(
219
+ // migratePTableFilters(
220
+ // mapPTableDef(rawDef, (c) => c.id),
221
+ // this.logger,
222
+ // ),
223
+ // );
224
+ // const specFrame = createSpecFrame(columnsMap);
225
+ // const specQuery = specFrame.rewriteLegacyQuery(sortedDef);
226
+ // const { tableSpec, dataQuery } = specFrame.evaluateQuery(specQuery);
227
+
228
+ // const pTableEntry = this.pTableDefs.acquire({
229
+ // type: "v2",
230
+ // pFrameHandle: pFrameEntry.key,
231
+ // def: {
232
+ // tableSpec,
233
+ // dataQuery,
234
+ // },
235
+ // });
236
+ // if (logPFrames()) {
237
+ // this.logger(
238
+ // "info",
239
+ // `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,
240
+ // );
241
+ // }
242
+
243
+ // const unref = () => {
244
+ // pTableEntry.unref();
245
+ // pFrameEntry.unref();
246
+ // };
247
+ // return {
248
+ // key: pTableEntry.key,
249
+ // resource: pTableEntry.resource,
250
+ // unref,
251
+ // [Symbol.dispose]: unref,
252
+ // };
253
+ }
254
+
205
255
  //
206
256
  // PFrame instance methods
207
257
  //
@@ -276,6 +326,7 @@ export class AbstractPFrameDriver<
276
326
  }
277
327
 
278
328
  const table = this.pTables.acquire({
329
+ type: "v1",
279
330
  pFrameHandle: handle,
280
331
  def: sortPTableDef(migratePTableFilters(request, this.logger)),
281
332
  });
@@ -2,7 +2,8 @@ import { PFrameDriverError, type PTableHandle } from "@platforma-sdk/model";
2
2
  import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
3
3
  import { RefCountPoolBase } from "@milaboratories/ts-helpers";
4
4
  import { logPFrames } from "./logging";
5
- import { stableKeyFromFullPTableDef, type FullPTableDef } from "./ptable_shared";
5
+ import type { FullPTableDef } from "./ptable_shared";
6
+ import { stableKeyFromFullPTableDef } from "./ptable_shared";
6
7
 
7
8
  export class PTableDefHolder implements Disposable {
8
9
  private readonly abortController = new AbortController();
@@ -13,7 +13,12 @@ import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
13
13
  import { RefCountPoolBase, type PoolEntry } from "@milaboratories/ts-helpers";
14
14
  import { logPFrames } from "./logging";
15
15
  import type { PFramePool } from "./pframe_pool";
16
- import { stableKeyFromFullPTableDef, type FullPTableDef } from "./ptable_shared";
16
+ import {
17
+ FullPTableDefV1,
18
+ FullPTableDefV2,
19
+ stableKeyFromFullPTableDef,
20
+ type FullPTableDef,
21
+ } from "./ptable_shared";
17
22
  import type { PTableDefPool } from "./ptable_def_pool";
18
23
 
19
24
  export class PTableHolder implements Disposable {
@@ -72,53 +77,83 @@ export class PTablePool<TreeEntry extends JsonSerializable> extends RefCountPool
72
77
  );
73
78
  }
74
79
 
75
- const handle = params.pFrameHandle;
76
- const { pFramePromise, disposeSignal } = this.pFrames.getByKey(handle);
80
+ switch (params.type) {
81
+ case "v1":
82
+ return this.createNewResourceV1(params, key);
83
+ case "v2":
84
+ return this.createNewResourceV2(params, key);
85
+ default:
86
+ // @ts-expect-error `params.type` is a string, but we want to make sure all cases are handled
87
+ throw new PFrameDriverError(`Unsupported FullPTableDef type: ${params.type}`);
88
+ }
89
+ }
90
+
91
+ protected createNewResourceV1(params: FullPTableDefV1, key: PTableHandle): PTableHolder {
92
+ const { def, pFrameHandle } = params;
93
+ const { pFramePromise, disposeSignal } = this.pFrames.getByKey(pFrameHandle);
77
94
 
78
95
  const defDisposeSignal = this.pTableDefs.tryGetByKey(key)?.disposeSignal;
79
96
  const combinedSignal = AbortSignal.any([disposeSignal, defDisposeSignal].filter((s) => !!s));
80
97
 
81
98
  // 3. Sort
82
- if (params.def.sorting.length > 0) {
99
+ if (def.sorting.length > 0) {
83
100
  const predecessor = this.acquire({
84
101
  ...params,
85
102
  def: {
86
- ...params.def,
103
+ ...def,
87
104
  sorting: [],
88
105
  },
89
106
  });
90
107
  const {
91
108
  resource: { pTablePromise },
92
109
  } = predecessor;
93
- const sortedTable = pTablePromise.then((pTable) => pTable.sort(key, params.def.sorting));
94
- return new PTableHolder(handle, combinedSignal, sortedTable, predecessor);
110
+ const sortedTable = pTablePromise.then((pTable) => pTable.sort(key, def.sorting));
111
+ return new PTableHolder(pFrameHandle, combinedSignal, sortedTable, predecessor);
95
112
  }
96
113
 
97
114
  // 2. Filter (except the case with artificial columns where cartesian creates too many rows)
98
- if (!hasArtificialColumns(params.def.src) && params.def.filters.length > 0) {
115
+ if (!hasArtificialColumns(def.src) && def.filters.length > 0) {
99
116
  const predecessor = this.acquire({
100
117
  ...params,
101
118
  def: {
102
- ...params.def,
119
+ ...def,
103
120
  filters: [],
104
121
  },
105
122
  });
106
123
  const {
107
124
  resource: { pTablePromise },
108
125
  } = predecessor;
109
- const filteredTable = pTablePromise.then((pTable) => pTable.filter(key, params.def.filters));
110
- return new PTableHolder(handle, combinedSignal, filteredTable, predecessor);
126
+ const filteredTable = pTablePromise.then((pTable) => pTable.filter(key, def.filters));
127
+ return new PTableHolder(pFrameHandle, combinedSignal, filteredTable, predecessor);
111
128
  }
112
129
 
113
130
  // 1. Join
114
131
  const table = pFramePromise.then((pFrame) =>
115
132
  pFrame.createTable(key, {
116
- src: joinEntryToInternal(params.def.src),
117
- // `params.def.filters` would be non-empty only when join has artificial columns
118
- filters: [...params.def.partitionFilters, ...params.def.filters],
133
+ src: joinEntryToInternal(def.src),
134
+ // `def.filters` would be non-empty only when join has artificial columns
135
+ filters: [...def.partitionFilters, ...def.filters],
119
136
  }),
120
137
  );
121
- return new PTableHolder(handle, combinedSignal, table);
138
+ return new PTableHolder(pFrameHandle, combinedSignal, table);
139
+ }
140
+
141
+ protected createNewResourceV2(params: FullPTableDefV2, key: PTableHandle): PTableHolder {
142
+ if (logPFrames()) {
143
+ this.logger(
144
+ "info",
145
+ `PTable creation (pTableHandle = ${key}): ` + `${JSON.stringify(params, bigintReplacer)}`,
146
+ );
147
+ }
148
+
149
+ const { pFrameHandle } = params;
150
+ const { pFramePromise, disposeSignal } = this.pFrames.getByKey(pFrameHandle);
151
+
152
+ const defDisposeSignal = this.pTableDefs.tryGetByKey(key)?.disposeSignal;
153
+ const combinedSignal = AbortSignal.any([disposeSignal, defDisposeSignal].filter((s) => !!s));
154
+
155
+ const table = pFramePromise.then((pFrame) => pFrame.createTableByV2(key, params.def));
156
+ return new PTableHolder(pFrameHandle, combinedSignal, table);
122
157
  }
123
158
 
124
159
  public getByKey(key: PTableHandle): PTableHolder {
@@ -1,11 +1,30 @@
1
- import type { PObjectId, PFrameHandle, PTableDef, PTableHandle } from "@platforma-sdk/model";
1
+ import type {
2
+ PObjectId,
3
+ PFrameHandle,
4
+ PTableDef,
5
+ PTableHandle,
6
+ QueryData,
7
+ PTableColumnSpec,
8
+ } from "@platforma-sdk/model";
2
9
  import { hashJson } from "@milaboratories/pl-model-middle-layer";
3
10
 
4
- export type FullPTableDef = {
11
+ export type FullPTableDefV1 = {
12
+ type: "v1";
5
13
  pFrameHandle: PFrameHandle;
6
14
  def: PTableDef<PObjectId>;
7
15
  };
8
16
 
17
+ export type FullPTableDefV2 = {
18
+ type: "v2";
19
+ pFrameHandle: PFrameHandle;
20
+ def: {
21
+ tableSpec: PTableColumnSpec[];
22
+ dataQuery: QueryData;
23
+ };
24
+ };
25
+
26
+ export type FullPTableDef = FullPTableDefV1 | FullPTableDefV2;
27
+
9
28
  export function stableKeyFromFullPTableDef(data: FullPTableDef): PTableHandle {
10
29
  return hashJson(data) as string as PTableHandle;
11
30
  }