@platforma-sdk/model 1.61.1 → 1.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/block_model.cjs +17 -10
- package/dist/block_model.cjs.map +1 -1
- package/dist/block_model.d.ts +22 -5
- package/dist/block_model.js +16 -10
- package/dist/block_model.js.map +1 -1
- package/dist/columns/column_collection_builder.cjs +26 -14
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +9 -8
- package/dist/columns/column_collection_builder.js +26 -14
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +93 -89
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +2 -2
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +93 -89
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.d.ts +2 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.cjs +1 -1
- package/dist/components/PlMultiSequenceAlignment.cjs.map +1 -1
- package/dist/components/PlMultiSequenceAlignment.js +2 -2
- package/dist/components/PlMultiSequenceAlignment.js.map +1 -1
- package/dist/components/PlSelectionModel.cjs.map +1 -1
- package/dist/components/PlSelectionModel.d.ts +1 -1
- package/dist/components/PlSelectionModel.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/pframe_utils/index.cjs +2 -5
- package/dist/pframe_utils/index.cjs.map +1 -1
- package/dist/pframe_utils/index.js +2 -5
- package/dist/pframe_utils/index.js.map +1 -1
- package/dist/platforma.d.ts +8 -4
- package/dist/plugin_handle.cjs.map +1 -1
- package/dist/plugin_handle.d.ts +13 -7
- package/dist/plugin_handle.js.map +1 -1
- package/dist/plugin_model.cjs +37 -11
- package/dist/plugin_model.cjs.map +1 -1
- package/dist/plugin_model.d.ts +80 -39
- package/dist/plugin_model.js +37 -11
- package/dist/plugin_model.js.map +1 -1
- package/dist/render/api.cjs +13 -24
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +11 -14
- package/dist/render/api.js +13 -24
- package/dist/render/api.js.map +1 -1
- package/dist/render/internal.cjs.map +1 -1
- package/dist/render/internal.d.ts +3 -14
- package/dist/render/internal.js.map +1 -1
- package/dist/services/block_services.cjs +18 -0
- package/dist/services/block_services.cjs.map +1 -0
- package/dist/services/block_services.d.ts +18 -0
- package/dist/services/block_services.js +16 -0
- package/dist/services/block_services.js.map +1 -0
- package/dist/services/index.cjs +2 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +2 -0
- package/dist/services/service_bridge.cjs +35 -0
- package/dist/services/service_bridge.cjs.map +1 -0
- package/dist/services/service_bridge.d.ts +18 -0
- package/dist/services/service_bridge.js +33 -0
- package/dist/services/service_bridge.js.map +1 -0
- package/dist/services/service_resolve.d.ts +13 -0
- package/package.json +9 -9
- package/src/block_model.ts +47 -14
- package/src/columns/column_collection_builder.test.ts +23 -2
- package/src/columns/column_collection_builder.ts +38 -30
- package/src/columns/ctx_column_sources.ts +2 -2
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +159 -153
- package/src/components/PlDataTable/createPlDataTable/index.ts +5 -4
- package/src/components/PlMultiSequenceAlignment.ts +1 -2
- package/src/components/PlSelectionModel.ts +1 -1
- package/src/index.ts +1 -0
- package/src/pframe_utils/index.ts +2 -6
- package/src/platforma.ts +14 -2
- package/src/plugin_handle.ts +24 -6
- package/src/plugin_model.ts +252 -84
- package/src/render/api.ts +50 -51
- package/src/render/internal.ts +3 -38
- package/src/services/block_services.ts +17 -0
- package/src/services/index.ts +3 -0
- package/src/services/service_bridge.ts +71 -0
- package/src/services/service_resolve.ts +71 -0
|
@@ -15,8 +15,8 @@ let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common")
|
|
|
15
15
|
*/
|
|
16
16
|
var ColumnCollectionBuilder = class {
|
|
17
17
|
providers = [];
|
|
18
|
-
constructor(
|
|
19
|
-
this.
|
|
18
|
+
constructor(specDriver) {
|
|
19
|
+
this.specDriver = specDriver;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Register a column source. Sources added first take precedence for dedup.
|
|
@@ -43,13 +43,13 @@ var ColumnCollectionBuilder = class {
|
|
|
43
43
|
if (hasAnchors) {
|
|
44
44
|
const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);
|
|
45
45
|
const idDeriver = new _milaboratories_pl_model_common.AnchoredIdDeriver(anchorSpecs);
|
|
46
|
-
return new AnchoredColumnCollectionImpl(this.
|
|
46
|
+
return new AnchoredColumnCollectionImpl(this.specDriver, {
|
|
47
47
|
columns: columnMap,
|
|
48
48
|
idDeriver,
|
|
49
49
|
anchorSpecs,
|
|
50
50
|
columnListComplete: allowPartial ? allComplete : false
|
|
51
51
|
});
|
|
52
|
-
} else return new ColumnCollectionImpl(this.
|
|
52
|
+
} else return new ColumnCollectionImpl(this.specDriver, {
|
|
53
53
|
columns: columnMap,
|
|
54
54
|
columnListComplete: allowPartial ? allComplete : false
|
|
55
55
|
});
|
|
@@ -81,13 +81,19 @@ const PLAIN_CONSTRAINTS = {
|
|
|
81
81
|
};
|
|
82
82
|
var ColumnCollectionImpl = class {
|
|
83
83
|
columns;
|
|
84
|
-
|
|
84
|
+
specFrameEntry;
|
|
85
85
|
columnListComplete;
|
|
86
|
-
constructor(
|
|
87
|
-
this.
|
|
86
|
+
constructor(specDriver, options) {
|
|
87
|
+
this.specDriver = specDriver;
|
|
88
88
|
this.columns = options.columns;
|
|
89
89
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
90
|
-
this.
|
|
90
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])));
|
|
91
|
+
}
|
|
92
|
+
dispose() {
|
|
93
|
+
this.specFrameEntry.unref();
|
|
94
|
+
}
|
|
95
|
+
[Symbol.dispose]() {
|
|
96
|
+
this.dispose();
|
|
91
97
|
}
|
|
92
98
|
getColumn(id) {
|
|
93
99
|
const col = this.columns.get(id);
|
|
@@ -97,7 +103,7 @@ var ColumnCollectionImpl = class {
|
|
|
97
103
|
findColumns(options) {
|
|
98
104
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
|
|
99
105
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
|
|
100
|
-
return this.
|
|
106
|
+
return this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
101
107
|
includeColumns,
|
|
102
108
|
excludeColumns,
|
|
103
109
|
axes: [],
|
|
@@ -112,23 +118,29 @@ var ColumnCollectionImpl = class {
|
|
|
112
118
|
var AnchoredColumnCollectionImpl = class {
|
|
113
119
|
columns;
|
|
114
120
|
idDeriver;
|
|
115
|
-
|
|
121
|
+
specFrameEntry;
|
|
116
122
|
anchorAxes;
|
|
117
123
|
/** Reverse lookup: SUniversalPColumnId → PObjectId */
|
|
118
124
|
idToOriginal;
|
|
119
125
|
columnListComplete;
|
|
120
|
-
constructor(
|
|
121
|
-
this.
|
|
126
|
+
constructor(specDriver, options) {
|
|
127
|
+
this.specDriver = specDriver;
|
|
122
128
|
this.columns = options.columns;
|
|
123
129
|
this.idDeriver = options.idDeriver;
|
|
124
130
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
125
|
-
this.
|
|
131
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])));
|
|
126
132
|
this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({
|
|
127
133
|
axesSpec: spec.axesSpec,
|
|
128
134
|
qualifications: []
|
|
129
135
|
}));
|
|
130
136
|
this.idToOriginal = new Map(Array.from(this.columns.entries()).map(([id, col]) => [this.idDeriver.deriveS(col.spec), id]));
|
|
131
137
|
}
|
|
138
|
+
dispose() {
|
|
139
|
+
this.specFrameEntry.unref();
|
|
140
|
+
}
|
|
141
|
+
[Symbol.dispose]() {
|
|
142
|
+
this.dispose();
|
|
143
|
+
}
|
|
132
144
|
getColumn(id) {
|
|
133
145
|
const origId = this.idToOriginal.get(id);
|
|
134
146
|
if (origId === void 0) return void 0;
|
|
@@ -140,7 +152,7 @@ var AnchoredColumnCollectionImpl = class {
|
|
|
140
152
|
const constraints = matchingModeToConstraints(options?.mode ?? "enrichment");
|
|
141
153
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
|
|
142
154
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
|
|
143
|
-
return this.
|
|
155
|
+
return this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
144
156
|
includeColumns,
|
|
145
157
|
excludeColumns,
|
|
146
158
|
constraints,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_collection_builder.cjs","names":["TreeNodeAccessor","ArrayColumnProvider","toColumnSnapshotProvider","AnchoredIdDeriver","createColumnSnapshot","normalizeSelectors"],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n ColumnAxesWithQualifications,\n DiscoverColumnsConstraints,\n DiscoverColumnsStepInfo,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PlRef,\n PObjectId,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { AnchoredIdDeriver, deriveNativeId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelectorInput } from \"./column_selector\";\nimport { normalizeSelectors } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport { createColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { GlobalCfgRenderCtxMethods } from \"../render/internal\";\n\n/** Subset of render context methods needed for spec frame operations. */\ntype SpecFrameCtx = Pick<\n GlobalCfgRenderCtxMethods,\n \"createSpecFrame\" | \"specFrameDiscoverColumns\" | \"disposeSpecFrame\"\n>;\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelectorInput;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelectorInput;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection {\n /** Point lookup by provider-native ID. */\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection {\n /** Point lookup by anchored ID. */\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<SUniversalPColumnId>;\n /** Provider-native ID — for lookups back to the source provider. */\n readonly originalId: PObjectId;\n /** Match variants — different paths/qualifications that reach this column. */\n readonly variants: MatchVariant[];\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: DiscoverColumnsStepInfo[];\n}\n\n/** Qualifications needed for both query (already-integrated) columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for each query (already-integrated) column set. */\n readonly forQueries: AxisQualification[][];\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specFrameCtx: SpecFrameCtx) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columnMap = this.collectColumns();\n\n if (hasAnchors) {\n const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);\n const idDeriver = new AnchoredIdDeriver(anchorSpecs);\n\n return new AnchoredColumnCollectionImpl(this.specFrameCtx, {\n columns: columnMap,\n idDeriver,\n anchorSpecs,\n columnListComplete: allowPartial ? allComplete : false,\n });\n } else {\n return new ColumnCollectionImpl(this.specFrameCtx, {\n columns: columnMap,\n columnListComplete: allowPartial ? allComplete : false,\n });\n }\n }\n\n /**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\n private collectColumns(): Map<PObjectId, ColumnSnapshot<PObjectId>> {\n const seen = new Set<NativePObjectId>();\n const result = new Map<PObjectId, ColumnSnapshot<PObjectId>>();\n\n for (const provider of this.providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.set(col.id, col);\n }\n }\n\n return result;\n }\n}\n\n// --- Permissive constraints for plain (non-anchored) filtering ---\n\nconst PLAIN_CONSTRAINTS: DiscoverColumnsConstraints = {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n};\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n readonly columnListComplete?: boolean;\n}\n\nclass ColumnCollectionImpl implements ColumnCollection {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameHandle: string;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly ctx: SpecFrameCtx,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.columnListComplete = options.columnListComplete ?? false;\n this.specFrameHandle = this.ctx.createSpecFrame(\n Array.from(this.columns.entries()).reduce(\n (acc, [id, col]) => ((acc[id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n ),\n );\n }\n\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {\n const col = this.columns.get(id);\n if (col === undefined) return undefined;\n return this.toSnapshot(col);\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.ctx.specFrameDiscoverColumns(this.specFrameHandle, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: PLAIN_CONSTRAINTS,\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined)\n .map((col) => this.toSnapshot(col));\n\n return results;\n }\n\n private toSnapshot(col: ColumnSnapshot<PObjectId>): ColumnSnapshot<PObjectId> {\n return remapSnapshot(col.id, col);\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly idDeriver: AnchoredIdDeriver;\n readonly anchorSpecs: Record<string, PColumnSpec>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly idDeriver: AnchoredIdDeriver;\n private readonly specFrameHandle: string;\n private readonly anchorAxes: ColumnAxesWithQualifications[];\n /** Reverse lookup: SUniversalPColumnId → PObjectId */\n private readonly idToOriginal: Map<SUniversalPColumnId, PObjectId>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly ctx: SpecFrameCtx,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.idDeriver = options.idDeriver;\n this.columnListComplete = options.columnListComplete ?? false;\n\n // Create spec frame from all collected columns\n this.specFrameHandle = this.ctx.createSpecFrame(\n Array.from(this.columns.entries()).reduce(\n (acc, [id, col]) => ((acc[id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n ),\n );\n\n // Build anchor axes for discovery requests\n this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({\n axesSpec: spec.axesSpec,\n qualifications: [],\n }));\n\n // Build reverse lookup map\n this.idToOriginal = new Map(\n Array.from(this.columns.entries()).map(\n ([id, col]) => [this.idDeriver.deriveS(col.spec), id] as const,\n ),\n );\n }\n\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {\n const origId = this.idToOriginal.get(id);\n if (origId === undefined) return undefined;\n const col = this.columns.get(origId);\n if (col === undefined) return undefined;\n return this.toSnapshot(id, col);\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.ctx.specFrameDiscoverColumns(this.specFrameHandle, {\n includeColumns,\n excludeColumns,\n constraints,\n axes: this.anchorAxes,\n maxHops: options?.maxHops ?? 4,\n });\n\n // Map hits back to ColumnMatch entries\n const results = response.hits\n .map((hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col = this.columns.get(origId);\n if (!col) return undefined;\n const universalId = this.idDeriver.deriveS(col.spec);\n return {\n column: this.toSnapshot(universalId, col),\n originalId: origId,\n variants: hit.mappingVariants.map(\n (v): MatchVariant => ({\n qualifications: v.qualifications,\n distinctiveQualifications: v.distinctiveQualifications,\n }),\n ),\n path: hit.path,\n } satisfies ColumnMatch;\n })\n .filter((m): m is ColumnMatch => m !== undefined);\n\n return results;\n }\n\n private toSnapshot(\n universalId: SUniversalPColumnId,\n col: ColumnSnapshot<PObjectId>,\n ): ColumnSnapshot<SUniversalPColumnId> {\n return remapSnapshot(universalId, col);\n }\n}\n\n// --- Shared snapshot helpers ---\n\n/** Create a new snapshot with a different ID, preserving data accessors. */\nfunction remapSnapshot<Id extends PObjectId>(\n id: Id,\n col: ColumnSnapshot<PObjectId>,\n): ColumnSnapshot<Id> {\n return createColumnSnapshot(id, col.spec, col.dataStatus, col.data);\n}\n\n/** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {\n return normalizeSelectors(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor value to a PColumnSpec.\n * - PColumnSpec: used directly\n * - PObjectId (string): looked up in the collected column map\n * - PlRef: not supported at this level — caller must resolve before building\n */\nfunction resolveAnchorSpecs(\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>,\n columnMap: Map<PObjectId, ColumnSnapshot<PObjectId>>,\n): Record<string, PColumnSpec> {\n const result: Record<string, PColumnSpec> = {};\n for (const [key, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n // PObjectId — look up in collected columns\n const col = columnMap.get(anchor as PObjectId);\n if (!col) throw new Error(`Anchor \"${key}\": column with id \"${anchor}\" not found in sources`);\n result[key] = col.spec;\n } else if (isPlRef(anchor)) {\n throw new Error(\n `Anchor \"${key}\": PlRef anchors must be resolved to PColumnSpec before building. ` +\n `Use the column's spec directly or pass its PObjectId.`,\n );\n } else {\n // PColumnSpec\n result[key] = anchor;\n }\n }\n return result;\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"column_collection_builder.cjs","names":["TreeNodeAccessor","ArrayColumnProvider","toColumnSnapshotProvider","AnchoredIdDeriver","createColumnSnapshot","normalizeSelectors"],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n ColumnAxesWithQualifications,\n DiscoverColumnsConstraints,\n DiscoverColumnsStepInfo,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PlRef,\n PObjectId,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { AnchoredIdDeriver, deriveNativeId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelectorInput } from \"./column_selector\";\nimport { normalizeSelectors } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport { createColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelectorInput;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelectorInput;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n /** Point lookup by provider-native ID. */\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n /** Point lookup by anchored ID. */\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<SUniversalPColumnId>;\n /** Provider-native ID — for lookups back to the source provider. */\n readonly originalId: PObjectId;\n /** Match variants — different paths/qualifications that reach this column. */\n readonly variants: MatchVariant[];\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: DiscoverColumnsStepInfo[];\n}\n\n/** Qualifications needed for both query (already-integrated) columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for each query (already-integrated) column set. */\n readonly forQueries: AxisQualification[][];\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columnMap = this.collectColumns();\n\n if (hasAnchors) {\n const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);\n const idDeriver = new AnchoredIdDeriver(anchorSpecs);\n\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n columns: columnMap,\n idDeriver,\n anchorSpecs,\n columnListComplete: allowPartial ? allComplete : false,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns: columnMap,\n columnListComplete: allowPartial ? allComplete : false,\n });\n }\n }\n\n /**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\n private collectColumns(): Map<PObjectId, ColumnSnapshot<PObjectId>> {\n const seen = new Set<NativePObjectId>();\n const result = new Map<PObjectId, ColumnSnapshot<PObjectId>>();\n\n for (const provider of this.providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.set(col.id, col);\n }\n }\n\n return result;\n }\n}\n\n// --- Permissive constraints for plain (non-anchored) filtering ---\n\nconst PLAIN_CONSTRAINTS: DiscoverColumnsConstraints = {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n};\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n readonly columnListComplete?: boolean;\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.columnListComplete = options.columnListComplete ?? false;\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {\n const col = this.columns.get(id);\n if (col === undefined) return undefined;\n return this.toSnapshot(col);\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: PLAIN_CONSTRAINTS,\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined)\n .map((col) => this.toSnapshot(col));\n\n return results;\n }\n\n private toSnapshot(col: ColumnSnapshot<PObjectId>): ColumnSnapshot<PObjectId> {\n return remapSnapshot(col.id, col);\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly idDeriver: AnchoredIdDeriver;\n readonly anchorSpecs: Record<string, PColumnSpec>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly idDeriver: AnchoredIdDeriver;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n private readonly anchorAxes: ColumnAxesWithQualifications[];\n /** Reverse lookup: SUniversalPColumnId → PObjectId */\n private readonly idToOriginal: Map<SUniversalPColumnId, PObjectId>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.idDeriver = options.idDeriver;\n this.columnListComplete = options.columnListComplete ?? false;\n\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),\n );\n\n // Build anchor axes for discovery requests\n this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({\n axesSpec: spec.axesSpec,\n qualifications: [],\n }));\n\n // Build reverse lookup map\n this.idToOriginal = new Map(\n Array.from(this.columns.entries()).map(\n ([id, col]) => [this.idDeriver.deriveS(col.spec), id] as const,\n ),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {\n const origId = this.idToOriginal.get(id);\n if (origId === undefined) return undefined;\n const col = this.columns.get(origId);\n if (col === undefined) return undefined;\n return this.toSnapshot(id, col);\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n axes: this.anchorAxes,\n maxHops: options?.maxHops ?? 4,\n });\n\n // Map hits back to ColumnMatch entries\n const results = response.hits\n .map((hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col = this.columns.get(origId);\n if (!col) return undefined;\n const universalId = this.idDeriver.deriveS(col.spec);\n return {\n column: this.toSnapshot(universalId, col),\n originalId: origId,\n variants: hit.mappingVariants.map(\n (v): MatchVariant => ({\n qualifications: v.qualifications,\n distinctiveQualifications: v.distinctiveQualifications,\n }),\n ),\n path: hit.path,\n } satisfies ColumnMatch;\n })\n .filter((m): m is ColumnMatch => m !== undefined);\n\n return results;\n }\n\n private toSnapshot(\n universalId: SUniversalPColumnId,\n col: ColumnSnapshot<PObjectId>,\n ): ColumnSnapshot<SUniversalPColumnId> {\n return remapSnapshot(universalId, col);\n }\n}\n\n// --- Shared snapshot helpers ---\n\n/** Create a new snapshot with a different ID, preserving data accessors. */\nfunction remapSnapshot<Id extends PObjectId>(\n id: Id,\n col: ColumnSnapshot<PObjectId>,\n): ColumnSnapshot<Id> {\n return createColumnSnapshot(id, col.spec, col.dataStatus, col.data);\n}\n\n/** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {\n return normalizeSelectors(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor value to a PColumnSpec.\n * - PColumnSpec: used directly\n * - PObjectId (string): looked up in the collected column map\n * - PlRef: not supported at this level — caller must resolve before building\n */\nfunction resolveAnchorSpecs(\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>,\n columnMap: Map<PObjectId, ColumnSnapshot<PObjectId>>,\n): Record<string, PColumnSpec> {\n const result: Record<string, PColumnSpec> = {};\n for (const [key, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n // PObjectId — look up in collected columns\n const col = columnMap.get(anchor as PObjectId);\n if (!col) throw new Error(`Anchor \"${key}\": column with id \"${anchor}\" not found in sources`);\n result[key] = col.spec;\n } else if (isPlRef(anchor)) {\n throw new Error(\n `Anchor \"${key}\": PlRef anchors must be resolved to PColumnSpec before building. ` +\n `Use the column's spec directly or pass its PObjectId.`,\n );\n } else {\n // PColumnSpec\n result[key] = anchor;\n }\n }\n return result;\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { GlobalCfgRenderCtxMethods } from "../render/internal.js";
|
|
2
1
|
import { TreeNodeAccessor } from "../render/accessor.js";
|
|
3
2
|
import { ColumnSnapshot } from "./column_snapshot.js";
|
|
4
3
|
import { ColumnSource } from "./column_snapshot_provider.js";
|
|
5
4
|
import { ColumnSelectorInput } from "./column_selector.js";
|
|
6
|
-
import { AxisQualification, DiscoverColumnsStepInfo, PColumnSpec, PObjectId, PlRef, SUniversalPColumnId } from "@milaboratories/pl-model-common";
|
|
5
|
+
import { AxisQualification, DiscoverColumnsStepInfo, PColumnSpec, PFrameSpecDriver, PObjectId, PlRef, SUniversalPColumnId } from "@milaboratories/pl-model-common";
|
|
7
6
|
|
|
8
7
|
//#region src/columns/column_collection_builder.d.ts
|
|
9
|
-
/** Subset of render context methods needed for spec frame operations. */
|
|
10
|
-
type SpecFrameCtx = Pick<GlobalCfgRenderCtxMethods, "createSpecFrame" | "specFrameDiscoverColumns" | "disposeSpecFrame">;
|
|
11
8
|
/** Options for plain collection findColumns. */
|
|
12
9
|
interface FindColumnsOptions {
|
|
13
10
|
/** Include columns matching these selectors. If omitted, includes all columns. */
|
|
@@ -16,7 +13,9 @@ interface FindColumnsOptions {
|
|
|
16
13
|
exclude?: ColumnSelectorInput;
|
|
17
14
|
}
|
|
18
15
|
/** Plain collection — no axis context, selector-based filtering only. */
|
|
19
|
-
interface ColumnCollection {
|
|
16
|
+
interface ColumnCollection extends Disposable {
|
|
17
|
+
/** Release the underlying spec frame WASM resource. */
|
|
18
|
+
dispose(): void;
|
|
20
19
|
/** Point lookup by provider-native ID. */
|
|
21
20
|
getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;
|
|
22
21
|
/** Find columns matching selectors. Returns flat list of snapshots.
|
|
@@ -25,7 +24,9 @@ interface ColumnCollection {
|
|
|
25
24
|
findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];
|
|
26
25
|
}
|
|
27
26
|
/** Axis-aware column collection with anchored identity derivation. */
|
|
28
|
-
interface AnchoredColumnCollection {
|
|
27
|
+
interface AnchoredColumnCollection extends Disposable {
|
|
28
|
+
/** Release the underlying spec frame WASM resource. */
|
|
29
|
+
dispose(): void;
|
|
29
30
|
/** Point lookup by anchored ID. */
|
|
30
31
|
getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;
|
|
31
32
|
/** Axis-aware column discovery. */
|
|
@@ -79,9 +80,9 @@ interface AnchoredBuildOptions extends BuildOptions {
|
|
|
79
80
|
* computable framework where each output tracks its own dependencies.
|
|
80
81
|
*/
|
|
81
82
|
declare class ColumnCollectionBuilder {
|
|
82
|
-
private readonly
|
|
83
|
+
private readonly specDriver;
|
|
83
84
|
private readonly providers;
|
|
84
|
-
constructor(
|
|
85
|
+
constructor(specDriver: PFrameSpecDriver);
|
|
85
86
|
/**
|
|
86
87
|
* Register a column source. Sources added first take precedence for dedup.
|
|
87
88
|
* Does NOT accept undefined — if a source isn't available yet,
|
|
@@ -14,8 +14,8 @@ import { AnchoredIdDeriver, deriveNativeId, isPlRef } from "@milaboratories/pl-m
|
|
|
14
14
|
*/
|
|
15
15
|
var ColumnCollectionBuilder = class {
|
|
16
16
|
providers = [];
|
|
17
|
-
constructor(
|
|
18
|
-
this.
|
|
17
|
+
constructor(specDriver) {
|
|
18
|
+
this.specDriver = specDriver;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Register a column source. Sources added first take precedence for dedup.
|
|
@@ -42,13 +42,13 @@ var ColumnCollectionBuilder = class {
|
|
|
42
42
|
if (hasAnchors) {
|
|
43
43
|
const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);
|
|
44
44
|
const idDeriver = new AnchoredIdDeriver(anchorSpecs);
|
|
45
|
-
return new AnchoredColumnCollectionImpl(this.
|
|
45
|
+
return new AnchoredColumnCollectionImpl(this.specDriver, {
|
|
46
46
|
columns: columnMap,
|
|
47
47
|
idDeriver,
|
|
48
48
|
anchorSpecs,
|
|
49
49
|
columnListComplete: allowPartial ? allComplete : false
|
|
50
50
|
});
|
|
51
|
-
} else return new ColumnCollectionImpl(this.
|
|
51
|
+
} else return new ColumnCollectionImpl(this.specDriver, {
|
|
52
52
|
columns: columnMap,
|
|
53
53
|
columnListComplete: allowPartial ? allComplete : false
|
|
54
54
|
});
|
|
@@ -80,13 +80,19 @@ const PLAIN_CONSTRAINTS = {
|
|
|
80
80
|
};
|
|
81
81
|
var ColumnCollectionImpl = class {
|
|
82
82
|
columns;
|
|
83
|
-
|
|
83
|
+
specFrameEntry;
|
|
84
84
|
columnListComplete;
|
|
85
|
-
constructor(
|
|
86
|
-
this.
|
|
85
|
+
constructor(specDriver, options) {
|
|
86
|
+
this.specDriver = specDriver;
|
|
87
87
|
this.columns = options.columns;
|
|
88
88
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
89
|
-
this.
|
|
89
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])));
|
|
90
|
+
}
|
|
91
|
+
dispose() {
|
|
92
|
+
this.specFrameEntry.unref();
|
|
93
|
+
}
|
|
94
|
+
[Symbol.dispose]() {
|
|
95
|
+
this.dispose();
|
|
90
96
|
}
|
|
91
97
|
getColumn(id) {
|
|
92
98
|
const col = this.columns.get(id);
|
|
@@ -96,7 +102,7 @@ var ColumnCollectionImpl = class {
|
|
|
96
102
|
findColumns(options) {
|
|
97
103
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
|
|
98
104
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
|
|
99
|
-
return this.
|
|
105
|
+
return this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
100
106
|
includeColumns,
|
|
101
107
|
excludeColumns,
|
|
102
108
|
axes: [],
|
|
@@ -111,23 +117,29 @@ var ColumnCollectionImpl = class {
|
|
|
111
117
|
var AnchoredColumnCollectionImpl = class {
|
|
112
118
|
columns;
|
|
113
119
|
idDeriver;
|
|
114
|
-
|
|
120
|
+
specFrameEntry;
|
|
115
121
|
anchorAxes;
|
|
116
122
|
/** Reverse lookup: SUniversalPColumnId → PObjectId */
|
|
117
123
|
idToOriginal;
|
|
118
124
|
columnListComplete;
|
|
119
|
-
constructor(
|
|
120
|
-
this.
|
|
125
|
+
constructor(specDriver, options) {
|
|
126
|
+
this.specDriver = specDriver;
|
|
121
127
|
this.columns = options.columns;
|
|
122
128
|
this.idDeriver = options.idDeriver;
|
|
123
129
|
this.columnListComplete = options.columnListComplete ?? false;
|
|
124
|
-
this.
|
|
130
|
+
this.specFrameEntry = this.specDriver.createSpecFrame(Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])));
|
|
125
131
|
this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({
|
|
126
132
|
axesSpec: spec.axesSpec,
|
|
127
133
|
qualifications: []
|
|
128
134
|
}));
|
|
129
135
|
this.idToOriginal = new Map(Array.from(this.columns.entries()).map(([id, col]) => [this.idDeriver.deriveS(col.spec), id]));
|
|
130
136
|
}
|
|
137
|
+
dispose() {
|
|
138
|
+
this.specFrameEntry.unref();
|
|
139
|
+
}
|
|
140
|
+
[Symbol.dispose]() {
|
|
141
|
+
this.dispose();
|
|
142
|
+
}
|
|
131
143
|
getColumn(id) {
|
|
132
144
|
const origId = this.idToOriginal.get(id);
|
|
133
145
|
if (origId === void 0) return void 0;
|
|
@@ -139,7 +151,7 @@ var AnchoredColumnCollectionImpl = class {
|
|
|
139
151
|
const constraints = matchingModeToConstraints(options?.mode ?? "enrichment");
|
|
140
152
|
const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : void 0;
|
|
141
153
|
const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : void 0;
|
|
142
|
-
return this.
|
|
154
|
+
return this.specDriver.discoverColumns(this.specFrameEntry.key, {
|
|
143
155
|
includeColumns,
|
|
144
156
|
excludeColumns,
|
|
145
157
|
constraints,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n ColumnAxesWithQualifications,\n DiscoverColumnsConstraints,\n DiscoverColumnsStepInfo,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PlRef,\n PObjectId,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { AnchoredIdDeriver, deriveNativeId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelectorInput } from \"./column_selector\";\nimport { normalizeSelectors } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport { createColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { GlobalCfgRenderCtxMethods } from \"../render/internal\";\n\n/** Subset of render context methods needed for spec frame operations. */\ntype SpecFrameCtx = Pick<\n GlobalCfgRenderCtxMethods,\n \"createSpecFrame\" | \"specFrameDiscoverColumns\" | \"disposeSpecFrame\"\n>;\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelectorInput;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelectorInput;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection {\n /** Point lookup by provider-native ID. */\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection {\n /** Point lookup by anchored ID. */\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<SUniversalPColumnId>;\n /** Provider-native ID — for lookups back to the source provider. */\n readonly originalId: PObjectId;\n /** Match variants — different paths/qualifications that reach this column. */\n readonly variants: MatchVariant[];\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: DiscoverColumnsStepInfo[];\n}\n\n/** Qualifications needed for both query (already-integrated) columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for each query (already-integrated) column set. */\n readonly forQueries: AxisQualification[][];\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specFrameCtx: SpecFrameCtx) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columnMap = this.collectColumns();\n\n if (hasAnchors) {\n const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);\n const idDeriver = new AnchoredIdDeriver(anchorSpecs);\n\n return new AnchoredColumnCollectionImpl(this.specFrameCtx, {\n columns: columnMap,\n idDeriver,\n anchorSpecs,\n columnListComplete: allowPartial ? allComplete : false,\n });\n } else {\n return new ColumnCollectionImpl(this.specFrameCtx, {\n columns: columnMap,\n columnListComplete: allowPartial ? allComplete : false,\n });\n }\n }\n\n /**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\n private collectColumns(): Map<PObjectId, ColumnSnapshot<PObjectId>> {\n const seen = new Set<NativePObjectId>();\n const result = new Map<PObjectId, ColumnSnapshot<PObjectId>>();\n\n for (const provider of this.providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.set(col.id, col);\n }\n }\n\n return result;\n }\n}\n\n// --- Permissive constraints for plain (non-anchored) filtering ---\n\nconst PLAIN_CONSTRAINTS: DiscoverColumnsConstraints = {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n};\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n readonly columnListComplete?: boolean;\n}\n\nclass ColumnCollectionImpl implements ColumnCollection {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameHandle: string;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly ctx: SpecFrameCtx,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.columnListComplete = options.columnListComplete ?? false;\n this.specFrameHandle = this.ctx.createSpecFrame(\n Array.from(this.columns.entries()).reduce(\n (acc, [id, col]) => ((acc[id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n ),\n );\n }\n\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {\n const col = this.columns.get(id);\n if (col === undefined) return undefined;\n return this.toSnapshot(col);\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.ctx.specFrameDiscoverColumns(this.specFrameHandle, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: PLAIN_CONSTRAINTS,\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined)\n .map((col) => this.toSnapshot(col));\n\n return results;\n }\n\n private toSnapshot(col: ColumnSnapshot<PObjectId>): ColumnSnapshot<PObjectId> {\n return remapSnapshot(col.id, col);\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly idDeriver: AnchoredIdDeriver;\n readonly anchorSpecs: Record<string, PColumnSpec>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly idDeriver: AnchoredIdDeriver;\n private readonly specFrameHandle: string;\n private readonly anchorAxes: ColumnAxesWithQualifications[];\n /** Reverse lookup: SUniversalPColumnId → PObjectId */\n private readonly idToOriginal: Map<SUniversalPColumnId, PObjectId>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly ctx: SpecFrameCtx,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.idDeriver = options.idDeriver;\n this.columnListComplete = options.columnListComplete ?? false;\n\n // Create spec frame from all collected columns\n this.specFrameHandle = this.ctx.createSpecFrame(\n Array.from(this.columns.entries()).reduce(\n (acc, [id, col]) => ((acc[id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n ),\n );\n\n // Build anchor axes for discovery requests\n this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({\n axesSpec: spec.axesSpec,\n qualifications: [],\n }));\n\n // Build reverse lookup map\n this.idToOriginal = new Map(\n Array.from(this.columns.entries()).map(\n ([id, col]) => [this.idDeriver.deriveS(col.spec), id] as const,\n ),\n );\n }\n\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {\n const origId = this.idToOriginal.get(id);\n if (origId === undefined) return undefined;\n const col = this.columns.get(origId);\n if (col === undefined) return undefined;\n return this.toSnapshot(id, col);\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.ctx.specFrameDiscoverColumns(this.specFrameHandle, {\n includeColumns,\n excludeColumns,\n constraints,\n axes: this.anchorAxes,\n maxHops: options?.maxHops ?? 4,\n });\n\n // Map hits back to ColumnMatch entries\n const results = response.hits\n .map((hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col = this.columns.get(origId);\n if (!col) return undefined;\n const universalId = this.idDeriver.deriveS(col.spec);\n return {\n column: this.toSnapshot(universalId, col),\n originalId: origId,\n variants: hit.mappingVariants.map(\n (v): MatchVariant => ({\n qualifications: v.qualifications,\n distinctiveQualifications: v.distinctiveQualifications,\n }),\n ),\n path: hit.path,\n } satisfies ColumnMatch;\n })\n .filter((m): m is ColumnMatch => m !== undefined);\n\n return results;\n }\n\n private toSnapshot(\n universalId: SUniversalPColumnId,\n col: ColumnSnapshot<PObjectId>,\n ): ColumnSnapshot<SUniversalPColumnId> {\n return remapSnapshot(universalId, col);\n }\n}\n\n// --- Shared snapshot helpers ---\n\n/** Create a new snapshot with a different ID, preserving data accessors. */\nfunction remapSnapshot<Id extends PObjectId>(\n id: Id,\n col: ColumnSnapshot<PObjectId>,\n): ColumnSnapshot<Id> {\n return createColumnSnapshot(id, col.spec, col.dataStatus, col.data);\n}\n\n/** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {\n return normalizeSelectors(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor value to a PColumnSpec.\n * - PColumnSpec: used directly\n * - PObjectId (string): looked up in the collected column map\n * - PlRef: not supported at this level — caller must resolve before building\n */\nfunction resolveAnchorSpecs(\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>,\n columnMap: Map<PObjectId, ColumnSnapshot<PObjectId>>,\n): Record<string, PColumnSpec> {\n const result: Record<string, PColumnSpec> = {};\n for (const [key, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n // PObjectId — look up in collected columns\n const col = columnMap.get(anchor as PObjectId);\n if (!col) throw new Error(`Anchor \"${key}\": column with id \"${anchor}\" not found in sources`);\n result[key] = col.spec;\n } else if (isPlRef(anchor)) {\n throw new Error(\n `Anchor \"${key}\": PlRef anchors must be resolved to PColumnSpec before building. ` +\n `Use the column's spec directly or pass its PObjectId.`,\n );\n } else {\n // PColumnSpec\n result[key] = anchor;\n }\n }\n return result;\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"column_collection_builder.js","names":[],"sources":["../../src/columns/column_collection_builder.ts"],"sourcesContent":["import type {\n AxisQualification,\n ColumnAxesWithQualifications,\n DiscoverColumnsConstraints,\n DiscoverColumnsStepInfo,\n MultiColumnSelector,\n NativePObjectId,\n PColumnSpec,\n PlRef,\n PObjectId,\n SUniversalPColumnId,\n} from \"@milaboratories/pl-model-common\";\nimport { AnchoredIdDeriver, deriveNativeId, isPlRef } from \"@milaboratories/pl-model-common\";\nimport type { ColumnSelectorInput } from \"./column_selector\";\nimport { normalizeSelectors } from \"./column_selector\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport { createColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider, ColumnSource } from \"./column_snapshot_provider\";\nimport { ArrayColumnProvider, toColumnSnapshotProvider } from \"./column_snapshot_provider\";\n\nimport type { PFrameSpecDriver, PoolEntry, SpecFrameHandle } from \"@milaboratories/pl-model-common\";\n\n// --- FindColumnsOptions ---\n\n/** Options for plain collection findColumns. */\nexport interface FindColumnsOptions {\n /** Include columns matching these selectors. If omitted, includes all columns. */\n include?: ColumnSelectorInput;\n /** Exclude columns matching these selectors. */\n exclude?: ColumnSelectorInput;\n}\n\n// --- ColumnCollection ---\n\n/** Plain collection — no axis context, selector-based filtering only. */\nexport interface ColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n /** Point lookup by provider-native ID. */\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId>;\n\n /** Find columns matching selectors. Returns flat list of snapshots.\n * No axis compatibility matching, no linker traversal.\n * Never returns undefined — the \"not ready\" state was absorbed by the builder. */\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[];\n}\n\n// --- AnchoredColumnCollection ---\n\n/** Axis-aware column collection with anchored identity derivation. */\nexport interface AnchoredColumnCollection extends Disposable {\n /** Release the underlying spec frame WASM resource. */\n dispose(): void;\n /** Point lookup by anchored ID. */\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId>;\n\n /** Axis-aware column discovery. */\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[];\n}\n\n/** Controls axis matching behavior for anchored discovery. */\nexport type MatchingMode = \"enrichment\" | \"related\" | \"exact\";\n\n/** Options for anchored collection findColumns. */\nexport interface AnchoredFindColumnsOptions extends FindColumnsOptions {\n /** Controls axis matching behavior. Default: 'enrichment'. */\n mode?: MatchingMode;\n /** Maximum linker hops for cross-domain discovery (0 = direct only, default: 4). */\n maxHops?: number;\n}\n\n/** Result of anchored discovery — column snapshot + routing info. */\nexport interface ColumnMatch {\n /** Column snapshot with anchored SUniversalPColumnId. */\n readonly column: ColumnSnapshot<SUniversalPColumnId>;\n /** Provider-native ID — for lookups back to the source provider. */\n readonly originalId: PObjectId;\n /** Match variants — different paths/qualifications that reach this column. */\n readonly variants: MatchVariant[];\n /** Linker steps traversed to reach this hit; empty for direct matches. */\n readonly path: DiscoverColumnsStepInfo[];\n}\n\n/** Qualifications needed for both query (already-integrated) columns and the hit column. */\nexport interface MatchQualifications {\n /** Qualifications for each query (already-integrated) column set. */\n readonly forQueries: AxisQualification[][];\n /** Qualifications for the hit column. */\n readonly forHit: AxisQualification[];\n}\n\n/** A single mapping variant describing how a hit column can be integrated. */\nexport interface MatchVariant {\n /** Full qualifications needed for integration. */\n readonly qualifications: MatchQualifications;\n /** Distinctive (minimal) qualifications needed for integration. */\n readonly distinctiveQualifications: MatchQualifications;\n}\n\n// --- Build options ---\n\nexport interface BuildOptions {\n allowPartialColumnList?: true;\n}\n\nexport interface AnchoredBuildOptions extends BuildOptions {\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>;\n}\n\n// --- ColumnCollectionBuilder ---\n\n/**\n * Mutable builder that accumulates column sources, then produces\n * a ColumnCollection (plain) or AnchoredColumnCollection (with anchors).\n *\n * Each output lambda creates its own builder — a constraint of the\n * computable framework where each output tracks its own dependencies.\n */\nexport class ColumnCollectionBuilder {\n private readonly providers: ColumnSnapshotProvider[] = [];\n\n constructor(private readonly specDriver: PFrameSpecDriver) {}\n\n /**\n * Register a column source. Sources added first take precedence for dedup.\n * Does NOT accept undefined — if a source isn't available yet,\n * the caller should return undefined from the output lambda.\n */\n addSource(source: ColumnSource | TreeNodeAccessor): this {\n if (source instanceof TreeNodeAccessor) {\n const columns = source.getPColumns();\n if (columns) this.providers.push(new ArrayColumnProvider(columns));\n } else {\n this.providers.push(toColumnSnapshotProvider(source));\n }\n return this;\n }\n\n addSources(sources: (ColumnSource | TreeNodeAccessor)[]): this {\n for (const source of sources) {\n this.addSource(source);\n }\n return this;\n }\n\n /** Plain collection — selector-based filtering, PObjectId namespace. */\n build(): undefined | ColumnCollection;\n build(options: {\n allowPartialColumnList: true;\n }): ColumnCollection & { readonly columnListComplete: boolean };\n /** Anchored collection — axis-aware discovery, SUniversalPColumnId namespace. */\n build(\n options: AnchoredBuildOptions & { allowPartialColumnList: true },\n ): AnchoredColumnCollection & { readonly columnListComplete: boolean };\n build(options: AnchoredBuildOptions): undefined | AnchoredColumnCollection;\n build(\n options?: BuildOptions | AnchoredBuildOptions,\n ):\n | undefined\n | ColumnCollection\n | AnchoredColumnCollection\n | (ColumnCollection & { readonly columnListComplete: boolean })\n | (AnchoredColumnCollection & { readonly columnListComplete: boolean }) {\n const allowPartial = options?.allowPartialColumnList === true;\n const hasAnchors = options !== undefined && \"anchors\" in options;\n\n // Check column list completeness\n const allComplete = this.providers.every((p) => p.isColumnListComplete());\n if (!allComplete && !allowPartial) return undefined;\n\n // Collect all columns, dedup by native ID (first source wins)\n const columnMap = this.collectColumns();\n\n if (hasAnchors) {\n const anchorSpecs = resolveAnchorSpecs(options.anchors, columnMap);\n const idDeriver = new AnchoredIdDeriver(anchorSpecs);\n\n return new AnchoredColumnCollectionImpl(this.specDriver, {\n columns: columnMap,\n idDeriver,\n anchorSpecs,\n columnListComplete: allowPartial ? allComplete : false,\n });\n } else {\n return new ColumnCollectionImpl(this.specDriver, {\n columns: columnMap,\n columnListComplete: allowPartial ? allComplete : false,\n });\n }\n }\n\n /**\n * Collect all columns from all providers, dedup by NativePObjectId.\n * First source wins.\n */\n private collectColumns(): Map<PObjectId, ColumnSnapshot<PObjectId>> {\n const seen = new Set<NativePObjectId>();\n const result = new Map<PObjectId, ColumnSnapshot<PObjectId>>();\n\n for (const provider of this.providers) {\n const columns = provider.getAllColumns();\n for (const col of columns) {\n const nativeId = deriveNativeId(col.spec);\n if (seen.has(nativeId)) continue;\n seen.add(nativeId);\n result.set(col.id, col);\n }\n }\n\n return result;\n }\n}\n\n// --- Permissive constraints for plain (non-anchored) filtering ---\n\nconst PLAIN_CONSTRAINTS: DiscoverColumnsConstraints = {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n};\n\n// --- ColumnCollectionImpl ---\n\ninterface ColumnCollectionImplOptions {\n readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n readonly columnListComplete?: boolean;\n}\n\nclass ColumnCollectionImpl implements ColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: ColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.columnListComplete = options.columnListComplete ?? false;\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getColumn(id: PObjectId): undefined | ColumnSnapshot<PObjectId> {\n const col = this.columns.get(id);\n if (col === undefined) return undefined;\n return this.toSnapshot(col);\n }\n\n findColumns(options?: FindColumnsOptions): ColumnSnapshot<PObjectId>[] {\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n axes: [],\n maxHops: 0,\n constraints: PLAIN_CONSTRAINTS,\n });\n\n // Map hits back to snapshots\n const results = response.hits\n .map((hit) => this.columns.get(hit.hit.columnId as PObjectId))\n .filter((col): col is ColumnSnapshot<PObjectId> => col !== undefined)\n .map((col) => this.toSnapshot(col));\n\n return results;\n }\n\n private toSnapshot(col: ColumnSnapshot<PObjectId>): ColumnSnapshot<PObjectId> {\n return remapSnapshot(col.id, col);\n }\n}\n\n// --- AnchoredColumnCollectionImpl ---\n\ninterface AnchoredColumnCollectionImplOptions extends ColumnCollectionImplOptions {\n readonly idDeriver: AnchoredIdDeriver;\n readonly anchorSpecs: Record<string, PColumnSpec>;\n}\n\nclass AnchoredColumnCollectionImpl implements AnchoredColumnCollection, Disposable {\n private readonly columns: Map<PObjectId, ColumnSnapshot<PObjectId>>;\n private readonly idDeriver: AnchoredIdDeriver;\n private readonly specFrameEntry: PoolEntry<SpecFrameHandle>;\n private readonly anchorAxes: ColumnAxesWithQualifications[];\n /** Reverse lookup: SUniversalPColumnId → PObjectId */\n private readonly idToOriginal: Map<SUniversalPColumnId, PObjectId>;\n public readonly columnListComplete: boolean;\n\n constructor(\n private readonly specDriver: PFrameSpecDriver,\n options: AnchoredColumnCollectionImplOptions,\n ) {\n this.columns = options.columns;\n this.idDeriver = options.idDeriver;\n this.columnListComplete = options.columnListComplete ?? false;\n\n // Create spec frame from all collected columns\n this.specFrameEntry = this.specDriver.createSpecFrame(\n Object.fromEntries(Array.from(this.columns.entries(), ([id, col]) => [id, col.spec])),\n );\n\n // Build anchor axes for discovery requests\n this.anchorAxes = Object.values(options.anchorSpecs).map((spec) => ({\n axesSpec: spec.axesSpec,\n qualifications: [],\n }));\n\n // Build reverse lookup map\n this.idToOriginal = new Map(\n Array.from(this.columns.entries()).map(\n ([id, col]) => [this.idDeriver.deriveS(col.spec), id] as const,\n ),\n );\n }\n\n dispose(): void {\n this.specFrameEntry.unref();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n getColumn(id: SUniversalPColumnId): undefined | ColumnSnapshot<SUniversalPColumnId> {\n const origId = this.idToOriginal.get(id);\n if (origId === undefined) return undefined;\n const col = this.columns.get(origId);\n if (col === undefined) return undefined;\n return this.toSnapshot(id, col);\n }\n\n findColumns(options?: AnchoredFindColumnsOptions): ColumnMatch[] {\n const mode = options?.mode ?? \"enrichment\";\n const constraints = matchingModeToConstraints(mode);\n const includeColumns = options?.include ? toMultiColumnSelectors(options.include) : undefined;\n const excludeColumns = options?.exclude ? toMultiColumnSelectors(options.exclude) : undefined;\n\n const response = this.specDriver.discoverColumns(this.specFrameEntry.key, {\n includeColumns,\n excludeColumns,\n constraints,\n axes: this.anchorAxes,\n maxHops: options?.maxHops ?? 4,\n });\n\n // Map hits back to ColumnMatch entries\n const results = response.hits\n .map((hit) => {\n const origId = hit.hit.columnId as PObjectId;\n const col = this.columns.get(origId);\n if (!col) return undefined;\n const universalId = this.idDeriver.deriveS(col.spec);\n return {\n column: this.toSnapshot(universalId, col),\n originalId: origId,\n variants: hit.mappingVariants.map(\n (v): MatchVariant => ({\n qualifications: v.qualifications,\n distinctiveQualifications: v.distinctiveQualifications,\n }),\n ),\n path: hit.path,\n } satisfies ColumnMatch;\n })\n .filter((m): m is ColumnMatch => m !== undefined);\n\n return results;\n }\n\n private toSnapshot(\n universalId: SUniversalPColumnId,\n col: ColumnSnapshot<PObjectId>,\n ): ColumnSnapshot<SUniversalPColumnId> {\n return remapSnapshot(universalId, col);\n }\n}\n\n// --- Shared snapshot helpers ---\n\n/** Create a new snapshot with a different ID, preserving data accessors. */\nfunction remapSnapshot<Id extends PObjectId>(\n id: Id,\n col: ColumnSnapshot<PObjectId>,\n): ColumnSnapshot<Id> {\n return createColumnSnapshot(id, col.spec, col.dataStatus, col.data);\n}\n\n/** Normalize SDK ColumnSelectorInput to MultiColumnSelector[]. */\nfunction toMultiColumnSelectors(input: ColumnSelectorInput): MultiColumnSelector[] {\n return normalizeSelectors(input);\n}\n\n// --- Anchor resolution ---\n\n/**\n * Resolve each anchor value to a PColumnSpec.\n * - PColumnSpec: used directly\n * - PObjectId (string): looked up in the collected column map\n * - PlRef: not supported at this level — caller must resolve before building\n */\nfunction resolveAnchorSpecs(\n anchors: Record<string, PlRef | PObjectId | PColumnSpec>,\n columnMap: Map<PObjectId, ColumnSnapshot<PObjectId>>,\n): Record<string, PColumnSpec> {\n const result: Record<string, PColumnSpec> = {};\n for (const [key, anchor] of Object.entries(anchors)) {\n if (typeof anchor === \"string\") {\n // PObjectId — look up in collected columns\n const col = columnMap.get(anchor as PObjectId);\n if (!col) throw new Error(`Anchor \"${key}\": column with id \"${anchor}\" not found in sources`);\n result[key] = col.spec;\n } else if (isPlRef(anchor)) {\n throw new Error(\n `Anchor \"${key}\": PlRef anchors must be resolved to PColumnSpec before building. ` +\n `Use the column's spec directly or pass its PObjectId.`,\n );\n } else {\n // PColumnSpec\n result[key] = anchor;\n }\n }\n return result;\n}\n\n// --- MatchingMode → DiscoverColumnsConstraints ---\n\nfunction matchingModeToConstraints(mode: MatchingMode): DiscoverColumnsConstraints {\n switch (mode) {\n case \"enrichment\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n case \"related\":\n return {\n allowFloatingSourceAxes: true,\n allowFloatingHitAxes: true,\n allowSourceQualifications: true,\n allowHitQualifications: true,\n };\n case \"exact\":\n return {\n allowFloatingSourceAxes: false,\n allowFloatingHitAxes: false,\n allowSourceQualifications: false,\n allowHitQualifications: false,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ctx_column_sources.cjs","names":["ResourceTypeName","OutputColumnProvider"],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U>(\n ctx: RenderCtxBase<A, U>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,AAAiB,MAAkB;EAAlB;;CAE7B,gBAAkC;AAEhC,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UACgB;AAChB,KAAI,aAAa,OACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,QAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAaA,iDAAiB,QAAQ;AACxC,MAAI,KAAK,IAAIC,sDAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAaD,iDAAiB,UAAU,aAAaA,iDAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
|
|
1
|
+
{"version":3,"file":"ctx_column_sources.cjs","names":["ResourceTypeName","OutputColumnProvider"],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U, S>(\n ctx: RenderCtxBase<A, U, S>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,AAAiB,MAAkB;EAAlB;;CAE7B,gBAAkC;AAEhC,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UACgB;AAChB,KAAI,aAAa,OACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,QAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAaA,iDAAiB,QAAQ;AACxC,MAAI,KAAK,IAAIC,sDAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAaD,iDAAiB,UAAU,aAAaA,iDAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
|
|
@@ -13,7 +13,7 @@ import { ColumnSnapshotProvider } from "./column_snapshot_provider.js";
|
|
|
13
13
|
*
|
|
14
14
|
* Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.
|
|
15
15
|
*/
|
|
16
|
-
declare function collectCtxColumnSnapshotProviders<A, U>(ctx: RenderCtxBase<A, U>): ColumnSnapshotProvider[];
|
|
16
|
+
declare function collectCtxColumnSnapshotProviders<A, U, S>(ctx: RenderCtxBase<A, U, S>): ColumnSnapshotProvider[];
|
|
17
17
|
/**
|
|
18
18
|
* Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.
|
|
19
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ctx_column_sources.js","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U>(\n ctx: RenderCtxBase<A, U>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,AAAiB,MAAkB;EAAlB;;CAE7B,gBAAkC;AAEhC,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UACgB;AAChB,KAAI,aAAa,OACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,QAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAa,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAI,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAa,iBAAiB,UAAU,aAAa,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
|
|
1
|
+
{"version":3,"file":"ctx_column_sources.js","names":[],"sources":["../../src/columns/ctx_column_sources.ts"],"sourcesContent":["import type { PColumnSpec, PObjectId } from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../render/accessor\";\nimport type { RenderCtxBase, ResultPool } from \"../render\";\nimport type { ColumnSnapshot } from \"./column_snapshot\";\nimport type { ColumnDataStatus } from \"./column_snapshot\";\nimport type { ColumnSnapshotProvider } from \"./column_snapshot_provider\";\nimport { OutputColumnProvider } from \"./column_snapshot_provider\";\nimport { ResourceTypeName } from \"@milaboratories/pl-model-common\";\nimport type { ValueOf } from \"@milaboratories/helpers\";\n\n/**\n * Collect ColumnSnapshotProviders from all render context sources:\n *\n * - **resultPool** — all upstream columns (always included)\n * - **outputs** — PFrame fields from block execution outputs\n * - **prerun** — PFrame fields from prerun/staging results\n *\n * Returns an array of providers suitable for `ColumnCollectionBuilder.addSource()`.\n */\nexport function collectCtxColumnSnapshotProviders<A, U, S>(\n ctx: RenderCtxBase<A, U, S>,\n): ColumnSnapshotProvider[] {\n const providers: ColumnSnapshotProvider[] = [];\n\n // ResultPool — all upstream columns\n providers.push(new ResultPoolColumnSnapshotProvider(ctx.resultPool));\n\n // Outputs — each PFrame-like output field becomes a provider\n const outputs = ctx.outputs;\n if (outputs) {\n providers.push(...collectPFrameProviders(outputs));\n }\n\n // Prerun — same treatment as outputs\n const prerun = ctx.prerun;\n if (prerun) {\n providers.push(...collectPFrameProviders(prerun));\n }\n\n return providers;\n}\n\n/**\n * Adapter wrapping ResultPool into the new ColumnSnapshotProvider interface.\n *\n * - `isColumnListComplete()` always returns true — the result pool\n * is a stable snapshot within a single render cycle.\n * - Data status is derived from the underlying TreeNodeAccessor:\n * ready (getIsReadyOrError), computing, or absent (no data resource).\n */\nexport class ResultPoolColumnSnapshotProvider implements ColumnSnapshotProvider {\n constructor(private readonly pool: ResultPool) {}\n\n getAllColumns(): ColumnSnapshot[] {\n const pColumns = this.pool.selectColumns(() => true);\n return pColumns.map((col) => toSnapshot(col.id, col.spec, col.data));\n }\n\n isColumnListComplete(): boolean {\n return true;\n }\n}\n\nfunction toSnapshot(\n id: PObjectId,\n spec: PColumnSpec,\n accessor: TreeNodeAccessor | undefined,\n): ColumnSnapshot {\n if (accessor === undefined) {\n return { id, spec, dataStatus: \"absent\" as ColumnDataStatus, data: undefined };\n }\n const isReady = accessor.getIsReadyOrError();\n return {\n id,\n spec,\n dataStatus: (isReady ? \"ready\" : \"computing\") as ColumnDataStatus,\n data: { get: () => (isReady ? accessor : undefined) },\n };\n}\n\n/**\n * Recursively walk the output tree starting from `accessor`.\n * - If a node's resourceType is PFrame → wrap it as OutputColumnProvider.\n * - If a node's resourceType is StdMap/std/map → recurse into its output fields.\n * - Otherwise → skip (leaf of unknown type).\n */\nfunction collectPFrameProviders(accessor: TreeNodeAccessor): ColumnSnapshotProvider[] {\n const out: ColumnSnapshotProvider[] = [];\n walkTree(accessor, out);\n return out;\n}\n\nfunction walkTree(node: TreeNodeAccessor, out: ColumnSnapshotProvider[]): void {\n const typeName = node.resourceType.name as ValueOf<typeof ResourceTypeName>;\n\n if (typeName === ResourceTypeName.PFrame) {\n out.push(new OutputColumnProvider(node));\n return;\n }\n\n if (typeName === ResourceTypeName.StdMap || typeName === ResourceTypeName.StdMapSlash) {\n for (const field of node.listInputFields()) {\n const child = node.resolve(field);\n if (child) walkTree(child, out);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,SAAgB,kCACd,KAC0B;CAC1B,MAAM,YAAsC,EAAE;AAG9C,WAAU,KAAK,IAAI,iCAAiC,IAAI,WAAW,CAAC;CAGpE,MAAM,UAAU,IAAI;AACpB,KAAI,QACF,WAAU,KAAK,GAAG,uBAAuB,QAAQ,CAAC;CAIpD,MAAM,SAAS,IAAI;AACnB,KAAI,OACF,WAAU,KAAK,GAAG,uBAAuB,OAAO,CAAC;AAGnD,QAAO;;;;;;;;;;AAWT,IAAa,mCAAb,MAAgF;CAC9E,YAAY,AAAiB,MAAkB;EAAlB;;CAE7B,gBAAkC;AAEhC,SADiB,KAAK,KAAK,oBAAoB,KAAK,CACpC,KAAK,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,CAAC;;CAGtE,uBAAgC;AAC9B,SAAO;;;AAIX,SAAS,WACP,IACA,MACA,UACgB;AAChB,KAAI,aAAa,OACf,QAAO;EAAE;EAAI;EAAM,YAAY;EAA8B,MAAM;EAAW;CAEhF,MAAM,UAAU,SAAS,mBAAmB;AAC5C,QAAO;EACL;EACA;EACA,YAAa,UAAU,UAAU;EACjC,MAAM,EAAE,WAAY,UAAU,WAAW,QAAY;EACtD;;;;;;;;AASH,SAAS,uBAAuB,UAAsD;CACpF,MAAM,MAAgC,EAAE;AACxC,UAAS,UAAU,IAAI;AACvB,QAAO;;AAGT,SAAS,SAAS,MAAwB,KAAqC;CAC7E,MAAM,WAAW,KAAK,aAAa;AAEnC,KAAI,aAAa,iBAAiB,QAAQ;AACxC,MAAI,KAAK,IAAI,qBAAqB,KAAK,CAAC;AACxC;;AAGF,KAAI,aAAa,iBAAiB,UAAU,aAAa,iBAAiB,YACxE,MAAK,MAAM,SAAS,KAAK,iBAAiB,EAAE;EAC1C,MAAM,QAAQ,KAAK,QAAQ,MAAM;AACjC,MAAI,MAAO,UAAS,OAAO,IAAI"}
|