@platforma-sdk/model 1.78.16 → 1.79.2

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/index.cjs CHANGED
@@ -180,6 +180,7 @@ exports.getImportProgress = require_actions.getImportProgress;
180
180
  exports.getJsonField = require_actions.getJsonField;
181
181
  exports.getLastLogs = require_actions.getLastLogs;
182
182
  exports.getLogHandle = require_actions.getLogHandle;
183
+ exports.getNumberOfRows = require_pcolumn_data.getNumberOfRows;
183
184
  exports.getOnDemandBlobContent = require_actions.getOnDemandBlobContent;
184
185
  exports.getOrderPriority = require_utils.getOrderPriority;
185
186
  exports.getPartitionKeysList = require_pcolumn_data.getPartitionKeysList;
package/dist/index.d.ts CHANGED
@@ -32,7 +32,7 @@ import { DeriveLabelsFormatters, DeriveLabelsOptions, Entry, LinkerStep, Trace,
32
32
  import { deriveLabels } from "./render/util/label.js";
33
33
  import { AxisLabelProvider, ColumnProvider, PColumnCollection, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnLazyUniversal, PColumnLazyWithLabel } from "./render/util/column_collection.js";
34
34
  import { BlockRenderCtx, InferRenderFunctionReturn, PluginRenderCtx, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResultPool, UniversalColumnOption, UnwrapFutureRef } from "./render/api.js";
35
- import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./render/util/pcolumn_data.js";
35
+ import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./render/util/pcolumn_data.js";
36
36
  import { filterDataInfoEntries } from "./render/util/axis_filtering.js";
37
37
  import { PluginConfig, PluginData, PluginDataModel, PluginDataModelBuilder, PluginDataModelVersions, PluginFactory, PluginInstance, PluginModel, PluginOutputs, PluginParams, PluginPublicOutputs, PublicOutputFieldDef } from "./plugin_model.js";
38
38
  import { BlockModelV3, ParamsInput, PluginRecord } from "./block_model.js";
@@ -74,4 +74,4 @@ import { getService } from "./services/get_services.js";
74
74
  import { getEnvironmentValue } from "./env_value.js";
75
75
  export * from "@milaboratories/pl-model-common";
76
76
  export * from "@milaboratories/pl-error-like";
77
- export { ActAnd, ActExtractArchiveAndGetURL, ActFlatten, ActGetBlobContent, ActGetBlobContentAsJson, ActGetBlobContentAsString, ActGetDownloadedBlobContent, ActGetField, ActGetFromCtx, ActGetImmediate, ActGetLastLogs, ActGetLogHandle, ActGetOnDemandBlobContent, ActGetProgressLog, ActGetProgressLogWithInfo, ActGetResourceField, ActGetResourceValueAsJson, ActImportProgress, ActIsEmpty, ActIsolate, ActMakeArray, ActMakeObject, ActMapArrayValues, ActMapRecordValues, ActMapResourceFields, ActNot, ActOr, ActionResult, AnchorEntry, AnchoredBuildOptions, AnchoredColumnCollection, AnchoredFindColumnsOptions, AndFilter, AnnotationFilter, AnnotationMode, AnnotationScript, AnnotationScript2, AnnotationScriptUi, AnnotationSpec, AnnotationSpecUi, AnnotationStep, AnnotationStepUi, AnyForm, Args, ArrayColumnProvider, AxesVault, AxisLabelProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockApiV1, BlockApiV2, BlockConfig, BlockConfigV3, BlockConfigV4, BlockDefaultModelServices, BlockDefaultUiServices, BlockModel, BlockModelInfo, BlockModelV3, BlockRenderCtx, BlockServiceFlags, BlockStatePatch, type BlockStorage, BlockStorageFacade, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, type BlockStorageSchemaVersion, BuildDatasetOptions, BuildOptions, CancelSubscription, Cfg, CfgAnd, CfgBlobContent, CfgBlobContentAsJson, CfgBlobContentAsString, CfgDownloadedBlobContent, CfgExtractArchiveAndGetURL, CfgFlatten, CfgGetFromCtx, CfgGetJsonField, CfgGetResourceField, CfgImmediate, CfgImportProgress, CfgIsEmpty, CfgIsolate, CfgLastLogs, CfgLogHandle, CfgMakeArray, CfgMakeObject, CfgMapArrayValues, CfgMapRecordValues, CfgMapResourceFields, CfgNot, CfgOnDemandBlobContent, CfgOr, CfgProgressLog, CfgProgressLogWithInfo, CfgRenderingMode, CfgResourceValueAsJson, Checked, ColumnCollection, ColumnCollectionBuilder, ColumnData, ColumnDataStatus, ColumnMatch, ColumnMatcher, ColumnOrderRule, ColumnProvider, ColumnSelector, ColumnSnapshot, ColumnSnapshotProvider, ColumnSource, ColumnVariant, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, CommonFieldTraverseOps, CommonTraversalOps, ConfAction, ConfigRenderLambda, ConfigRenderLambdaFlags, ConfigResult, CurrentSdkInfo, DataModel, DataModelBuilder, DatasetOption, DatasetSelection, DeriveHref, DeriveLabelsFormatters, DeriveLabelsOptions, Entry, ExpandByPartitionOpts, ExpandByPartitionResult, ExpressionSpec, ExtractAction, ExtractFunctionHandleReturn, ExtractFutureRefType, FieldTraversalStep, FieldType, FilterMatchOptions, FilterSpec, FilterSpecLeaf, FilterSpecNode, FilterSpecOfType, FilterSpecType, FilterSpecUi, FilterUi, FilterUiOfType, FilterUiType, FindColumnsOptions, FormField, FutureRef, GetFieldStep, InferArgsType, InferBlockState, InferBlockStatePatch, InferDataType, InferFactoryData, InferFactoryModelServices, InferFactoryOutputs, InferFactoryParams, InferFactoryUiServices, InferHrefType, InferOutputType, InferOutputsFromConfigs, InferOutputsFromLambdas, InferOutputsType, InferPluginData, InferPluginHandle, InferPluginNames, InferPluginUiEntries, InferRenderFunctionReturn, InferUiState, InferVarTypeSafe, IsNA, It, internal_d_exports as JsRenderInternal, DeriveLabelsOptions as LabelDerivationOps, LinkerStep, Log10, MainOutputs, MatchQualifications, MatchVariant, MatchingMode, type MigrateBlockStorageConfig, type MigrationFailure, type MigrationResult, type MigrationSuccess, ModelServices, type MutateStoragePayload, NotFilter, NumericalComparisonFilter, OptionalPlResourceEntry, OrFilter, OutputColumnProvider, OutputColumnProviderOpts, OutputError, PColumnCollection, PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnKeyList, PColumnLazyUniversal, PColumnLazyWithLabel, PColumnPredicate, PColumnResourceMapData, PColumnResourceMapEntry, PFrameImpl, POCExtractAction, PTableKey, PTableParamsV2, type ParamsInput, Patch, PatternFilter, PatternPredicate, PatternPredicateContainSubsequence, PatternPredicateEquals, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlMultiSequenceAlignmentColorSchemeOption, PlMultiSequenceAlignmentModel, PlMultiSequenceAlignmentSettings, PlMultiSequenceAlignmentWidget, PlResourceEntry, PlSelectionModel, PlTableColumnIdJson, Platforma, PlatformaApiVersion, PlatformaExtended, PlatformaFactory, PlatformaSDKVersion, PlatformaV1, PlatformaV2, PlatformaV3, type PluginConfig, type PluginData, PluginDataModel, PluginDataModelBuilder, type PluginDataModelVersions, type PluginFactory, PluginFactoryLike, PluginHandle, PluginInstance, PluginModel, type PluginName, type PluginOutputs, type PluginParams, type PluginPublicOutputs, type PluginRecord, type PluginRegistry, PluginRenderCtx, PrimitiveOrConfig, PrimitiveToCfg, type PublicOutputFieldDef, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RelaxedAxisSelector, RelaxedColumnSelector, RelaxedRecord, RelaxedStringMatchers, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResolveCfgType, ResolveModelServices, ResolveUiServices, ResourceTraversalOps, ResourceType, ResultPool, ResultPoolColumnSnapshotProvider, SdkInfo, ServiceProxy, SimplifiedPColumnSpec, SimplifiedUniversalPColumnEntry, SnapshotColumnProvider, SortedCumulativeSum, Entry as SpecExtractorResult, SplitAxis, StagingOutputs, StdCtx, StdCtxArgsOnly, StringMatcher, TooltipEntry, Trace, TraceEntry, TransformedColumn, TreeNodeAccessor, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, TypedConfig, TypedConfigOrConfigLambda, TypedConfigOrString, UiServices, UiState, Unionize, UniversalColumnOption, UnwrapFutureRef, ValueRank, type VersionedData, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableOptionsV3, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
77
+ export { ActAnd, ActExtractArchiveAndGetURL, ActFlatten, ActGetBlobContent, ActGetBlobContentAsJson, ActGetBlobContentAsString, ActGetDownloadedBlobContent, ActGetField, ActGetFromCtx, ActGetImmediate, ActGetLastLogs, ActGetLogHandle, ActGetOnDemandBlobContent, ActGetProgressLog, ActGetProgressLogWithInfo, ActGetResourceField, ActGetResourceValueAsJson, ActImportProgress, ActIsEmpty, ActIsolate, ActMakeArray, ActMakeObject, ActMapArrayValues, ActMapRecordValues, ActMapResourceFields, ActNot, ActOr, ActionResult, AnchorEntry, AnchoredBuildOptions, AnchoredColumnCollection, AnchoredFindColumnsOptions, AndFilter, AnnotationFilter, AnnotationMode, AnnotationScript, AnnotationScript2, AnnotationScriptUi, AnnotationSpec, AnnotationSpecUi, AnnotationStep, AnnotationStepUi, AnyForm, Args, ArrayColumnProvider, AxesVault, AxisLabelProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockApiV1, BlockApiV2, BlockConfig, BlockConfigV3, BlockConfigV4, BlockDefaultModelServices, BlockDefaultUiServices, BlockModel, BlockModelInfo, BlockModelV3, BlockRenderCtx, BlockServiceFlags, BlockStatePatch, type BlockStorage, BlockStorageFacade, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, type BlockStorageSchemaVersion, BuildDatasetOptions, BuildOptions, CancelSubscription, Cfg, CfgAnd, CfgBlobContent, CfgBlobContentAsJson, CfgBlobContentAsString, CfgDownloadedBlobContent, CfgExtractArchiveAndGetURL, CfgFlatten, CfgGetFromCtx, CfgGetJsonField, CfgGetResourceField, CfgImmediate, CfgImportProgress, CfgIsEmpty, CfgIsolate, CfgLastLogs, CfgLogHandle, CfgMakeArray, CfgMakeObject, CfgMapArrayValues, CfgMapRecordValues, CfgMapResourceFields, CfgNot, CfgOnDemandBlobContent, CfgOr, CfgProgressLog, CfgProgressLogWithInfo, CfgRenderingMode, CfgResourceValueAsJson, Checked, ColumnCollection, ColumnCollectionBuilder, ColumnData, ColumnDataStatus, ColumnMatch, ColumnMatcher, ColumnOrderRule, ColumnProvider, ColumnSelector, ColumnSnapshot, ColumnSnapshotProvider, ColumnSource, ColumnVariant, ColumnVisibilityRule, ColumnsDisplayOptions, ColumnsSelectorConfig, CommonFieldTraverseOps, CommonTraversalOps, ConfAction, ConfigRenderLambda, ConfigRenderLambdaFlags, ConfigResult, CurrentSdkInfo, DataModel, DataModelBuilder, DatasetOption, DatasetSelection, DeriveHref, DeriveLabelsFormatters, DeriveLabelsOptions, Entry, ExpandByPartitionOpts, ExpandByPartitionResult, ExpressionSpec, ExtractAction, ExtractFunctionHandleReturn, ExtractFutureRefType, FieldTraversalStep, FieldType, FilterMatchOptions, FilterSpec, FilterSpecLeaf, FilterSpecNode, FilterSpecOfType, FilterSpecType, FilterSpecUi, FilterUi, FilterUiOfType, FilterUiType, FindColumnsOptions, FormField, FutureRef, GetFieldStep, InferArgsType, InferBlockState, InferBlockStatePatch, InferDataType, InferFactoryData, InferFactoryModelServices, InferFactoryOutputs, InferFactoryParams, InferFactoryUiServices, InferHrefType, InferOutputType, InferOutputsFromConfigs, InferOutputsFromLambdas, InferOutputsType, InferPluginData, InferPluginHandle, InferPluginNames, InferPluginUiEntries, InferRenderFunctionReturn, InferUiState, InferVarTypeSafe, IsNA, It, internal_d_exports as JsRenderInternal, DeriveLabelsOptions as LabelDerivationOps, LinkerStep, Log10, MainOutputs, MatchQualifications, MatchVariant, MatchingMode, type MigrateBlockStorageConfig, type MigrationFailure, type MigrationResult, type MigrationSuccess, ModelServices, type MutateStoragePayload, NotFilter, NumericalComparisonFilter, OptionalPlResourceEntry, OrFilter, OutputColumnProvider, OutputColumnProviderOpts, OutputError, PColumnCollection, PColumnDataUniversal, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnKeyList, PColumnLazyUniversal, PColumnLazyWithLabel, PColumnPredicate, PColumnResourceMapData, PColumnResourceMapEntry, PFrameImpl, POCExtractAction, PTableKey, PTableParamsV2, type ParamsInput, Patch, PatternFilter, PatternPredicate, PatternPredicateContainSubsequence, PatternPredicateEquals, PlDataTableFilterMeta, PlDataTableFilterSpecLeaf, PlDataTableFilters, PlDataTableFiltersWithMeta, PlDataTableGridStateCore, PlDataTableModel, PlDataTableSheet, PlDataTableSheetState, PlDataTableStateV2, PlDataTableStateV2CacheEntry, PlDataTableStateV2Normalized, PlMultiSequenceAlignmentColorSchemeOption, PlMultiSequenceAlignmentModel, PlMultiSequenceAlignmentSettings, PlMultiSequenceAlignmentWidget, PlResourceEntry, PlSelectionModel, PlTableColumnIdJson, Platforma, PlatformaApiVersion, PlatformaExtended, PlatformaFactory, PlatformaSDKVersion, PlatformaV1, PlatformaV2, PlatformaV3, type PluginConfig, type PluginData, PluginDataModel, PluginDataModelBuilder, type PluginDataModelVersions, type PluginFactory, PluginFactoryLike, PluginHandle, PluginInstance, PluginModel, type PluginName, type PluginOutputs, type PluginParams, type PluginPublicOutputs, type PluginRecord, type PluginRegistry, PluginRenderCtx, PrimitiveOrConfig, PrimitiveToCfg, type PublicOutputFieldDef, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RelaxedAxisSelector, RelaxedColumnSelector, RelaxedRecord, RelaxedStringMatchers, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResolveCfgType, ResolveModelServices, ResolveUiServices, ResourceTraversalOps, ResourceType, ResultPool, ResultPoolColumnSnapshotProvider, SdkInfo, ServiceProxy, SimplifiedPColumnSpec, SimplifiedUniversalPColumnEntry, SnapshotColumnProvider, SortedCumulativeSum, Entry as SpecExtractorResult, SplitAxis, StagingOutputs, StdCtx, StdCtxArgsOnly, StringMatcher, TooltipEntry, Trace, TraceEntry, TransformedColumn, TreeNodeAccessor, TypeField, TypeFieldRecord, TypeForm, TypeToLiteral, TypedConfig, TypedConfigOrConfigLambda, TypedConfigOrString, UiServices, UiState, Unionize, UniversalColumnOption, UnwrapFutureRef, ValueRank, type VersionedData, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableOptionsV3, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getNumberOfRows, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { internal_exports } from "./render/internal.js";
11
11
  import { filterDataInfoEntries } from "./render/util/axis_filtering.js";
12
12
  import { deriveDistinctLabels } from "./labels/derive_distinct_labels.js";
13
13
  import { deriveLabels } from "./render/util/label.js";
14
- import { RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./render/util/pcolumn_data.js";
14
+ import { RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./render/util/pcolumn_data.js";
15
15
  import { PColumnCollection } from "./render/util/column_collection.js";
16
16
  import { BLOCK_SERVICE_FLAGS, blockServiceNames } from "./services/block_services.js";
17
17
  import { buildServices, createServiceProxy } from "./services/service_bridge.js";
@@ -65,4 +65,4 @@ import { getAxisUniqueValues, getColumnOrAxisValueLabelsId, getColumnSpecById, g
65
65
  import { getEnvironmentValue } from "./env_value.js";
66
66
  export * from "@milaboratories/pl-model-common";
67
67
  export * from "@milaboratories/pl-error-like";
68
- export { Args, ArrayColumnProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockModel, BlockModelV3, BlockRenderCtx, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, ColumnCollectionBuilder, CurrentSdkInfo, DataModel, DataModelBuilder, FutureRef, It, internal_exports as JsRenderInternal, MainOutputs, OutputColumnProvider, OutputError, PColumnCollection, PFrameImpl, PlatformaSDKVersion, PluginDataModel, PluginDataModelBuilder, PluginInstance, PluginModel, PluginRenderCtx, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RenderCtxBase, RenderCtxLegacy, ResultPool, ResultPoolColumnSnapshotProvider, SnapshotColumnProvider, StagingOutputs, TreeNodeAccessor, UiState, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
68
+ export { Args, ArrayColumnProvider, BLOCK_SERVICE_FLAGS, BLOCK_STORAGE_FACADE_VERSION, BlockModel, BlockModelV3, BlockRenderCtx, BlockStorageFacadeCallbacks, BlockStorageFacadeHandles, ColumnCollectionBuilder, CurrentSdkInfo, DataModel, DataModelBuilder, FutureRef, It, internal_exports as JsRenderInternal, MainOutputs, OutputColumnProvider, OutputError, PColumnCollection, PFrameImpl, PlatformaSDKVersion, PluginDataModel, PluginDataModelBuilder, PluginInstance, PluginModel, PluginRenderCtx, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, RenderCtxBase, RenderCtxLegacy, ResultPool, ResultPoolColumnSnapshotProvider, SnapshotColumnProvider, StagingOutputs, TreeNodeAccessor, UiState, allPColumnsReady, and, blockServiceNames, buildDatasetOptions, buildRefMap, buildServices, collectCtxColumnSnapshotProviders, compileAnnotationScript, compileFilter, compileFilters, convertColumnSelectorToMultiColumnSelector, convertFilterSpecsToExpressionSpecs, convertFilterUiToExpressionImpl, convertFilterUiToExpressions, convertOrParsePColumnData, convertRelaxedAxisSelectorToMultiAxisSelector, convertRelaxedColumnSelectorToMultiColumnSelector, createBlockStorage, createColumnSnapshot, createDatasetSelection, createDefaultPTableParams, createPFrameForGraphs, createPlDataTable, createPlDataTableSheet, createPlDataTableStateV2, createPlDataTableV2, createPlDataTableV3, createPlSelectionModel, createReadyColumnData, createRowSelectionColumn, createServiceProxy, deriveDataFromStorage, deriveDistinctLabels, deriveDistinctTooltips, deriveLabels, discoverTableColumnSnaphots, distillFilterSpec, downgradeCfgOrLambda, enrichCompatible, expandByPartition, extractArchiveAndGetURL, extractConfig, filterDataInfoEntries, filterMatchesToOptions, filterSpecToSpecQueryExpr, findFilterColumns, flatten, fromPlOption, fromPlRef, getAllRelatedColumns, getAvailableWithLinkersAxes, getAxisUniqueValues, getBlobContent, getBlobContentAsJson, getBlobContentAsString, getColumnOrAxisValueLabelsId, getColumnSpecById, getColumnUniqueValues, getColumnsFull, getDownloadedBlobContent, getEffectiveVisibility, getEnvironmentValue, getFromCfg, getImmediate, getImportProgress, getJsonField, getLastLogs, getLogHandle, getNumberOfRows, getOnDemandBlobContent, getOrderPriority, getPartitionKeysList, getPlatformaApiVersion, getPluginData, getProgressLog, getProgressLogWithInfo, getRawPlatformaInstance, getRelatedColumns, getRequestColumnsFromSelectedSources, getResourceField, getResourceValueAsJson, getService, getSingleColumnData, getStorageData, getUniquePartitionKeys, getUniqueSourceValuesWithLabels, ifDef, isBlockStorage, isColumnHidden, isColumnOptional, isColumnSnapshotProvider, isConfigLambda, isDatasetSelection, isEmpty, isHiddenFromGraphColumn, isHiddenFromUIColumn, isPColumnReady, isPluginOutputKey, isolate, makeArray, makeObject, mapArrayValues, mapRecordValues, mapResourceFields, migrateBlockStorage, normalizeBlockStorage, not, or, parsePColumnData, parseResourceMap, pluginOutputKey, pluginOutputPrefix, readOutput, registerFacadeCallbacks, toColumnSnapshotProvider, unreachable, updateStorageData, upgradePlDataTableStateV2, wrapOutputs };
package/dist/package.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "1.78.16";
2
+ var version = "1.79.2";
3
3
  //#endregion
4
4
  Object.defineProperty(exports, "version", {
5
5
  enumerable: true,
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "1.78.16";
2
+ var version = "1.79.2";
3
3
  //#endregion
4
4
  export { version };
5
5
 
@@ -6,5 +6,5 @@ import { DeriveLabelsOptions, Entry, Trace } from "../labels/derive_distinct_lab
6
6
  import { deriveLabels } from "./util/label.js";
7
7
  import { AxisLabelProvider, ColumnProvider, PColumnCollection, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnLazyUniversal, PColumnLazyWithLabel } from "./util/column_collection.js";
8
8
  import { BlockRenderCtx, InferRenderFunctionReturn, PluginRenderCtx, RenderCtx, RenderCtxBase, RenderCtxLegacy, RenderFunction, RenderFunctionLegacy, ResultPool, UniversalColumnOption, UnwrapFutureRef } from "./api.js";
9
- import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./util/pcolumn_data.js";
9
+ import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./util/pcolumn_data.js";
10
10
  import { filterDataInfoEntries } from "./util/axis_filtering.js";
@@ -1,5 +1,5 @@
1
1
  import { DeriveLabelsOptions, Entry, Trace } from "../../labels/derive_distinct_labels.js";
2
2
  import { deriveLabels } from "./label.js";
3
3
  import { AxisLabelProvider, ColumnProvider, PColumnCollection, PColumnEntryUniversal, PColumnEntryWithLabel, PColumnLazyUniversal, PColumnLazyWithLabel } from "./column_collection.js";
4
- import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./pcolumn_data.js";
4
+ import { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap } from "./pcolumn_data.js";
5
5
  import { filterDataInfoEntries } from "./axis_filtering.js";
@@ -331,6 +331,47 @@ function convertOrParsePColumnData(acc) {
331
331
  if (acc instanceof require_accessor.TreeNodeAccessor) return parsePColumnData(acc);
332
332
  throw new Error(`Unexpected input type: ${typeof acc}`);
333
333
  }
334
+ /**
335
+ * Returns the total number of rows in a PColumn, or `undefined` when the count
336
+ * cannot be determined without downloading data blobs.
337
+ *
338
+ * Derivable cases:
339
+ * - Inline values ({@link PColumnValues}): one entry per row.
340
+ * - Inline `Json` {@link DataInfo}: one entry per row.
341
+ * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from
342
+ * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,
343
+ * read from the chunk resource metadata without downloading the parquet files.
344
+ *
345
+ * Returns `undefined` when:
346
+ * - the data is `undefined` or still computing / not ready,
347
+ * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts
348
+ * live inside opaque blobs and are not readable here),
349
+ * - any parquet chunk is missing `stats.numberOfRows`.
350
+ *
351
+ * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which
352
+ * are axis-tuple lengths, not row counts.
353
+ */
354
+ function getNumberOfRows(data) {
355
+ if (data === void 0) return void 0;
356
+ if (Array.isArray(data)) return data.length;
357
+ const entries = convertOrParsePColumnData(data);
358
+ if (entries === void 0) return void 0;
359
+ switch (entries.type) {
360
+ case "Json": return entries.data.length;
361
+ case "JsonPartitioned":
362
+ case "BinaryPartitioned": return;
363
+ case "ParquetPartitioned": {
364
+ let total = 0;
365
+ for (const { value } of entries.parts) {
366
+ const rows = value.getDataAsJsonOrUndefined()?.stats?.numberOfRows;
367
+ if (typeof rows !== "number") return void 0;
368
+ total += rows;
369
+ }
370
+ return total;
371
+ }
372
+ default: (0, _milaboratories_pl_model_common.assertNever)(entries);
373
+ }
374
+ }
334
375
  function isPColumnReady(c) {
335
376
  const isValues = (d) => Array.isArray(d);
336
377
  const isAccessor = (d) => d instanceof require_accessor.TreeNodeAccessor;
@@ -356,6 +397,7 @@ exports.RT_RESOURCE_MAP = RT_RESOURCE_MAP;
356
397
  exports.RT_RESOURCE_MAP_PARTITIONED = RT_RESOURCE_MAP_PARTITIONED;
357
398
  exports.allPColumnsReady = allPColumnsReady;
358
399
  exports.convertOrParsePColumnData = convertOrParsePColumnData;
400
+ exports.getNumberOfRows = getNumberOfRows;
359
401
  exports.getPartitionKeysList = getPartitionKeysList;
360
402
  exports.getUniquePartitionKeys = getUniquePartitionKeys;
361
403
  exports.isPColumnReady = isPColumnReady;
@@ -1 +1 @@
1
- {"version":3,"file":"pcolumn_data.cjs","names":["TreeNodeAccessor"],"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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"}
1
+ {"version":3,"file":"pcolumn_data.cjs","names":["TreeNodeAccessor"],"sources":["../../../src/render/util/pcolumn_data.ts"],"sourcesContent":["import type {\n DataInfo,\n ParquetChunkMetadata,\n PartitionedDataInfoEntries,\n PColumn,\n PColumnLazy,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport {\n assertNever,\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\n/**\n * Returns the total number of rows in a PColumn, or `undefined` when the count\n * cannot be determined without downloading data blobs.\n *\n * Derivable cases:\n * - Inline values ({@link PColumnValues}): one entry per row.\n * - Inline `Json` {@link DataInfo}: one entry per row.\n * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from\n * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,\n * read from the chunk resource metadata without downloading the parquet files.\n *\n * Returns `undefined` when:\n * - the data is `undefined` or still computing / not ready,\n * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts\n * live inside opaque blobs and are not readable here),\n * - any parquet chunk is missing `stats.numberOfRows`.\n *\n * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which\n * are axis-tuple lengths, not row counts.\n */\nexport function getNumberOfRows(data: PColumnDataUniversal | undefined): number | undefined {\n if (data === undefined) return undefined;\n\n // Inline explicit values: one entry per row.\n if (Array.isArray(data)) return data.length;\n\n const entries = convertOrParsePColumnData(data);\n if (entries === undefined) return undefined;\n\n switch (entries.type) {\n case \"Json\":\n // Inline Json: one entry per row.\n return entries.data.length;\n\n case \"JsonPartitioned\":\n case \"BinaryPartitioned\":\n // Per-part row counts live inside opaque blobs; not knowable without download.\n return undefined;\n\n case \"ParquetPartitioned\": {\n let total = 0;\n for (const { value } of entries.parts) {\n // The part accessor points at a ParquetChunk resource whose JSON payload\n // is ParquetChunkMetadata. Reading it does not download the parquet file\n // (the file lives in a separate `blob` sub-field of the chunk resource).\n const rows = value.getDataAsJsonOrUndefined<ParquetChunkMetadata>()?.stats?.numberOfRows;\n // stats / numberOfRows are Partial: if any chunk lacks it, the total is unknowable.\n if (typeof rows !== \"number\") return undefined;\n total += rows;\n }\n return total;\n }\n\n default:\n assertNever(entries);\n }\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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"}
@@ -47,8 +47,29 @@ declare function parsePColumnData(acc: TreeNodeAccessor | undefined, keyPrefix?:
47
47
  * @returns The data in DataInfoEntries format, or undefined if the input was undefined or data is not ready.
48
48
  */
49
49
  declare function convertOrParsePColumnData(acc: TreeNodeAccessor | DataInfoEntries<TreeNodeAccessor> | DataInfo<TreeNodeAccessor> | undefined): DataInfoEntries<TreeNodeAccessor> | undefined;
50
+ /**
51
+ * Returns the total number of rows in a PColumn, or `undefined` when the count
52
+ * cannot be determined without downloading data blobs.
53
+ *
54
+ * Derivable cases:
55
+ * - Inline values ({@link PColumnValues}): one entry per row.
56
+ * - Inline `Json` {@link DataInfo}: one entry per row.
57
+ * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from
58
+ * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,
59
+ * read from the chunk resource metadata without downloading the parquet files.
60
+ *
61
+ * Returns `undefined` when:
62
+ * - the data is `undefined` or still computing / not ready,
63
+ * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts
64
+ * live inside opaque blobs and are not readable here),
65
+ * - any parquet chunk is missing `stats.numberOfRows`.
66
+ *
67
+ * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which
68
+ * are axis-tuple lengths, not row counts.
69
+ */
70
+ declare function getNumberOfRows(data: PColumnDataUniversal | undefined): number | undefined;
50
71
  declare function isPColumnReady(c: PColumn<undefined | PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>): c is PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal>;
51
72
  declare function allPColumnsReady(columns: (PColumn<undefined | PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>)[]): columns is (PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal>)[];
52
73
  //#endregion
53
- export { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap };
74
+ export { PColumnKeyList, PColumnResourceMapData, PColumnResourceMapEntry, RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap };
54
75
  //# sourceMappingURL=pcolumn_data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pcolumn_data.d.ts","names":[],"sources":["../../../src/render/util/pcolumn_data.ts"],"mappings":";;;;;cAsBa,eAAA;AAAA,cACA,2BAAA;AAAA,cAEA,mBAAA;AAAA,cACA,qBAAA;AAAA,cACA,sBAAA;AAAA,cAGA,yBAAA;AAAA,cACA,2BAAA;AAAA,cACA,4BAAA;AAAA,KAED,uBAAA;EACV,GAAA,EAAK,UAAA;EACL,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,sBAAA;EACV,UAAA;EACA,IAAA,EAAM,uBAAA,CAAwB,CAAA;AAAA;AAAA,iBA+ChB,gBAAA,GAAA,CACd,GAAA,EAAK,gBAAA,cACL,cAAA,GAAiB,GAAA,EAAK,gBAAA,KAAqB,CAAA,cAC3C,oBAAA,UACC,sBAAA,CAAuB,WAAA,CAAY,CAAA;AAAA,iBACtB,gBAAA,GAAA,CACd,GAAA,EAAK,gBAAA,cACL,cAAA,GAAiB,GAAA,EAAK,gBAAA,KAAqB,CAAA,cAC3C,oBAAA,SACC,sBAAA,CAAuB,CAAA;AAAA,KAWd,cAAA;EAlFyD,oBAoFnE,IAAA,EAAM,UAAA,IAnFK;EAqFX,SAAA;AAAA;;iBAec,oBAAA,CACd,GAAA,EAAK,gBAAA,eACJ,cAAA;AAnGH;AAAA,iBA4MgB,sBAAA,CAAuB,GAAA,EAAK,eAAA;AAAA,iBAC5B,sBAAA,CACd,GAAA,EAAK,eAAA,YAA2B,gBAAA;;;AA7MlC;;;;;AACA;;iBAqPgB,gBAAA,CACd,GAAA,EAAK,gBAAA,cACL,SAAA,GAAW,UAAA,GACV,0BAAA,CAA2B,gBAAA;;;AAtP9B;;;;iBAifgB,yBAAA,CACd,GAAA,EACI,gBAAA,GACA,eAAA,CAAgB,gBAAA,IAChB,QAAA,CAAS,gBAAA,gBAEZ,eAAA,CAAgB,gBAAA;AAAA,iBAUH,cAAA,CACd,CAAA,EAAG,OAAA,aAAoB,oBAAA,IAAwB,WAAA,aAAwB,oBAAA,IACtE,CAAA,IAAK,OAAA,CAAQ,oBAAA,IAAwB,WAAA,CAAY,oBAAA;AAAA,iBAmBpC,gBAAA,CACd,OAAA,GACI,OAAA,aAAoB,oBAAA,IACpB,WAAA,aAAwB,oBAAA,OAE3B,OAAA,KAAY,OAAA,CAAQ,oBAAA,IAAwB,WAAA,CAAY,oBAAA"}
1
+ {"version":3,"file":"pcolumn_data.d.ts","names":[],"sources":["../../../src/render/util/pcolumn_data.ts"],"mappings":";;;;;cAwBa,eAAA;AAAA,cACA,2BAAA;AAAA,cAEA,mBAAA;AAAA,cACA,qBAAA;AAAA,cACA,sBAAA;AAAA,cAGA,yBAAA;AAAA,cACA,2BAAA;AAAA,cACA,4BAAA;AAAA,KAED,uBAAA;EACV,GAAA,EAAK,UAAA;EACL,KAAA,EAAO,CAAA;AAAA;AAAA,KAGG,sBAAA;EACV,UAAA;EACA,IAAA,EAAM,uBAAA,CAAwB,CAAA;AAAA;AAAA,iBA+ChB,gBAAA,GAAA,CACd,GAAA,EAAK,gBAAA,cACL,cAAA,GAAiB,GAAA,EAAK,gBAAA,KAAqB,CAAA,cAC3C,oBAAA,UACC,sBAAA,CAAuB,WAAA,CAAY,CAAA;AAAA,iBACtB,gBAAA,GAAA,CACd,GAAA,EAAK,gBAAA,cACL,cAAA,GAAiB,GAAA,EAAK,gBAAA,KAAqB,CAAA,cAC3C,oBAAA,SACC,sBAAA,CAAuB,CAAA;AAAA,KAWd,cAAA;EAlFyD,oBAoFnE,IAAA,EAAM,UAAA,IAnFK;EAqFX,SAAA;AAAA;;iBAec,oBAAA,CACd,GAAA,EAAK,gBAAA,eACJ,cAAA;AAnGH;AAAA,iBA4MgB,sBAAA,CAAuB,GAAA,EAAK,eAAA;AAAA,iBAC5B,sBAAA,CACd,GAAA,EAAK,eAAA,YAA2B,gBAAA;;;AA7MlC;;;;;AACA;;iBAqPgB,gBAAA,CACd,GAAA,EAAK,gBAAA,cACL,SAAA,GAAW,UAAA,GACV,0BAAA,CAA2B,gBAAA;;;AAtP9B;;;;iBAifgB,yBAAA,CACd,GAAA,EACI,gBAAA,GACA,eAAA,CAAgB,gBAAA,IAChB,QAAA,CAAS,gBAAA,gBAEZ,eAAA,CAAgB,gBAAA;;;;;;;AAlfnB;;;;;;;;;;;AAiDA;;;iBA+dgB,eAAA,CAAgB,IAAA,EAAM,oBAAA;AAAA,iBAsCtB,cAAA,CACd,CAAA,EAAG,OAAA,aAAoB,oBAAA,IAAwB,WAAA,aAAwB,oBAAA,IACtE,CAAA,IAAK,OAAA,CAAQ,oBAAA,IAAwB,WAAA,CAAY,oBAAA;AAAA,iBAmBpC,gBAAA,CACd,OAAA,GACI,OAAA,aAAoB,oBAAA,IACpB,WAAA,aAAwB,oBAAA,OAE3B,OAAA,KAAY,OAAA,CAAQ,oBAAA,IAAwB,WAAA,CAAY,oBAAA"}
@@ -1,5 +1,5 @@
1
1
  import { TreeNodeAccessor } from "../accessor.js";
2
- import { dataInfoToEntries, isDataInfo, isDataInfoEntries, visitDataInfo } from "@milaboratories/pl-model-common";
2
+ import { assertNever, dataInfoToEntries, isDataInfo, isDataInfoEntries, visitDataInfo } from "@milaboratories/pl-model-common";
3
3
  //#region src/render/util/pcolumn_data.ts
4
4
  const PCD_PREFIX = "PColumnData/";
5
5
  const RT_RESOURCE_MAP = PCD_PREFIX + "ResourceMap";
@@ -330,6 +330,47 @@ function convertOrParsePColumnData(acc) {
330
330
  if (acc instanceof TreeNodeAccessor) return parsePColumnData(acc);
331
331
  throw new Error(`Unexpected input type: ${typeof acc}`);
332
332
  }
333
+ /**
334
+ * Returns the total number of rows in a PColumn, or `undefined` when the count
335
+ * cannot be determined without downloading data blobs.
336
+ *
337
+ * Derivable cases:
338
+ * - Inline values ({@link PColumnValues}): one entry per row.
339
+ * - Inline `Json` {@link DataInfo}: one entry per row.
340
+ * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from
341
+ * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,
342
+ * read from the chunk resource metadata without downloading the parquet files.
343
+ *
344
+ * Returns `undefined` when:
345
+ * - the data is `undefined` or still computing / not ready,
346
+ * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts
347
+ * live inside opaque blobs and are not readable here),
348
+ * - any parquet chunk is missing `stats.numberOfRows`.
349
+ *
350
+ * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which
351
+ * are axis-tuple lengths, not row counts.
352
+ */
353
+ function getNumberOfRows(data) {
354
+ if (data === void 0) return void 0;
355
+ if (Array.isArray(data)) return data.length;
356
+ const entries = convertOrParsePColumnData(data);
357
+ if (entries === void 0) return void 0;
358
+ switch (entries.type) {
359
+ case "Json": return entries.data.length;
360
+ case "JsonPartitioned":
361
+ case "BinaryPartitioned": return;
362
+ case "ParquetPartitioned": {
363
+ let total = 0;
364
+ for (const { value } of entries.parts) {
365
+ const rows = value.getDataAsJsonOrUndefined()?.stats?.numberOfRows;
366
+ if (typeof rows !== "number") return void 0;
367
+ total += rows;
368
+ }
369
+ return total;
370
+ }
371
+ default: assertNever(entries);
372
+ }
373
+ }
333
374
  function isPColumnReady(c) {
334
375
  const isValues = (d) => Array.isArray(d);
335
376
  const isAccessor = (d) => d instanceof TreeNodeAccessor;
@@ -345,6 +386,6 @@ function allPColumnsReady(columns) {
345
386
  return columns.every(isPColumnReady);
346
387
  }
347
388
  //#endregion
348
- export { RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap };
389
+ export { RT_BINARY_PARTITIONED, RT_BINARY_SUPER_PARTITIONED, RT_JSON_PARTITIONED, RT_JSON_SUPER_PARTITIONED, RT_PARQUET_PARTITIONED, RT_PARQUET_SUPER_PARTITIONED, RT_RESOURCE_MAP, RT_RESOURCE_MAP_PARTITIONED, allPColumnsReady, convertOrParsePColumnData, getNumberOfRows, getPartitionKeysList, getUniquePartitionKeys, isPColumnReady, parsePColumnData, parseResourceMap };
349
390
 
350
391
  //# sourceMappingURL=pcolumn_data.js.map
@@ -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<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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"}
1
+ {"version":3,"file":"pcolumn_data.js","names":[],"sources":["../../../src/render/util/pcolumn_data.ts"],"sourcesContent":["import type {\n DataInfo,\n ParquetChunkMetadata,\n PartitionedDataInfoEntries,\n PColumn,\n PColumnLazy,\n PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport {\n assertNever,\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\n/**\n * Returns the total number of rows in a PColumn, or `undefined` when the count\n * cannot be determined without downloading data blobs.\n *\n * Derivable cases:\n * - Inline values ({@link PColumnValues}): one entry per row.\n * - Inline `Json` {@link DataInfo}: one entry per row.\n * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from\n * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,\n * read from the chunk resource metadata without downloading the parquet files.\n *\n * Returns `undefined` when:\n * - the data is `undefined` or still computing / not ready,\n * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts\n * live inside opaque blobs and are not readable here),\n * - any parquet chunk is missing `stats.numberOfRows`.\n *\n * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which\n * are axis-tuple lengths, not row counts.\n */\nexport function getNumberOfRows(data: PColumnDataUniversal | undefined): number | undefined {\n if (data === undefined) return undefined;\n\n // Inline explicit values: one entry per row.\n if (Array.isArray(data)) return data.length;\n\n const entries = convertOrParsePColumnData(data);\n if (entries === undefined) return undefined;\n\n switch (entries.type) {\n case \"Json\":\n // Inline Json: one entry per row.\n return entries.data.length;\n\n case \"JsonPartitioned\":\n case \"BinaryPartitioned\":\n // Per-part row counts live inside opaque blobs; not knowable without download.\n return undefined;\n\n case \"ParquetPartitioned\": {\n let total = 0;\n for (const { value } of entries.parts) {\n // The part accessor points at a ParquetChunk resource whose JSON payload\n // is ParquetChunkMetadata. Reading it does not download the parquet file\n // (the file lives in a separate `blob` sub-field of the chunk resource).\n const rows = value.getDataAsJsonOrUndefined<ParquetChunkMetadata>()?.stats?.numberOfRows;\n // stats / numberOfRows are Partial: if any chunk lacks it, the total is unknowable.\n if (typeof rows !== \"number\") return undefined;\n total += rows;\n }\n return total;\n }\n\n default:\n assertNever(entries);\n }\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.78.16",
3
+ "version": "1.79.2",
4
4
  "description": "Platforma.bio SDK / Block Model",
5
5
  "files": [
6
6
  "./dist/**/*",
@@ -31,20 +31,20 @@
31
31
  "utility-types": "^3.11.0",
32
32
  "zod": "~3.25.76",
33
33
  "@milaboratories/helpers": "1.14.2",
34
+ "@milaboratories/pl-model-common": "1.46.1",
34
35
  "@milaboratories/pl-error-like": "1.12.10",
35
- "@milaboratories/pl-model-common": "1.46.0",
36
- "@milaboratories/pl-model-middle-layer": "1.30.3",
37
- "@milaboratories/ptabler-expression-js": "1.2.29"
36
+ "@milaboratories/pl-model-middle-layer": "1.30.4",
37
+ "@milaboratories/ptabler-expression-js": "1.2.30"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@vitest/coverage-istanbul": "^4.1.3",
41
41
  "fast-json-patch": "^3.1.1",
42
42
  "typescript": "~5.9.3",
43
43
  "vitest": "^4.1.3",
44
- "@milaboratories/pf-driver": "1.7.7",
45
44
  "@milaboratories/build-configs": "2.0.0",
46
45
  "@milaboratories/ts-builder": "1.5.0",
47
- "@milaboratories/pf-spec-driver": "1.4.9",
46
+ "@milaboratories/pf-spec-driver": "1.4.10",
47
+ "@milaboratories/pf-driver": "1.7.8",
48
48
  "@milaboratories/ts-configs": "1.2.3"
49
49
  },
50
50
  "scripts": {
@@ -0,0 +1,200 @@
1
+ import { afterEach, expect, test, vi } from "vitest";
2
+ import type {
3
+ DataInfo,
4
+ ParquetChunkMetadata,
5
+ PColumnValues,
6
+ } from "@milaboratories/pl-model-common";
7
+ import * as internal from "../../internal";
8
+ import type { AccessorHandle } from "../internal";
9
+ import { TreeNodeAccessor } from "../accessor";
10
+ import {
11
+ getNumberOfRows,
12
+ RT_JSON_PARTITIONED,
13
+ RT_PARQUET_PARTITIONED,
14
+ RT_PARQUET_SUPER_PARTITIONED,
15
+ } from "./pcolumn_data";
16
+
17
+ type RenderCtx = ReturnType<typeof internal.getCfgRenderCtx>;
18
+
19
+ /**
20
+ * Fake resource in a mocked resource tree.
21
+ * - `type` — resource type name (e.g. {@link RT_PARQUET_PARTITIONED}).
22
+ * - `data` — the resource's own JSON payload (what `getDataAsString` returns).
23
+ * For a ParquetChunk resource this is the {@link ParquetChunkMetadata}.
24
+ * - `fields` — input fields: stringified partition key → child handle.
25
+ * - `ready` — readiness flag (default true).
26
+ */
27
+ type FakeResource = {
28
+ type: string;
29
+ data?: unknown;
30
+ fields?: Record<string, string>;
31
+ ready?: boolean;
32
+ };
33
+
34
+ /**
35
+ * Builds a handle-dispatched render context over a fake resource tree, so a
36
+ * `TreeNodeAccessor` rooted at `topHandle` walks real partition fields and reads
37
+ * real chunk metadata — the same path a parquet PColumn takes at runtime.
38
+ */
39
+ function accessorOver(tree: Record<string, FakeResource>, topHandle: string): TreeNodeAccessor {
40
+ const get = (h: AccessorHandle): FakeResource => {
41
+ const r = tree[h as string];
42
+ if (r === undefined) throw new Error(`no fake resource for handle ${String(h)}`);
43
+ return r;
44
+ };
45
+ const ctx: Partial<RenderCtx> = {
46
+ getIsReadyOrError: (h) => get(h).ready ?? true,
47
+ getError: () => undefined,
48
+ getResourceType: (h) => ({ name: get(h).type, version: "1" }),
49
+ getInputsLocked: () => true,
50
+ getDataAsString: (h) => {
51
+ const data = get(h).data;
52
+ return data === undefined ? undefined : JSON.stringify(data);
53
+ },
54
+ listInputFields: (h) => Object.keys(get(h).fields ?? {}),
55
+ resolveWithCommon: (h, _common, ...steps) => {
56
+ const step = steps[0];
57
+ const field = typeof step === "string" ? step : step.field;
58
+ return get(h).fields?.[field] as AccessorHandle | undefined;
59
+ },
60
+ };
61
+ vi.spyOn(internal, "getCfgRenderCtx").mockReturnValue(ctx as RenderCtx);
62
+ return new TreeNodeAccessor(topHandle as AccessorHandle, []);
63
+ }
64
+
65
+ /** Realistic ParquetChunk resource payload with a row count. */
66
+ function chunkMeta(numberOfRows: number): ParquetChunkMetadata {
67
+ return {
68
+ dataDigest: `digest-${numberOfRows}`,
69
+ stats: {
70
+ numberOfRows,
71
+ size: { axes: [8 * numberOfRows], column: 4 * numberOfRows },
72
+ },
73
+ };
74
+ }
75
+
76
+ afterEach(() => {
77
+ vi.restoreAllMocks();
78
+ });
79
+
80
+ test("getNumberOfRows sums chunk row counts for a real parquet partitioned column", () => {
81
+ // Tree: ParquetPartitioned root with two partition fields, each pointing at a
82
+ // ParquetChunk resource whose own JSON payload carries stats.numberOfRows.
83
+ const acc = accessorOver(
84
+ {
85
+ top: {
86
+ type: RT_PARQUET_PARTITIONED,
87
+ data: { partitionKeyLength: 1 },
88
+ fields: { '["s1"]': "chunkA", '["s2"]': "chunkB" },
89
+ },
90
+ chunkA: { type: "PColumnData/ParquetChunk", data: chunkMeta(100) },
91
+ chunkB: { type: "PColumnData/ParquetChunk", data: chunkMeta(50) },
92
+ },
93
+ "top",
94
+ );
95
+
96
+ expect(getNumberOfRows(acc)).toBe(150);
97
+ });
98
+
99
+ test("getNumberOfRows sums across super partitions for a parquet super-partitioned column", () => {
100
+ const acc = accessorOver(
101
+ {
102
+ topSuper: {
103
+ type: RT_PARQUET_SUPER_PARTITIONED,
104
+ data: { superPartitionKeyLength: 1, partitionKeyLength: 1 },
105
+ fields: { '["g1"]': "innerP", '["g2"]': "innerQ" },
106
+ },
107
+ innerP: {
108
+ type: RT_PARQUET_PARTITIONED,
109
+ data: { partitionKeyLength: 1 },
110
+ fields: { '["s1"]': "chunkA" },
111
+ },
112
+ innerQ: {
113
+ type: RT_PARQUET_PARTITIONED,
114
+ data: { partitionKeyLength: 1 },
115
+ fields: { '["s1"]': "chunkB", '["s2"]': "chunkC" },
116
+ },
117
+ chunkA: { type: "PColumnData/ParquetChunk", data: chunkMeta(10) },
118
+ chunkB: { type: "PColumnData/ParquetChunk", data: chunkMeta(20) },
119
+ chunkC: { type: "PColumnData/ParquetChunk", data: chunkMeta(30) },
120
+ },
121
+ "topSuper",
122
+ );
123
+
124
+ expect(getNumberOfRows(acc)).toBe(60);
125
+ });
126
+
127
+ test("getNumberOfRows returns undefined when any parquet chunk lacks stats.numberOfRows", () => {
128
+ const acc = accessorOver(
129
+ {
130
+ top: {
131
+ type: RT_PARQUET_PARTITIONED,
132
+ data: { partitionKeyLength: 1 },
133
+ fields: { '["s1"]': "chunkA", '["s2"]': "chunkB" },
134
+ },
135
+ chunkA: { type: "PColumnData/ParquetChunk", data: chunkMeta(100) },
136
+ // stats omitted entirely (it is Partial on the chunk metadata).
137
+ chunkB: { type: "PColumnData/ParquetChunk", data: { dataDigest: "no-stats" } },
138
+ },
139
+ "top",
140
+ );
141
+
142
+ expect(getNumberOfRows(acc)).toBeUndefined();
143
+ });
144
+
145
+ test("getNumberOfRows returns undefined while a parquet column is still computing", () => {
146
+ const acc = accessorOver(
147
+ {
148
+ top: {
149
+ type: RT_PARQUET_PARTITIONED,
150
+ data: { partitionKeyLength: 1 },
151
+ fields: { '["s1"]': "chunkA" },
152
+ ready: false,
153
+ },
154
+ chunkA: { type: "PColumnData/ParquetChunk", data: chunkMeta(100) },
155
+ },
156
+ "top",
157
+ );
158
+
159
+ expect(getNumberOfRows(acc)).toBeUndefined();
160
+ });
161
+
162
+ test("getNumberOfRows returns undefined for JsonPartitioned (counts live in opaque blobs)", () => {
163
+ const acc = accessorOver(
164
+ {
165
+ top: {
166
+ type: RT_JSON_PARTITIONED,
167
+ data: { partitionKeyLength: 1 },
168
+ fields: { '["s1"]': "blobA", '["s2"]': "blobB" },
169
+ },
170
+ blobA: { type: "Blob", data: {} },
171
+ blobB: { type: "Blob", data: {} },
172
+ },
173
+ "top",
174
+ );
175
+
176
+ expect(getNumberOfRows(acc)).toBeUndefined();
177
+ });
178
+
179
+ test("getNumberOfRows counts entries of an inline Json DataInfo", () => {
180
+ const json: DataInfo<TreeNodeAccessor> = {
181
+ type: "Json",
182
+ keyLength: 1,
183
+ data: { '["a"]': 1, '["b"]': 2, '["c"]': 3 },
184
+ };
185
+
186
+ expect(getNumberOfRows(json)).toBe(3);
187
+ });
188
+
189
+ test("getNumberOfRows counts inline explicit values", () => {
190
+ const values: PColumnValues = [
191
+ { key: ["a"], val: 1 },
192
+ { key: ["b"], val: 2 },
193
+ ];
194
+
195
+ expect(getNumberOfRows(values)).toBe(2);
196
+ });
197
+
198
+ test("getNumberOfRows returns undefined for undefined data", () => {
199
+ expect(getNumberOfRows(undefined)).toBeUndefined();
200
+ });
@@ -1,11 +1,13 @@
1
1
  import type {
2
2
  DataInfo,
3
+ ParquetChunkMetadata,
3
4
  PartitionedDataInfoEntries,
4
5
  PColumn,
5
6
  PColumnLazy,
6
7
  PColumnValues,
7
8
  } from "@milaboratories/pl-model-common";
8
9
  import {
10
+ assertNever,
9
11
  dataInfoToEntries,
10
12
  isDataInfo,
11
13
  isDataInfoEntries,
@@ -545,6 +547,64 @@ export function convertOrParsePColumnData(
545
547
  throw new Error(`Unexpected input type: ${typeof acc}`);
546
548
  }
547
549
 
550
+ /**
551
+ * Returns the total number of rows in a PColumn, or `undefined` when the count
552
+ * cannot be determined without downloading data blobs.
553
+ *
554
+ * Derivable cases:
555
+ * - Inline values ({@link PColumnValues}): one entry per row.
556
+ * - Inline `Json` {@link DataInfo}: one entry per row.
557
+ * - Parquet (`ParquetPartitioned` / `ParquetSuperPartitioned`): summed from
558
+ * each chunk's precomputed {@link ParquetChunkMetadata.stats} `numberOfRows`,
559
+ * read from the chunk resource metadata without downloading the parquet files.
560
+ *
561
+ * Returns `undefined` when:
562
+ * - the data is `undefined` or still computing / not ready,
563
+ * - the data is `JsonPartitioned` or `BinaryPartitioned` (per-part row counts
564
+ * live inside opaque blobs and are not readable here),
565
+ * - any parquet chunk is missing `stats.numberOfRows`.
566
+ *
567
+ * Note: do not confuse row count with `keyLength` / `partitionKeyLength`, which
568
+ * are axis-tuple lengths, not row counts.
569
+ */
570
+ export function getNumberOfRows(data: PColumnDataUniversal | undefined): number | undefined {
571
+ if (data === undefined) return undefined;
572
+
573
+ // Inline explicit values: one entry per row.
574
+ if (Array.isArray(data)) return data.length;
575
+
576
+ const entries = convertOrParsePColumnData(data);
577
+ if (entries === undefined) return undefined;
578
+
579
+ switch (entries.type) {
580
+ case "Json":
581
+ // Inline Json: one entry per row.
582
+ return entries.data.length;
583
+
584
+ case "JsonPartitioned":
585
+ case "BinaryPartitioned":
586
+ // Per-part row counts live inside opaque blobs; not knowable without download.
587
+ return undefined;
588
+
589
+ case "ParquetPartitioned": {
590
+ let total = 0;
591
+ for (const { value } of entries.parts) {
592
+ // The part accessor points at a ParquetChunk resource whose JSON payload
593
+ // is ParquetChunkMetadata. Reading it does not download the parquet file
594
+ // (the file lives in a separate `blob` sub-field of the chunk resource).
595
+ const rows = value.getDataAsJsonOrUndefined<ParquetChunkMetadata>()?.stats?.numberOfRows;
596
+ // stats / numberOfRows are Partial: if any chunk lacks it, the total is unknowable.
597
+ if (typeof rows !== "number") return undefined;
598
+ total += rows;
599
+ }
600
+ return total;
601
+ }
602
+
603
+ default:
604
+ assertNever(entries);
605
+ }
606
+ }
607
+
548
608
  export function isPColumnReady(
549
609
  c: PColumn<undefined | PColumnDataUniversal> | PColumnLazy<undefined | PColumnDataUniversal>,
550
610
  ): c is PColumn<PColumnDataUniversal> | PColumnLazy<PColumnDataUniversal> {