Skip to content

Commit

Permalink
fix(importDataSources): return only loadable results
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulHax committed Nov 3, 2023
1 parent b75e531 commit ea61baf
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 30 deletions.
28 changes: 24 additions & 4 deletions src/io/import/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ import { ARCHIVE_FILE_TYPES } from '@/src/io/mimeTypes';
import { Awaitable } from '@vueuse/core';
import { Config } from '@/src/io/import/configSchema';

export interface ImportResult {
interface DataResult {
dataSource: DataSource;
dataID?: string;
dataType?: 'image' | 'dicom' | 'model';
config?: Config;
}

export interface LoadableResult extends DataResult {
dataID: string;
dataType: 'image' | 'dicom' | 'model';
}

export interface ConfigResult extends DataResult {
config: Config;
}

export type ImportResult = LoadableResult | ConfigResult | DataResult;

export type ArchiveContents = Record<string, File>;
export type ArchiveCache = Map<File, Awaitable<ArchiveContents>>;

Expand All @@ -31,3 +39,15 @@ export function isArchive(
): ds is DataSource & { fileSrc: FileSource } {
return !!ds.fileSrc && ARCHIVE_FILE_TYPES.has(ds.fileSrc.fileType);
}

export function isLoadableResult(
importResult: ImportResult
): importResult is LoadableResult {
return 'dataID' in importResult && 'dataType' in importResult;
}

export function isConfigResult(
importResult: ImportResult
): importResult is ConfigResult {
return 'config' in importResult;
}
62 changes: 39 additions & 23 deletions src/io/import/importDataSources.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import Pipeline, { PipelineResult } from '@/src/core/pipeline';
import { ImportHandler, ImportResult } from '@/src/io/import/common';
import Pipeline, {
PipelineResult,
PipelineResultSuccess,
} from '@/src/core/pipeline';
import {
isConfigResult,
ImportHandler,
ImportResult,
LoadableResult,
isLoadableResult,
} from '@/src/io/import/common';
import { DataSource, DataSourceWithFile } from '@/src/io/import/dataSource';
import { nonNullable } from '@/src/utils';
import handleDicomFile from '@/src/io/import/processors/handleDicomFile';
import downloadUrl from '@/src/io/import/processors/downloadUrl';
import extractArchive from '@/src/io/import/processors/extractArchive';
Expand Down Expand Up @@ -34,6 +42,23 @@ const unhandledResource: ImportHandler = () => {
throw new Error('Failed to handle resource');
};

function isSelectable(
result: PipelineResult<DataSource, ImportResult>
): result is PipelineResultSuccess<LoadableResult> {
if (!result.ok) return false;

if (result.data.length === 0) {
return false;
}

const importResult = result.data[0];
if (!isLoadableResult(importResult)) {
return false;
}

return true;
}

const importConfigs = async (
results: Array<PipelineResult<DataSource, ImportResult>>
) => {
Expand All @@ -42,8 +67,8 @@ const importConfigs = async (
.flatMap((pipelineResult) =>
pipelineResult.ok ? pipelineResult.data : []
)
.map((result) => result.config)
.filter(nonNullable)
.filter(isConfigResult)
.map(({ config }) => config)
.forEach(applyConfig);
return {
ok: true as const,
Expand Down Expand Up @@ -81,14 +106,11 @@ const importDicomFiles = async (
const volumeKeys = await useDICOMStore().importFiles(dicomDataSources);
return {
ok: true as const,
data: volumeKeys.map(
(key) =>
({
dataID: key,
dataType: 'dicom' as const,
dataSource: resultSources,
} as const)
),
data: volumeKeys.map((key) => ({
dataID: key,
dataType: 'dicom' as const,
dataSource: resultSources,
})),
};
} catch (err) {
return {
Expand Down Expand Up @@ -141,8 +163,9 @@ export async function importDataSources(dataSources: DataSource[]) {
...results,
dicomResult,
configResult,
// remove ok results that have no result data
].filter((result) => !result.ok || result.data.length);
// Consuming code expects only errors and image import results.
// Remove ok results that don't result in something to load (like config.JSON files)
].filter((result) => !result.ok || isSelectable(result));
}

export type ImportDataSourcesResult = Awaited<
Expand All @@ -152,16 +175,9 @@ export type ImportDataSourcesResult = Awaited<
export function convertSuccessResultToDataSelection(
result: ImportDataSourcesResult
) {
if (!result.ok) return null;

if (result.data.length === 0) {
return null;
}
if (!isSelectable(result)) return null;

const { dataID, dataType } = result.data[0];
if (!dataID) {
return null;
}

if (dataType === 'dicom') {
return makeDICOMSelection(dataID);
Expand Down
7 changes: 4 additions & 3 deletions src/io/import/processors/restoreStateFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ImportContext,
ImportHandler,
ImportResult,
isLoadableResult,
} from '@/src/io/import/common';
import {
DataSource,
Expand Down Expand Up @@ -201,12 +202,12 @@ async function restoreDatasets(
);
}

const { dataID } = result.data[0];
if (!dataID) {
const importResult = result.data[0];
if (!isLoadableResult(importResult)) {
throw new Error('Failed to import dataset');
}

stateIDToStoreID[dataset.id] = dataID;
stateIDToStoreID[dataset.id] = importResult.dataID;
} else {
throw new Error('Could not load any data from the session');
}
Expand Down

0 comments on commit ea61baf

Please sign in to comment.