@platforma-sdk/model 1.76.4 → 1.76.5
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/components/PlDatasetSelector/build_dataset_options.cjs +5 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.d.ts +6 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.js +5 -1
- package/dist/components/PlDatasetSelector/build_dataset_options.js.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.cjs +21 -30
- package/dist/components/PlDatasetSelector/filter_discovery.cjs.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts +20 -20
- package/dist/components/PlDatasetSelector/filter_discovery.d.ts.map +1 -1
- package/dist/components/PlDatasetSelector/filter_discovery.js +21 -30
- package/dist/components/PlDatasetSelector/filter_discovery.js.map +1 -1
- package/dist/components/PlDatasetSelector/index.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/package.json +4 -4
- package/src/components/PlDatasetSelector/build_dataset_options.ts +10 -2
- package/src/components/PlDatasetSelector/filter_discovery.test.ts +116 -19
- package/src/components/PlDatasetSelector/filter_discovery.ts +46 -39
|
@@ -37,7 +37,11 @@ function buildDatasetOptions(ctx, opts) {
|
|
|
37
37
|
});
|
|
38
38
|
enrichmentCollection = enrichmentSources !== void 0 ? new require_column_collection_builder.ColumnCollectionBuilder(pframeSpec).addSources(enrichmentSources).build({ anchors: { main: datasetSpec } }) : void 0;
|
|
39
39
|
const filterMatches = require_filter_discovery.findFilterColumns(filterCollection).filter((m) => filterPredicate(m.column.spec));
|
|
40
|
-
const filters = filterMatches.length === 0 ? void 0 : require_filter_discovery.filterMatchesToOptions(filterMatches,
|
|
40
|
+
const filters = filterMatches.length === 0 ? void 0 : require_filter_discovery.filterMatchesToOptions(filterMatches, {
|
|
41
|
+
refsByObjectId: refMap,
|
|
42
|
+
datasetSpec,
|
|
43
|
+
labelOptions: opts?.labelOptions
|
|
44
|
+
});
|
|
41
45
|
let enrichments;
|
|
42
46
|
if (enrichmentCollection && withEnrichments) {
|
|
43
47
|
const enrichmentVariants = require_enrichment_discovery.findEnrichmentColumns(enrichmentCollection, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_dataset_options.cjs","names":["buildRefMap","ResultPoolColumnSnapshotProvider","collectCtxColumnSnapshotProviders","ColumnCollectionBuilder","findFilterColumns","filterMatchesToOptions","findEnrichmentColumns","enrichmentVariantsToRefs"],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} from \"../../columns/ctx_column_sources\";\nimport type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n
|
|
1
|
+
{"version":3,"file":"build_dataset_options.cjs","names":["buildRefMap","ResultPoolColumnSnapshotProvider","collectCtxColumnSnapshotProviders","ColumnCollectionBuilder","findFilterColumns","filterMatchesToOptions","findEnrichmentColumns","enrichmentVariantsToRefs"],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} from \"../../columns/ctx_column_sources\";\nimport type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n /**\n * Formatting options forwarded to label derivation for both filter and\n * enrichment rows. `formatters.native` on the filter path is overridden\n * — see `FilterMatchOptions.labelOptions`.\n */\n labelOptions?: DeriveLabelsOptions;\n /**\n * Enables enrichment discovery and filters hits attached to\n * `DatasetOption.enrichments`. Use `() => true` to accept all; omit to disable.\n */\n withEnrichments?: SpecPredicateOption;\n /** Maximum linker hops considered. Only used when `withEnrichments` is set. */\n enrichmentMaxHops?: number;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, {\n refsByObjectId: refMap,\n datasetSpec,\n labelOptions: opts?.labelOptions,\n });\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: withEnrichments }),\n });\n if (enrichmentVariants.length > 0) {\n enrichments = enrichmentVariantsToRefs(enrichmentVariants, opts?.labelOptions);\n }\n }\n\n return {\n primary,\n ...(filters !== undefined && filters.length > 0 ? { filters } : {}),\n ...(enrichments !== undefined && enrichments.length > 0 ? { enrichments } : {}),\n };\n } finally {\n filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,OAAA,GAAA,gCAAA,iCAAsC,IAAI;;;;;;;;AAiC/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAASA,yBAAAA,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAIC,2BAAAA,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkBC,2BAAAA,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAIC,kCAAAA,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAIA,kCAAAA,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgBC,yBAAAA,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACAC,yBAAAA,uBAAuB,eAAe;IACpC,gBAAgB;IAChB;IACA,cAAc,MAAM;IACrB,CAAC;GAER,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqBC,6BAAAA,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAcC,6BAAAA,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,UAAO;IACL;IACA,GAAI,YAAY,KAAA,KAAa,QAAQ,SAAS,IAAI,EAAE,SAAS,GAAG,EAAE;IAClE,GAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,IAAI,EAAE,aAAa,GAAG,EAAE;IAC/E;YACO;AACR,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
|
|
@@ -12,7 +12,12 @@ type BuildDatasetOptions = {
|
|
|
12
12
|
* with the built-in `pl7.app/isSubset: "true"` constraint. Defaults to
|
|
13
13
|
* accept-all.
|
|
14
14
|
*/
|
|
15
|
-
filter?: SpecPredicateOption;
|
|
15
|
+
filter?: SpecPredicateOption;
|
|
16
|
+
/**
|
|
17
|
+
* Formatting options forwarded to label derivation for both filter and
|
|
18
|
+
* enrichment rows. `formatters.native` on the filter path is overridden
|
|
19
|
+
* — see `FilterMatchOptions.labelOptions`.
|
|
20
|
+
*/
|
|
16
21
|
labelOptions?: DeriveLabelsOptions;
|
|
17
22
|
/**
|
|
18
23
|
* Enables enrichment discovery and filters hits attached to
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":";;;;;;KAcK,mBAAA,GACD,mBAAA,GACA,mBAAA,OACE,IAAA,EAAM,WAAA;AAAA,KAOA,mBAAA;wEAEV,OAAA,GAAU,mBAAA;EAZY;;;;;EAkBtB,MAAA,GAAS,mBAAA
|
|
1
|
+
{"version":3,"file":"build_dataset_options.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"mappings":";;;;;;KAcK,mBAAA,GACD,mBAAA,GACA,mBAAA,OACE,IAAA,EAAM,WAAA;AAAA,KAOA,mBAAA;wEAEV,OAAA,GAAU,mBAAA;EAZY;;;;;EAkBtB,MAAA,GAAS,mBAAA;EAfY;;;;;EAqBrB,YAAA,GAAe,mBAAA;EArBM;AAOvB;;;EAmBE,eAAA,GAAkB,mBAAA,EAXT;EAaT,iBAAA;AAAA;;;;;;;iBASc,mBAAA,CACd,GAAA,EAAK,aAAA,EACL,IAAA,GAAO,mBAAA,GACN,aAAA"}
|
|
@@ -36,7 +36,11 @@ function buildDatasetOptions(ctx, opts) {
|
|
|
36
36
|
});
|
|
37
37
|
enrichmentCollection = enrichmentSources !== void 0 ? new ColumnCollectionBuilder(pframeSpec).addSources(enrichmentSources).build({ anchors: { main: datasetSpec } }) : void 0;
|
|
38
38
|
const filterMatches = findFilterColumns(filterCollection).filter((m) => filterPredicate(m.column.spec));
|
|
39
|
-
const filters = filterMatches.length === 0 ? void 0 : filterMatchesToOptions(filterMatches,
|
|
39
|
+
const filters = filterMatches.length === 0 ? void 0 : filterMatchesToOptions(filterMatches, {
|
|
40
|
+
refsByObjectId: refMap,
|
|
41
|
+
datasetSpec,
|
|
42
|
+
labelOptions: opts?.labelOptions
|
|
43
|
+
});
|
|
40
44
|
let enrichments;
|
|
41
45
|
if (enrichmentCollection && withEnrichments) {
|
|
42
46
|
const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build_dataset_options.js","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} from \"../../columns/ctx_column_sources\";\nimport type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n
|
|
1
|
+
{"version":3,"file":"build_dataset_options.js","names":[],"sources":["../../../src/components/PlDatasetSelector/build_dataset_options.ts"],"sourcesContent":["import type { MultiColumnSelector, Option, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport { multiColumnSelectorsToPredicate } from \"@milaboratories/pl-model-common\";\nimport type { DeriveLabelsOptions } from \"../../labels/derive_distinct_labels\";\nimport type { RenderCtxBase } from \"../../render\";\nimport type { AnchoredColumnCollection } from \"../../columns/column_collection_builder\";\nimport { ColumnCollectionBuilder } from \"../../columns/column_collection_builder\";\nimport {\n ResultPoolColumnSnapshotProvider,\n collectCtxColumnSnapshotProviders,\n} from \"../../columns/ctx_column_sources\";\nimport type { DatasetOption } from \"./dataset_selection\";\nimport { buildRefMap, filterMatchesToOptions, findFilterColumns } from \"./filter_discovery\";\nimport { enrichmentVariantsToRefs, findEnrichmentColumns } from \"./enrichment_discovery\";\n\ntype SpecPredicateOption =\n | MultiColumnSelector\n | MultiColumnSelector[]\n | ((spec: PObjectSpec) => boolean);\n\nfunction toPredicate(opt: SpecPredicateOption | undefined): (spec: PObjectSpec) => boolean {\n if (opt === undefined) return () => true;\n return typeof opt === \"function\" ? opt : multiColumnSelectorsToPredicate(opt);\n}\n\nexport type BuildDatasetOptions = {\n /** Which result pool columns qualify as datasets. Defaults to all. */\n primary?: SpecPredicateOption;\n /**\n * Restricts which result pool columns are considered as filters. Intersected\n * with the built-in `pl7.app/isSubset: \"true\"` constraint. Defaults to\n * accept-all.\n */\n filter?: SpecPredicateOption;\n /**\n * Formatting options forwarded to label derivation for both filter and\n * enrichment rows. `formatters.native` on the filter path is overridden\n * — see `FilterMatchOptions.labelOptions`.\n */\n labelOptions?: DeriveLabelsOptions;\n /**\n * Enables enrichment discovery and filters hits attached to\n * `DatasetOption.enrichments`. Use `() => true` to accept all; omit to disable.\n */\n withEnrichments?: SpecPredicateOption;\n /** Maximum linker hops considered. Only used when `withEnrichments` is set. */\n enrichmentMaxHops?: number;\n};\n\n/**\n * Usage:\n * ```ts\n * .output(\"datasetOptions\", (ctx) => buildDatasetOptions(ctx))\n * ```\n */\nexport function buildDatasetOptions(\n ctx: RenderCtxBase,\n opts?: BuildDatasetOptions,\n): DatasetOption[] | undefined {\n const primaryPredicate = toPredicate(opts?.primary);\n const filterPredicate = toPredicate(opts?.filter);\n\n const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });\n if (options.length === 0) return [];\n\n const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);\n const pframeSpec = ctx.getService(\"pframeSpec\");\n\n const withEnrichments = opts?.withEnrichments ?? false;\n const filterSource = new ResultPoolColumnSnapshotProvider(ctx.resultPool);\n // Hoisted out of the per-option loop: collectCtxColumnSnapshotProviders\n // walks the entire output tree, so calling it once per dataset option would\n // be O(N × tree).\n const enrichmentSources = withEnrichments ? collectCtxColumnSnapshotProviders(ctx) : undefined;\n\n return options.map((primary: Option): DatasetOption => {\n const datasetSpec = ctx.resultPool.getPColumnSpecByRef(primary.ref);\n if (!datasetSpec) return { primary };\n\n // Allocations happen inside try so a throw on the second build()\n // still disposes the first collection.\n let filterCollection: AnchoredColumnCollection | undefined;\n let enrichmentCollection: AnchoredColumnCollection | undefined;\n try {\n // ResultPoolColumnSnapshotProvider is always complete;\n // allowPartialColumnList narrows the return type to non-undefined.\n filterCollection = new ColumnCollectionBuilder(pframeSpec)\n .addSource(filterSource)\n .build({ anchors: { main: datasetSpec }, allowPartialColumnList: true });\n\n enrichmentCollection =\n enrichmentSources !== undefined\n ? new ColumnCollectionBuilder(pframeSpec)\n .addSources(enrichmentSources)\n .build({ anchors: { main: datasetSpec } })\n : undefined;\n\n const filterMatches = findFilterColumns(filterCollection).filter((m) =>\n filterPredicate(m.column.spec),\n );\n const filters =\n filterMatches.length === 0\n ? undefined\n : filterMatchesToOptions(filterMatches, {\n refsByObjectId: refMap,\n datasetSpec,\n labelOptions: opts?.labelOptions,\n });\n\n let enrichments;\n if (enrichmentCollection && withEnrichments) {\n const enrichmentVariants = findEnrichmentColumns(enrichmentCollection, {\n maxHops: opts?.enrichmentMaxHops,\n ...(typeof withEnrichments === \"function\"\n ? { predicate: withEnrichments }\n : { include: withEnrichments }),\n });\n if (enrichmentVariants.length > 0) {\n enrichments = enrichmentVariantsToRefs(enrichmentVariants, opts?.labelOptions);\n }\n }\n\n return {\n primary,\n ...(filters !== undefined && filters.length > 0 ? { filters } : {}),\n ...(enrichments !== undefined && enrichments.length > 0 ? { enrichments } : {}),\n };\n } finally {\n filterCollection?.dispose();\n enrichmentCollection?.dispose();\n }\n });\n}\n"],"mappings":";;;;;;AAmBA,SAAS,YAAY,KAAsE;AACzF,KAAI,QAAQ,KAAA,EAAW,cAAa;AACpC,QAAO,OAAO,QAAQ,aAAa,MAAM,gCAAgC,IAAI;;;;;;;;AAiC/E,SAAgB,oBACd,KACA,MAC6B;CAC7B,MAAM,mBAAmB,YAAY,MAAM,QAAQ;CACnD,MAAM,kBAAkB,YAAY,MAAM,OAAO;CAEjD,MAAM,UAAU,IAAI,WAAW,WAAW,kBAAkB,EAAE,qBAAqB,MAAM,CAAC;AAC1F,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,SAAS,YAAY,IAAI,WAAW,UAAU,CAAC,QAAQ;CAC7D,MAAM,aAAa,IAAI,WAAW,aAAa;CAE/C,MAAM,kBAAkB,MAAM,mBAAmB;CACjD,MAAM,eAAe,IAAI,iCAAiC,IAAI,WAAW;CAIzE,MAAM,oBAAoB,kBAAkB,kCAAkC,IAAI,GAAG,KAAA;AAErF,QAAO,QAAQ,KAAK,YAAmC;EACrD,MAAM,cAAc,IAAI,WAAW,oBAAoB,QAAQ,IAAI;AACnE,MAAI,CAAC,YAAa,QAAO,EAAE,SAAS;EAIpC,IAAI;EACJ,IAAI;AACJ,MAAI;AAGF,sBAAmB,IAAI,wBAAwB,WAAW,CACvD,UAAU,aAAa,CACvB,MAAM;IAAE,SAAS,EAAE,MAAM,aAAa;IAAE,wBAAwB;IAAM,CAAC;AAE1E,0BACE,sBAAsB,KAAA,IAClB,IAAI,wBAAwB,WAAW,CACpC,WAAW,kBAAkB,CAC7B,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,EAAE,CAAC,GAC5C,KAAA;GAEN,MAAM,gBAAgB,kBAAkB,iBAAiB,CAAC,QAAQ,MAChE,gBAAgB,EAAE,OAAO,KAAK,CAC/B;GACD,MAAM,UACJ,cAAc,WAAW,IACrB,KAAA,IACA,uBAAuB,eAAe;IACpC,gBAAgB;IAChB;IACA,cAAc,MAAM;IACrB,CAAC;GAER,IAAI;AACJ,OAAI,wBAAwB,iBAAiB;IAC3C,MAAM,qBAAqB,sBAAsB,sBAAsB;KACrE,SAAS,MAAM;KACf,GAAI,OAAO,oBAAoB,aAC3B,EAAE,WAAW,iBAAiB,GAC9B,EAAE,SAAS,iBAAiB;KACjC,CAAC;AACF,QAAI,mBAAmB,SAAS,EAC9B,eAAc,yBAAyB,oBAAoB,MAAM,aAAa;;AAIlF,UAAO;IACL;IACA,GAAI,YAAY,KAAA,KAAa,QAAQ,SAAS,IAAI,EAAE,SAAS,GAAG,EAAE;IAClE,GAAI,gBAAgB,KAAA,KAAa,YAAY,SAAS,IAAI,EAAE,aAAa,GAAG,EAAE;IAC/E;YACO;AACR,qBAAkB,SAAS;AAC3B,yBAAsB,SAAS;;GAEjC"}
|
|
@@ -5,12 +5,8 @@ let canonicalize = require("canonicalize");
|
|
|
5
5
|
canonicalize = require_runtime.__toESM(canonicalize);
|
|
6
6
|
//#region src/components/PlDatasetSelector/filter_discovery.ts
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
|
|
11
|
-
* `allowFloatingHitAxes: false` — every axis of the matched column must be
|
|
12
|
-
* present in the anchor's axes. See `matchingModeToConstraints()` in
|
|
13
|
-
* `column_collection_builder.ts`.
|
|
8
|
+
* Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
|
|
9
|
+
* The axes-subset constraint comes from `mode: "enrichment"`.
|
|
14
10
|
*/
|
|
15
11
|
function findFilterColumns(collection) {
|
|
16
12
|
return collection.findColumns({
|
|
@@ -19,42 +15,37 @@ function findFilterColumns(collection) {
|
|
|
19
15
|
});
|
|
20
16
|
}
|
|
21
17
|
/**
|
|
22
|
-
* Derive
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* skipped — they cannot be exposed as user-selectable options.
|
|
26
|
-
*
|
|
27
|
-
* @param matches - from findFilterColumns()
|
|
28
|
-
* @param refsByObjectId - from {@link buildRefMap}
|
|
29
|
-
* @param labelOptions - forwarded to deriveDistinctLabels()
|
|
18
|
+
* Derive labels for filter column matches (for `DatasetOption.filters`).
|
|
19
|
+
* Matches whose column id is missing from `refsByObjectId` are silently
|
|
20
|
+
* dropped — they cannot be exposed as selectable options.
|
|
30
21
|
*/
|
|
31
|
-
function filterMatchesToOptions(matches,
|
|
22
|
+
function filterMatchesToOptions(matches, options) {
|
|
32
23
|
if (matches.length === 0) return [];
|
|
33
|
-
const
|
|
24
|
+
const { refsByObjectId, datasetSpec, labelOptions } = options;
|
|
25
|
+
const entries = matches.flatMap((match) => {
|
|
34
26
|
const ref = refsByObjectId.get(match.column.id);
|
|
35
27
|
if (ref === void 0) return [];
|
|
36
28
|
return match.variants.map((variant) => ({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
ref,
|
|
30
|
+
spec: match.column.spec,
|
|
31
|
+
linkerPath: variant.path.map((p) => ({ spec: p.linker.spec }))
|
|
40
32
|
}));
|
|
41
33
|
});
|
|
42
|
-
const labels = require_derive_distinct_labels.deriveDistinctLabels(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
const labels = require_derive_distinct_labels.deriveDistinctLabels([...entries, { spec: datasetSpec }], {
|
|
35
|
+
...labelOptions,
|
|
36
|
+
formatters: {
|
|
37
|
+
...labelOptions?.formatters,
|
|
38
|
+
native: () => void 0
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return entries.map(({ ref }, i) => ({
|
|
47
42
|
ref,
|
|
48
43
|
label: labels[i]
|
|
49
44
|
}));
|
|
50
45
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
|
|
53
|
-
*/
|
|
46
|
+
/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
|
|
54
47
|
function buildRefMap(entries) {
|
|
55
|
-
|
|
56
|
-
for (const entry of entries) map.set((0, canonicalize.default)(entry.ref), entry.ref);
|
|
57
|
-
return map;
|
|
48
|
+
return new Map(entries.map((e) => [(0, canonicalize.default)(e.ref), e.ref]));
|
|
58
49
|
}
|
|
59
50
|
//#endregion
|
|
60
51
|
exports.buildRefMap = buildRefMap;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter_discovery.cjs","names":["Annotation","deriveDistinctLabels"],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"filter_discovery.cjs","names":["Annotation","deriveDistinctLabels"],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n * Columns annotated `pl7.app/isSubset: \"true\"` whose axes ⊆ anchor axes.\n * The axes-subset constraint comes from `mode: \"enrichment\"`.\n */\nexport function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {\n return collection.findColumns({\n mode: \"enrichment\",\n include: {\n annotations: { [Annotation.IsSubset]: \"true\" },\n },\n });\n}\n\nexport type FilterMatchOptions = {\n /** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */\n refsByObjectId: ReadonlyMap<PObjectId, PlRef>;\n /** Spec of the dataset the filters are subsets of. */\n datasetSpec: PObjectSpec;\n /**\n * Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller\n * sets is silently overridden — the function relies on a no-op native\n * formatter to keep the algorithm from short-circuiting on filters'\n * inherited `pl7.app/label`.\n */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Derive labels for filter column matches (for `DatasetOption.filters`).\n * Matches whose column id is missing from `refsByObjectId` are silently\n * dropped — they cannot be exposed as selectable options.\n */\nexport function filterMatchesToOptions(\n matches: ColumnMatch[],\n options: FilterMatchOptions,\n): Option[] {\n if (matches.length === 0) return [];\n\n const { refsByObjectId, datasetSpec, labelOptions } = options;\n\n // One entry per match-variant (different paths to the same column are\n // exposed as separate Options). The `ref` field rides along on the\n // Entry-shaped objects via structural typing; `deriveDistinctLabels`\n // ignores extra fields.\n const entries = matches.flatMap((match): (Entry & { ref: PlRef })[] => {\n const ref = refsByObjectId.get(match.column.id);\n if (ref === undefined) return [];\n return match.variants.map((variant) => ({\n ref,\n spec: match.column.spec,\n linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),\n }));\n });\n\n // Appending the dataset forces a discriminating trace step into every\n // filter label (yielding e.g. \"Bulk / Top 10\"); the dataset's own label\n // is dropped because we only zip `entries`. Native label is force-\n // suppressed (the override sits after caller's spread) — filters\n // inherit the dataset's `pl7.app/label` and would otherwise satisfy\n // uniqueness before any trace step is consulted.\n const labels = deriveDistinctLabels([...entries, { spec: datasetSpec }], {\n ...labelOptions,\n formatters: { ...labelOptions?.formatters, native: () => undefined },\n });\n\n return entries.map(({ ref }, i) => ({ ref, label: labels[i] }));\n}\n\n/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */\nexport function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {\n return new Map(entries.map((e) => [canonicalize(e.ref)! as PObjectId, e.ref]));\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,kBAAkB,YAAqD;AACrF,QAAO,WAAW,YAAY;EAC5B,MAAM;EACN,SAAS,EACP,aAAa,GAAGA,gCAAAA,WAAW,WAAW,QAAQ,EAC/C;EACF,CAAC;;;;;;;AAsBJ,SAAgB,uBACd,SACA,SACU;AACV,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,EAAE,gBAAgB,aAAa,iBAAiB;CAMtD,MAAM,UAAU,QAAQ,SAAS,UAAsC;EACrE,MAAM,MAAM,eAAe,IAAI,MAAM,OAAO,GAAG;AAC/C,MAAI,QAAQ,KAAA,EAAW,QAAO,EAAE;AAChC,SAAO,MAAM,SAAS,KAAK,aAAa;GACtC;GACA,MAAM,MAAM,OAAO;GACnB,YAAY,QAAQ,KAAK,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,EAAE;GAC/D,EAAE;GACH;CAQF,MAAM,SAASC,+BAAAA,qBAAqB,CAAC,GAAG,SAAS,EAAE,MAAM,aAAa,CAAC,EAAE;EACvE,GAAG;EACH,YAAY;GAAE,GAAG,cAAc;GAAY,cAAc,KAAA;GAAW;EACrE,CAAC;AAEF,QAAO,QAAQ,KAAK,EAAE,OAAO,OAAO;EAAE;EAAK,OAAO,OAAO;EAAI,EAAE;;;AAIjE,SAAgB,YAAY,SAAoE;AAC9F,QAAO,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAA,GAAA,aAAA,SAAc,EAAE,IAAI,EAAgB,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { AnchoredColumnCollection, ColumnMatch } from "../../columns/column_collection_builder.js";
|
|
2
2
|
import { DeriveLabelsOptions } from "../../labels/derive_distinct_labels.js";
|
|
3
|
-
import { Option, PObjectId, PlRef } from "@milaboratories/pl-model-common";
|
|
3
|
+
import { Option, PObjectId, PObjectSpec, PlRef } from "@milaboratories/pl-model-common";
|
|
4
4
|
|
|
5
5
|
//#region src/components/PlDatasetSelector/filter_discovery.d.ts
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
|
|
10
|
-
* `allowFloatingHitAxes: false` — every axis of the matched column must be
|
|
11
|
-
* present in the anchor's axes. See `matchingModeToConstraints()` in
|
|
12
|
-
* `column_collection_builder.ts`.
|
|
7
|
+
* Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
|
|
8
|
+
* The axes-subset constraint comes from `mode: "enrichment"`.
|
|
13
9
|
*/
|
|
14
10
|
declare function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[];
|
|
11
|
+
type FilterMatchOptions = {
|
|
12
|
+
/** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */refsByObjectId: ReadonlyMap<PObjectId, PlRef>; /** Spec of the dataset the filters are subsets of. */
|
|
13
|
+
datasetSpec: PObjectSpec;
|
|
14
|
+
/**
|
|
15
|
+
* Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller
|
|
16
|
+
* sets is silently overridden — the function relies on a no-op native
|
|
17
|
+
* formatter to keep the algorithm from short-circuiting on filters'
|
|
18
|
+
* inherited `pl7.app/label`.
|
|
19
|
+
*/
|
|
20
|
+
labelOptions?: DeriveLabelsOptions;
|
|
21
|
+
};
|
|
15
22
|
/**
|
|
16
|
-
* Derive
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* skipped — they cannot be exposed as user-selectable options.
|
|
20
|
-
*
|
|
21
|
-
* @param matches - from findFilterColumns()
|
|
22
|
-
* @param refsByObjectId - from {@link buildRefMap}
|
|
23
|
-
* @param labelOptions - forwarded to deriveDistinctLabels()
|
|
24
|
-
*/
|
|
25
|
-
declare function filterMatchesToOptions(matches: ColumnMatch[], refsByObjectId: ReadonlyMap<PObjectId, PlRef>, labelOptions?: DeriveLabelsOptions): Option[];
|
|
26
|
-
/**
|
|
27
|
-
* Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
|
|
23
|
+
* Derive labels for filter column matches (for `DatasetOption.filters`).
|
|
24
|
+
* Matches whose column id is missing from `refsByObjectId` are silently
|
|
25
|
+
* dropped — they cannot be exposed as selectable options.
|
|
28
26
|
*/
|
|
27
|
+
declare function filterMatchesToOptions(matches: ColumnMatch[], options: FilterMatchOptions): Option[];
|
|
28
|
+
/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
|
|
29
29
|
declare function buildRefMap(entries: readonly {
|
|
30
30
|
readonly ref: PlRef;
|
|
31
31
|
}[]): Map<PObjectId, PlRef>;
|
|
32
32
|
//#endregion
|
|
33
|
-
export { buildRefMap, filterMatchesToOptions, findFilterColumns };
|
|
33
|
+
export { FilterMatchOptions, buildRefMap, filterMatchesToOptions, findFilterColumns };
|
|
34
34
|
//# sourceMappingURL=filter_discovery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter_discovery.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"filter_discovery.d.ts","names":[],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"mappings":";;;;;;;AAiBA;;iBAAgB,iBAAA,CAAkB,UAAA,EAAY,wBAAA,GAA2B,WAAA;AAAA,KAS7D,kBAAA;EATkC,qFAW5C,cAAA,EAAgB,WAAA,CAAY,SAAA,EAAW,KAAA,GAXgC;EAavE,WAAA,EAAa,WAAA;EAbqE;AASpF;;;;;EAWE,YAAA,GAAe,mBAAA;AAAA;;;;;;iBAQD,sBAAA,CACd,OAAA,EAAS,WAAA,IACT,OAAA,EAAS,kBAAA,GACR,MAAA;;iBAkCa,WAAA,CAAY,OAAA;EAAA,SAA6B,GAAA,EAAK,KAAA;AAAA,MAAY,GAAA,CAAI,SAAA,EAAW,KAAA"}
|
|
@@ -3,12 +3,8 @@ import { Annotation } from "@milaboratories/pl-model-common";
|
|
|
3
3
|
import canonicalize from "canonicalize";
|
|
4
4
|
//#region src/components/PlDatasetSelector/filter_discovery.ts
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
|
|
9
|
-
* `allowFloatingHitAxes: false` — every axis of the matched column must be
|
|
10
|
-
* present in the anchor's axes. See `matchingModeToConstraints()` in
|
|
11
|
-
* `column_collection_builder.ts`.
|
|
6
|
+
* Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
|
|
7
|
+
* The axes-subset constraint comes from `mode: "enrichment"`.
|
|
12
8
|
*/
|
|
13
9
|
function findFilterColumns(collection) {
|
|
14
10
|
return collection.findColumns({
|
|
@@ -17,42 +13,37 @@ function findFilterColumns(collection) {
|
|
|
17
13
|
});
|
|
18
14
|
}
|
|
19
15
|
/**
|
|
20
|
-
* Derive
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* skipped — they cannot be exposed as user-selectable options.
|
|
24
|
-
*
|
|
25
|
-
* @param matches - from findFilterColumns()
|
|
26
|
-
* @param refsByObjectId - from {@link buildRefMap}
|
|
27
|
-
* @param labelOptions - forwarded to deriveDistinctLabels()
|
|
16
|
+
* Derive labels for filter column matches (for `DatasetOption.filters`).
|
|
17
|
+
* Matches whose column id is missing from `refsByObjectId` are silently
|
|
18
|
+
* dropped — they cannot be exposed as selectable options.
|
|
28
19
|
*/
|
|
29
|
-
function filterMatchesToOptions(matches,
|
|
20
|
+
function filterMatchesToOptions(matches, options) {
|
|
30
21
|
if (matches.length === 0) return [];
|
|
31
|
-
const
|
|
22
|
+
const { refsByObjectId, datasetSpec, labelOptions } = options;
|
|
23
|
+
const entries = matches.flatMap((match) => {
|
|
32
24
|
const ref = refsByObjectId.get(match.column.id);
|
|
33
25
|
if (ref === void 0) return [];
|
|
34
26
|
return match.variants.map((variant) => ({
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
ref,
|
|
28
|
+
spec: match.column.spec,
|
|
29
|
+
linkerPath: variant.path.map((p) => ({ spec: p.linker.spec }))
|
|
38
30
|
}));
|
|
39
31
|
});
|
|
40
|
-
const labels = deriveDistinctLabels(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
const labels = deriveDistinctLabels([...entries, { spec: datasetSpec }], {
|
|
33
|
+
...labelOptions,
|
|
34
|
+
formatters: {
|
|
35
|
+
...labelOptions?.formatters,
|
|
36
|
+
native: () => void 0
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return entries.map(({ ref }, i) => ({
|
|
45
40
|
ref,
|
|
46
41
|
label: labels[i]
|
|
47
42
|
}));
|
|
48
43
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
|
|
51
|
-
*/
|
|
44
|
+
/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
|
|
52
45
|
function buildRefMap(entries) {
|
|
53
|
-
|
|
54
|
-
for (const entry of entries) map.set(canonicalize(entry.ref), entry.ref);
|
|
55
|
-
return map;
|
|
46
|
+
return new Map(entries.map((e) => [canonicalize(e.ref), e.ref]));
|
|
56
47
|
}
|
|
57
48
|
//#endregion
|
|
58
49
|
export { buildRefMap, filterMatchesToOptions, findFilterColumns };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter_discovery.js","names":[],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"filter_discovery.js","names":[],"sources":["../../../src/components/PlDatasetSelector/filter_discovery.ts"],"sourcesContent":["import { Annotation } from \"@milaboratories/pl-model-common\";\nimport type { Option, PlRef, PObjectId, PObjectSpec } from \"@milaboratories/pl-model-common\";\nimport canonicalize from \"canonicalize\";\nimport type {\n AnchoredColumnCollection,\n ColumnMatch,\n} from \"../../columns/column_collection_builder\";\nimport {\n deriveDistinctLabels,\n type DeriveLabelsOptions,\n type Entry,\n} from \"../../labels/derive_distinct_labels\";\n\n/**\n * Columns annotated `pl7.app/isSubset: \"true\"` whose axes ⊆ anchor axes.\n * The axes-subset constraint comes from `mode: \"enrichment\"`.\n */\nexport function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {\n return collection.findColumns({\n mode: \"enrichment\",\n include: {\n annotations: { [Annotation.IsSubset]: \"true\" },\n },\n });\n}\n\nexport type FilterMatchOptions = {\n /** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */\n refsByObjectId: ReadonlyMap<PObjectId, PlRef>;\n /** Spec of the dataset the filters are subsets of. */\n datasetSpec: PObjectSpec;\n /**\n * Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller\n * sets is silently overridden — the function relies on a no-op native\n * formatter to keep the algorithm from short-circuiting on filters'\n * inherited `pl7.app/label`.\n */\n labelOptions?: DeriveLabelsOptions;\n};\n\n/**\n * Derive labels for filter column matches (for `DatasetOption.filters`).\n * Matches whose column id is missing from `refsByObjectId` are silently\n * dropped — they cannot be exposed as selectable options.\n */\nexport function filterMatchesToOptions(\n matches: ColumnMatch[],\n options: FilterMatchOptions,\n): Option[] {\n if (matches.length === 0) return [];\n\n const { refsByObjectId, datasetSpec, labelOptions } = options;\n\n // One entry per match-variant (different paths to the same column are\n // exposed as separate Options). The `ref` field rides along on the\n // Entry-shaped objects via structural typing; `deriveDistinctLabels`\n // ignores extra fields.\n const entries = matches.flatMap((match): (Entry & { ref: PlRef })[] => {\n const ref = refsByObjectId.get(match.column.id);\n if (ref === undefined) return [];\n return match.variants.map((variant) => ({\n ref,\n spec: match.column.spec,\n linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),\n }));\n });\n\n // Appending the dataset forces a discriminating trace step into every\n // filter label (yielding e.g. \"Bulk / Top 10\"); the dataset's own label\n // is dropped because we only zip `entries`. Native label is force-\n // suppressed (the override sits after caller's spread) — filters\n // inherit the dataset's `pl7.app/label` and would otherwise satisfy\n // uniqueness before any trace step is consulted.\n const labels = deriveDistinctLabels([...entries, { spec: datasetSpec }], {\n ...labelOptions,\n formatters: { ...labelOptions?.formatters, native: () => undefined },\n });\n\n return entries.map(({ ref }, i) => ({ ref, label: labels[i] }));\n}\n\n/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */\nexport function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {\n return new Map(entries.map((e) => [canonicalize(e.ref)! as PObjectId, e.ref]));\n}\n"],"mappings":";;;;;;;;AAiBA,SAAgB,kBAAkB,YAAqD;AACrF,QAAO,WAAW,YAAY;EAC5B,MAAM;EACN,SAAS,EACP,aAAa,GAAG,WAAW,WAAW,QAAQ,EAC/C;EACF,CAAC;;;;;;;AAsBJ,SAAgB,uBACd,SACA,SACU;AACV,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;CAEnC,MAAM,EAAE,gBAAgB,aAAa,iBAAiB;CAMtD,MAAM,UAAU,QAAQ,SAAS,UAAsC;EACrE,MAAM,MAAM,eAAe,IAAI,MAAM,OAAO,GAAG;AAC/C,MAAI,QAAQ,KAAA,EAAW,QAAO,EAAE;AAChC,SAAO,MAAM,SAAS,KAAK,aAAa;GACtC;GACA,MAAM,MAAM,OAAO;GACnB,YAAY,QAAQ,KAAK,KAAK,OAAO,EAAE,MAAM,EAAE,OAAO,MAAM,EAAE;GAC/D,EAAE;GACH;CAQF,MAAM,SAAS,qBAAqB,CAAC,GAAG,SAAS,EAAE,MAAM,aAAa,CAAC,EAAE;EACvE,GAAG;EACH,YAAY;GAAE,GAAG,cAAc;GAAY,cAAc,KAAA;GAAW;EACrE,CAAC;AAEF,QAAO,QAAQ,KAAK,EAAE,OAAO,OAAO;EAAE;EAAK,OAAO,OAAO;EAAI,EAAE;;;AAIjE,SAAgB,YAAY,SAAoE;AAC9F,QAAO,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC,aAAa,EAAE,IAAI,EAAgB,EAAE,IAAI,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { DatasetOption, DatasetSelection, createDatasetSelection, isDatasetSelection } from "./dataset_selection.js";
|
|
2
|
-
import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
|
|
2
|
+
import { FilterMatchOptions, buildRefMap, filterMatchesToOptions, findFilterColumns } from "./filter_discovery.js";
|
|
3
3
|
import { BuildDatasetOptions, buildDatasetOptions } from "./build_dataset_options.js";
|
|
@@ -3,7 +3,7 @@ import { createPFrameForGraphs, isHiddenFromGraphColumn, isHiddenFromUIColumn }
|
|
|
3
3
|
import { AndFilter, AnnotationFilter, AnnotationMode, AnnotationScript, AnnotationScript2, AnnotationStep, IsNA, Log10, NotFilter, NumericalComparisonFilter, OrFilter, PatternFilter, PatternPredicate, PatternPredicateContainSubsequence, PatternPredicateEquals, SortedCumulativeSum, TransformedColumn, ValueRank } from "./PlAnnotations/filter.js";
|
|
4
4
|
import { AnnotationScriptUi, AnnotationStepUi, AnyForm, FilterUi, FilterUiOfType, FilterUiType, FormField, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, compileAnnotationScript, compileFilter, compileFilters, unreachable } from "./PlAnnotations/filters_ui.js";
|
|
5
5
|
import { DatasetOption, DatasetSelection, createDatasetSelection, isDatasetSelection } from "./PlDatasetSelector/dataset_selection.js";
|
|
6
|
-
import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./PlDatasetSelector/filter_discovery.js";
|
|
6
|
+
import { FilterMatchOptions, buildRefMap, filterMatchesToOptions, findFilterColumns } from "./PlDatasetSelector/filter_discovery.js";
|
|
7
7
|
import { BuildDatasetOptions, buildDatasetOptions } from "./PlDatasetSelector/build_dataset_options.js";
|
|
8
8
|
import { PTableParamsV2, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlTableColumnIdJson } from "./PlDataTable/typesV6.js";
|
|
9
9
|
import { PlDataTableStateV2, createDefaultPTableParams, createPlDataTableStateV2, upgradePlDataTableStateV2 } from "./PlDataTable/state-migration.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ import { AnnotationSpec, AnnotationSpecUi, ExpressionSpec, FilterSpecUi } from "
|
|
|
49
49
|
import { convertFilterSpecsToExpressionSpecs } from "./annotations/converter.js";
|
|
50
50
|
import { AnnotationScriptUi, AnnotationStepUi, AnyForm, FilterUi, FilterUiOfType, FilterUiType, FormField, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, compileAnnotationScript, compileFilter, compileFilters, unreachable } from "./components/PlAnnotations/filters_ui.js";
|
|
51
51
|
import { DatasetOption, DatasetSelection, createDatasetSelection, isDatasetSelection } from "./components/PlDatasetSelector/dataset_selection.js";
|
|
52
|
-
import { buildRefMap, filterMatchesToOptions, findFilterColumns } from "./components/PlDatasetSelector/filter_discovery.js";
|
|
52
|
+
import { FilterMatchOptions, buildRefMap, filterMatchesToOptions, findFilterColumns } from "./components/PlDatasetSelector/filter_discovery.js";
|
|
53
53
|
import { BuildDatasetOptions, buildDatasetOptions } from "./components/PlDatasetSelector/build_dataset_options.js";
|
|
54
54
|
import { PTableParamsV2, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlTableColumnIdJson } from "./components/PlDataTable/typesV6.js";
|
|
55
55
|
import { PlDataTableStateV2, createDefaultPTableParams, createPlDataTableStateV2, upgradePlDataTableStateV2 } from "./components/PlDataTable/state-migration.js";
|
|
@@ -74,4 +74,4 @@ import { getService } from "./services/get_services.js";
|
|
|
74
74
|
import { getEnvironmentValue } from "./env_value.js";
|
|
75
75
|
export * from "@milaboratories/pl-model-common";
|
|
76
76
|
export * from "@milaboratories/pl-error-like";
|
|
77
|
-
export { ActAnd, ActExtractArchiveAndGetURL, ActFlatten, ActGetBlobContent, ActGetBlobContentAsJson, ActGetBlobContentAsString, ActGetDownloadedBlobContent, ActGetField, ActGetFromCtx, ActGetImmediate, ActGetLastLogs, ActGetLogHandle, ActGetOnDemandBlobContent, ActGetProgressLog, ActGetProgressLogWithInfo, ActGetResourceField, ActGetResourceValueAsJson, ActImportProgress, ActIsEmpty, ActIsolate, ActMakeArray, ActMakeObject, ActMapArrayValues, ActMapRecordValues, ActMapResourceFields, ActNot, ActOr, ActionResult, AnchorEntry, AnchoredBuildOptions, AnchoredColumnCollection, AnchoredFindColumnsOptions, AndFilter, AnnotationFilter, AnnotationMode, AnnotationScript, AnnotationScript2, AnnotationScriptUi, AnnotationSpec, AnnotationSpecUi, AnnotationStep, AnnotationStepUi, AnyForm, Args, ArrayColumnProvider, AxesVault, AxisLabelProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockApiV1, BlockApiV2, BlockConfig, BlockConfigV3, BlockConfigV4, BlockDefaultModelServices, BlockDefaultUiServices, BlockModel, BlockModelInfo, BlockModelV3, BlockRenderCtx, BlockServiceFlags, BlockStatePatch, type BlockStorage, BlockStorageFacade, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, type BlockStorageSchemaVersion, BuildDatasetOptions, BuildOptions, CancelSubscription, Cfg, CfgAnd, CfgBlobContent, CfgBlobContentAsJson, CfgBlobContentAsString, CfgDownloadedBlobContent, CfgExtractArchiveAndGetURL, CfgFlatten, CfgGetFromCtx, CfgGetJsonField, CfgGetResourceField, CfgImmediate, CfgImportProgress, CfgIsEmpty, CfgIsolate, CfgLastLogs, CfgLogHandle, CfgMakeArray, CfgMakeObject, CfgMapArrayValues, CfgMapRecordValues, CfgMapResourceFields, CfgNot, CfgOnDemandBlobContent, CfgOr, CfgProgressLog, CfgProgressLogWithInfo, CfgRenderingMode, CfgResourceValueAsJson, Checked, ColumnCollection, ColumnCollectionBuilder, ColumnData, ColumnDataStatus, ColumnMatch, ColumnMatcher, ColumnOrderRule, ColumnProvider, ColumnSelector, ColumnSnapshot, ColumnSnapshotProvider, ColumnSource, ColumnVariant, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, CommonFieldTraverseOps, CommonTraversalOps, ConfAction, ConfigRenderLambda, ConfigRenderLambdaFlags, ConfigResult, CurrentSdkInfo, DataModel, DataModelBuilder, DatasetOption, DatasetSelection, DeriveHref, DeriveLabelsFormatters, DeriveLabelsOptions, Entry, ExpandByPartitionOpts, ExpandByPartitionResult, ExpressionSpec, ExtractAction, ExtractFunctionHandleReturn, ExtractFutureRefType, FieldTraversalStep, FieldType, FilterSpec, FilterSpecLeaf, FilterSpecNode, FilterSpecOfType, FilterSpecType, FilterSpecUi, FilterUi, FilterUiOfType, FilterUiType, FindColumnsOptions, FormField, FutureRef, GetFieldStep, InferArgsType, InferBlockState, InferBlockStatePatch, InferDataType, InferFactoryData, InferFactoryModelServices, InferFactoryOutputs, InferFactoryParams, InferFactoryUiServices, InferHrefType, InferOutputType, InferOutputsFromConfigs, InferOutputsFromLambdas, InferOutputsType, InferPluginData, InferPluginHandle, InferPluginNames, InferPluginUiEntries, InferRenderFunctionReturn, InferUiState, InferVarTypeSafe, IsNA, It, internal_d_exports as JsRenderInternal, DeriveLabelsOptions as LabelDerivationOps, LinkerStep, Log10, MainOutputs, MatchQualifications, MatchVariant, MatchingMode, type MigrateBlockStorageConfig, type MigrationFailure, type MigrationResult, type MigrationSuccess, ModelServices, type MutateStoragePayload, NotFilter, NumericalComparisonFilter, OptionalPlResourceEntry, OrFilter, OutputColumnProvider, OutputColumnProviderOpts, OutputError, PColumnCollection, PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnKeyList, PColumnLazyUniversal, PColumnLazyWithLabel, PColumnPredicate, PColumnResourceMapData, PColumnResourceMapEntry, PFrameImpl, POCExtractAction, PTableKey, PTableParamsV2, type ParamsInput, Patch, PatternFilter, PatternPredicate, PatternPredicateContainSubsequence, PatternPredicateEquals, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlMultiSequenceAlignmentColorSchemeOption, PlMultiSequenceAlignmentModel, PlMultiSequenceAlignmentSettings, PlMultiSequenceAlignmentWidget, PlResourceEntry, PlSelectionModel, PlTableColumnIdJson, Platforma, PlatformaApiVersion, PlatformaExtended, PlatformaFactory, PlatformaSDKVersion, PlatformaV1, PlatformaV2, PlatformaV3, type PluginConfig, type PluginData, PluginDataModel, PluginDataModelBuilder, type PluginDataModelVersions, type PluginFactory, PluginFactoryLike, PluginHandle, PluginInstance, PluginModel, type PluginName, type PluginOutputs, type PluginParams, type PluginPublicOutputs, type PluginRecord, type PluginRegistry, PluginRenderCtx, PrimitiveOrConfig, PrimitiveToCfg, type PublicOutputFieldDef, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RelaxedAxisSelector, RelaxedColumnSelector, RelaxedRecord, RelaxedStringMatchers, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResolveCfgType, ResolveModelServices, ResolveUiServices, ResourceTraversalOps, ResourceType, ResultPool, ResultPoolColumnSnapshotProvider, SdkInfo, ServiceProxy, SimplifiedPColumnSpec, SimplifiedUniversalPColumnEntry, SnapshotColumnProvider, SortedCumulativeSum, Entry as SpecExtractorResult, SplitAxis, StagingOutputs, StdCtx, StdCtxArgsOnly, StringMatcher, TooltipEntry, Trace, TraceEntry, TransformedColumn, TreeNodeAccessor, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, TypedConfig, TypedConfigOrConfigLambda, TypedConfigOrString, UiServices, UiState, Unionize, UniversalColumnOption, UnwrapFutureRef, ValueRank, type VersionedData, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableOptionsV3, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
|
|
77
|
+
export { ActAnd, ActExtractArchiveAndGetURL, ActFlatten, ActGetBlobContent, ActGetBlobContentAsJson, ActGetBlobContentAsString, ActGetDownloadedBlobContent, ActGetField, ActGetFromCtx, ActGetImmediate, ActGetLastLogs, ActGetLogHandle, ActGetOnDemandBlobContent, ActGetProgressLog, ActGetProgressLogWithInfo, ActGetResourceField, ActGetResourceValueAsJson, ActImportProgress, ActIsEmpty, ActIsolate, ActMakeArray, ActMakeObject, ActMapArrayValues, ActMapRecordValues, ActMapResourceFields, ActNot, ActOr, ActionResult, AnchorEntry, AnchoredBuildOptions, AnchoredColumnCollection, AnchoredFindColumnsOptions, AndFilter, AnnotationFilter, AnnotationMode, AnnotationScript, AnnotationScript2, AnnotationScriptUi, AnnotationSpec, AnnotationSpecUi, AnnotationStep, AnnotationStepUi, AnyForm, Args, ArrayColumnProvider, AxesVault, AxisLabelProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockApiV1, BlockApiV2, BlockConfig, BlockConfigV3, BlockConfigV4, BlockDefaultModelServices, BlockDefaultUiServices, BlockModel, BlockModelInfo, BlockModelV3, BlockRenderCtx, BlockServiceFlags, BlockStatePatch, type BlockStorage, BlockStorageFacade, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, type BlockStorageSchemaVersion, BuildDatasetOptions, BuildOptions, CancelSubscription, Cfg, CfgAnd, CfgBlobContent, CfgBlobContentAsJson, CfgBlobContentAsString, CfgDownloadedBlobContent, CfgExtractArchiveAndGetURL, CfgFlatten, CfgGetFromCtx, CfgGetJsonField, CfgGetResourceField, CfgImmediate, CfgImportProgress, CfgIsEmpty, CfgIsolate, CfgLastLogs, CfgLogHandle, CfgMakeArray, CfgMakeObject, CfgMapArrayValues, CfgMapRecordValues, CfgMapResourceFields, CfgNot, CfgOnDemandBlobContent, CfgOr, CfgProgressLog, CfgProgressLogWithInfo, CfgRenderingMode, CfgResourceValueAsJson, Checked, ColumnCollection, ColumnCollectionBuilder, ColumnData, ColumnDataStatus, ColumnMatch, ColumnMatcher, ColumnOrderRule, ColumnProvider, ColumnSelector, ColumnSnapshot, ColumnSnapshotProvider, ColumnSource, ColumnVariant, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, CommonFieldTraverseOps, CommonTraversalOps, ConfAction, ConfigRenderLambda, ConfigRenderLambdaFlags, ConfigResult, CurrentSdkInfo, DataModel, DataModelBuilder, DatasetOption, DatasetSelection, DeriveHref, DeriveLabelsFormatters, DeriveLabelsOptions, Entry, ExpandByPartitionOpts, ExpandByPartitionResult, ExpressionSpec, ExtractAction, ExtractFunctionHandleReturn, ExtractFutureRefType, FieldTraversalStep, FieldType, FilterMatchOptions, FilterSpec, FilterSpecLeaf, FilterSpecNode, FilterSpecOfType, FilterSpecType, FilterSpecUi, FilterUi, FilterUiOfType, FilterUiType, FindColumnsOptions, FormField, FutureRef, GetFieldStep, InferArgsType, InferBlockState, InferBlockStatePatch, InferDataType, InferFactoryData, InferFactoryModelServices, InferFactoryOutputs, InferFactoryParams, InferFactoryUiServices, InferHrefType, InferOutputType, InferOutputsFromConfigs, InferOutputsFromLambdas, InferOutputsType, InferPluginData, InferPluginHandle, InferPluginNames, InferPluginUiEntries, InferRenderFunctionReturn, InferUiState, InferVarTypeSafe, IsNA, It, internal_d_exports as JsRenderInternal, DeriveLabelsOptions as LabelDerivationOps, LinkerStep, Log10, MainOutputs, MatchQualifications, MatchVariant, MatchingMode, type MigrateBlockStorageConfig, type MigrationFailure, type MigrationResult, type MigrationSuccess, ModelServices, type MutateStoragePayload, NotFilter, NumericalComparisonFilter, OptionalPlResourceEntry, OrFilter, OutputColumnProvider, OutputColumnProviderOpts, OutputError, PColumnCollection, PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnKeyList, PColumnLazyUniversal, PColumnLazyWithLabel, PColumnPredicate, PColumnResourceMapData, PColumnResourceMapEntry, PFrameImpl, POCExtractAction, PTableKey, PTableParamsV2, type ParamsInput, Patch, PatternFilter, PatternPredicate, PatternPredicateContainSubsequence, PatternPredicateEquals, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlMultiSequenceAlignmentColorSchemeOption, PlMultiSequenceAlignmentModel, PlMultiSequenceAlignmentSettings, PlMultiSequenceAlignmentWidget, PlResourceEntry, PlSelectionModel, PlTableColumnIdJson, Platforma, PlatformaApiVersion, PlatformaExtended, PlatformaFactory, PlatformaSDKVersion, PlatformaV1, PlatformaV2, PlatformaV3, type PluginConfig, type PluginData, PluginDataModel, PluginDataModelBuilder, type PluginDataModelVersions, type PluginFactory, PluginFactoryLike, PluginHandle, PluginInstance, PluginModel, type PluginName, type PluginOutputs, type PluginParams, type PluginPublicOutputs, type PluginRecord, type PluginRegistry, PluginRenderCtx, PrimitiveOrConfig, PrimitiveToCfg, type PublicOutputFieldDef, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RelaxedAxisSelector, RelaxedColumnSelector, RelaxedRecord, RelaxedStringMatchers, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResolveCfgType, ResolveModelServices, ResolveUiServices, ResourceTraversalOps, ResourceType, ResultPool, ResultPoolColumnSnapshotProvider, SdkInfo, ServiceProxy, SimplifiedPColumnSpec, SimplifiedUniversalPColumnEntry, SnapshotColumnProvider, SortedCumulativeSum, Entry as SpecExtractorResult, SplitAxis, StagingOutputs, StdCtx, StdCtxArgsOnly, StringMatcher, TooltipEntry, Trace, TraceEntry, TransformedColumn, TreeNodeAccessor, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, TypedConfig, TypedConfigOrConfigLambda, TypedConfigOrString, UiServices, UiState, Unionize, UniversalColumnOption, UnwrapFutureRef, ValueRank, type VersionedData, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableOptionsV3, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
|
package/dist/package.cjs
CHANGED
package/dist/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/model",
|
|
3
|
-
"version": "1.76.
|
|
3
|
+
"version": "1.76.5",
|
|
4
4
|
"description": "Platforma.bio SDK / Block Model",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"fast-json-patch": "^3.1.1",
|
|
42
42
|
"typescript": "~5.9.3",
|
|
43
43
|
"vitest": "^4.1.3",
|
|
44
|
+
"@milaboratories/ts-configs": "1.2.3",
|
|
44
45
|
"@milaboratories/build-configs": "2.0.0",
|
|
45
|
-
"@milaboratories/pf-spec-driver": "1.3.16",
|
|
46
|
-
"@milaboratories/ts-builder": "1.4.0",
|
|
47
46
|
"@milaboratories/pf-driver": "1.4.11",
|
|
48
|
-
"@milaboratories/
|
|
47
|
+
"@milaboratories/pf-spec-driver": "1.3.16",
|
|
48
|
+
"@milaboratories/ts-builder": "1.4.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "ts-builder build --target node",
|
|
@@ -31,7 +31,11 @@ export type BuildDatasetOptions = {
|
|
|
31
31
|
* accept-all.
|
|
32
32
|
*/
|
|
33
33
|
filter?: SpecPredicateOption;
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Formatting options forwarded to label derivation for both filter and
|
|
36
|
+
* enrichment rows. `formatters.native` on the filter path is overridden
|
|
37
|
+
* — see `FilterMatchOptions.labelOptions`.
|
|
38
|
+
*/
|
|
35
39
|
labelOptions?: DeriveLabelsOptions;
|
|
36
40
|
/**
|
|
37
41
|
* Enables enrichment discovery and filters hits attached to
|
|
@@ -96,7 +100,11 @@ export function buildDatasetOptions(
|
|
|
96
100
|
const filters =
|
|
97
101
|
filterMatches.length === 0
|
|
98
102
|
? undefined
|
|
99
|
-
: filterMatchesToOptions(filterMatches,
|
|
103
|
+
: filterMatchesToOptions(filterMatches, {
|
|
104
|
+
refsByObjectId: refMap,
|
|
105
|
+
datasetSpec,
|
|
106
|
+
labelOptions: opts?.labelOptions,
|
|
107
|
+
});
|
|
100
108
|
|
|
101
109
|
let enrichments;
|
|
102
110
|
if (enrichmentCollection && withEnrichments) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Annotation, createPlRef } from "@milaboratories/pl-model-common";
|
|
2
|
-
import type { AxisSpec, PColumnSpec,
|
|
2
|
+
import type { AxisSpec, PColumnSpec, PObjectId } from "@milaboratories/pl-model-common";
|
|
3
3
|
import { SpecDriver } from "@milaboratories/pf-spec-driver";
|
|
4
4
|
import canonicalize from "canonicalize";
|
|
5
5
|
import { afterEach, describe, expect, test } from "vitest";
|
|
@@ -85,10 +85,7 @@ describe("buildRefMap", () => {
|
|
|
85
85
|
test("maps canonicalized PlRef to original ref", () => {
|
|
86
86
|
const ref1 = createPlRef("b1", "out1");
|
|
87
87
|
const ref2 = createPlRef("b2", "out2", true);
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
const map = buildRefMap(entries);
|
|
91
|
-
|
|
88
|
+
const map = buildRefMap([{ ref: ref1 }, { ref: ref2 }]);
|
|
92
89
|
expect(map.get(canonicalize(ref1)! as PObjectId)).toBe(ref1);
|
|
93
90
|
expect(map.get(canonicalize(ref2)! as PObjectId)).toBe(ref2);
|
|
94
91
|
expect(map.size).toBe(2);
|
|
@@ -104,18 +101,10 @@ describe("filterMatchesToOptions", () => {
|
|
|
104
101
|
const filterRef1 = createPlRef("b1", "filter-top1000");
|
|
105
102
|
const filterRef2 = createPlRef("b1", "filter-highconf");
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
const refMap = buildRefMap([
|
|
109
|
-
{ ref: anchorSnap.id as unknown as PlRef }, // anchor — won't be looked up
|
|
110
|
-
{ ref: filterRef1 },
|
|
111
|
-
{ ref: filterRef2 },
|
|
112
|
-
]);
|
|
113
|
-
|
|
114
|
-
// Build filter specs with isSubset annotation
|
|
104
|
+
const refMap = buildRefMap([{ ref: filterRef1 }, { ref: filterRef2 }]);
|
|
115
105
|
const filterSpec1 = spec("filter1", [axis("sample")], { [Annotation.IsSubset]: "true" });
|
|
116
106
|
const filterSpec2 = spec("filter2", [axis("sample")], { [Annotation.IsSubset]: "true" });
|
|
117
107
|
|
|
118
|
-
// Use the canonical PlRef as the PObjectId (matches how result pool works)
|
|
119
108
|
const f1Snap = snap(canonicalize(filterRef1)! as string, filterSpec1);
|
|
120
109
|
const f2Snap = snap(canonicalize(filterRef2)! as string, filterSpec2);
|
|
121
110
|
|
|
@@ -126,7 +115,10 @@ describe("filterMatchesToOptions", () => {
|
|
|
126
115
|
const matches = findFilterColumns(collection);
|
|
127
116
|
expect(matches.length).toBe(2);
|
|
128
117
|
|
|
129
|
-
const options = filterMatchesToOptions(matches,
|
|
118
|
+
const options = filterMatchesToOptions(matches, {
|
|
119
|
+
refsByObjectId: refMap,
|
|
120
|
+
datasetSpec: anchorSpec,
|
|
121
|
+
});
|
|
130
122
|
expect(options).toHaveLength(2);
|
|
131
123
|
// Each option has a ref and label
|
|
132
124
|
for (const opt of options) {
|
|
@@ -136,11 +128,114 @@ describe("filterMatchesToOptions", () => {
|
|
|
136
128
|
}
|
|
137
129
|
});
|
|
138
130
|
|
|
131
|
+
test("single filter: dataset name prefixes the discriminating trace step", () => {
|
|
132
|
+
// Regression: without the dataset in the input, deriveDistinctLabels
|
|
133
|
+
// picks the highest-importance step it sees — the dataset's own
|
|
134
|
+
// `samples-and-data/dataset` step (importance 100) — and the filter
|
|
135
|
+
// shows "Bulk" instead of "Top 10". Appending the dataset forces the
|
|
136
|
+
// algorithm to include the lower-importance lead-selection step too.
|
|
137
|
+
const datasetSpec = spec("dataset", [axis("sample"), axis("gene")], {
|
|
138
|
+
[Annotation.Label]: "Bulk",
|
|
139
|
+
[Annotation.Trace]: JSON.stringify([
|
|
140
|
+
{ type: "milaboratories.samples-and-data/dataset", label: "Bulk", importance: 100 },
|
|
141
|
+
{ type: "milaboratories.mixcr-clonotyping", label: "MiXCR", importance: 20 },
|
|
142
|
+
]),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const filterRef = createPlRef("b1", "filter");
|
|
146
|
+
const refMap = buildRefMap([{ ref: filterRef }]);
|
|
147
|
+
const filterSpec = spec("filter", [axis("sample")], {
|
|
148
|
+
[Annotation.IsSubset]: "true",
|
|
149
|
+
[Annotation.Label]: "Selected Leads",
|
|
150
|
+
[Annotation.Trace]: JSON.stringify([
|
|
151
|
+
{ type: "milaboratories.samples-and-data/dataset", label: "Bulk", importance: 100 },
|
|
152
|
+
{ type: "milaboratories.mixcr-clonotyping", label: "MiXCR", importance: 20 },
|
|
153
|
+
{ type: "milaboratories.antibody-tcr-lead-selection", label: "Top 10", importance: 30 },
|
|
154
|
+
]),
|
|
155
|
+
});
|
|
156
|
+
const fSnap = snap(canonicalize(filterRef)! as string, filterSpec);
|
|
157
|
+
|
|
158
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
159
|
+
builder.addSource([fSnap, anchorSnap]);
|
|
160
|
+
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
161
|
+
|
|
162
|
+
const matches = findFilterColumns(collection);
|
|
163
|
+
expect(matches).toHaveLength(1);
|
|
164
|
+
|
|
165
|
+
const options = filterMatchesToOptions(matches, { refsByObjectId: refMap, datasetSpec });
|
|
166
|
+
expect(options).toHaveLength(1);
|
|
167
|
+
expect(options[0].label).toBe("Bulk / Top 10");
|
|
168
|
+
|
|
169
|
+
// Caller's `formatters.native` must NOT override the internal
|
|
170
|
+
// suppression — otherwise the algorithm short-circuits on the
|
|
171
|
+
// inherited "Selected Leads" label.
|
|
172
|
+
const withCustomNative = filterMatchesToOptions(matches, {
|
|
173
|
+
refsByObjectId: refMap,
|
|
174
|
+
datasetSpec,
|
|
175
|
+
labelOptions: { formatters: { native: (l) => `<<${l}>>` } },
|
|
176
|
+
});
|
|
177
|
+
expect(withCustomNative[0].label).toBe("Bulk / Top 10");
|
|
178
|
+
|
|
179
|
+
// Non-native label options (here `separator`) flow through.
|
|
180
|
+
const withSeparator = filterMatchesToOptions(matches, {
|
|
181
|
+
refsByObjectId: refMap,
|
|
182
|
+
datasetSpec,
|
|
183
|
+
labelOptions: { separator: " :: " },
|
|
184
|
+
});
|
|
185
|
+
expect(withSeparator[0].label).toBe("Bulk :: Top 10");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("multiple filters with shared dataset trace disambiguate by filter-specific steps", () => {
|
|
189
|
+
const datasetSpec = spec("dataset", [axis("sample"), axis("gene")], {
|
|
190
|
+
[Annotation.Label]: "Bulk",
|
|
191
|
+
[Annotation.Trace]: JSON.stringify([
|
|
192
|
+
{ type: "milaboratories.samples-and-data/dataset", label: "Bulk", importance: 100 },
|
|
193
|
+
{ type: "milaboratories.mixcr-clonotyping", label: "MiXCR", importance: 20 },
|
|
194
|
+
]),
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const ref1 = createPlRef("b1", "f1");
|
|
198
|
+
const ref2 = createPlRef("b2", "f2");
|
|
199
|
+
const refMap = buildRefMap([{ ref: ref1 }, { ref: ref2 }]);
|
|
200
|
+
const filterSpec1 = spec("filter1", [axis("sample")], {
|
|
201
|
+
[Annotation.IsSubset]: "true",
|
|
202
|
+
[Annotation.Label]: "Selected Leads",
|
|
203
|
+
[Annotation.Trace]: JSON.stringify([
|
|
204
|
+
{ type: "milaboratories.samples-and-data/dataset", label: "Bulk", importance: 100 },
|
|
205
|
+
{ type: "milaboratories.mixcr-clonotyping", label: "MiXCR", importance: 20 },
|
|
206
|
+
{ type: "milaboratories.antibody-tcr-lead-selection", label: "Top 10", importance: 30 },
|
|
207
|
+
]),
|
|
208
|
+
});
|
|
209
|
+
const filterSpec2 = spec("filter2", [axis("sample")], {
|
|
210
|
+
[Annotation.IsSubset]: "true",
|
|
211
|
+
[Annotation.Label]: "Selected Leads",
|
|
212
|
+
[Annotation.Trace]: JSON.stringify([
|
|
213
|
+
{ type: "milaboratories.samples-and-data/dataset", label: "Bulk", importance: 100 },
|
|
214
|
+
{ type: "milaboratories.mixcr-clonotyping", label: "MiXCR", importance: 20 },
|
|
215
|
+
{ type: "milaboratories.antibody-tcr-lead-selection", label: "Top 11", importance: 30 },
|
|
216
|
+
]),
|
|
217
|
+
});
|
|
218
|
+
const f1Snap = snap(canonicalize(ref1)! as string, filterSpec1);
|
|
219
|
+
const f2Snap = snap(canonicalize(ref2)! as string, filterSpec2);
|
|
220
|
+
|
|
221
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
222
|
+
builder.addSource([f1Snap, f2Snap, anchorSnap]);
|
|
223
|
+
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
224
|
+
|
|
225
|
+
const matches = findFilterColumns(collection);
|
|
226
|
+
expect(matches).toHaveLength(2);
|
|
227
|
+
|
|
228
|
+
const options = filterMatchesToOptions(matches, { refsByObjectId: refMap, datasetSpec });
|
|
229
|
+
expect(options.map((o) => o.label).sort()).toEqual(["Bulk / Top 10", "Bulk / Top 11"]);
|
|
230
|
+
});
|
|
231
|
+
|
|
139
232
|
test("returns empty array for empty matches", () => {
|
|
140
|
-
expect(
|
|
233
|
+
expect(
|
|
234
|
+
filterMatchesToOptions([], { refsByObjectId: new Map(), datasetSpec: anchorSpec }),
|
|
235
|
+
).toEqual([]);
|
|
141
236
|
});
|
|
142
237
|
|
|
143
|
-
test("skips entries whose
|
|
238
|
+
test("skips entries whose id is not in refsByObjectId", () => {
|
|
144
239
|
const knownRef = createPlRef("b1", "known");
|
|
145
240
|
const knownSpec = spec("known", [axis("sample")], { [Annotation.IsSubset]: "true" });
|
|
146
241
|
const orphanSpec = spec("orphan", [axis("sample")], { [Annotation.IsSubset]: "true" });
|
|
@@ -153,9 +248,11 @@ describe("filterMatchesToOptions", () => {
|
|
|
153
248
|
|
|
154
249
|
const matches = findFilterColumns(collection);
|
|
155
250
|
expect(matches.length).toBe(2);
|
|
156
|
-
|
|
157
251
|
const refMap = buildRefMap([{ ref: knownRef }]);
|
|
158
|
-
const options = filterMatchesToOptions(matches,
|
|
252
|
+
const options = filterMatchesToOptions(matches, {
|
|
253
|
+
refsByObjectId: refMap,
|
|
254
|
+
datasetSpec: anchorSpec,
|
|
255
|
+
});
|
|
159
256
|
expect(options).toHaveLength(1);
|
|
160
257
|
expect(options[0].ref).toBe(knownRef);
|
|
161
258
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Annotation } from "@milaboratories/pl-model-common";
|
|
2
|
-
import type { Option, PlRef, PObjectId } from "@milaboratories/pl-model-common";
|
|
2
|
+
import type { Option, PlRef, PObjectId, PObjectSpec } from "@milaboratories/pl-model-common";
|
|
3
3
|
import canonicalize from "canonicalize";
|
|
4
4
|
import type {
|
|
5
5
|
AnchoredColumnCollection,
|
|
@@ -12,12 +12,8 @@ import {
|
|
|
12
12
|
} from "../../labels/derive_distinct_labels";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* The axes-subset constraint is enforced by `mode: "enrichment"`, which sets
|
|
18
|
-
* `allowFloatingHitAxes: false` — every axis of the matched column must be
|
|
19
|
-
* present in the anchor's axes. See `matchingModeToConstraints()` in
|
|
20
|
-
* `column_collection_builder.ts`.
|
|
15
|
+
* Columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
|
|
16
|
+
* The axes-subset constraint comes from `mode: "enrichment"`.
|
|
21
17
|
*/
|
|
22
18
|
export function findFilterColumns(collection: AnchoredColumnCollection): ColumnMatch[] {
|
|
23
19
|
return collection.findColumns({
|
|
@@ -28,51 +24,62 @@ export function findFilterColumns(collection: AnchoredColumnCollection): ColumnM
|
|
|
28
24
|
});
|
|
29
25
|
}
|
|
30
26
|
|
|
27
|
+
export type FilterMatchOptions = {
|
|
28
|
+
/** Maps result-pool column id back to its source PlRef (see {@link buildRefMap}). */
|
|
29
|
+
refsByObjectId: ReadonlyMap<PObjectId, PlRef>;
|
|
30
|
+
/** Spec of the dataset the filters are subsets of. */
|
|
31
|
+
datasetSpec: PObjectSpec;
|
|
32
|
+
/**
|
|
33
|
+
* Forwarded to `deriveDistinctLabels`. Any `formatters.native` caller
|
|
34
|
+
* sets is silently overridden — the function relies on a no-op native
|
|
35
|
+
* formatter to keep the algorithm from short-circuiting on filters'
|
|
36
|
+
* inherited `pl7.app/label`.
|
|
37
|
+
*/
|
|
38
|
+
labelOptions?: DeriveLabelsOptions;
|
|
39
|
+
};
|
|
40
|
+
|
|
31
41
|
/**
|
|
32
|
-
* Derive
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* skipped — they cannot be exposed as user-selectable options.
|
|
36
|
-
*
|
|
37
|
-
* @param matches - from findFilterColumns()
|
|
38
|
-
* @param refsByObjectId - from {@link buildRefMap}
|
|
39
|
-
* @param labelOptions - forwarded to deriveDistinctLabels()
|
|
42
|
+
* Derive labels for filter column matches (for `DatasetOption.filters`).
|
|
43
|
+
* Matches whose column id is missing from `refsByObjectId` are silently
|
|
44
|
+
* dropped — they cannot be exposed as selectable options.
|
|
40
45
|
*/
|
|
41
46
|
export function filterMatchesToOptions(
|
|
42
47
|
matches: ColumnMatch[],
|
|
43
|
-
|
|
44
|
-
labelOptions?: DeriveLabelsOptions,
|
|
48
|
+
options: FilterMatchOptions,
|
|
45
49
|
): Option[] {
|
|
46
50
|
if (matches.length === 0) return [];
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
52
|
+
const { refsByObjectId, datasetSpec, labelOptions } = options;
|
|
53
|
+
|
|
54
|
+
// One entry per match-variant (different paths to the same column are
|
|
55
|
+
// exposed as separate Options). The `ref` field rides along on the
|
|
56
|
+
// Entry-shaped objects via structural typing; `deriveDistinctLabels`
|
|
57
|
+
// ignores extra fields.
|
|
58
|
+
const entries = matches.flatMap((match): (Entry & { ref: PlRef })[] => {
|
|
54
59
|
const ref = refsByObjectId.get(match.column.id);
|
|
55
60
|
if (ref === undefined) return [];
|
|
56
|
-
return match.variants.map((variant) => ({
|
|
61
|
+
return match.variants.map((variant) => ({
|
|
62
|
+
ref,
|
|
63
|
+
spec: match.column.spec,
|
|
64
|
+
linkerPath: variant.path.map((p) => ({ spec: p.linker.spec })),
|
|
65
|
+
}));
|
|
57
66
|
});
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
// Appending the dataset forces a discriminating trace step into every
|
|
69
|
+
// filter label (yielding e.g. "Bulk / Top 10"); the dataset's own label
|
|
70
|
+
// is dropped because we only zip `entries`. Native label is force-
|
|
71
|
+
// suppressed (the override sits after caller's spread) — filters
|
|
72
|
+
// inherit the dataset's `pl7.app/label` and would otherwise satisfy
|
|
73
|
+
// uniqueness before any trace step is consulted.
|
|
74
|
+
const labels = deriveDistinctLabels([...entries, { spec: datasetSpec }], {
|
|
75
|
+
...labelOptions,
|
|
76
|
+
formatters: { ...labelOptions?.formatters, native: () => undefined },
|
|
77
|
+
});
|
|
65
78
|
|
|
66
|
-
return
|
|
79
|
+
return entries.map(({ ref }, i) => ({ ref, label: labels[i] }));
|
|
67
80
|
}
|
|
68
81
|
|
|
69
|
-
/**
|
|
70
|
-
* Usage: `buildRefMap(ctx.resultPool.getSpecs().entries)`
|
|
71
|
-
*/
|
|
82
|
+
/** Build the `refsByObjectId` map from `ctx.resultPool.getSpecs().entries`. */
|
|
72
83
|
export function buildRefMap(entries: readonly { readonly ref: PlRef }[]): Map<PObjectId, PlRef> {
|
|
73
|
-
|
|
74
|
-
for (const entry of entries) {
|
|
75
|
-
map.set(canonicalize(entry.ref)! as PObjectId, entry.ref);
|
|
76
|
-
}
|
|
77
|
-
return map;
|
|
84
|
+
return new Map(entries.map((e) => [canonicalize(e.ref)! as PObjectId, e.ref]));
|
|
78
85
|
}
|