Skip to content

Commit 6dd364b

Browse files
Merge pull request #1637 from nextstrain/fix/web-crash-dataset-json
2 parents bb64371 + 020acd7 commit 6dd364b

5 files changed

Lines changed: 60 additions & 40 deletions

File tree

packages/nextclade-web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
"next-compose-plugins": "2.2.1",
127127
"numbro": "2.3.6",
128128
"p-memoize": "4.0.4",
129+
"p-props": "4.0.0",
129130
"polished": "4.2.2",
130131
"pretty-bytes": "5.6.0",
131132
"prop-types": "15.8.1",

packages/nextclade-web/src/helpers/notUndefined.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ export function notUndefinedOrNull<T>(x: T | undefined | null): x is NonNullable
1010
return x !== undefined && x !== null
1111
}
1212

13-
export function filterValuesNotUndefinedOrNull<T extends object>(obj: T): T {
14-
return Object.fromEntries(Object.entries(obj).filter(([_, value]) => notUndefinedOrNull(value))) as T
15-
}
16-
1713
export function pairValueNotUndefinedOrNull<K, V>(pair: [K, V | undefined | null]): pair is [K, V] {
1814
return notUndefinedOrNull(pair[1])
1915
}
2016

21-
/** If value is not undefined, map it according to a fn, otherwise return unmodified (i.e. undefined) */
22-
export function mapMaybe<T, U>(value: T | undefined, fn: (v: T) => U): U | undefined {
23-
return !isNil(value) ? fn(value) : value
17+
/** If value is not undefined or null, map it according to a fn, otherwise return undefined */
18+
export function mapMaybe<T, U>(value: T | undefined | null, fn: (v: NonNullable<T>) => U): U | undefined {
19+
if (isNil(value)) {
20+
return undefined
21+
}
22+
return fn(value as NonNullable<T>)
2423
}

packages/nextclade-web/src/helpers/promise.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

packages/nextclade-web/src/hooks/useRunAnalysis.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import type { AuspiceJsonV2 } from 'auspice'
22
import { concurrent } from 'fasy'
3-
import { isEmpty, isNil } from 'lodash'
3+
import { isEmpty, isNil, omitBy } from 'lodash'
4+
import pProps from 'p-props'
45
import { useRouter } from 'next/router'
56
import { useRecoilCallback } from 'recoil'
67
import { REF_NODE_CLADE_FOUNDER, REF_NODE_PARENT, REF_NODE_ROOT } from 'src/constants'
78
import { ErrorInternal } from 'src/helpers/ErrorInternal'
8-
import { filterValuesNotUndefinedOrNull } from 'src/helpers/notUndefined'
9-
import { promiseAllObject } from 'src/helpers/promise'
109
import {
1110
seqIndexToTopDatasetNameAtom,
1211
seqIndicesWithoutDatasetSuggestionsAtom,
@@ -237,24 +236,31 @@ async function resolveParams(
237236
datasets: Dataset[] | undefined,
238237
): Promise<NextcladeParamsRaw> {
239238
if (tree) {
240-
return resolveInputsForAuspiceDataset(tree, overrides)
239+
if (!datasets?.[0]) {
240+
throw new ErrorInternal('Attempted to start analysis with Auspice JSON, but without dataset info resolved')
241+
}
242+
return resolveInputsForAuspiceDataset(tree, overrides, datasets[0].path)
241243
}
242244
return resolveInputsForNextcladeDataset(overrides, datasets)
243245
}
244246

245-
async function resolveInputsForAuspiceDataset(tree: AuspiceTree | undefined, overrides: DatasetFilesOverrides) {
246-
const resolvedOverrides = await promiseAllObject({
247-
genomeAnnotation: async () => resolveOverride(overrides.genomeAnnotation),
248-
reference: async () => resolveOverride(overrides.reference),
249-
treeJson: async () => resolveOverride(overrides.treeJson),
250-
pathogenJson: async () => resolveOverride(overrides.pathogenJson),
247+
async function resolveInputsForAuspiceDataset(
248+
tree: AuspiceTree | undefined,
249+
overrides: DatasetFilesOverrides,
250+
datasetName: string,
251+
): Promise<NextcladeParamsRaw> {
252+
const resolvedOverrides = await pProps({
253+
genomeAnnotation: resolveOverride(overrides.genomeAnnotation),
254+
reference: resolveOverride(overrides.reference),
255+
treeJson: resolveOverride(overrides.treeJson),
256+
pathogenJson: resolveOverride(overrides.pathogenJson),
251257
})
252-
const filteredOverrides = filterValuesNotUndefinedOrNull(resolvedOverrides)
258+
const filteredOverrides = omitBy(resolvedOverrides, isNil)
253259
return {
254260
Auspice: {
255261
auspiceJson: JSON.stringify(tree),
256262
...filteredOverrides,
257-
datasetName: 'Auspice JSON',
263+
datasetName,
258264
},
259265
}
260266
}
@@ -281,13 +287,13 @@ async function getDatasetsFiles(
281287
/** Resolves all dataset files into strings */
282288
async function getDatasetFiles(datasets: Dataset[]): Promise<NextcladeParamsRawDir[]> {
283289
return concurrent.map(async (dataset) => {
284-
return promiseAllObject({
290+
return {
285291
datasetName: dataset.path,
286292
genomeAnnotation: await axiosFetchRawMaybe(dataset.files?.genomeAnnotation),
287293
reference: await axiosFetchRaw(dataset.files?.reference),
288294
treeJson: await axiosFetchRawMaybe(dataset.files?.treeJson),
289295
pathogenJson: await axiosFetchRaw(dataset.files?.pathogenJson),
290-
})
296+
}
291297
}, datasets)
292298
}
293299

@@ -296,13 +302,13 @@ async function getDatasetFilesWithOverrides(
296302
overrides: DatasetFilesOverrides,
297303
dataset: Dataset,
298304
): Promise<NextcladeParamsRawDir> {
299-
return promiseAllObject({
305+
return {
300306
datasetName: dataset.path,
301-
genomeAnnotation: resolveOverrideOrDatasetFile(overrides.genomeAnnotation, dataset.files?.genomeAnnotation),
302-
reference: resolveOverrideOrDatasetFileRequired(overrides.reference, dataset.files?.reference),
303-
treeJson: resolveOverrideOrDatasetFile(overrides.treeJson, dataset.files?.treeJson),
304-
pathogenJson: resolveOverrideOrDatasetFileRequired(overrides.pathogenJson, dataset.files?.pathogenJson),
305-
})
307+
genomeAnnotation: await resolveOverrideOrDatasetFile(overrides.genomeAnnotation, dataset.files?.genomeAnnotation),
308+
reference: await resolveOverrideOrDatasetFileRequired(overrides.reference, dataset.files?.reference),
309+
treeJson: await resolveOverrideOrDatasetFile(overrides.treeJson, dataset.files?.treeJson),
310+
pathogenJson: await resolveOverrideOrDatasetFileRequired(overrides.pathogenJson, dataset.files?.pathogenJson),
311+
}
306312
}
307313

308314
async function resolveOverrideOrDatasetFileRequired(

packages/nextclade-web/yarn.lock

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,6 +4282,14 @@ agent-base@6:
42824282
dependencies:
42834283
debug "4"
42844284

4285+
aggregate-error@^3.0.0:
4286+
version "3.1.0"
4287+
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
4288+
integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
4289+
dependencies:
4290+
clean-stack "^2.0.0"
4291+
indent-string "^4.0.0"
4292+
42854293
ajv-formats@^2.1.1:
42864294
version "2.1.1"
42874295
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
@@ -5588,6 +5596,11 @@ clean-regexp@^1.0.0:
55885596
dependencies:
55895597
escape-string-regexp "^1.0.5"
55905598

5599+
clean-stack@^2.0.0:
5600+
version "2.2.0"
5601+
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
5602+
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
5603+
55915604
clean-webpack-plugin@^4.0.0:
55925605
version "4.0.0"
55935606
resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz#72947d4403d452f38ed61a9ff0ada8122aacd729"
@@ -12514,6 +12527,13 @@ p-map@^2.0.0:
1251412527
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
1251512528
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
1251612529

12530+
p-map@^4.0.0:
12531+
version "4.0.0"
12532+
resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
12533+
integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
12534+
dependencies:
12535+
aggregate-error "^3.0.0"
12536+
1251712537
p-memoize@4.0.4:
1251812538
version "4.0.4"
1251912539
resolved "https://registry.yarnpkg.com/p-memoize/-/p-memoize-4.0.4.tgz#90a4c4668866737fc5c8364c56b06f6ca44afb15"
@@ -12523,6 +12543,13 @@ p-memoize@4.0.4:
1252312543
mimic-fn "^3.0.0"
1252412544
p-settle "^4.1.1"
1252512545

12546+
p-props@4.0.0:
12547+
version "4.0.0"
12548+
resolved "https://registry.yarnpkg.com/p-props/-/p-props-4.0.0.tgz#f37c877a9a722057833e1dc38d43edf3906b3437"
12549+
integrity sha512-3iKFbPdoPG7Ne3cMA53JnjPsTMaIzE9gxKZnvKJJivTAeqLEZPBu6zfi6DYq9AsH1nYycWmo3sWCNI8Kz6T2Zg==
12550+
dependencies:
12551+
p-map "^4.0.0"
12552+
1252612553
p-reflect@^2.1.0:
1252712554
version "2.1.0"
1252812555
resolved "https://registry.yarnpkg.com/p-reflect/-/p-reflect-2.1.0.tgz#5d67c7b3c577c4e780b9451fc9129675bd99fe67"

0 commit comments

Comments
 (0)