@platforma-sdk/model 1.63.12 → 1.65.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/columns/column_collection_builder.cjs +105 -92
- package/dist/columns/column_collection_builder.cjs.map +1 -1
- package/dist/columns/column_collection_builder.d.ts +13 -12
- package/dist/columns/column_collection_builder.d.ts.map +1 -1
- package/dist/columns/column_collection_builder.js +107 -94
- package/dist/columns/column_collection_builder.js.map +1 -1
- package/dist/columns/column_selector.cjs +8 -80
- package/dist/columns/column_selector.cjs.map +1 -1
- package/dist/columns/column_selector.d.ts +6 -14
- package/dist/columns/column_selector.d.ts.map +1 -1
- package/dist/columns/column_selector.js +6 -77
- package/dist/columns/column_selector.js.map +1 -1
- package/dist/columns/column_snapshot.cjs +3 -3
- package/dist/columns/column_snapshot.cjs.map +1 -1
- package/dist/columns/column_snapshot.d.ts +3 -3
- package/dist/columns/column_snapshot.d.ts.map +1 -1
- package/dist/columns/column_snapshot.js +3 -3
- package/dist/columns/column_snapshot.js.map +1 -1
- package/dist/columns/column_snapshot_provider.cjs +1 -1
- package/dist/columns/column_snapshot_provider.cjs.map +1 -1
- package/dist/columns/column_snapshot_provider.d.ts +8 -8
- package/dist/columns/column_snapshot_provider.d.ts.map +1 -1
- package/dist/columns/column_snapshot_provider.js +1 -1
- package/dist/columns/column_snapshot_provider.js.map +1 -1
- package/dist/columns/ctx_column_sources.cjs.map +1 -1
- package/dist/columns/ctx_column_sources.d.ts +2 -1
- package/dist/columns/ctx_column_sources.d.ts.map +1 -1
- package/dist/columns/ctx_column_sources.js.map +1 -1
- package/dist/columns/expand_by_partition.cjs +106 -0
- package/dist/columns/expand_by_partition.cjs.map +1 -0
- package/dist/columns/expand_by_partition.d.ts +33 -0
- package/dist/columns/expand_by_partition.d.ts.map +1 -0
- package/dist/columns/expand_by_partition.js +105 -0
- package/dist/columns/expand_by_partition.js.map +1 -0
- package/dist/columns/index.cjs +1 -0
- package/dist/columns/index.d.ts +4 -3
- package/dist/columns/index.js +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs +26 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js +25 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV2.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs +68 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js +67 -0
- package/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs +27 -17
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts +4 -0
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js +28 -18
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV2.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs +258 -175
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.cjs.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts +37 -21
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js +261 -175
- package/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs +64 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts +17 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js +63 -0
- package/dist/components/PlDataTable/createPlDataTable/discoverColumns.js.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/index.cjs +2 -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.d.ts.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js +2 -1
- package/dist/components/PlDataTable/createPlDataTable/index.js.map +1 -1
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs +109 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.cjs.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts +19 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.d.ts.map +1 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.js +102 -0
- package/dist/components/PlDataTable/createPlDataTable/utils.js.map +1 -0
- package/dist/components/PlDataTable/index.cjs +3 -1
- package/dist/components/PlDataTable/index.d.ts +5 -3
- package/dist/components/PlDataTable/index.js +3 -1
- package/dist/components/PlDataTable/labels.cjs +25 -11
- package/dist/components/PlDataTable/labels.cjs.map +1 -1
- package/dist/components/PlDataTable/labels.js +25 -11
- package/dist/components/PlDataTable/labels.js.map +1 -1
- package/dist/components/PlDataTable/state-migration.cjs +8 -2
- package/dist/components/PlDataTable/state-migration.cjs.map +1 -1
- package/dist/components/PlDataTable/state-migration.d.ts.map +1 -1
- package/dist/components/PlDataTable/state-migration.js +8 -2
- package/dist/components/PlDataTable/state-migration.js.map +1 -1
- package/dist/components/PlDataTable/typesV5.d.ts +23 -15
- package/dist/components/PlDataTable/typesV5.d.ts.map +1 -1
- package/dist/components/index.cjs +3 -1
- package/dist/components/index.d.ts +4 -2
- package/dist/components/index.js +3 -1
- package/dist/index.cjs +13 -9
- package/dist/index.d.ts +9 -7
- package/dist/index.js +6 -4
- package/dist/labels/derive_distinct_labels.cjs +39 -27
- package/dist/labels/derive_distinct_labels.cjs.map +1 -1
- package/dist/labels/derive_distinct_labels.d.ts +15 -15
- package/dist/labels/derive_distinct_labels.d.ts.map +1 -1
- package/dist/labels/derive_distinct_labels.js +39 -27
- package/dist/labels/derive_distinct_labels.js.map +1 -1
- package/dist/labels/index.cjs +0 -1
- package/dist/labels/index.d.ts +1 -2
- package/dist/labels/index.js +0 -1
- package/dist/package.cjs +1 -1
- package/dist/package.js +1 -1
- package/dist/render/api.cjs +10 -3
- package/dist/render/api.cjs.map +1 -1
- package/dist/render/api.d.ts +2 -2
- package/dist/render/api.d.ts.map +1 -1
- package/dist/render/api.js +10 -3
- package/dist/render/api.js.map +1 -1
- package/dist/render/util/column_collection.cjs +3 -3
- package/dist/render/util/column_collection.cjs.map +1 -1
- package/dist/render/util/column_collection.d.ts.map +1 -1
- package/dist/render/util/column_collection.js +3 -3
- package/dist/render/util/column_collection.js.map +1 -1
- package/dist/render/util/label.cjs +2 -2
- package/dist/render/util/label.cjs.map +1 -1
- package/dist/render/util/label.js +2 -2
- package/dist/render/util/label.js.map +1 -1
- package/dist/render/util/pcolumn_data.cjs.map +1 -1
- package/dist/render/util/pcolumn_data.d.ts +2 -2
- package/dist/render/util/pcolumn_data.d.ts.map +1 -1
- package/dist/render/util/pcolumn_data.js.map +1 -1
- package/package.json +7 -7
- package/src/columns/column_collection_builder.test.ts +40 -27
- package/src/columns/column_collection_builder.ts +176 -131
- package/src/columns/column_selector.test.ts +17 -399
- package/src/columns/column_selector.ts +14 -127
- package/src/columns/column_snapshot.ts +5 -5
- package/src/columns/column_snapshot_provider.ts +11 -10
- package/src/columns/ctx_column_sources.ts +2 -2
- package/src/columns/expand_by_partition.test.ts +4 -4
- package/src/columns/expand_by_partition.ts +4 -3
- package/src/columns/index.ts +1 -0
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV2.ts +42 -0
- package/src/components/PlDataTable/createPlDataTable/createPTableDefV3.ts +89 -0
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV2.ts +51 -19
- package/src/components/PlDataTable/createPlDataTable/createPlDataTableV3.ts +500 -313
- package/src/components/PlDataTable/createPlDataTable/discoverColumns.ts +122 -0
- package/src/components/PlDataTable/createPlDataTable/index.ts +4 -2
- package/src/components/PlDataTable/createPlDataTable/utils.test.ts +257 -0
- package/src/components/PlDataTable/createPlDataTable/utils.ts +160 -0
- package/src/components/PlDataTable/index.ts +15 -2
- package/src/components/PlDataTable/labels.ts +29 -18
- package/src/components/PlDataTable/state-migration.ts +6 -1
- package/src/components/PlDataTable/typesV5.ts +25 -12
- package/src/labels/derive_distinct_labels.test.ts +143 -45
- package/src/labels/derive_distinct_labels.ts +102 -49
- package/src/labels/index.ts +0 -1
- package/src/render/api.ts +15 -5
- package/src/render/util/column_collection.ts +4 -3
- package/src/render/util/label.ts +2 -2
- package/src/render/util/pcolumn_data.ts +5 -3
- package/dist/labels/write_labels_to_specs.cjs +0 -14
- package/dist/labels/write_labels_to_specs.cjs.map +0 -1
- package/dist/labels/write_labels_to_specs.d.ts +0 -7
- package/dist/labels/write_labels_to_specs.d.ts.map +0 -1
- package/dist/labels/write_labels_to_specs.js +0 -13
- package/dist/labels/write_labels_to_specs.js.map +0 -1
- package/src/labels/write_labels_to_specs.ts +0 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pcolumn_data.js","names":[],"sources":["../../../src/render/util/pcolumn_data.ts"],"sourcesContent":["import type {\n DataInfo,\n PartitionedDataInfoEntries,\n PColumn,\n PColumnLazy,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport {\n dataInfoToEntries,\n isDataInfo,\n isDataInfoEntries,\n visitDataInfo,\n type BinaryChunk,\n type DataInfoEntries,\n type PColumnDataEntry,\n type PColumnKey,\n} from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../accessor\";\nimport type { PColumnDataUniversal } from \"../internal\";\n\nconst PCD_PREFIX = \"PColumnData/\";\n\nexport const RT_RESOURCE_MAP = PCD_PREFIX + \"ResourceMap\";\nexport const RT_RESOURCE_MAP_PARTITIONED = PCD_PREFIX + \"Partitioned/ResourceMap\";\n\nexport const RT_JSON_PARTITIONED = PCD_PREFIX + \"JsonPartitioned\";\nexport const RT_BINARY_PARTITIONED = PCD_PREFIX + \"BinaryPartitioned\";\nexport const RT_PARQUET_PARTITIONED = PCD_PREFIX + \"ParquetPartitioned\";\n\nconst PCD_SUP_PREFIX = PCD_PREFIX + \"Partitioned/\";\nexport const RT_JSON_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"JsonPartitioned\";\nexport const RT_BINARY_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"BinaryPartitioned\";\nexport const RT_PARQUET_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"ParquetPartitioned\";\n\nexport type PColumnResourceMapEntry<T> = {\n key: PColumnKey;\n value: T;\n};\n\nexport type PColumnResourceMapData<T> = {\n isComplete: boolean;\n data: PColumnResourceMapEntry<T>[];\n};\n\nfunction populateResourceMapData<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n data: PColumnResourceMapEntry<T | undefined>[],\n keyPrefix: PColumnKey = [],\n addEntriesWithNoData: boolean,\n): boolean {\n if (acc === undefined) return false;\n switch (acc.resourceType.name) {\n case RT_RESOURCE_MAP: {\n let isComplete = acc.getInputsLocked();\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n const converted = value === undefined ? undefined : resourceParser(value);\n if (converted === undefined) isComplete = false;\n if (converted !== undefined || addEntriesWithNoData) data.push({ key, value: converted });\n }\n return isComplete;\n }\n case RT_RESOURCE_MAP_PARTITIONED: {\n let isComplete = acc.getInputsLocked();\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) isComplete = false;\n else {\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n const populateResult = populateResourceMapData(\n value,\n resourceParser,\n data,\n key,\n addEntriesWithNoData,\n );\n isComplete = isComplete && populateResult;\n }\n }\n return isComplete;\n }\n default:\n throw new Error(`Unknown resource type: ${acc.resourceType.name}`);\n }\n}\n\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: false,\n): PColumnResourceMapData<NonNullable<T>>;\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: true,\n): PColumnResourceMapData<T | undefined>;\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: boolean = false,\n): PColumnResourceMapData<T | undefined> {\n const data: PColumnResourceMapEntry<T | undefined>[] = [];\n const isComplete = populateResourceMapData(acc, resourceParser, data, [], addEntriesWithNoData);\n return { isComplete, data };\n}\n\nexport type PColumnKeyList = {\n /** array of keys */\n data: PColumnKey[];\n /** length of partition key */\n keyLength: number;\n};\n\nconst removeIndexSuffix = (keyStr: string): { baseKey: string; type: \"index\" | \"values\" } => {\n if (keyStr.endsWith(\".index\")) {\n return { baseKey: keyStr.substring(0, keyStr.length - 6), type: \"index\" };\n } else if (keyStr.endsWith(\".values\")) {\n return { baseKey: keyStr.substring(0, keyStr.length - 7), type: \"values\" };\n } else {\n throw new Error(`key must ends on .index/.values for binary p-column, got: ${keyStr}`);\n }\n};\n\n// @TODO define a class with various resource map operations\n/** Returns a list of all partition keys appeared in the p-column */\nexport function getPartitionKeysList(\n acc: TreeNodeAccessor | undefined,\n): PColumnKeyList | undefined {\n if (!acc) return undefined;\n\n const rt = acc.resourceType.name;\n const meta = acc.getDataAsJson<Record<string, number>>();\n const data: PColumnKey[] = [];\n\n let keyLength = 0;\n // @TODO validate meta shape\n switch (rt) {\n case RT_RESOURCE_MAP:\n keyLength = meta[\"keyLength\"];\n break;\n\n case RT_RESOURCE_MAP_PARTITIONED:\n keyLength = meta[\"partitionKeyLength\"] + meta[\"keyLength\"];\n break;\n\n case RT_JSON_PARTITIONED:\n case RT_BINARY_PARTITIONED:\n case RT_PARQUET_PARTITIONED:\n keyLength = meta[\"partitionKeyLength\"];\n break;\n\n case RT_BINARY_SUPER_PARTITIONED:\n case RT_JSON_SUPER_PARTITIONED:\n case RT_PARQUET_SUPER_PARTITIONED:\n keyLength = meta[\"superPartitionKeyLength\"] + meta[\"partitionKeyLength\"];\n break;\n }\n\n switch (rt) {\n case RT_RESOURCE_MAP:\n case RT_JSON_PARTITIONED:\n case RT_BINARY_PARTITIONED:\n case RT_PARQUET_PARTITIONED:\n for (let keyStr of acc.listInputFields()) {\n if (rt === RT_BINARY_PARTITIONED) {\n keyStr = removeIndexSuffix(keyStr).baseKey;\n }\n const key = [...JSON.parse(keyStr)] as PColumnKey;\n data.push(key);\n }\n\n break;\n\n case RT_RESOURCE_MAP_PARTITIONED:\n case RT_BINARY_SUPER_PARTITIONED:\n case RT_JSON_SUPER_PARTITIONED:\n case RT_PARQUET_SUPER_PARTITIONED:\n for (const supKeyStr of acc.listInputFields()) {\n const keyPrefix = [...JSON.parse(supKeyStr)] as PColumnKey;\n\n const value = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (value !== undefined) {\n for (let keyStr of value.listInputFields()) {\n if (rt === RT_BINARY_SUPER_PARTITIONED) {\n keyStr = removeIndexSuffix(keyStr).baseKey;\n }\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n data.push(key);\n }\n }\n }\n break;\n }\n\n return { data, keyLength };\n}\n\nfunction getUniquePartitionKeysForDataEntries(\n list: DataInfoEntries<unknown>,\n): (string | number)[][] {\n if (\n list.type !== \"JsonPartitioned\" &&\n list.type !== \"BinaryPartitioned\" &&\n list.type !== \"ParquetPartitioned\"\n )\n throw new Error(`Splitting requires Partitioned DataInfoEntries, got ${list.type}`);\n\n const { parts, partitionKeyLength } = list;\n\n const result: Set<string | number>[] = [];\n for (let i = 0; i < partitionKeyLength; ++i) {\n result.push(new Set());\n }\n\n for (const part of parts) {\n const key = part.key;\n if (key.length !== partitionKeyLength) {\n throw new Error(\n `Key length (${key.length}) does not match partition length (${partitionKeyLength}) for key: ${JSON.stringify(\n key,\n )}`,\n );\n }\n for (let i = 0; i < partitionKeyLength; ++i) {\n result[i].add(key[i]);\n }\n }\n\n return result.map((s) => Array.from(s.values()));\n}\n\n/** Returns an array of unique partition keys for each column: the i-th element in the resulting 2d array contains all unique values of i-th partition axis. */\nexport function getUniquePartitionKeys(acc: DataInfoEntries<unknown>): (string | number)[][];\nexport function getUniquePartitionKeys(\n acc: DataInfoEntries<unknown> | TreeNodeAccessor | undefined,\n): (string | number)[][] | undefined;\nexport function getUniquePartitionKeys(\n acc: TreeNodeAccessor | DataInfoEntries<unknown> | undefined,\n): (string | number)[][] | undefined {\n if (acc === undefined) return undefined;\n\n if (isDataInfoEntries(acc)) return getUniquePartitionKeysForDataEntries(acc);\n\n const list = getPartitionKeysList(acc);\n if (!list) return undefined;\n\n const { data, keyLength } = list;\n\n const result: Set<string | number>[] = [];\n\n for (let i = 0; i < keyLength; ++i) {\n result.push(new Set());\n }\n\n for (const l of data) {\n if (l.length !== keyLength) {\n throw new Error(\"key length does not match partition length\");\n }\n for (let i = 0; i < keyLength; ++i) {\n result[i].add(l[i]);\n }\n }\n\n return result.map((s) => Array.from(s.values()));\n}\n\n/**\n * Parses the PColumn data from a TreeNodeAccessor into a DataInfoEntries structure.\n * Returns undefined if any required data is missing.\n * Throws error on validation failures.\n *\n * @param acc - The TreeNodeAccessor containing PColumn data\n * @param keyPrefix - Optional key prefix for recursive calls\n * @returns DataInfoEntries representation of the PColumn data, or undefined if incomplete\n */\nexport function parsePColumnData(\n acc: TreeNodeAccessor | undefined,\n keyPrefix: PColumnKey = [],\n): PartitionedDataInfoEntries<TreeNodeAccessor> | undefined {\n if (acc === undefined) return undefined;\n\n if (!acc.getIsReadyOrError()) return undefined;\n\n const resourceType = acc.resourceType.name;\n const meta = acc.getDataAsJson<Record<string, number>>();\n\n // Prevent recursive super-partitioned resources\n if (\n keyPrefix.length > 0 &&\n (resourceType === RT_JSON_SUPER_PARTITIONED ||\n resourceType === RT_BINARY_SUPER_PARTITIONED ||\n resourceType === RT_PARQUET_SUPER_PARTITIONED)\n ) {\n throw new Error(`Unexpected nested super-partitioned resource: ${resourceType}`);\n }\n\n switch (resourceType) {\n case RT_RESOURCE_MAP:\n case RT_RESOURCE_MAP_PARTITIONED:\n throw new Error(`Only data columns are supported, got: ${resourceType}`);\n\n case RT_JSON_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(keyStr)];\n parts.push({ key, value });\n }\n\n return {\n type: \"JsonPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_BINARY_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<BinaryChunk<TreeNodeAccessor>>[] = [];\n const baseKeys = new Map<string, { index?: TreeNodeAccessor; values?: TreeNodeAccessor }>();\n\n // Group fields by base key (without .index/.values suffix)\n for (const keyStr of acc.listInputFields()) {\n const suffix = removeIndexSuffix(keyStr);\n\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n let entry = baseKeys.get(suffix.baseKey);\n if (!entry) {\n entry = {};\n baseKeys.set(suffix.baseKey, entry);\n }\n\n if (suffix.type === \"index\") {\n entry.index = value;\n } else {\n entry.values = value;\n }\n }\n\n // Process complete binary chunks only\n for (const [baseKeyStr, entry] of baseKeys.entries()) {\n if (!entry.index || !entry.values) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(baseKeyStr)];\n parts.push({\n key,\n value: {\n index: entry.index,\n values: entry.values,\n },\n });\n }\n\n return {\n type: \"BinaryPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_PARQUET_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(keyStr)];\n parts.push({ key, value });\n }\n\n return {\n type: \"ParquetPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_JSON_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_JSON_PARTITIONED) {\n throw new Error(\n `Expected ${RT_JSON_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"JsonPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"JsonPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n case RT_BINARY_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<BinaryChunk<TreeNodeAccessor>>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_BINARY_PARTITIONED) {\n throw new Error(\n `Expected ${RT_BINARY_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"BinaryPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"BinaryPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n case RT_PARQUET_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_PARQUET_PARTITIONED) {\n throw new Error(\n `Expected ${RT_PARQUET_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"ParquetPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"ParquetPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n default:\n throw new Error(`Unknown resource type: ${resourceType}`);\n }\n}\n\n/**\n * Converts or parses the input into DataInfoEntries format.\n\n * @param acc - The input data, which can be TreeNodeAccessor, DataInfoEntries, DataInfo, or undefined.\n * @returns The data in DataInfoEntries format, or undefined if the input was undefined or data is not ready.\n */\nexport function convertOrParsePColumnData(\n acc:\n | TreeNodeAccessor\n | DataInfoEntries<TreeNodeAccessor>\n | DataInfo<TreeNodeAccessor>\n | undefined,\n): DataInfoEntries<TreeNodeAccessor> | undefined {\n if (acc === undefined) return undefined;\n\n if (isDataInfoEntries(acc)) return acc;\n if (isDataInfo(acc)) return dataInfoToEntries(acc);\n if (acc instanceof TreeNodeAccessor) return parsePColumnData(acc);\n\n throw new Error(`Unexpected input type: ${typeof acc}`);\n}\n\nexport function isPColumnReady(\n c: PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>,\n): c is PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal> {\n const isValues = (d: PColumnDataUniversal): d is PColumnValues => Array.isArray(d);\n const isAccessor = (d: PColumnDataUniversal): d is TreeNodeAccessor =>\n d instanceof TreeNodeAccessor;\n\n let ready = true;\n const data = typeof c.data === \"function\" ? c.data() : c.data;\n if (data == null) {\n return false;\n } else if (isAccessor(data)) {\n ready &&= data.getIsReadyOrError();\n } else if (isDataInfo(data)) {\n visitDataInfo(data, (v) => (ready &&= v.getIsReadyOrError()));\n } else if (!isValues(data)) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw Error(`unsupported column data type: ${data satisfies never}`);\n }\n return ready;\n}\n\nexport function allPColumnsReady(\n columns: (PColumn<PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>)[],\n): columns is (PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal>)[] {\n return columns.every(isPColumnReady);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pcolumn_data.js","names":[],"sources":["../../../src/render/util/pcolumn_data.ts"],"sourcesContent":["import type {\n DataInfo,\n PartitionedDataInfoEntries,\n PColumn,\n PColumnLazy,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport {\n dataInfoToEntries,\n isDataInfo,\n isDataInfoEntries,\n visitDataInfo,\n type BinaryChunk,\n type DataInfoEntries,\n type PColumnDataEntry,\n type PColumnKey,\n} from \"@milaboratories/pl-model-common\";\nimport { TreeNodeAccessor } from \"../accessor\";\nimport type { PColumnDataUniversal } from \"../internal\";\n\nconst PCD_PREFIX = \"PColumnData/\";\n\nexport const RT_RESOURCE_MAP = PCD_PREFIX + \"ResourceMap\";\nexport const RT_RESOURCE_MAP_PARTITIONED = PCD_PREFIX + \"Partitioned/ResourceMap\";\n\nexport const RT_JSON_PARTITIONED = PCD_PREFIX + \"JsonPartitioned\";\nexport const RT_BINARY_PARTITIONED = PCD_PREFIX + \"BinaryPartitioned\";\nexport const RT_PARQUET_PARTITIONED = PCD_PREFIX + \"ParquetPartitioned\";\n\nconst PCD_SUP_PREFIX = PCD_PREFIX + \"Partitioned/\";\nexport const RT_JSON_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"JsonPartitioned\";\nexport const RT_BINARY_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"BinaryPartitioned\";\nexport const RT_PARQUET_SUPER_PARTITIONED = PCD_SUP_PREFIX + \"ParquetPartitioned\";\n\nexport type PColumnResourceMapEntry<T> = {\n key: PColumnKey;\n value: T;\n};\n\nexport type PColumnResourceMapData<T> = {\n isComplete: boolean;\n data: PColumnResourceMapEntry<T>[];\n};\n\nfunction populateResourceMapData<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n data: PColumnResourceMapEntry<T | undefined>[],\n keyPrefix: PColumnKey = [],\n addEntriesWithNoData: boolean,\n): boolean {\n if (acc === undefined) return false;\n switch (acc.resourceType.name) {\n case RT_RESOURCE_MAP: {\n let isComplete = acc.getInputsLocked();\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n const converted = value === undefined ? undefined : resourceParser(value);\n if (converted === undefined) isComplete = false;\n if (converted !== undefined || addEntriesWithNoData) data.push({ key, value: converted });\n }\n return isComplete;\n }\n case RT_RESOURCE_MAP_PARTITIONED: {\n let isComplete = acc.getInputsLocked();\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) isComplete = false;\n else {\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n const populateResult = populateResourceMapData(\n value,\n resourceParser,\n data,\n key,\n addEntriesWithNoData,\n );\n isComplete = isComplete && populateResult;\n }\n }\n return isComplete;\n }\n default:\n throw new Error(`Unknown resource type: ${acc.resourceType.name}`);\n }\n}\n\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: false,\n): PColumnResourceMapData<NonNullable<T>>;\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: true,\n): PColumnResourceMapData<T | undefined>;\nexport function parseResourceMap<T>(\n acc: TreeNodeAccessor | undefined,\n resourceParser: (acc: TreeNodeAccessor) => T | undefined,\n addEntriesWithNoData: boolean = false,\n): PColumnResourceMapData<T | undefined> {\n const data: PColumnResourceMapEntry<T | undefined>[] = [];\n const isComplete = populateResourceMapData(acc, resourceParser, data, [], addEntriesWithNoData);\n return { isComplete, data };\n}\n\nexport type PColumnKeyList = {\n /** array of keys */\n data: PColumnKey[];\n /** length of partition key */\n keyLength: number;\n};\n\nconst removeIndexSuffix = (keyStr: string): { baseKey: string; type: \"index\" | \"values\" } => {\n if (keyStr.endsWith(\".index\")) {\n return { baseKey: keyStr.substring(0, keyStr.length - 6), type: \"index\" };\n } else if (keyStr.endsWith(\".values\")) {\n return { baseKey: keyStr.substring(0, keyStr.length - 7), type: \"values\" };\n } else {\n throw new Error(`key must ends on .index/.values for binary p-column, got: ${keyStr}`);\n }\n};\n\n// @TODO define a class with various resource map operations\n/** Returns a list of all partition keys appeared in the p-column */\nexport function getPartitionKeysList(\n acc: TreeNodeAccessor | undefined,\n): PColumnKeyList | undefined {\n if (!acc) return undefined;\n\n const rt = acc.resourceType.name;\n const meta = acc.getDataAsJson<Record<string, number>>();\n const data: PColumnKey[] = [];\n\n let keyLength = 0;\n // @TODO validate meta shape\n switch (rt) {\n case RT_RESOURCE_MAP:\n keyLength = meta[\"keyLength\"];\n break;\n\n case RT_RESOURCE_MAP_PARTITIONED:\n keyLength = meta[\"partitionKeyLength\"] + meta[\"keyLength\"];\n break;\n\n case RT_JSON_PARTITIONED:\n case RT_BINARY_PARTITIONED:\n case RT_PARQUET_PARTITIONED:\n keyLength = meta[\"partitionKeyLength\"];\n break;\n\n case RT_BINARY_SUPER_PARTITIONED:\n case RT_JSON_SUPER_PARTITIONED:\n case RT_PARQUET_SUPER_PARTITIONED:\n keyLength = meta[\"superPartitionKeyLength\"] + meta[\"partitionKeyLength\"];\n break;\n }\n\n switch (rt) {\n case RT_RESOURCE_MAP:\n case RT_JSON_PARTITIONED:\n case RT_BINARY_PARTITIONED:\n case RT_PARQUET_PARTITIONED:\n for (let keyStr of acc.listInputFields()) {\n if (rt === RT_BINARY_PARTITIONED) {\n keyStr = removeIndexSuffix(keyStr).baseKey;\n }\n const key = [...JSON.parse(keyStr)] as PColumnKey;\n data.push(key);\n }\n\n break;\n\n case RT_RESOURCE_MAP_PARTITIONED:\n case RT_BINARY_SUPER_PARTITIONED:\n case RT_JSON_SUPER_PARTITIONED:\n case RT_PARQUET_SUPER_PARTITIONED:\n for (const supKeyStr of acc.listInputFields()) {\n const keyPrefix = [...JSON.parse(supKeyStr)] as PColumnKey;\n\n const value = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (value !== undefined) {\n for (let keyStr of value.listInputFields()) {\n if (rt === RT_BINARY_SUPER_PARTITIONED) {\n keyStr = removeIndexSuffix(keyStr).baseKey;\n }\n const key = [...keyPrefix, ...JSON.parse(keyStr)] as PColumnKey;\n data.push(key);\n }\n }\n }\n break;\n }\n\n return { data, keyLength };\n}\n\nfunction getUniquePartitionKeysForDataEntries(\n list: DataInfoEntries<unknown>,\n): (string | number)[][] {\n if (\n list.type !== \"JsonPartitioned\" &&\n list.type !== \"BinaryPartitioned\" &&\n list.type !== \"ParquetPartitioned\"\n )\n throw new Error(`Splitting requires Partitioned DataInfoEntries, got ${list.type}`);\n\n const { parts, partitionKeyLength } = list;\n\n const result: Set<string | number>[] = [];\n for (let i = 0; i < partitionKeyLength; ++i) {\n result.push(new Set());\n }\n\n for (const part of parts) {\n const key = part.key;\n if (key.length !== partitionKeyLength) {\n throw new Error(\n `Key length (${key.length}) does not match partition length (${partitionKeyLength}) for key: ${JSON.stringify(\n key,\n )}`,\n );\n }\n for (let i = 0; i < partitionKeyLength; ++i) {\n result[i].add(key[i]);\n }\n }\n\n return result.map((s) => Array.from(s.values()));\n}\n\n/** Returns an array of unique partition keys for each column: the i-th element in the resulting 2d array contains all unique values of i-th partition axis. */\nexport function getUniquePartitionKeys(acc: DataInfoEntries<unknown>): (string | number)[][];\nexport function getUniquePartitionKeys(\n acc: DataInfoEntries<unknown> | TreeNodeAccessor | undefined,\n): (string | number)[][] | undefined;\nexport function getUniquePartitionKeys(\n acc: TreeNodeAccessor | DataInfoEntries<unknown> | undefined,\n): (string | number)[][] | undefined {\n if (acc === undefined) return undefined;\n\n if (isDataInfoEntries(acc)) return getUniquePartitionKeysForDataEntries(acc);\n\n const list = getPartitionKeysList(acc);\n if (!list) return undefined;\n\n const { data, keyLength } = list;\n\n const result: Set<string | number>[] = [];\n\n for (let i = 0; i < keyLength; ++i) {\n result.push(new Set());\n }\n\n for (const l of data) {\n if (l.length !== keyLength) {\n throw new Error(\"key length does not match partition length\");\n }\n for (let i = 0; i < keyLength; ++i) {\n result[i].add(l[i]);\n }\n }\n\n return result.map((s) => Array.from(s.values()));\n}\n\n/**\n * Parses the PColumn data from a TreeNodeAccessor into a DataInfoEntries structure.\n * Returns undefined if any required data is missing.\n * Throws error on validation failures.\n *\n * @param acc - The TreeNodeAccessor containing PColumn data\n * @param keyPrefix - Optional key prefix for recursive calls\n * @returns DataInfoEntries representation of the PColumn data, or undefined if incomplete\n */\nexport function parsePColumnData(\n acc: TreeNodeAccessor | undefined,\n keyPrefix: PColumnKey = [],\n): PartitionedDataInfoEntries<TreeNodeAccessor> | undefined {\n if (acc === undefined) return undefined;\n\n if (!acc.getIsReadyOrError()) return undefined;\n\n const resourceType = acc.resourceType.name;\n const meta = acc.getDataAsJson<Record<string, number>>();\n\n // Prevent recursive super-partitioned resources\n if (\n keyPrefix.length > 0 &&\n (resourceType === RT_JSON_SUPER_PARTITIONED ||\n resourceType === RT_BINARY_SUPER_PARTITIONED ||\n resourceType === RT_PARQUET_SUPER_PARTITIONED)\n ) {\n throw new Error(`Unexpected nested super-partitioned resource: ${resourceType}`);\n }\n\n switch (resourceType) {\n case RT_RESOURCE_MAP:\n case RT_RESOURCE_MAP_PARTITIONED:\n throw new Error(`Only data columns are supported, got: ${resourceType}`);\n\n case RT_JSON_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(keyStr)];\n parts.push({ key, value });\n }\n\n return {\n type: \"JsonPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_BINARY_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<BinaryChunk<TreeNodeAccessor>>[] = [];\n const baseKeys = new Map<string, { index?: TreeNodeAccessor; values?: TreeNodeAccessor }>();\n\n // Group fields by base key (without .index/.values suffix)\n for (const keyStr of acc.listInputFields()) {\n const suffix = removeIndexSuffix(keyStr);\n\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n let entry = baseKeys.get(suffix.baseKey);\n if (!entry) {\n entry = {};\n baseKeys.set(suffix.baseKey, entry);\n }\n\n if (suffix.type === \"index\") {\n entry.index = value;\n } else {\n entry.values = value;\n }\n }\n\n // Process complete binary chunks only\n for (const [baseKeyStr, entry] of baseKeys.entries()) {\n if (!entry.index || !entry.values) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(baseKeyStr)];\n parts.push({\n key,\n value: {\n index: entry.index,\n values: entry.values,\n },\n });\n }\n\n return {\n type: \"BinaryPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_PARQUET_PARTITIONED: {\n if (typeof meta?.partitionKeyLength !== \"number\") {\n throw new Error(`Missing partitionKeyLength in metadata for ${resourceType}`);\n }\n\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n for (const keyStr of acc.listInputFields()) {\n const value = acc.resolve({ field: keyStr, assertFieldType: \"Input\" });\n if (value === undefined) return undefined;\n\n const key = [...keyPrefix, ...JSON.parse(keyStr)];\n parts.push({ key, value });\n }\n\n return {\n type: \"ParquetPartitioned\",\n partitionKeyLength: meta.partitionKeyLength,\n parts,\n };\n }\n\n case RT_JSON_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_JSON_PARTITIONED) {\n throw new Error(\n `Expected ${RT_JSON_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"JsonPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"JsonPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n case RT_BINARY_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<BinaryChunk<TreeNodeAccessor>>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_BINARY_PARTITIONED) {\n throw new Error(\n `Expected ${RT_BINARY_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"BinaryPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"BinaryPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n case RT_PARQUET_SUPER_PARTITIONED: {\n if (\n typeof meta?.superPartitionKeyLength !== \"number\" ||\n typeof meta?.partitionKeyLength !== \"number\"\n ) {\n throw new Error(\n `Missing superPartitionKeyLength or partitionKeyLength in metadata for ${resourceType}`,\n );\n }\n\n const totalKeyLength = meta.superPartitionKeyLength + meta.partitionKeyLength;\n const parts: PColumnDataEntry<TreeNodeAccessor>[] = [];\n\n // Process all super partitions\n for (const supKeyStr of acc.listInputFields()) {\n const superPartition = acc.resolve({ field: supKeyStr, assertFieldType: \"Input\" });\n if (superPartition === undefined) return undefined;\n\n // Validate inner type\n if (superPartition.resourceType.name !== RT_PARQUET_PARTITIONED) {\n throw new Error(\n `Expected ${RT_PARQUET_PARTITIONED} inside ${resourceType}, but got ${superPartition.resourceType.name}`,\n );\n }\n\n const innerResult = parsePColumnData(superPartition, JSON.parse(supKeyStr) as PColumnKey);\n\n if (innerResult === undefined) return undefined;\n\n if (innerResult.type !== \"ParquetPartitioned\")\n throw new Error(`Unexpected inner result type for ${resourceType}: ${innerResult.type}`);\n\n parts.push(...innerResult.parts);\n }\n\n return {\n type: \"ParquetPartitioned\",\n partitionKeyLength: totalKeyLength,\n parts,\n };\n }\n\n default:\n throw new Error(`Unknown resource type: ${resourceType}`);\n }\n}\n\n/**\n * Converts or parses the input into DataInfoEntries format.\n\n * @param acc - The input data, which can be TreeNodeAccessor, DataInfoEntries, DataInfo, or undefined.\n * @returns The data in DataInfoEntries format, or undefined if the input was undefined or data is not ready.\n */\nexport function convertOrParsePColumnData(\n acc:\n | TreeNodeAccessor\n | DataInfoEntries<TreeNodeAccessor>\n | DataInfo<TreeNodeAccessor>\n | undefined,\n): DataInfoEntries<TreeNodeAccessor> | undefined {\n if (acc === undefined) return undefined;\n\n if (isDataInfoEntries(acc)) return acc;\n if (isDataInfo(acc)) return dataInfoToEntries(acc);\n if (acc instanceof TreeNodeAccessor) return parsePColumnData(acc);\n\n throw new Error(`Unexpected input type: ${typeof acc}`);\n}\n\nexport function isPColumnReady(\n c: PColumn<undefined | PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>,\n): c is PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal> {\n const isValues = (d: PColumnDataUniversal): d is PColumnValues => Array.isArray(d);\n const isAccessor = (d: PColumnDataUniversal): d is TreeNodeAccessor =>\n d instanceof TreeNodeAccessor;\n\n let ready = true;\n const data = typeof c.data === \"function\" ? c.data() : c.data;\n if (data == null) {\n return false;\n } else if (isAccessor(data)) {\n ready &&= data.getIsReadyOrError();\n } else if (isDataInfo(data)) {\n visitDataInfo(data, (v) => (ready &&= v.getIsReadyOrError()));\n } else if (!isValues(data)) {\n throw Error(`unsupported column data type: ${data satisfies never}`);\n }\n return ready;\n}\n\nexport function allPColumnsReady(\n columns: (\n | PColumn<undefined | PColumnDataUniversal>\n | PColumnLazy<undefined | PColumnDataUniversal>\n )[],\n): columns is (PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal>)[] {\n return columns.every(isPColumnReady);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/model",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.65.0",
|
|
4
4
|
"description": "Platforma.bio SDK / Block Model",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"utility-types": "^3.11.0",
|
|
32
32
|
"zod": "~3.25.76",
|
|
33
33
|
"@milaboratories/helpers": "1.14.1",
|
|
34
|
-
"@milaboratories/pl-model-middle-layer": "1.16.4",
|
|
35
34
|
"@milaboratories/pl-error-like": "1.12.9",
|
|
36
|
-
"@milaboratories/pl-model-
|
|
37
|
-
"@milaboratories/ptabler-expression-js": "1.2.6"
|
|
35
|
+
"@milaboratories/pl-model-middle-layer": "1.16.4",
|
|
36
|
+
"@milaboratories/ptabler-expression-js": "1.2.6",
|
|
37
|
+
"@milaboratories/pl-model-common": "1.31.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@vitest/coverage-istanbul": "^4.1.3",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"typescript": "~5.9.3",
|
|
43
43
|
"vitest": "^4.1.3",
|
|
44
44
|
"@milaboratories/build-configs": "2.0.0",
|
|
45
|
-
"@milaboratories/ts-builder": "1.3.1",
|
|
46
45
|
"@milaboratories/pf-driver": "1.3.5",
|
|
47
|
-
"@milaboratories/
|
|
48
|
-
"@milaboratories/
|
|
46
|
+
"@milaboratories/pf-spec-driver": "1.2.5",
|
|
47
|
+
"@milaboratories/ts-builder": "1.3.1",
|
|
48
|
+
"@milaboratories/ts-configs": "1.2.3"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "ts-builder build --target node",
|
|
@@ -108,17 +108,17 @@ describe("ColumnCollectionBuilder", () => {
|
|
|
108
108
|
|
|
109
109
|
const collection = builder.build({ allowPartialColumnList: true });
|
|
110
110
|
expect(collection).toBeDefined();
|
|
111
|
-
expect(collection.columnListComplete).toBe(false);
|
|
112
111
|
expect(collection.findColumns()).toHaveLength(1);
|
|
113
112
|
});
|
|
114
113
|
|
|
115
|
-
test("allowPartialColumnList with complete providers
|
|
114
|
+
test("allowPartialColumnList with complete providers returns collection", () => {
|
|
116
115
|
const snap = createSnapshot("id1", createSpec("col1"));
|
|
117
116
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
118
117
|
builder.addSource(createProvider([snap], true));
|
|
119
118
|
|
|
120
119
|
const collection = builder.build({ allowPartialColumnList: true });
|
|
121
|
-
expect(collection
|
|
120
|
+
expect(collection).toBeDefined();
|
|
121
|
+
expect(collection.findColumns()).toHaveLength(1);
|
|
122
122
|
});
|
|
123
123
|
});
|
|
124
124
|
|
|
@@ -290,25 +290,30 @@ describe("multiple providers", () => {
|
|
|
290
290
|
expect(builder.build()).toBeUndefined();
|
|
291
291
|
});
|
|
292
292
|
|
|
293
|
-
test("allowPartialColumnList
|
|
293
|
+
test("allowPartialColumnList returns collection when any provider incomplete", () => {
|
|
294
294
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
295
295
|
builder.addSource(createProvider([createSnapshot("id1", createSpec("col1"))], true));
|
|
296
296
|
builder.addSource(createProvider([createSnapshot("id2", createSpec("col2"))], false));
|
|
297
297
|
|
|
298
298
|
const collection = builder.build({ allowPartialColumnList: true });
|
|
299
|
-
expect(collection
|
|
299
|
+
expect(collection).toBeDefined();
|
|
300
|
+
expect(collection.findColumns()).toHaveLength(2);
|
|
300
301
|
});
|
|
301
302
|
});
|
|
302
303
|
|
|
303
304
|
describe("AnchoredColumnCollection", () => {
|
|
305
|
+
// The anchor spec must also exist as a source column — the new implementation
|
|
306
|
+
// resolves PColumnSpec anchors by matching native ID in the collected columns.
|
|
304
307
|
const anchorSpec = createSpec("anchor-col", {
|
|
305
308
|
axesSpec: [sampleAxis("sample"), sampleAxis("gene")],
|
|
306
309
|
});
|
|
310
|
+
const anchorSnap = createSnapshot("anchor-snap-id", anchorSpec);
|
|
307
311
|
|
|
308
312
|
test("build with PColumnSpec anchor returns anchored collection", () => {
|
|
309
313
|
const s1 = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
310
314
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
311
|
-
|
|
315
|
+
// anchorSnap must be in sources so resolveAnchorMap can find it by native ID
|
|
316
|
+
builder.addSource([s1, anchorSnap]);
|
|
312
317
|
|
|
313
318
|
const collection = builder.build({ anchors: { main: anchorSpec } });
|
|
314
319
|
expect(collection).toBeDefined();
|
|
@@ -333,18 +338,11 @@ describe("AnchoredColumnCollection", () => {
|
|
|
333
338
|
);
|
|
334
339
|
});
|
|
335
340
|
|
|
336
|
-
test("build with PlRef anchor throws", () => {
|
|
337
|
-
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
338
|
-
const plRef = { __isRef: true as const, blockId: "b1", name: "out" };
|
|
339
|
-
|
|
340
|
-
expect(() => builder.build({ anchors: { main: plRef } })).toThrow(/PlRef/);
|
|
341
|
-
});
|
|
342
|
-
|
|
343
341
|
test("getColumn returns snapshot by SUniversalPColumnId", () => {
|
|
344
342
|
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
345
343
|
const snap = createSnapshot("id1", spec);
|
|
346
344
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
347
|
-
builder.addSource([snap]);
|
|
345
|
+
builder.addSource([snap, anchorSnap]);
|
|
348
346
|
|
|
349
347
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
350
348
|
|
|
@@ -360,50 +358,65 @@ describe("AnchoredColumnCollection", () => {
|
|
|
360
358
|
test("getColumn returns undefined for unknown id", () => {
|
|
361
359
|
const snap = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
362
360
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
363
|
-
builder.addSource([snap]);
|
|
361
|
+
builder.addSource([snap, anchorSnap]);
|
|
364
362
|
|
|
365
363
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
366
364
|
expect(collection.getColumn("not-a-real-id" as SUniversalPColumnId)).toBeUndefined();
|
|
367
365
|
});
|
|
368
366
|
|
|
367
|
+
test("getAnchors returns resolved anchor map", () => {
|
|
368
|
+
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
369
|
+
const snap = createSnapshot("id1", spec);
|
|
370
|
+
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
371
|
+
builder.addSource([snap, anchorSnap]);
|
|
372
|
+
|
|
373
|
+
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
374
|
+
const anchors = collection.getAnchors();
|
|
375
|
+
expect(anchors.size).toBe(1);
|
|
376
|
+
expect(anchors.get("main")).toBeDefined();
|
|
377
|
+
expect(anchors.get("main")!.spec.name).toBe("anchor-col");
|
|
378
|
+
});
|
|
379
|
+
|
|
369
380
|
test("findColumns returns ColumnMatch with originalId and variants", () => {
|
|
370
381
|
const spec = createSpec("col1", { axesSpec: [sampleAxis("sample")] });
|
|
371
382
|
const snap = createSnapshot("id1", spec);
|
|
372
383
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
373
|
-
|
|
384
|
+
// anchorSnap itself also appears in findColumns results (axes ⊆ anchor axes)
|
|
385
|
+
builder.addSource([snap, anchorSnap]);
|
|
374
386
|
|
|
375
387
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
376
388
|
const matches = collection.findColumns();
|
|
377
389
|
|
|
378
|
-
|
|
379
|
-
expect(matches
|
|
380
|
-
|
|
381
|
-
expect(
|
|
390
|
+
// col1 + anchor-col are both discovered
|
|
391
|
+
expect(matches.length).toBeGreaterThanOrEqual(1);
|
|
392
|
+
const col1Match = matches.find((m) => m.column.spec.name === "col1")!;
|
|
393
|
+
expect(col1Match).toBeDefined();
|
|
394
|
+
expect(col1Match.originalId).toBe("id1");
|
|
395
|
+
expect(col1Match.variants).toBeDefined();
|
|
382
396
|
});
|
|
383
397
|
|
|
384
398
|
test("findColumns exclude filters out matching columns", () => {
|
|
385
399
|
const snap1 = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
386
400
|
const snap2 = createSnapshot("id2", createSpec("col2", { axesSpec: [sampleAxis("sample")] }));
|
|
387
401
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
388
|
-
builder.addSource([snap1, snap2]);
|
|
402
|
+
builder.addSource([snap1, snap2, anchorSnap]);
|
|
389
403
|
|
|
390
404
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
391
405
|
const results = collection.findColumns({ exclude: { name: "col1" } });
|
|
392
|
-
expect(results).
|
|
393
|
-
expect(results
|
|
406
|
+
expect(results.every((r) => r.column.spec.name !== "col1")).toBe(true);
|
|
407
|
+
expect(results.some((r) => r.column.spec.name === "col2")).toBe(true);
|
|
394
408
|
});
|
|
395
409
|
|
|
396
|
-
test("allowPartialColumnList with anchors
|
|
410
|
+
test("allowPartialColumnList with anchors returns collection when incomplete", () => {
|
|
397
411
|
const snap = createSnapshot("id1", createSpec("col1", { axesSpec: [sampleAxis("sample")] }));
|
|
398
412
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
399
|
-
builder.addSource(createProvider([snap], false));
|
|
413
|
+
builder.addSource(createProvider([snap, anchorSnap], false));
|
|
400
414
|
|
|
401
415
|
const collection = builder.build({
|
|
402
416
|
anchors: { main: anchorSpec },
|
|
403
417
|
allowPartialColumnList: true,
|
|
404
418
|
});
|
|
405
419
|
expect(collection).toBeDefined();
|
|
406
|
-
expect(collection.columnListComplete).toBe(false);
|
|
407
420
|
});
|
|
408
421
|
|
|
409
422
|
test("build returns undefined with anchors when incomplete and no allowPartial", () => {
|
|
@@ -420,7 +433,7 @@ describe("AnchoredColumnCollection", () => {
|
|
|
420
433
|
const snap = createSnapshot("id1", spec, "computing");
|
|
421
434
|
|
|
422
435
|
const builder = new ColumnCollectionBuilder(createSpecFrameCtx());
|
|
423
|
-
builder.addSource([snap]);
|
|
436
|
+
builder.addSource([snap, anchorSnap]);
|
|
424
437
|
|
|
425
438
|
const collection = builder.build({ anchors: { main: anchorSpec } })!;
|
|
426
439
|
|