-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathuseLoadSpectra.ts
More file actions
116 lines (99 loc) · 3.49 KB
/
useLoadSpectra.ts
File metadata and controls
116 lines (99 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { FifoLogger } from 'fifo-logger';
import { fileCollectionFromFiles } from 'filelist-utils';
import type { NmriumState, ParsingOptions, ViewState } from 'nmr-load-save';
import { CURRENT_EXPORT_VERSION, read, readFromWebSource } from 'nmr-load-save';
import { useCallback, useMemo, useState } from 'react';
import events from '../events/event.js';
import { getFileNameFromURL } from '../utilities/getFileNameFromURL.js';
import { isArrayOfString } from '../utilities/isArrayOfString.js';
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
const logger = new FifoLogger();
function handleLogger({ detail: { logs } }) {
const log = logs.at(-1);
if (log && ['error', 'fatal', 'warn'].includes(log.levelLabel)) {
const error = log?.error || new Error(log?.message);
events.trigger('error', error);
// eslint-disable-next-line no-console
console.log(error);
}
}
logger.addEventListener('change', handleLogger);
const PARSING_OPTIONS: Partial<ParsingOptions> = {
onLoadProcessing: { autoProcessing: true },
experimentalFeatures: true,
sourceSelector: { general: { dataSelection: 'preferFT' } },
logger,
};
async function loadSpectraFromFiles(files: File[]) {
const fileCollection = await fileCollectionFromFiles(files);
const {
nmriumState: { data },
} = await read(fileCollection, PARSING_OPTIONS);
return data;
}
async function loadSpectraFromURLs(urls: string[]) {
const entries = urls.map((url) => {
const refURL = new URL(url);
const name = getFileNameFromURL(url);
let path = refURL.pathname;
const hasExtension = name?.includes('.');
if (!hasExtension) {
path = `${path}.zip`;
}
return { relativePath: path, baseURL: refURL.origin };
}, []);
const { data } = await readFromWebSource({ entries }, PARSING_OPTIONS);
return data;
}
type NMRiumData = NmriumState['data'];
type LoadOptions =
| { urls: string[]; activeTab?: string }
| { files: File[]; activeTab?: string };
interface UseLoadSpectraResult {
data: { version: number; data: NMRiumData };
load: (options: LoadOptions) => void;
isLoading: boolean;
}
export function useLoadSpectra(): UseLoadSpectraResult {
const [data, setData] = useState<NMRiumData>({ spectra: [], molecules: [] });
const [activeTab, setActiveTab] = useState<string>();
const [isLoading, setLoading] = useState<boolean>(false);
const load = useCallback(async (options: LoadOptions) => {
setLoading(true);
try {
if ('urls' in options) {
if (isArrayOfString(options.urls)) {
const result = await loadSpectraFromURLs(options.urls);
setData(result as NMRiumData);
setActiveTab(options?.activeTab);
} else {
throw new Error('The input must be a valid urls array of string[]');
}
} else if ('files' in options) {
const result = await loadSpectraFromFiles(options.files);
setData(result as NMRiumData);
setActiveTab(options?.activeTab);
}
} catch (error: unknown) {
const loadError = error as Error;
events.trigger('error', loadError);
// eslint-disable-next-line no-console
console.log(error);
} finally {
setLoading(false);
}
}, []);
return useMemo(() => {
let view: DeepPartial<ViewState> = {};
if (activeTab) {
view = { spectra: { activeTab } };
}
return {
data: { version: CURRENT_EXPORT_VERSION, data, view },
load,
isLoading,
};
}, [activeTab, data, isLoading, load]);
}