@platforma-open/milaboratories.sequence-properties.model 1.2.4 → 1.3.1
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/.turbo/turbo-build.log +18 -14
- package/.turbo/turbo-check.log +4 -4
- package/.turbo/turbo-test.log +15 -0
- package/CHANGELOG.md +21 -0
- package/dist/bundle.js +24 -4
- package/dist/bundle.js.map +1 -1
- package/dist/dataModel.cjs +10 -2
- package/dist/dataModel.cjs.map +1 -1
- package/dist/dataModel.d.ts.map +1 -1
- package/dist/dataModel.js +10 -2
- package/dist/dataModel.js.map +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/label.cjs +13 -0
- package/dist/label.cjs.map +1 -0
- package/dist/label.js +12 -0
- package/dist/label.js.map +1 -0
- package/dist/model.json +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/dataModel.test.ts +63 -0
- package/src/dataModel.ts +24 -6
- package/src/index.ts +3 -1
- package/src/label.test.ts +62 -0
- package/src/label.ts +17 -0
- package/src/types.ts +16 -4
- package/vitest.config.mts +8 -0
package/dist/types.d.ts
CHANGED
|
@@ -7,12 +7,19 @@ type BlockDataV1 = {
|
|
|
7
7
|
tableState: PlDataTableStateV2;
|
|
8
8
|
defaultBlockLabel?: string;
|
|
9
9
|
};
|
|
10
|
-
type
|
|
10
|
+
type BlockDataV2 = Omit<BlockDataV1, "defaultBlockLabel"> & {
|
|
11
|
+
defaultBlockLabel?: string;
|
|
12
|
+
customBlockLabel?: string;
|
|
11
13
|
graphStateScatter: GraphMakerState;
|
|
12
14
|
graphStateHistogram: GraphMakerState;
|
|
13
15
|
};
|
|
16
|
+
type BlockData = Omit<BlockDataV2, "defaultBlockLabel"> & {
|
|
17
|
+
defaultBlockLabel: string;
|
|
18
|
+
customBlockLabel: string;
|
|
19
|
+
};
|
|
14
20
|
type BlockArgs = {
|
|
15
21
|
inputAnchor: PlRef;
|
|
22
|
+
traceLabel: string;
|
|
16
23
|
};
|
|
17
24
|
type WorkflowMode = "peptide" | "antibody_tcr_universal" | "antibody_tcr_legacy_bulk" | "antibody_tcr_legacy_sc";
|
|
18
25
|
type WorkflowReceptor = "IG" | "TCRAB" | "TCRGD";
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;KAKY,WAAA;EACV,WAAA,GAAc,KAAA;EACd,UAAA,EAAY,kBAAA;EAIZ,iBAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;KAKY,WAAA;EACV,WAAA,GAAc,KAAA;EACd,UAAA,EAAY,kBAAA;EAIZ,iBAAA;AAAA;AAAA,KAOU,WAAA,GAAc,IAAA,CAAK,WAAA;EAC7B,iBAAA;EACA,gBAAA;EACA,iBAAA,EAAmB,eAAA;EACnB,mBAAA,EAAqB,eAAA;AAAA;AAAA,KAGX,SAAA,GAAY,IAAA,CAAK,WAAA;EAC3B,iBAAA;EACA,gBAAA;AAAA;AAAA,KAGU,SAAA;EACV,WAAA,EAAa,KAAA;EACb,UAAA;AAAA;AAAA,KAGU,YAAA;AAAA,KAMA,gBAAA;AAAA,KAEA,YAAA;EACV,IAAA,GAAO,YAAA;EACP,QAAA,GAAW,gBAAA;EACX,YAAA;EACA,QAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-open/milaboratories.sequence-properties.model",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Block model",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@milaboratories/ts-builder": "1.4.0",
|
|
23
23
|
"@milaboratories/ts-configs": "1.2.3",
|
|
24
|
-
"@platforma-sdk/block-tools": "2.
|
|
24
|
+
"@platforma-sdk/block-tools": "2.10.0",
|
|
25
|
+
"vitest": "^4.0.18"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"@types/node": "*",
|
|
@@ -31,6 +32,8 @@
|
|
|
31
32
|
"fmt": "ts-builder format",
|
|
32
33
|
"watch": "ts-builder build --target block-model --watch",
|
|
33
34
|
"build": "ts-builder build --target block-model && block-tools build-model",
|
|
34
|
-
"check": "ts-builder check --target block-model"
|
|
35
|
+
"check": "ts-builder check --target block-model",
|
|
36
|
+
"test": "vitest --run --passWithNoTests",
|
|
37
|
+
"test:watch": "vitest"
|
|
35
38
|
}
|
|
36
39
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Tests drive the migration callbacks directly because @platforma-sdk/model's
|
|
2
|
+
// DataModelBuilder exposes no introspection / external-apply API. The builder
|
|
3
|
+
// wiring in dataModel.ts (the two `.migrate(...)` calls) is only exercised
|
|
4
|
+
// when a real block loads — these unit tests would still pass if someone
|
|
5
|
+
// deleted a `.migrate(...)` line while keeping the named callback exported.
|
|
6
|
+
|
|
7
|
+
import { describe, expect, it } from "vitest";
|
|
8
|
+
import type { BlockData, BlockDataV1, BlockDataV2 } from "./types";
|
|
9
|
+
import { migrateV1toV2, migrateV2toV2_1 } from "./dataModel";
|
|
10
|
+
|
|
11
|
+
const tableState = {
|
|
12
|
+
pTableParams: {
|
|
13
|
+
defaultFilters: null,
|
|
14
|
+
filters: null,
|
|
15
|
+
hiddenColIds: null,
|
|
16
|
+
sorting: [],
|
|
17
|
+
sourceId: null,
|
|
18
|
+
},
|
|
19
|
+
stateCache: [],
|
|
20
|
+
version: 6,
|
|
21
|
+
} as BlockDataV2["tableState"];
|
|
22
|
+
|
|
23
|
+
const v2Graph: Pick<BlockDataV2, "graphStateScatter" | "graphStateHistogram"> = {
|
|
24
|
+
graphStateScatter: { currentTab: null, template: "dots", title: "Property Relationships" },
|
|
25
|
+
graphStateHistogram: {
|
|
26
|
+
currentTab: null,
|
|
27
|
+
layersSettings: { bins: { fillColor: "#99e099" } },
|
|
28
|
+
template: "bins",
|
|
29
|
+
title: "Property Distribution",
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe("blockDataModel Ver_2026_05_18 backfill", () => {
|
|
34
|
+
it("backfills both label fields to '' on a bare V2 payload", () => {
|
|
35
|
+
const v2: BlockDataV2 = { tableState, ...v2Graph };
|
|
36
|
+
const upgraded: BlockData = migrateV2toV2_1(v2);
|
|
37
|
+
expect(upgraded.customBlockLabel).toBe("");
|
|
38
|
+
expect(upgraded.defaultBlockLabel).toBe("");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("preserves an interim-deployed customBlockLabel", () => {
|
|
42
|
+
const v2: BlockDataV2 = { tableState, ...v2Graph, customBlockLabel: "X" };
|
|
43
|
+
const upgraded: BlockData = migrateV2toV2_1(v2);
|
|
44
|
+
expect(upgraded.customBlockLabel).toBe("X");
|
|
45
|
+
expect(upgraded.defaultBlockLabel).toBe("");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("preserves an interim-deployed defaultBlockLabel", () => {
|
|
49
|
+
const v2: BlockDataV2 = { tableState, ...v2Graph, defaultBlockLabel: "Y" };
|
|
50
|
+
const upgraded: BlockData = migrateV2toV2_1(v2);
|
|
51
|
+
expect(upgraded.defaultBlockLabel).toBe("Y");
|
|
52
|
+
expect(upgraded.customBlockLabel).toBe("");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("runs the full V1 → V2 → V2.1 chain on legacy data", () => {
|
|
56
|
+
const v1: BlockDataV1 = { tableState, defaultBlockLabel: "Old" };
|
|
57
|
+
const upgraded: BlockData = migrateV2toV2_1(migrateV1toV2(v1));
|
|
58
|
+
expect(upgraded.defaultBlockLabel).toBe("Old");
|
|
59
|
+
expect(upgraded.customBlockLabel).toBe("");
|
|
60
|
+
expect(upgraded.graphStateScatter).toBeDefined();
|
|
61
|
+
expect(upgraded.graphStateHistogram).toBeDefined();
|
|
62
|
+
});
|
|
63
|
+
});
|
package/src/dataModel.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { GraphMakerState } from "@milaboratories/graph-maker";
|
|
2
2
|
import { createPlDataTableStateV2, DataModelBuilder } from "@platforma-sdk/model";
|
|
3
|
-
import type { BlockData, BlockDataV1 } from "./types";
|
|
3
|
+
import type { BlockData, BlockDataV1, BlockDataV2 } from "./types";
|
|
4
4
|
|
|
5
5
|
const DEFAULT_SCATTER_STATE: GraphMakerState = {
|
|
6
6
|
title: "Property Relationships",
|
|
@@ -17,15 +17,33 @@ const DEFAULT_HISTOGRAM_STATE: GraphMakerState = {
|
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export const migrateV1toV2 = (v1: BlockDataV1): BlockDataV2 => ({
|
|
21
|
+
...v1,
|
|
22
|
+
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
23
|
+
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const migrateV2toV2_1 = (v2: BlockDataV2): BlockData => ({
|
|
27
|
+
...v2,
|
|
28
|
+
defaultBlockLabel: v2.defaultBlockLabel ?? "",
|
|
29
|
+
customBlockLabel: v2.customBlockLabel ?? "",
|
|
30
|
+
});
|
|
31
|
+
|
|
20
32
|
export const blockDataModel = new DataModelBuilder()
|
|
21
33
|
.from<BlockDataV1>("Ver_2026_04_28")
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
// Already-deployed step. Future field additions must go into a new step
|
|
35
|
+
// below — editing this body has no effect on projects already tagged
|
|
36
|
+
// Ver_2026_05_05 (DataModelBuilder skips matching-version migrations).
|
|
37
|
+
.migrate<BlockDataV2>("Ver_2026_05_05", migrateV1toV2)
|
|
38
|
+
// Backfills label fields onto V2-tagged projects. `?? ""` preserves any
|
|
39
|
+
// interim-deployed value; missing fields default to "". The args
|
|
40
|
+
// projection (resolveTraceLabel in label.ts) requires both fields to be
|
|
41
|
+
// strings, never undefined.
|
|
42
|
+
.migrate<BlockData>("Ver_2026_05_18", migrateV2toV2_1)
|
|
27
43
|
.init(() => ({
|
|
28
44
|
tableState: createPlDataTableStateV2(),
|
|
45
|
+
defaultBlockLabel: "",
|
|
46
|
+
customBlockLabel: "",
|
|
29
47
|
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
30
48
|
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },
|
|
31
49
|
}));
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
createPlDataTableV2,
|
|
7
7
|
} from "@platforma-sdk/model";
|
|
8
8
|
import { blockDataModel } from "./dataModel";
|
|
9
|
+
import { resolveSubtitle, resolveTraceLabel } from "./label";
|
|
9
10
|
import type { BlockArgs, WorkflowInfo } from "./types";
|
|
10
11
|
|
|
11
12
|
export type * from "@milaboratories/helpers";
|
|
@@ -41,6 +42,7 @@ export const platforma = BlockModelV3.create(blockDataModel)
|
|
|
41
42
|
}
|
|
42
43
|
return {
|
|
43
44
|
inputAnchor: data.inputAnchor,
|
|
45
|
+
traceLabel: resolveTraceLabel(data),
|
|
44
46
|
};
|
|
45
47
|
})
|
|
46
48
|
.output("inputOptions", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs))
|
|
@@ -107,7 +109,7 @@ export const platforma = BlockModelV3.create(blockDataModel)
|
|
|
107
109
|
return pCols.map((c) => ({ columnId: c.id, spec: c.spec }) satisfies PColumnIdAndSpec);
|
|
108
110
|
})
|
|
109
111
|
.title(() => "Sequence Properties")
|
|
110
|
-
.subtitle((ctx) => ctx.data
|
|
112
|
+
.subtitle((ctx) => resolveSubtitle(ctx.data))
|
|
111
113
|
.sections(() => [
|
|
112
114
|
{ type: "link", href: "/", label: "Main" },
|
|
113
115
|
{ type: "link", href: "/scatter", label: "Property Relationships" },
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import type { BlockData } from "./types";
|
|
3
|
+
import { resolveSubtitle, resolveTraceLabel } from "./label";
|
|
4
|
+
|
|
5
|
+
const base: Omit<BlockData, "customBlockLabel" | "defaultBlockLabel"> = {
|
|
6
|
+
tableState: {
|
|
7
|
+
pTableParams: {
|
|
8
|
+
defaultFilters: null,
|
|
9
|
+
filters: null,
|
|
10
|
+
hiddenColIds: null,
|
|
11
|
+
sorting: [],
|
|
12
|
+
sourceId: null,
|
|
13
|
+
},
|
|
14
|
+
stateCache: [],
|
|
15
|
+
version: 6,
|
|
16
|
+
} as BlockData["tableState"],
|
|
17
|
+
graphStateScatter: {
|
|
18
|
+
currentTab: null,
|
|
19
|
+
template: "dots",
|
|
20
|
+
title: "Property Relationships",
|
|
21
|
+
} as BlockData["graphStateScatter"],
|
|
22
|
+
graphStateHistogram: {
|
|
23
|
+
currentTab: null,
|
|
24
|
+
layersSettings: { bins: { fillColor: "#99e099" } },
|
|
25
|
+
template: "bins",
|
|
26
|
+
title: "Property Distribution",
|
|
27
|
+
} as BlockData["graphStateHistogram"],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const make = (custom: string, def: string): BlockData => ({
|
|
31
|
+
...(base as BlockData),
|
|
32
|
+
customBlockLabel: custom,
|
|
33
|
+
defaultBlockLabel: def,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("resolveSubtitle", () => {
|
|
37
|
+
it("uses customBlockLabel when set", () => {
|
|
38
|
+
expect(resolveSubtitle(make("My label", "Dataset"))).toBe("My label");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("falls back to defaultBlockLabel when customBlockLabel is empty", () => {
|
|
42
|
+
expect(resolveSubtitle(make("", "Dataset"))).toBe("Dataset");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("returns empty string when both label fields are empty", () => {
|
|
46
|
+
expect(resolveSubtitle(make("", ""))).toBe("");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe("resolveTraceLabel", () => {
|
|
51
|
+
it("uses customBlockLabel when set", () => {
|
|
52
|
+
expect(resolveTraceLabel(make("My label", "Dataset"))).toBe("My label");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("falls back to defaultBlockLabel when customBlockLabel is empty", () => {
|
|
56
|
+
expect(resolveTraceLabel(make("", "Dataset"))).toBe("Dataset");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("falls back to the block-type default when both label fields are empty", () => {
|
|
60
|
+
expect(resolveTraceLabel(make("", ""))).toBe("Sequence Properties");
|
|
61
|
+
});
|
|
62
|
+
});
|
package/src/label.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BlockData } from "./types";
|
|
2
|
+
|
|
3
|
+
const STATIC_FALLBACK = "Sequence Properties";
|
|
4
|
+
|
|
5
|
+
// Subtitle resolution for the PlBlockPage. Empty string is a valid result
|
|
6
|
+
// (the page renders the title alone).
|
|
7
|
+
export function resolveSubtitle(data: BlockData): string {
|
|
8
|
+
return data.customBlockLabel || data.defaultBlockLabel;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Trace-label resolution for the workflow's pl7.app/trace.label. Same chain
|
|
12
|
+
// as resolveSubtitle plus a static block-type last-resort, so automated
|
|
13
|
+
// pipelines that run before the UI populates defaultBlockLabel still emit
|
|
14
|
+
// a non-empty label downstream.
|
|
15
|
+
export function resolveTraceLabel(data: BlockData): string {
|
|
16
|
+
return data.customBlockLabel || data.defaultBlockLabel || STATIC_FALLBACK;
|
|
17
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -6,19 +6,31 @@ import type { PlDataTableStateV2, PlRef } from "@platforma-sdk/model";
|
|
|
6
6
|
export type BlockDataV1 = {
|
|
7
7
|
inputAnchor?: PlRef;
|
|
8
8
|
tableState: PlDataTableStateV2;
|
|
9
|
-
// UI-only state.
|
|
10
|
-
//
|
|
11
|
-
//
|
|
9
|
+
// Historically optional UI-only state. Required in the current BlockData
|
|
10
|
+
// shape; consumed by the label helpers in label.ts (resolveSubtitle for
|
|
11
|
+
// the PlBlockPage subtitle, resolveTraceLabel for the workflow trace).
|
|
12
12
|
defaultBlockLabel?: string;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// V2 shape — what the deployed Ver_2026_05_05 migration produces. Input to
|
|
16
|
+
// the new Ver_2026_05_18 step that backfills the label fields. Both label
|
|
17
|
+
// fields are optional here so the V2→V2.1 migration can read-or-default any
|
|
18
|
+
// value an interim deployment may have written.
|
|
19
|
+
export type BlockDataV2 = Omit<BlockDataV1, "defaultBlockLabel"> & {
|
|
20
|
+
defaultBlockLabel?: string;
|
|
21
|
+
customBlockLabel?: string;
|
|
16
22
|
graphStateScatter: GraphMakerState;
|
|
17
23
|
graphStateHistogram: GraphMakerState;
|
|
18
24
|
};
|
|
19
25
|
|
|
26
|
+
export type BlockData = Omit<BlockDataV2, "defaultBlockLabel"> & {
|
|
27
|
+
defaultBlockLabel: string;
|
|
28
|
+
customBlockLabel: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
20
31
|
export type BlockArgs = {
|
|
21
32
|
inputAnchor: PlRef;
|
|
33
|
+
traceLabel: string;
|
|
22
34
|
};
|
|
23
35
|
|
|
24
36
|
export type WorkflowMode =
|