@platforma-open/milaboratories.sequence-properties.model 1.2.4 → 1.3.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/.turbo/turbo-build.log +18 -16
- package/.turbo/turbo-check.log +4 -4
- package/.turbo/turbo-test.log +15 -0
- package/CHANGELOG.md +11 -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/dataModel.cjs
CHANGED
|
@@ -11,12 +11,20 @@ const DEFAULT_HISTOGRAM_STATE = {
|
|
|
11
11
|
currentTab: null,
|
|
12
12
|
layersSettings: { bins: { fillColor: "#99e099" } }
|
|
13
13
|
};
|
|
14
|
-
const
|
|
14
|
+
const migrateV1toV2 = (v1) => ({
|
|
15
15
|
...v1,
|
|
16
16
|
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
17
17
|
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }
|
|
18
|
-
})
|
|
18
|
+
});
|
|
19
|
+
const migrateV2toV2_1 = (v2) => ({
|
|
20
|
+
...v2,
|
|
21
|
+
defaultBlockLabel: v2.defaultBlockLabel ?? "",
|
|
22
|
+
customBlockLabel: v2.customBlockLabel ?? ""
|
|
23
|
+
});
|
|
24
|
+
const blockDataModel = new _platforma_sdk_model.DataModelBuilder().from("Ver_2026_04_28").migrate("Ver_2026_05_05", migrateV1toV2).migrate("Ver_2026_05_18", migrateV2toV2_1).init(() => ({
|
|
19
25
|
tableState: (0, _platforma_sdk_model.createPlDataTableStateV2)(),
|
|
26
|
+
defaultBlockLabel: "",
|
|
27
|
+
customBlockLabel: "",
|
|
20
28
|
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
21
29
|
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }
|
|
22
30
|
}));
|
package/dist/dataModel.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataModel.cjs","names":["DataModelBuilder"],"sources":["../src/dataModel.ts"],"sourcesContent":["import type { GraphMakerState } from \"@milaboratories/graph-maker\";\nimport { createPlDataTableStateV2, DataModelBuilder } from \"@platforma-sdk/model\";\nimport type { BlockData, BlockDataV1 } from \"./types\";\n\nconst DEFAULT_SCATTER_STATE: GraphMakerState = {\n title: \"Property Relationships\",\n template: \"dots\",\n currentTab: null,\n};\n\nconst DEFAULT_HISTOGRAM_STATE: GraphMakerState = {\n title: \"Property Distribution\",\n template: \"bins\",\n currentTab: null,\n layersSettings: {\n bins: { fillColor: \"#99e099\" },\n },\n};\n\nexport const blockDataModel = new DataModelBuilder()\n .from<BlockDataV1>(\"Ver_2026_04_28\")\n .migrate<
|
|
1
|
+
{"version":3,"file":"dataModel.cjs","names":["DataModelBuilder"],"sources":["../src/dataModel.ts"],"sourcesContent":["import type { GraphMakerState } from \"@milaboratories/graph-maker\";\nimport { createPlDataTableStateV2, DataModelBuilder } from \"@platforma-sdk/model\";\nimport type { BlockData, BlockDataV1, BlockDataV2 } from \"./types\";\n\nconst DEFAULT_SCATTER_STATE: GraphMakerState = {\n title: \"Property Relationships\",\n template: \"dots\",\n currentTab: null,\n};\n\nconst DEFAULT_HISTOGRAM_STATE: GraphMakerState = {\n title: \"Property Distribution\",\n template: \"bins\",\n currentTab: null,\n layersSettings: {\n bins: { fillColor: \"#99e099\" },\n },\n};\n\nexport const migrateV1toV2 = (v1: BlockDataV1): BlockDataV2 => ({\n ...v1,\n graphStateScatter: { ...DEFAULT_SCATTER_STATE },\n graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },\n});\n\nexport const migrateV2toV2_1 = (v2: BlockDataV2): BlockData => ({\n ...v2,\n defaultBlockLabel: v2.defaultBlockLabel ?? \"\",\n customBlockLabel: v2.customBlockLabel ?? \"\",\n});\n\nexport const blockDataModel = new DataModelBuilder()\n .from<BlockDataV1>(\"Ver_2026_04_28\")\n // Already-deployed step. Future field additions must go into a new step\n // below — editing this body has no effect on projects already tagged\n // Ver_2026_05_05 (DataModelBuilder skips matching-version migrations).\n .migrate<BlockDataV2>(\"Ver_2026_05_05\", migrateV1toV2)\n // Backfills label fields onto V2-tagged projects. `?? \"\"` preserves any\n // interim-deployed value; missing fields default to \"\". The args\n // projection (resolveTraceLabel in label.ts) requires both fields to be\n // strings, never undefined.\n .migrate<BlockData>(\"Ver_2026_05_18\", migrateV2toV2_1)\n .init(() => ({\n tableState: createPlDataTableStateV2(),\n defaultBlockLabel: \"\",\n customBlockLabel: \"\",\n graphStateScatter: { ...DEFAULT_SCATTER_STATE },\n graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },\n }));\n"],"mappings":";;AAIA,MAAM,wBAAyC;CAC7C,OAAO;CACP,UAAU;CACV,YAAY;CACb;AAED,MAAM,0BAA2C;CAC/C,OAAO;CACP,UAAU;CACV,YAAY;CACZ,gBAAgB,EACd,MAAM,EAAE,WAAW,WAAW,EAC/B;CACF;AAED,MAAa,iBAAiB,QAAkC;CAC9D,GAAG;CACH,mBAAmB,EAAE,GAAG,uBAAuB;CAC/C,qBAAqB,EAAE,GAAG,yBAAyB;CACpD;AAED,MAAa,mBAAmB,QAAgC;CAC9D,GAAG;CACH,mBAAmB,GAAG,qBAAqB;CAC3C,kBAAkB,GAAG,oBAAoB;CAC1C;AAED,MAAa,iBAAiB,IAAIA,qBAAAA,kBAAkB,CACjD,KAAkB,iBAAiB,CAInC,QAAqB,kBAAkB,cAAc,CAKrD,QAAmB,kBAAkB,gBAAgB,CACrD,YAAY;CACX,aAAA,GAAA,qBAAA,2BAAsC;CACtC,mBAAmB;CACnB,kBAAkB;CAClB,mBAAmB,EAAE,GAAG,uBAAuB;CAC/C,qBAAqB,EAAE,GAAG,yBAAyB;CACpD,EAAE"}
|
package/dist/dataModel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataModel.d.ts","names":[],"sources":["../src/dataModel.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"dataModel.d.ts","names":[],"sources":["../src/dataModel.ts"],"mappings":";;;;cA+Ba,cAAA,EAAc,uBAAA,CAAA,SAAA,CAAA,SAAA"}
|
package/dist/dataModel.js
CHANGED
|
@@ -11,12 +11,20 @@ const DEFAULT_HISTOGRAM_STATE = {
|
|
|
11
11
|
currentTab: null,
|
|
12
12
|
layersSettings: { bins: { fillColor: "#99e099" } }
|
|
13
13
|
};
|
|
14
|
-
const
|
|
14
|
+
const migrateV1toV2 = (v1) => ({
|
|
15
15
|
...v1,
|
|
16
16
|
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
17
17
|
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }
|
|
18
|
-
})
|
|
18
|
+
});
|
|
19
|
+
const migrateV2toV2_1 = (v2) => ({
|
|
20
|
+
...v2,
|
|
21
|
+
defaultBlockLabel: v2.defaultBlockLabel ?? "",
|
|
22
|
+
customBlockLabel: v2.customBlockLabel ?? ""
|
|
23
|
+
});
|
|
24
|
+
const blockDataModel = new DataModelBuilder().from("Ver_2026_04_28").migrate("Ver_2026_05_05", migrateV1toV2).migrate("Ver_2026_05_18", migrateV2toV2_1).init(() => ({
|
|
19
25
|
tableState: createPlDataTableStateV2(),
|
|
26
|
+
defaultBlockLabel: "",
|
|
27
|
+
customBlockLabel: "",
|
|
20
28
|
graphStateScatter: { ...DEFAULT_SCATTER_STATE },
|
|
21
29
|
graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE }
|
|
22
30
|
}));
|
package/dist/dataModel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataModel.js","names":[],"sources":["../src/dataModel.ts"],"sourcesContent":["import type { GraphMakerState } from \"@milaboratories/graph-maker\";\nimport { createPlDataTableStateV2, DataModelBuilder } from \"@platforma-sdk/model\";\nimport type { BlockData, BlockDataV1 } from \"./types\";\n\nconst DEFAULT_SCATTER_STATE: GraphMakerState = {\n title: \"Property Relationships\",\n template: \"dots\",\n currentTab: null,\n};\n\nconst DEFAULT_HISTOGRAM_STATE: GraphMakerState = {\n title: \"Property Distribution\",\n template: \"bins\",\n currentTab: null,\n layersSettings: {\n bins: { fillColor: \"#99e099\" },\n },\n};\n\nexport const blockDataModel = new DataModelBuilder()\n .from<BlockDataV1>(\"Ver_2026_04_28\")\n .migrate<
|
|
1
|
+
{"version":3,"file":"dataModel.js","names":[],"sources":["../src/dataModel.ts"],"sourcesContent":["import type { GraphMakerState } from \"@milaboratories/graph-maker\";\nimport { createPlDataTableStateV2, DataModelBuilder } from \"@platforma-sdk/model\";\nimport type { BlockData, BlockDataV1, BlockDataV2 } from \"./types\";\n\nconst DEFAULT_SCATTER_STATE: GraphMakerState = {\n title: \"Property Relationships\",\n template: \"dots\",\n currentTab: null,\n};\n\nconst DEFAULT_HISTOGRAM_STATE: GraphMakerState = {\n title: \"Property Distribution\",\n template: \"bins\",\n currentTab: null,\n layersSettings: {\n bins: { fillColor: \"#99e099\" },\n },\n};\n\nexport const migrateV1toV2 = (v1: BlockDataV1): BlockDataV2 => ({\n ...v1,\n graphStateScatter: { ...DEFAULT_SCATTER_STATE },\n graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },\n});\n\nexport const migrateV2toV2_1 = (v2: BlockDataV2): BlockData => ({\n ...v2,\n defaultBlockLabel: v2.defaultBlockLabel ?? \"\",\n customBlockLabel: v2.customBlockLabel ?? \"\",\n});\n\nexport const blockDataModel = new DataModelBuilder()\n .from<BlockDataV1>(\"Ver_2026_04_28\")\n // Already-deployed step. Future field additions must go into a new step\n // below — editing this body has no effect on projects already tagged\n // Ver_2026_05_05 (DataModelBuilder skips matching-version migrations).\n .migrate<BlockDataV2>(\"Ver_2026_05_05\", migrateV1toV2)\n // Backfills label fields onto V2-tagged projects. `?? \"\"` preserves any\n // interim-deployed value; missing fields default to \"\". The args\n // projection (resolveTraceLabel in label.ts) requires both fields to be\n // strings, never undefined.\n .migrate<BlockData>(\"Ver_2026_05_18\", migrateV2toV2_1)\n .init(() => ({\n tableState: createPlDataTableStateV2(),\n defaultBlockLabel: \"\",\n customBlockLabel: \"\",\n graphStateScatter: { ...DEFAULT_SCATTER_STATE },\n graphStateHistogram: { ...DEFAULT_HISTOGRAM_STATE },\n }));\n"],"mappings":";;AAIA,MAAM,wBAAyC;CAC7C,OAAO;CACP,UAAU;CACV,YAAY;CACb;AAED,MAAM,0BAA2C;CAC/C,OAAO;CACP,UAAU;CACV,YAAY;CACZ,gBAAgB,EACd,MAAM,EAAE,WAAW,WAAW,EAC/B;CACF;AAED,MAAa,iBAAiB,QAAkC;CAC9D,GAAG;CACH,mBAAmB,EAAE,GAAG,uBAAuB;CAC/C,qBAAqB,EAAE,GAAG,yBAAyB;CACpD;AAED,MAAa,mBAAmB,QAAgC;CAC9D,GAAG;CACH,mBAAmB,GAAG,qBAAqB;CAC3C,kBAAkB,GAAG,oBAAoB;CAC1C;AAED,MAAa,iBAAiB,IAAI,kBAAkB,CACjD,KAAkB,iBAAiB,CAInC,QAAqB,kBAAkB,cAAc,CAKrD,QAAmB,kBAAkB,gBAAgB,CACrD,YAAY;CACX,YAAY,0BAA0B;CACtC,mBAAmB;CACnB,kBAAkB;CAClB,mBAAmB,EAAE,GAAG,uBAAuB;CAC/C,qBAAqB,EAAE,GAAG,yBAAyB;CACpD,EAAE"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_dataModel = require("./dataModel.cjs");
|
|
3
|
+
const require_label = require("./label.cjs");
|
|
3
4
|
let _platforma_sdk_model = require("@platforma-sdk/model");
|
|
4
5
|
//#region src/index.ts
|
|
5
6
|
const inputAnchorSpecs = [
|
|
@@ -22,7 +23,10 @@ const inputAnchorSpecs = [
|
|
|
22
23
|
];
|
|
23
24
|
const platforma = _platforma_sdk_model.BlockModelV3.create(require_dataModel.blockDataModel).args((data) => {
|
|
24
25
|
if (data.inputAnchor === void 0) throw new Error("Select an input dataset");
|
|
25
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
inputAnchor: data.inputAnchor,
|
|
28
|
+
traceLabel: require_label.resolveTraceLabel(data)
|
|
29
|
+
};
|
|
26
30
|
}).output("inputOptions", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs)).output("inputSpec", (ctx) => ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : void 0).output("info", (ctx) => ctx.outputs?.resolve("info")?.getDataAsJson()).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).output("processingLog", (ctx) => ctx.outputs?.resolve("processingLog")?.getLogHandle()).outputWithStatus("propertiesTable", (ctx) => {
|
|
27
31
|
if (ctx.data.inputAnchor === void 0) return void 0;
|
|
28
32
|
const ownCols = ctx.outputs?.resolve("propertiesPf")?.getPColumns();
|
|
@@ -48,7 +52,7 @@ const platforma = _platforma_sdk_model.BlockModelV3.create(require_dataModel.blo
|
|
|
48
52
|
columnId: c.id,
|
|
49
53
|
spec: c.spec
|
|
50
54
|
}));
|
|
51
|
-
}).title(() => "Sequence Properties").subtitle((ctx) => ctx.data
|
|
55
|
+
}).title(() => "Sequence Properties").subtitle((ctx) => require_label.resolveSubtitle(ctx.data)).sections(() => [
|
|
52
56
|
{
|
|
53
57
|
type: "link",
|
|
54
58
|
href: "/",
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["BlockModelV3","blockDataModel","Annotation"],"sources":["../src/index.ts"],"sourcesContent":["import type { InferOutputsType, PColumnIdAndSpec, PFrameHandle } from \"@platforma-sdk/model\";\nimport {\n Annotation,\n BlockModelV3,\n createPFrameForGraphs,\n createPlDataTableV2,\n} from \"@platforma-sdk/model\";\nimport { blockDataModel } from \"./dataModel\";\nimport type { BlockArgs, WorkflowInfo } from \"./types\";\n\nexport type * from \"@milaboratories/helpers\";\nexport { blockDataModel } from \"./dataModel\";\nexport type { BlockArgs, BlockData, WorkflowInfo, WorkflowMode, WorkflowReceptor } from \"./types\";\n\nconst inputAnchorSpecs = [\n // Peptide mode — universal naming\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/variantKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR bulk (cloneId per spec; clonotypeKey per current MiXCR output)\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/cloneId\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/clonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR single-cell\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/scClonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n];\n\nexport const platforma = BlockModelV3.create(blockDataModel)\n .args<BlockArgs>((data) => {\n if (data.inputAnchor === undefined) {\n throw new Error(\"Select an input dataset\");\n }\n return {\n inputAnchor: data.inputAnchor,\n };\n })\n .output(\"inputOptions\", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs))\n .output(\"inputSpec\", (ctx) =>\n ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : undefined,\n )\n .output(\"info\", (ctx) => ctx.outputs?.resolve(\"info\")?.getDataAsJson<WorkflowInfo>())\n .output(\"isRunning\", (ctx) => ctx.outputs?.getIsReadyOrError() === false)\n .output(\"processingLog\", (ctx) => ctx.outputs?.resolve(\"processingLog\")?.getLogHandle())\n .outputWithStatus(\"propertiesTable\", (ctx) => {\n if (ctx.data.inputAnchor === undefined) return undefined;\n const ownCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (ownCols === undefined) return undefined;\n // Temporary downgrade to V2 with a fixed, propertiesPf-only column list.\n // V3 default-visibility rules and the column picker are not yet stable for\n // the multi-source layout this block needs (upstream sequence column +\n // own scalar properties). Once V3 supports it natively, rewire across\n // blocks. aaFraction is 2-axis (variantKey × aminoAcid) — already filtered\n // from the graph pFrame; filtered here too so it doesn't widen the table.\n const tableCols = ownCols.filter((c) => c.spec.axesSpec.length === 1);\n return createPlDataTableV2(ctx, tableCols, ctx.data.tableState);\n })\n .outputWithStatus(\"propertiesPfHandle\", (ctx): PFrameHandle | undefined => {\n const allPCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (allPCols === undefined) return undefined;\n // Drop the AA fraction column from the pframe entirely. Two-axis\n // (variantKey × aminoAcid), at 50k peptides ~1M cells — enough to trip\n // graph-maker's cell-count guard on its own. The picker already excludes\n // it via `isNumericScalar` (axesSpec.length === 1), so the data was\n // pure overhead.\n const pCols = allPCols.filter((c) => c.spec.name !== \"pl7.app/aaFraction\");\n // Use `ctx.createPFrame` instead of `createPFrameForGraphs`. The latter\n // walks the result pool and pulls in this block's `exports.properties`\n // — a `trace.inject`-stamped re-emission of every column already in\n // `propertiesPf`, published for Lead Selection — so axis dropdowns\n // show e.g. \"Net Charge (pH7) / IG\" twice. Same workaround chosen by\n // cdr3-spectratype, batch-correction, cell-type-annotation, and\n // dimensionality-reduction.\n //\n // Pull single-axis metadata anchored to the input dataset's two axes\n // (idx 0 = sample, idx 1 = entity key) so sample groups / patient IDs /\n // peptide abundance and similar cols remain available for grouping and\n // filtering. Drop self-trace to keep our own exports out.\n const inputAnchor = ctx.data.inputAnchor;\n const upstreamMeta =\n inputAnchor !== undefined\n ? (\n ctx.resultPool.getAnchoredPColumns({ main: inputAnchor }, [\n { axes: [{ anchor: \"main\", idx: 0 }] },\n { axes: [{ anchor: \"main\", idx: 1 }] },\n ]) ?? []\n ).filter(\n (c) =>\n !c.spec.annotations?.[Annotation.Trace]?.includes(\n \"milaboratories.sequence-properties\",\n ),\n )\n : [];\n return createPFrameForGraphs(ctx, [...pCols, ...upstreamMeta]);\n })\n .output(\"propertiesPfCols\", (ctx): PColumnIdAndSpec[] | undefined => {\n const pCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (pCols === undefined) return undefined;\n return pCols.map((c) => ({ columnId: c.id, spec: c.spec }) satisfies PColumnIdAndSpec);\n })\n .title(() => \"Sequence Properties\")\n .subtitle((ctx) => ctx.data
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["BlockModelV3","blockDataModel","resolveTraceLabel","Annotation","resolveSubtitle"],"sources":["../src/index.ts"],"sourcesContent":["import type { InferOutputsType, PColumnIdAndSpec, PFrameHandle } from \"@platforma-sdk/model\";\nimport {\n Annotation,\n BlockModelV3,\n createPFrameForGraphs,\n createPlDataTableV2,\n} from \"@platforma-sdk/model\";\nimport { blockDataModel } from \"./dataModel\";\nimport { resolveSubtitle, resolveTraceLabel } from \"./label\";\nimport type { BlockArgs, WorkflowInfo } from \"./types\";\n\nexport type * from \"@milaboratories/helpers\";\nexport { blockDataModel } from \"./dataModel\";\nexport type { BlockArgs, BlockData, WorkflowInfo, WorkflowMode, WorkflowReceptor } from \"./types\";\n\nconst inputAnchorSpecs = [\n // Peptide mode — universal naming\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/variantKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR bulk (cloneId per spec; clonotypeKey per current MiXCR output)\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/cloneId\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/clonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR single-cell\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/scClonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n];\n\nexport const platforma = BlockModelV3.create(blockDataModel)\n .args<BlockArgs>((data) => {\n if (data.inputAnchor === undefined) {\n throw new Error(\"Select an input dataset\");\n }\n return {\n inputAnchor: data.inputAnchor,\n traceLabel: resolveTraceLabel(data),\n };\n })\n .output(\"inputOptions\", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs))\n .output(\"inputSpec\", (ctx) =>\n ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : undefined,\n )\n .output(\"info\", (ctx) => ctx.outputs?.resolve(\"info\")?.getDataAsJson<WorkflowInfo>())\n .output(\"isRunning\", (ctx) => ctx.outputs?.getIsReadyOrError() === false)\n .output(\"processingLog\", (ctx) => ctx.outputs?.resolve(\"processingLog\")?.getLogHandle())\n .outputWithStatus(\"propertiesTable\", (ctx) => {\n if (ctx.data.inputAnchor === undefined) return undefined;\n const ownCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (ownCols === undefined) return undefined;\n // Temporary downgrade to V2 with a fixed, propertiesPf-only column list.\n // V3 default-visibility rules and the column picker are not yet stable for\n // the multi-source layout this block needs (upstream sequence column +\n // own scalar properties). Once V3 supports it natively, rewire across\n // blocks. aaFraction is 2-axis (variantKey × aminoAcid) — already filtered\n // from the graph pFrame; filtered here too so it doesn't widen the table.\n const tableCols = ownCols.filter((c) => c.spec.axesSpec.length === 1);\n return createPlDataTableV2(ctx, tableCols, ctx.data.tableState);\n })\n .outputWithStatus(\"propertiesPfHandle\", (ctx): PFrameHandle | undefined => {\n const allPCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (allPCols === undefined) return undefined;\n // Drop the AA fraction column from the pframe entirely. Two-axis\n // (variantKey × aminoAcid), at 50k peptides ~1M cells — enough to trip\n // graph-maker's cell-count guard on its own. The picker already excludes\n // it via `isNumericScalar` (axesSpec.length === 1), so the data was\n // pure overhead.\n const pCols = allPCols.filter((c) => c.spec.name !== \"pl7.app/aaFraction\");\n // Use `ctx.createPFrame` instead of `createPFrameForGraphs`. The latter\n // walks the result pool and pulls in this block's `exports.properties`\n // — a `trace.inject`-stamped re-emission of every column already in\n // `propertiesPf`, published for Lead Selection — so axis dropdowns\n // show e.g. \"Net Charge (pH7) / IG\" twice. Same workaround chosen by\n // cdr3-spectratype, batch-correction, cell-type-annotation, and\n // dimensionality-reduction.\n //\n // Pull single-axis metadata anchored to the input dataset's two axes\n // (idx 0 = sample, idx 1 = entity key) so sample groups / patient IDs /\n // peptide abundance and similar cols remain available for grouping and\n // filtering. Drop self-trace to keep our own exports out.\n const inputAnchor = ctx.data.inputAnchor;\n const upstreamMeta =\n inputAnchor !== undefined\n ? (\n ctx.resultPool.getAnchoredPColumns({ main: inputAnchor }, [\n { axes: [{ anchor: \"main\", idx: 0 }] },\n { axes: [{ anchor: \"main\", idx: 1 }] },\n ]) ?? []\n ).filter(\n (c) =>\n !c.spec.annotations?.[Annotation.Trace]?.includes(\n \"milaboratories.sequence-properties\",\n ),\n )\n : [];\n return createPFrameForGraphs(ctx, [...pCols, ...upstreamMeta]);\n })\n .output(\"propertiesPfCols\", (ctx): PColumnIdAndSpec[] | undefined => {\n const pCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (pCols === undefined) return undefined;\n return pCols.map((c) => ({ columnId: c.id, spec: c.spec }) satisfies PColumnIdAndSpec);\n })\n .title(() => \"Sequence Properties\")\n .subtitle((ctx) => resolveSubtitle(ctx.data))\n .sections(() => [\n { type: \"link\", href: \"/\", label: \"Main\" },\n { type: \"link\", href: \"/scatter\", label: \"Property Relationships\" },\n { type: \"link\", href: \"/histogram\", label: \"Property Distribution\" },\n ])\n .done();\n\nexport type BlockOutputs = InferOutputsType<typeof platforma>;\n"],"mappings":";;;;;AAeA,MAAM,mBAAmB;CAEvB;EACE,MAAM,CAAC,EAAE,MAAM,oBAAoB,EAAE,EAAE,MAAM,sBAAsB,CAAC;EACpE,aAAa,EAAE,oBAAoB,QAAQ;EAC5C;CAED;EACE,MAAM,CAAC,EAAE,MAAM,oBAAoB,EAAE,EAAE,MAAM,uBAAuB,CAAC;EACrE,aAAa,EAAE,oBAAoB,QAAQ;EAC5C;CACD;EACE,MAAM,CAAC,EAAE,MAAM,oBAAoB,EAAE,EAAE,MAAM,4BAA4B,CAAC;EAC1E,aAAa,EAAE,oBAAoB,QAAQ;EAC5C;CAED;EACE,MAAM,CAAC,EAAE,MAAM,oBAAoB,EAAE,EAAE,MAAM,8BAA8B,CAAC;EAC5E,aAAa,EAAE,oBAAoB,QAAQ;EAC5C;CACF;AAED,MAAa,YAAYA,qBAAAA,aAAa,OAAOC,kBAAAA,eAAe,CACzD,MAAiB,SAAS;AACzB,KAAI,KAAK,gBAAgB,KAAA,EACvB,OAAM,IAAI,MAAM,0BAA0B;AAE5C,QAAO;EACL,aAAa,KAAK;EAClB,YAAYC,cAAAA,kBAAkB,KAAK;EACpC;EACD,CACD,OAAO,iBAAiB,QAAQ,IAAI,WAAW,WAAW,iBAAiB,CAAC,CAC5E,OAAO,cAAc,QACpB,IAAI,KAAK,cAAc,IAAI,WAAW,oBAAoB,IAAI,KAAK,YAAY,GAAG,KAAA,EACnF,CACA,OAAO,SAAS,QAAQ,IAAI,SAAS,QAAQ,OAAO,EAAE,eAA6B,CAAC,CACpF,OAAO,cAAc,QAAQ,IAAI,SAAS,mBAAmB,KAAK,MAAM,CACxE,OAAO,kBAAkB,QAAQ,IAAI,SAAS,QAAQ,gBAAgB,EAAE,cAAc,CAAC,CACvF,iBAAiB,oBAAoB,QAAQ;AAC5C,KAAI,IAAI,KAAK,gBAAgB,KAAA,EAAW,QAAO,KAAA;CAC/C,MAAM,UAAU,IAAI,SAAS,QAAQ,eAAe,EAAE,aAAa;AACnE,KAAI,YAAY,KAAA,EAAW,QAAO,KAAA;AAQlC,SAAA,GAAA,qBAAA,qBAA2B,KADT,QAAQ,QAAQ,MAAM,EAAE,KAAK,SAAS,WAAW,EAAE,EAC1B,IAAI,KAAK,WAAW;EAC/D,CACD,iBAAiB,uBAAuB,QAAkC;CACzE,MAAM,WAAW,IAAI,SAAS,QAAQ,eAAe,EAAE,aAAa;AACpE,KAAI,aAAa,KAAA,EAAW,QAAO,KAAA;CAMnC,MAAM,QAAQ,SAAS,QAAQ,MAAM,EAAE,KAAK,SAAS,qBAAqB;CAa1E,MAAM,cAAc,IAAI,KAAK;CAC7B,MAAM,eACJ,gBAAgB,KAAA,KAEV,IAAI,WAAW,oBAAoB,EAAE,MAAM,aAAa,EAAE,CACxD,EAAE,MAAM,CAAC;EAAE,QAAQ;EAAQ,KAAK;EAAG,CAAC,EAAE,EACtC,EAAE,MAAM,CAAC;EAAE,QAAQ;EAAQ,KAAK;EAAG,CAAC,EAAE,CACvC,CAAC,IAAI,EAAE,EACR,QACC,MACC,CAAC,EAAE,KAAK,cAAcC,qBAAAA,WAAW,QAAQ,SACvC,qCACD,CACJ,GACD,EAAE;AACR,SAAA,GAAA,qBAAA,uBAA6B,KAAK,CAAC,GAAG,OAAO,GAAG,aAAa,CAAC;EAC9D,CACD,OAAO,qBAAqB,QAAwC;CACnE,MAAM,QAAQ,IAAI,SAAS,QAAQ,eAAe,EAAE,aAAa;AACjE,KAAI,UAAU,KAAA,EAAW,QAAO,KAAA;AAChC,QAAO,MAAM,KAAK,OAAO;EAAE,UAAU,EAAE;EAAI,MAAM,EAAE;EAAM,EAA6B;EACtF,CACD,YAAY,sBAAsB,CAClC,UAAU,QAAQC,cAAAA,gBAAgB,IAAI,KAAK,CAAC,CAC5C,eAAe;CACd;EAAE,MAAM;EAAQ,MAAM;EAAK,OAAO;EAAQ;CAC1C;EAAE,MAAM;EAAQ,MAAM;EAAY,OAAO;EAA0B;CACnE;EAAE,MAAM;EAAQ,MAAM;EAAc,OAAO;EAAyB;CACrE,CAAC,CACD,MAAM"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;cAqCa,SAAA,EAAS,uBAAA,CAAA,iBAAA,yBAAA,WAAA,CAgFb,SAAA,EAhFa,SAAA,0BAAA,uBAAA;gBAAA,uBAAA,CAAA,kBAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAAA,uBAAA,CAAA,sBAAA;AAAA,KAkFV,YAAA,GAAe,gBAAA,QAAwB,SAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { blockDataModel } from "./dataModel.js";
|
|
2
|
+
import { resolveSubtitle, resolveTraceLabel } from "./label.js";
|
|
2
3
|
import { Annotation, BlockModelV3, createPFrameForGraphs, createPlDataTableV2 } from "@platforma-sdk/model";
|
|
3
4
|
//#region src/index.ts
|
|
4
5
|
const inputAnchorSpecs = [
|
|
@@ -21,7 +22,10 @@ const inputAnchorSpecs = [
|
|
|
21
22
|
];
|
|
22
23
|
const platforma = BlockModelV3.create(blockDataModel).args((data) => {
|
|
23
24
|
if (data.inputAnchor === void 0) throw new Error("Select an input dataset");
|
|
24
|
-
return {
|
|
25
|
+
return {
|
|
26
|
+
inputAnchor: data.inputAnchor,
|
|
27
|
+
traceLabel: resolveTraceLabel(data)
|
|
28
|
+
};
|
|
25
29
|
}).output("inputOptions", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs)).output("inputSpec", (ctx) => ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : void 0).output("info", (ctx) => ctx.outputs?.resolve("info")?.getDataAsJson()).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).output("processingLog", (ctx) => ctx.outputs?.resolve("processingLog")?.getLogHandle()).outputWithStatus("propertiesTable", (ctx) => {
|
|
26
30
|
if (ctx.data.inputAnchor === void 0) return void 0;
|
|
27
31
|
const ownCols = ctx.outputs?.resolve("propertiesPf")?.getPColumns();
|
|
@@ -47,7 +51,7 @@ const platforma = BlockModelV3.create(blockDataModel).args((data) => {
|
|
|
47
51
|
columnId: c.id,
|
|
48
52
|
spec: c.spec
|
|
49
53
|
}));
|
|
50
|
-
}).title(() => "Sequence Properties").subtitle((ctx) => ctx.data
|
|
54
|
+
}).title(() => "Sequence Properties").subtitle((ctx) => resolveSubtitle(ctx.data)).sections(() => [
|
|
51
55
|
{
|
|
52
56
|
type: "link",
|
|
53
57
|
href: "/",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { InferOutputsType, PColumnIdAndSpec, PFrameHandle } from \"@platforma-sdk/model\";\nimport {\n Annotation,\n BlockModelV3,\n createPFrameForGraphs,\n createPlDataTableV2,\n} from \"@platforma-sdk/model\";\nimport { blockDataModel } from \"./dataModel\";\nimport type { BlockArgs, WorkflowInfo } from \"./types\";\n\nexport type * from \"@milaboratories/helpers\";\nexport { blockDataModel } from \"./dataModel\";\nexport type { BlockArgs, BlockData, WorkflowInfo, WorkflowMode, WorkflowReceptor } from \"./types\";\n\nconst inputAnchorSpecs = [\n // Peptide mode — universal naming\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/variantKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR bulk (cloneId per spec; clonotypeKey per current MiXCR output)\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/cloneId\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/clonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR single-cell\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/scClonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n];\n\nexport const platforma = BlockModelV3.create(blockDataModel)\n .args<BlockArgs>((data) => {\n if (data.inputAnchor === undefined) {\n throw new Error(\"Select an input dataset\");\n }\n return {\n inputAnchor: data.inputAnchor,\n };\n })\n .output(\"inputOptions\", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs))\n .output(\"inputSpec\", (ctx) =>\n ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : undefined,\n )\n .output(\"info\", (ctx) => ctx.outputs?.resolve(\"info\")?.getDataAsJson<WorkflowInfo>())\n .output(\"isRunning\", (ctx) => ctx.outputs?.getIsReadyOrError() === false)\n .output(\"processingLog\", (ctx) => ctx.outputs?.resolve(\"processingLog\")?.getLogHandle())\n .outputWithStatus(\"propertiesTable\", (ctx) => {\n if (ctx.data.inputAnchor === undefined) return undefined;\n const ownCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (ownCols === undefined) return undefined;\n // Temporary downgrade to V2 with a fixed, propertiesPf-only column list.\n // V3 default-visibility rules and the column picker are not yet stable for\n // the multi-source layout this block needs (upstream sequence column +\n // own scalar properties). Once V3 supports it natively, rewire across\n // blocks. aaFraction is 2-axis (variantKey × aminoAcid) — already filtered\n // from the graph pFrame; filtered here too so it doesn't widen the table.\n const tableCols = ownCols.filter((c) => c.spec.axesSpec.length === 1);\n return createPlDataTableV2(ctx, tableCols, ctx.data.tableState);\n })\n .outputWithStatus(\"propertiesPfHandle\", (ctx): PFrameHandle | undefined => {\n const allPCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (allPCols === undefined) return undefined;\n // Drop the AA fraction column from the pframe entirely. Two-axis\n // (variantKey × aminoAcid), at 50k peptides ~1M cells — enough to trip\n // graph-maker's cell-count guard on its own. The picker already excludes\n // it via `isNumericScalar` (axesSpec.length === 1), so the data was\n // pure overhead.\n const pCols = allPCols.filter((c) => c.spec.name !== \"pl7.app/aaFraction\");\n // Use `ctx.createPFrame` instead of `createPFrameForGraphs`. The latter\n // walks the result pool and pulls in this block's `exports.properties`\n // — a `trace.inject`-stamped re-emission of every column already in\n // `propertiesPf`, published for Lead Selection — so axis dropdowns\n // show e.g. \"Net Charge (pH7) / IG\" twice. Same workaround chosen by\n // cdr3-spectratype, batch-correction, cell-type-annotation, and\n // dimensionality-reduction.\n //\n // Pull single-axis metadata anchored to the input dataset's two axes\n // (idx 0 = sample, idx 1 = entity key) so sample groups / patient IDs /\n // peptide abundance and similar cols remain available for grouping and\n // filtering. Drop self-trace to keep our own exports out.\n const inputAnchor = ctx.data.inputAnchor;\n const upstreamMeta =\n inputAnchor !== undefined\n ? (\n ctx.resultPool.getAnchoredPColumns({ main: inputAnchor }, [\n { axes: [{ anchor: \"main\", idx: 0 }] },\n { axes: [{ anchor: \"main\", idx: 1 }] },\n ]) ?? []\n ).filter(\n (c) =>\n !c.spec.annotations?.[Annotation.Trace]?.includes(\n \"milaboratories.sequence-properties\",\n ),\n )\n : [];\n return createPFrameForGraphs(ctx, [...pCols, ...upstreamMeta]);\n })\n .output(\"propertiesPfCols\", (ctx): PColumnIdAndSpec[] | undefined => {\n const pCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (pCols === undefined) return undefined;\n return pCols.map((c) => ({ columnId: c.id, spec: c.spec }) satisfies PColumnIdAndSpec);\n })\n .title(() => \"Sequence Properties\")\n .subtitle((ctx) => ctx.data
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { InferOutputsType, PColumnIdAndSpec, PFrameHandle } from \"@platforma-sdk/model\";\nimport {\n Annotation,\n BlockModelV3,\n createPFrameForGraphs,\n createPlDataTableV2,\n} from \"@platforma-sdk/model\";\nimport { blockDataModel } from \"./dataModel\";\nimport { resolveSubtitle, resolveTraceLabel } from \"./label\";\nimport type { BlockArgs, WorkflowInfo } from \"./types\";\n\nexport type * from \"@milaboratories/helpers\";\nexport { blockDataModel } from \"./dataModel\";\nexport type { BlockArgs, BlockData, WorkflowInfo, WorkflowMode, WorkflowReceptor } from \"./types\";\n\nconst inputAnchorSpecs = [\n // Peptide mode — universal naming\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/variantKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR bulk (cloneId per spec; clonotypeKey per current MiXCR output)\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/cloneId\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/clonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n // Antibody/TCR — legacy MiXCR single-cell\n {\n axes: [{ name: \"pl7.app/sampleId\" }, { name: \"pl7.app/vdj/scClonotypeKey\" }],\n annotations: { \"pl7.app/isAnchor\": \"true\" },\n },\n];\n\nexport const platforma = BlockModelV3.create(blockDataModel)\n .args<BlockArgs>((data) => {\n if (data.inputAnchor === undefined) {\n throw new Error(\"Select an input dataset\");\n }\n return {\n inputAnchor: data.inputAnchor,\n traceLabel: resolveTraceLabel(data),\n };\n })\n .output(\"inputOptions\", (ctx) => ctx.resultPool.getOptions(inputAnchorSpecs))\n .output(\"inputSpec\", (ctx) =>\n ctx.data.inputAnchor ? ctx.resultPool.getPColumnSpecByRef(ctx.data.inputAnchor) : undefined,\n )\n .output(\"info\", (ctx) => ctx.outputs?.resolve(\"info\")?.getDataAsJson<WorkflowInfo>())\n .output(\"isRunning\", (ctx) => ctx.outputs?.getIsReadyOrError() === false)\n .output(\"processingLog\", (ctx) => ctx.outputs?.resolve(\"processingLog\")?.getLogHandle())\n .outputWithStatus(\"propertiesTable\", (ctx) => {\n if (ctx.data.inputAnchor === undefined) return undefined;\n const ownCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (ownCols === undefined) return undefined;\n // Temporary downgrade to V2 with a fixed, propertiesPf-only column list.\n // V3 default-visibility rules and the column picker are not yet stable for\n // the multi-source layout this block needs (upstream sequence column +\n // own scalar properties). Once V3 supports it natively, rewire across\n // blocks. aaFraction is 2-axis (variantKey × aminoAcid) — already filtered\n // from the graph pFrame; filtered here too so it doesn't widen the table.\n const tableCols = ownCols.filter((c) => c.spec.axesSpec.length === 1);\n return createPlDataTableV2(ctx, tableCols, ctx.data.tableState);\n })\n .outputWithStatus(\"propertiesPfHandle\", (ctx): PFrameHandle | undefined => {\n const allPCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (allPCols === undefined) return undefined;\n // Drop the AA fraction column from the pframe entirely. Two-axis\n // (variantKey × aminoAcid), at 50k peptides ~1M cells — enough to trip\n // graph-maker's cell-count guard on its own. The picker already excludes\n // it via `isNumericScalar` (axesSpec.length === 1), so the data was\n // pure overhead.\n const pCols = allPCols.filter((c) => c.spec.name !== \"pl7.app/aaFraction\");\n // Use `ctx.createPFrame` instead of `createPFrameForGraphs`. The latter\n // walks the result pool and pulls in this block's `exports.properties`\n // — a `trace.inject`-stamped re-emission of every column already in\n // `propertiesPf`, published for Lead Selection — so axis dropdowns\n // show e.g. \"Net Charge (pH7) / IG\" twice. Same workaround chosen by\n // cdr3-spectratype, batch-correction, cell-type-annotation, and\n // dimensionality-reduction.\n //\n // Pull single-axis metadata anchored to the input dataset's two axes\n // (idx 0 = sample, idx 1 = entity key) so sample groups / patient IDs /\n // peptide abundance and similar cols remain available for grouping and\n // filtering. Drop self-trace to keep our own exports out.\n const inputAnchor = ctx.data.inputAnchor;\n const upstreamMeta =\n inputAnchor !== undefined\n ? (\n ctx.resultPool.getAnchoredPColumns({ main: inputAnchor }, [\n { axes: [{ anchor: \"main\", idx: 0 }] },\n { axes: [{ anchor: \"main\", idx: 1 }] },\n ]) ?? []\n ).filter(\n (c) =>\n !c.spec.annotations?.[Annotation.Trace]?.includes(\n \"milaboratories.sequence-properties\",\n ),\n )\n : [];\n return createPFrameForGraphs(ctx, [...pCols, ...upstreamMeta]);\n })\n .output(\"propertiesPfCols\", (ctx): PColumnIdAndSpec[] | undefined => {\n const pCols = ctx.outputs?.resolve(\"propertiesPf\")?.getPColumns();\n if (pCols === undefined) return undefined;\n return pCols.map((c) => ({ columnId: c.id, spec: c.spec }) satisfies PColumnIdAndSpec);\n })\n .title(() => \"Sequence Properties\")\n .subtitle((ctx) => resolveSubtitle(ctx.data))\n .sections(() => [\n { type: \"link\", href: \"/\", label: \"Main\" },\n { type: \"link\", href: \"/scatter\", label: \"Property Relationships\" },\n { type: \"link\", href: \"/histogram\", label: \"Property Distribution\" },\n ])\n .done();\n\nexport type BlockOutputs = InferOutputsType<typeof platforma>;\n"],"mappings":"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"}
|
package/dist/label.cjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/label.ts
|
|
2
|
+
const STATIC_FALLBACK = "Sequence Properties";
|
|
3
|
+
function resolveSubtitle(data) {
|
|
4
|
+
return data.customBlockLabel || data.defaultBlockLabel;
|
|
5
|
+
}
|
|
6
|
+
function resolveTraceLabel(data) {
|
|
7
|
+
return data.customBlockLabel || data.defaultBlockLabel || STATIC_FALLBACK;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
exports.resolveSubtitle = resolveSubtitle;
|
|
11
|
+
exports.resolveTraceLabel = resolveTraceLabel;
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=label.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label.cjs","names":[],"sources":["../src/label.ts"],"sourcesContent":["import type { BlockData } from \"./types\";\n\nconst STATIC_FALLBACK = \"Sequence Properties\";\n\n// Subtitle resolution for the PlBlockPage. Empty string is a valid result\n// (the page renders the title alone).\nexport function resolveSubtitle(data: BlockData): string {\n return data.customBlockLabel || data.defaultBlockLabel;\n}\n\n// Trace-label resolution for the workflow's pl7.app/trace.label. Same chain\n// as resolveSubtitle plus a static block-type last-resort, so automated\n// pipelines that run before the UI populates defaultBlockLabel still emit\n// a non-empty label downstream.\nexport function resolveTraceLabel(data: BlockData): string {\n return data.customBlockLabel || data.defaultBlockLabel || STATIC_FALLBACK;\n}\n"],"mappings":";AAEA,MAAM,kBAAkB;AAIxB,SAAgB,gBAAgB,MAAyB;AACvD,QAAO,KAAK,oBAAoB,KAAK;;AAOvC,SAAgB,kBAAkB,MAAyB;AACzD,QAAO,KAAK,oBAAoB,KAAK,qBAAqB"}
|
package/dist/label.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/label.ts
|
|
2
|
+
const STATIC_FALLBACK = "Sequence Properties";
|
|
3
|
+
function resolveSubtitle(data) {
|
|
4
|
+
return data.customBlockLabel || data.defaultBlockLabel;
|
|
5
|
+
}
|
|
6
|
+
function resolveTraceLabel(data) {
|
|
7
|
+
return data.customBlockLabel || data.defaultBlockLabel || STATIC_FALLBACK;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { resolveSubtitle, resolveTraceLabel };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label.js","names":[],"sources":["../src/label.ts"],"sourcesContent":["import type { BlockData } from \"./types\";\n\nconst STATIC_FALLBACK = \"Sequence Properties\";\n\n// Subtitle resolution for the PlBlockPage. Empty string is a valid result\n// (the page renders the title alone).\nexport function resolveSubtitle(data: BlockData): string {\n return data.customBlockLabel || data.defaultBlockLabel;\n}\n\n// Trace-label resolution for the workflow's pl7.app/trace.label. Same chain\n// as resolveSubtitle plus a static block-type last-resort, so automated\n// pipelines that run before the UI populates defaultBlockLabel still emit\n// a non-empty label downstream.\nexport function resolveTraceLabel(data: BlockData): string {\n return data.customBlockLabel || data.defaultBlockLabel || STATIC_FALLBACK;\n}\n"],"mappings":";AAEA,MAAM,kBAAkB;AAIxB,SAAgB,gBAAgB,MAAyB;AACvD,QAAO,KAAK,oBAAoB,KAAK;;AAOvC,SAAgB,kBAAkB,MAAyB;AACzD,QAAO,KAAK,oBAAoB,KAAK,qBAAqB"}
|