@milaboratories/pf-spec-driver 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/spec_driver.cjs +60 -0
- package/dist/spec_driver.cjs.map +1 -0
- package/dist/spec_driver.d.ts +25 -0
- package/dist/spec_driver.js +60 -0
- package/dist/spec_driver.js.map +1 -0
- package/package.json +46 -0
- package/src/index.ts +1 -0
- package/src/spec_driver.test.ts +38 -0
- package/src/spec_driver.ts +91 -0
package/dist/index.cjs
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
let _milaboratories_pframes_rs_wasm = require("@milaboratories/pframes-rs-wasm");
|
|
2
|
+
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
3
|
+
|
|
4
|
+
//#region src/spec_driver.ts
|
|
5
|
+
/**
|
|
6
|
+
* Manages spec-only PFrame instances (WASM) with handle-based lifecycle.
|
|
7
|
+
*
|
|
8
|
+
* All operations are synchronous — WASM computes results immediately.
|
|
9
|
+
*/
|
|
10
|
+
var SpecDriver = class {
|
|
11
|
+
frames = /* @__PURE__ */ new Map();
|
|
12
|
+
createSpecFrame(specs) {
|
|
13
|
+
const frame = (0, _milaboratories_pframes_rs_wasm.createPFrame)(specs);
|
|
14
|
+
const handle = crypto.randomUUID();
|
|
15
|
+
this.frames.set(handle, frame);
|
|
16
|
+
return handle;
|
|
17
|
+
}
|
|
18
|
+
specFrameDiscoverColumns(handle, request) {
|
|
19
|
+
return this.getFrame(handle).discoverColumns(request);
|
|
20
|
+
}
|
|
21
|
+
disposeSpecFrame(handle) {
|
|
22
|
+
const frame = this.frames.get(handle);
|
|
23
|
+
if (frame) {
|
|
24
|
+
frame[Symbol.dispose]();
|
|
25
|
+
this.frames.delete(handle);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
expandAxes(spec) {
|
|
29
|
+
return (0, _milaboratories_pframes_rs_wasm.expandAxes)(spec);
|
|
30
|
+
}
|
|
31
|
+
collapseAxes(ids) {
|
|
32
|
+
return (0, _milaboratories_pframes_rs_wasm.collapseAxes)(ids);
|
|
33
|
+
}
|
|
34
|
+
findAxis(spec, selector) {
|
|
35
|
+
return (0, _milaboratories_pframes_rs_wasm.findAxis)(spec, selector);
|
|
36
|
+
}
|
|
37
|
+
findTableColumn(tableSpec, selector) {
|
|
38
|
+
return (0, _milaboratories_pframes_rs_wasm.findTableColumn)(tableSpec, selector);
|
|
39
|
+
}
|
|
40
|
+
/** Dispose all managed spec frames. */
|
|
41
|
+
dispose() {
|
|
42
|
+
try {
|
|
43
|
+
for (const frame of this.frames.values()) frame[Symbol.dispose]();
|
|
44
|
+
} finally {
|
|
45
|
+
this.frames.clear();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
[Symbol.dispose]() {
|
|
49
|
+
this.dispose();
|
|
50
|
+
}
|
|
51
|
+
getFrame(handle) {
|
|
52
|
+
const frame = this.frames.get(handle);
|
|
53
|
+
if (frame === void 0) throw new _milaboratories_pl_model_common.PFrameSpecDriverError(`No such spec frame: ${handle}`);
|
|
54
|
+
return frame;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
exports.SpecDriver = SpecDriver;
|
|
60
|
+
//# sourceMappingURL=spec_driver.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec_driver.cjs","names":["PFrameSpecDriverError"],"sources":["../src/spec_driver.ts"],"sourcesContent":["import {\n createPFrame,\n expandAxes,\n collapseAxes,\n findAxis,\n findTableColumn,\n} from \"@milaboratories/pframes-rs-wasm\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport type {\n AxesId,\n AxesSpec,\n PColumnSpec,\n PFrameSpecDriver,\n PTableColumnId,\n PTableColumnSpec,\n SingleAxisSelector,\n SpecFrameHandle,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameSpecDriverError } from \"@milaboratories/pl-model-common\";\n\n/**\n * Manages spec-only PFrame instances (WASM) with handle-based lifecycle.\n *\n * All operations are synchronous — WASM computes results immediately.\n */\nexport class SpecDriver implements PFrameSpecDriver, Disposable {\n private readonly frames = new Map<SpecFrameHandle, PFrameInternal.PFrameWasmV2>();\n\n createSpecFrame(specs: Record<string, PColumnSpec>): SpecFrameHandle {\n // Explicit annotation ensures a WASM version mismatch surfaces at compile time\n // (skipLibCheck won't validate .d.ts in node_modules, but this assignment will)\n const frame: PFrameInternal.PFrameWasmV2 = createPFrame(specs);\n const handle = crypto.randomUUID() as SpecFrameHandle;\n this.frames.set(handle, frame);\n return handle;\n }\n\n specFrameDiscoverColumns(\n handle: SpecFrameHandle,\n request: DiscoverColumnsRequest,\n ): DiscoverColumnsResponse {\n return this.getFrame(handle).discoverColumns(request);\n }\n\n disposeSpecFrame(handle: SpecFrameHandle): void {\n const frame = this.frames.get(handle);\n if (frame) {\n frame[Symbol.dispose]();\n this.frames.delete(handle);\n }\n }\n\n expandAxes(spec: AxesSpec): AxesId {\n return expandAxes(spec);\n }\n\n collapseAxes(ids: AxesId): AxesSpec {\n return collapseAxes(ids);\n }\n\n findAxis(spec: AxesSpec, selector: SingleAxisSelector): number {\n return findAxis(spec, selector);\n }\n\n findTableColumn(tableSpec: PTableColumnSpec[], selector: PTableColumnId): number {\n return findTableColumn(tableSpec, selector);\n }\n\n /** Dispose all managed spec frames. */\n dispose(): void {\n try {\n for (const frame of this.frames.values()) {\n frame[Symbol.dispose]();\n }\n } finally {\n this.frames.clear();\n }\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n private getFrame(handle: SpecFrameHandle): PFrameInternal.PFrameWasmV2 {\n const frame = this.frames.get(handle);\n if (frame === undefined) throw new PFrameSpecDriverError(`No such spec frame: ${handle}`);\n return frame;\n }\n}\n"],"mappings":";;;;;;;;;AA2BA,IAAa,aAAb,MAAgE;CAC9D,AAAiB,yBAAS,IAAI,KAAmD;CAEjF,gBAAgB,OAAqD;EAGnE,MAAM,0DAAkD,MAAM;EAC9D,MAAM,SAAS,OAAO,YAAY;AAClC,OAAK,OAAO,IAAI,QAAQ,MAAM;AAC9B,SAAO;;CAGT,yBACE,QACA,SACyB;AACzB,SAAO,KAAK,SAAS,OAAO,CAAC,gBAAgB,QAAQ;;CAGvD,iBAAiB,QAA+B;EAC9C,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,MAAI,OAAO;AACT,SAAM,OAAO,UAAU;AACvB,QAAK,OAAO,OAAO,OAAO;;;CAI9B,WAAW,MAAwB;AACjC,yDAAkB,KAAK;;CAGzB,aAAa,KAAuB;AAClC,2DAAoB,IAAI;;CAG1B,SAAS,MAAgB,UAAsC;AAC7D,uDAAgB,MAAM,SAAS;;CAGjC,gBAAgB,WAA+B,UAAkC;AAC/E,8DAAuB,WAAW,SAAS;;;CAI7C,UAAgB;AACd,MAAI;AACF,QAAK,MAAM,SAAS,KAAK,OAAO,QAAQ,CACtC,OAAM,OAAO,UAAU;YAEjB;AACR,QAAK,OAAO,OAAO;;;CAIvB,CAAC,OAAO,WAAiB;AACvB,OAAK,SAAS;;CAGhB,AAAQ,SAAS,QAAsD;EACrE,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,MAAI,UAAU,OAAW,OAAM,IAAIA,sDAAsB,uBAAuB,SAAS;AACzF,SAAO"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AxesId, AxesSpec, DiscoverColumnsRequest, DiscoverColumnsResponse, PColumnSpec, PFrameSpecDriver, PTableColumnId, PTableColumnSpec, SingleAxisSelector, SpecFrameHandle } from "@milaboratories/pl-model-common";
|
|
2
|
+
|
|
3
|
+
//#region src/spec_driver.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Manages spec-only PFrame instances (WASM) with handle-based lifecycle.
|
|
6
|
+
*
|
|
7
|
+
* All operations are synchronous — WASM computes results immediately.
|
|
8
|
+
*/
|
|
9
|
+
declare class SpecDriver implements PFrameSpecDriver, Disposable {
|
|
10
|
+
private readonly frames;
|
|
11
|
+
createSpecFrame(specs: Record<string, PColumnSpec>): SpecFrameHandle;
|
|
12
|
+
specFrameDiscoverColumns(handle: SpecFrameHandle, request: DiscoverColumnsRequest): DiscoverColumnsResponse;
|
|
13
|
+
disposeSpecFrame(handle: SpecFrameHandle): void;
|
|
14
|
+
expandAxes(spec: AxesSpec): AxesId;
|
|
15
|
+
collapseAxes(ids: AxesId): AxesSpec;
|
|
16
|
+
findAxis(spec: AxesSpec, selector: SingleAxisSelector): number;
|
|
17
|
+
findTableColumn(tableSpec: PTableColumnSpec[], selector: PTableColumnId): number;
|
|
18
|
+
/** Dispose all managed spec frames. */
|
|
19
|
+
dispose(): void;
|
|
20
|
+
[Symbol.dispose](): void;
|
|
21
|
+
private getFrame;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { SpecDriver };
|
|
25
|
+
//# sourceMappingURL=spec_driver.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { collapseAxes, createPFrame, expandAxes, findAxis, findTableColumn } from "@milaboratories/pframes-rs-wasm";
|
|
2
|
+
import { PFrameSpecDriverError } from "@milaboratories/pl-model-common";
|
|
3
|
+
|
|
4
|
+
//#region src/spec_driver.ts
|
|
5
|
+
/**
|
|
6
|
+
* Manages spec-only PFrame instances (WASM) with handle-based lifecycle.
|
|
7
|
+
*
|
|
8
|
+
* All operations are synchronous — WASM computes results immediately.
|
|
9
|
+
*/
|
|
10
|
+
var SpecDriver = class {
|
|
11
|
+
frames = /* @__PURE__ */ new Map();
|
|
12
|
+
createSpecFrame(specs) {
|
|
13
|
+
const frame = createPFrame(specs);
|
|
14
|
+
const handle = crypto.randomUUID();
|
|
15
|
+
this.frames.set(handle, frame);
|
|
16
|
+
return handle;
|
|
17
|
+
}
|
|
18
|
+
specFrameDiscoverColumns(handle, request) {
|
|
19
|
+
return this.getFrame(handle).discoverColumns(request);
|
|
20
|
+
}
|
|
21
|
+
disposeSpecFrame(handle) {
|
|
22
|
+
const frame = this.frames.get(handle);
|
|
23
|
+
if (frame) {
|
|
24
|
+
frame[Symbol.dispose]();
|
|
25
|
+
this.frames.delete(handle);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
expandAxes(spec) {
|
|
29
|
+
return expandAxes(spec);
|
|
30
|
+
}
|
|
31
|
+
collapseAxes(ids) {
|
|
32
|
+
return collapseAxes(ids);
|
|
33
|
+
}
|
|
34
|
+
findAxis(spec, selector) {
|
|
35
|
+
return findAxis(spec, selector);
|
|
36
|
+
}
|
|
37
|
+
findTableColumn(tableSpec, selector) {
|
|
38
|
+
return findTableColumn(tableSpec, selector);
|
|
39
|
+
}
|
|
40
|
+
/** Dispose all managed spec frames. */
|
|
41
|
+
dispose() {
|
|
42
|
+
try {
|
|
43
|
+
for (const frame of this.frames.values()) frame[Symbol.dispose]();
|
|
44
|
+
} finally {
|
|
45
|
+
this.frames.clear();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
[Symbol.dispose]() {
|
|
49
|
+
this.dispose();
|
|
50
|
+
}
|
|
51
|
+
getFrame(handle) {
|
|
52
|
+
const frame = this.frames.get(handle);
|
|
53
|
+
if (frame === void 0) throw new PFrameSpecDriverError(`No such spec frame: ${handle}`);
|
|
54
|
+
return frame;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { SpecDriver };
|
|
60
|
+
//# sourceMappingURL=spec_driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec_driver.js","names":[],"sources":["../src/spec_driver.ts"],"sourcesContent":["import {\n createPFrame,\n expandAxes,\n collapseAxes,\n findAxis,\n findTableColumn,\n} from \"@milaboratories/pframes-rs-wasm\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport type {\n AxesId,\n AxesSpec,\n PColumnSpec,\n PFrameSpecDriver,\n PTableColumnId,\n PTableColumnSpec,\n SingleAxisSelector,\n SpecFrameHandle,\n DiscoverColumnsRequest,\n DiscoverColumnsResponse,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameSpecDriverError } from \"@milaboratories/pl-model-common\";\n\n/**\n * Manages spec-only PFrame instances (WASM) with handle-based lifecycle.\n *\n * All operations are synchronous — WASM computes results immediately.\n */\nexport class SpecDriver implements PFrameSpecDriver, Disposable {\n private readonly frames = new Map<SpecFrameHandle, PFrameInternal.PFrameWasmV2>();\n\n createSpecFrame(specs: Record<string, PColumnSpec>): SpecFrameHandle {\n // Explicit annotation ensures a WASM version mismatch surfaces at compile time\n // (skipLibCheck won't validate .d.ts in node_modules, but this assignment will)\n const frame: PFrameInternal.PFrameWasmV2 = createPFrame(specs);\n const handle = crypto.randomUUID() as SpecFrameHandle;\n this.frames.set(handle, frame);\n return handle;\n }\n\n specFrameDiscoverColumns(\n handle: SpecFrameHandle,\n request: DiscoverColumnsRequest,\n ): DiscoverColumnsResponse {\n return this.getFrame(handle).discoverColumns(request);\n }\n\n disposeSpecFrame(handle: SpecFrameHandle): void {\n const frame = this.frames.get(handle);\n if (frame) {\n frame[Symbol.dispose]();\n this.frames.delete(handle);\n }\n }\n\n expandAxes(spec: AxesSpec): AxesId {\n return expandAxes(spec);\n }\n\n collapseAxes(ids: AxesId): AxesSpec {\n return collapseAxes(ids);\n }\n\n findAxis(spec: AxesSpec, selector: SingleAxisSelector): number {\n return findAxis(spec, selector);\n }\n\n findTableColumn(tableSpec: PTableColumnSpec[], selector: PTableColumnId): number {\n return findTableColumn(tableSpec, selector);\n }\n\n /** Dispose all managed spec frames. */\n dispose(): void {\n try {\n for (const frame of this.frames.values()) {\n frame[Symbol.dispose]();\n }\n } finally {\n this.frames.clear();\n }\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n private getFrame(handle: SpecFrameHandle): PFrameInternal.PFrameWasmV2 {\n const frame = this.frames.get(handle);\n if (frame === undefined) throw new PFrameSpecDriverError(`No such spec frame: ${handle}`);\n return frame;\n }\n}\n"],"mappings":";;;;;;;;;AA2BA,IAAa,aAAb,MAAgE;CAC9D,AAAiB,yBAAS,IAAI,KAAmD;CAEjF,gBAAgB,OAAqD;EAGnE,MAAM,QAAqC,aAAa,MAAM;EAC9D,MAAM,SAAS,OAAO,YAAY;AAClC,OAAK,OAAO,IAAI,QAAQ,MAAM;AAC9B,SAAO;;CAGT,yBACE,QACA,SACyB;AACzB,SAAO,KAAK,SAAS,OAAO,CAAC,gBAAgB,QAAQ;;CAGvD,iBAAiB,QAA+B;EAC9C,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,MAAI,OAAO;AACT,SAAM,OAAO,UAAU;AACvB,QAAK,OAAO,OAAO,OAAO;;;CAI9B,WAAW,MAAwB;AACjC,SAAO,WAAW,KAAK;;CAGzB,aAAa,KAAuB;AAClC,SAAO,aAAa,IAAI;;CAG1B,SAAS,MAAgB,UAAsC;AAC7D,SAAO,SAAS,MAAM,SAAS;;CAGjC,gBAAgB,WAA+B,UAAkC;AAC/E,SAAO,gBAAgB,WAAW,SAAS;;;CAI7C,UAAgB;AACd,MAAI;AACF,QAAK,MAAM,SAAS,KAAK,OAAO,QAAQ,CACtC,OAAM,OAAO,UAAU;YAEjB;AACR,QAAK,OAAO,OAAO;;;CAIvB,CAAC,OAAO,WAAiB;AACvB,OAAK,SAAS;;CAGhB,AAAQ,SAAS,QAAsD;EACrE,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;AACrC,MAAI,UAAU,OAAW,OAAM,IAAI,sBAAsB,uBAAuB,SAAS;AACzF,SAAO"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@milaboratories/pf-spec-driver",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "PSpecDriver implementation: spec-only PFrame operations via WASM",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"files": [
|
|
8
|
+
"./dist/**/*",
|
|
9
|
+
"./src/**/*"
|
|
10
|
+
],
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"module": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@milaboratories/pframes-rs-wasm": "1.1.15",
|
|
24
|
+
"@milaboratories/pl-model-middle-layer": "1.16.0",
|
|
25
|
+
"@milaboratories/pl-model-common": "1.29.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@vitest/coverage-istanbul": "^4.0.18",
|
|
29
|
+
"typescript": "~5.9.3",
|
|
30
|
+
"vitest": "^4.0.18",
|
|
31
|
+
"@milaboratories/ts-configs": "1.2.2",
|
|
32
|
+
"@milaboratories/build-configs": "1.5.2",
|
|
33
|
+
"@milaboratories/ts-builder": "1.3.0"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "ts-builder build --target node",
|
|
37
|
+
"watch": "ts-builder build --target node --watch",
|
|
38
|
+
"check": "ts-builder check --target node",
|
|
39
|
+
"formatter:check": "ts-builder formatter --check",
|
|
40
|
+
"linter:check": "ts-builder linter --check",
|
|
41
|
+
"types:check": "ts-builder type-check --target node",
|
|
42
|
+
"test": "vitest run --coverage",
|
|
43
|
+
"do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz",
|
|
44
|
+
"fmt": "ts-builder format"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SpecDriver } from "./spec_driver";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AxisSpec, PColumnSpec } from "@milaboratories/pl-model-common";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { SpecDriver } from "./spec_driver";
|
|
4
|
+
|
|
5
|
+
function createSpec(name: string, axesSpec?: AxisSpec[]): PColumnSpec {
|
|
6
|
+
return {
|
|
7
|
+
kind: "PColumn",
|
|
8
|
+
name,
|
|
9
|
+
valueType: "Int",
|
|
10
|
+
axesSpec: axesSpec ?? [{ name: "id", type: "String" } as AxisSpec],
|
|
11
|
+
annotations: {},
|
|
12
|
+
} as PColumnSpec;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe("SpecDriver", () => {
|
|
16
|
+
test("discoverColumns returns all columns with no filters", () => {
|
|
17
|
+
using driver = new SpecDriver();
|
|
18
|
+
const handle = driver.createSpecFrame({
|
|
19
|
+
col1: createSpec("col1"),
|
|
20
|
+
col2: createSpec("col2"),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const response = driver.specFrameDiscoverColumns(handle, {
|
|
24
|
+
axes: [],
|
|
25
|
+
maxHops: 0,
|
|
26
|
+
constraints: {
|
|
27
|
+
allowFloatingSourceAxes: true,
|
|
28
|
+
allowFloatingHitAxes: true,
|
|
29
|
+
allowSourceQualifications: false,
|
|
30
|
+
allowHitQualifications: false,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(response.hits).toHaveLength(2);
|
|
35
|
+
const names = response.hits.map((h) => h.hit.spec.name).sort();
|
|
36
|
+
expect(names).toEqual(["col1", "col2"]);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPFrame,
|
|
3
|
+
expandAxes,
|
|
4
|
+
collapseAxes,
|
|
5
|
+
findAxis,
|
|
6
|
+
findTableColumn,
|
|
7
|
+
} from "@milaboratories/pframes-rs-wasm";
|
|
8
|
+
import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
|
|
9
|
+
import type {
|
|
10
|
+
AxesId,
|
|
11
|
+
AxesSpec,
|
|
12
|
+
PColumnSpec,
|
|
13
|
+
PFrameSpecDriver,
|
|
14
|
+
PTableColumnId,
|
|
15
|
+
PTableColumnSpec,
|
|
16
|
+
SingleAxisSelector,
|
|
17
|
+
SpecFrameHandle,
|
|
18
|
+
DiscoverColumnsRequest,
|
|
19
|
+
DiscoverColumnsResponse,
|
|
20
|
+
} from "@milaboratories/pl-model-common";
|
|
21
|
+
import { PFrameSpecDriverError } from "@milaboratories/pl-model-common";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Manages spec-only PFrame instances (WASM) with handle-based lifecycle.
|
|
25
|
+
*
|
|
26
|
+
* All operations are synchronous — WASM computes results immediately.
|
|
27
|
+
*/
|
|
28
|
+
export class SpecDriver implements PFrameSpecDriver, Disposable {
|
|
29
|
+
private readonly frames = new Map<SpecFrameHandle, PFrameInternal.PFrameWasmV2>();
|
|
30
|
+
|
|
31
|
+
createSpecFrame(specs: Record<string, PColumnSpec>): SpecFrameHandle {
|
|
32
|
+
// Explicit annotation ensures a WASM version mismatch surfaces at compile time
|
|
33
|
+
// (skipLibCheck won't validate .d.ts in node_modules, but this assignment will)
|
|
34
|
+
const frame: PFrameInternal.PFrameWasmV2 = createPFrame(specs);
|
|
35
|
+
const handle = crypto.randomUUID() as SpecFrameHandle;
|
|
36
|
+
this.frames.set(handle, frame);
|
|
37
|
+
return handle;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
specFrameDiscoverColumns(
|
|
41
|
+
handle: SpecFrameHandle,
|
|
42
|
+
request: DiscoverColumnsRequest,
|
|
43
|
+
): DiscoverColumnsResponse {
|
|
44
|
+
return this.getFrame(handle).discoverColumns(request);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
disposeSpecFrame(handle: SpecFrameHandle): void {
|
|
48
|
+
const frame = this.frames.get(handle);
|
|
49
|
+
if (frame) {
|
|
50
|
+
frame[Symbol.dispose]();
|
|
51
|
+
this.frames.delete(handle);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
expandAxes(spec: AxesSpec): AxesId {
|
|
56
|
+
return expandAxes(spec);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
collapseAxes(ids: AxesId): AxesSpec {
|
|
60
|
+
return collapseAxes(ids);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
findAxis(spec: AxesSpec, selector: SingleAxisSelector): number {
|
|
64
|
+
return findAxis(spec, selector);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
findTableColumn(tableSpec: PTableColumnSpec[], selector: PTableColumnId): number {
|
|
68
|
+
return findTableColumn(tableSpec, selector);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Dispose all managed spec frames. */
|
|
72
|
+
dispose(): void {
|
|
73
|
+
try {
|
|
74
|
+
for (const frame of this.frames.values()) {
|
|
75
|
+
frame[Symbol.dispose]();
|
|
76
|
+
}
|
|
77
|
+
} finally {
|
|
78
|
+
this.frames.clear();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[Symbol.dispose](): void {
|
|
83
|
+
this.dispose();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private getFrame(handle: SpecFrameHandle): PFrameInternal.PFrameWasmV2 {
|
|
87
|
+
const frame = this.frames.get(handle);
|
|
88
|
+
if (frame === undefined) throw new PFrameSpecDriverError(`No such spec frame: ${handle}`);
|
|
89
|
+
return frame;
|
|
90
|
+
}
|
|
91
|
+
}
|