1- import type { ParsingOptions , ViewState } from '@zakodium/nmrium-core' ;
1+ import type {
2+ CoreReadReturn ,
3+ ParsingOptions ,
4+ ViewState ,
5+ } from '@zakodium/nmrium-core' ;
26import { CURRENT_EXPORT_VERSION } from '@zakodium/nmrium-core' ;
37import init from '@zakodium/nmrium-core-plugins' ;
48import { FifoLogger } from 'fifo-logger' ;
59import { FileCollection } from 'file-collection' ;
6- import type { NMRiumState } from 'nmrium' ;
710import { useCallback , useMemo , useState } from 'react' ;
811
912import events from '../events/event.js' ;
1013import { getFileNameFromURL } from '../utilities/getFileNameFromURL.js' ;
1114import { isArrayOfString } from '../utilities/isArrayOfString.js' ;
1215
13- type DeepPartial < T > = {
14- [ K in keyof T ] ?: T [ K ] extends object ? DeepPartial < T [ K ] > : T [ K ] ;
16+ type LoadOptions =
17+ | { nmrium : object ; activeTab ?: string }
18+ | { urls : string [ ] ; activeTab ?: string }
19+ | { files : File [ ] ; activeTab ?: string } ;
20+
21+ // CoreReadReturn with `state.view` made optional to allow partial injection.
22+ export type NMRiumData = Omit < CoreReadReturn , 'state' > & {
23+ state : Omit < CoreReadReturn [ 'state' ] , 'view' > & { view ?: ViewState } ;
1524} ;
1625
17- const core = init ( ) ;
26+ interface UseLoadSpectraResult {
27+ data : NMRiumData | null ;
28+ load : ( options : LoadOptions ) => Promise < void > ;
29+ isLoading : boolean ;
30+ }
1831
32+ const core = init ( ) ;
1933const logger = new FifoLogger ( ) ;
2034
21- function handleLogger ( { detail : { logs } } ) {
35+ logger . addEventListener ( 'change' , ( { detail : { logs } } ) => {
2236 const log = logs . at ( - 1 ) ;
23- if ( log && [ 'error' , 'fatal' , 'warn' ] . includes ( log . levelLabel ) ) {
24- const error = log ?. error || new Error ( log ?. message ) ;
25- events . trigger ( 'error' , error ) ;
26- // eslint-disable-next-line no-console
27- console . log ( error ) ;
28- }
29- }
37+ if ( ! log || ! [ 'error' , 'fatal' , 'warn' ] . includes ( log . levelLabel ) ) return ;
3038
31- logger . addEventListener ( 'change' , handleLogger ) ;
39+ const error = log . error ?? new Error ( log . message ) ;
40+ events . trigger ( 'error' , error ) ;
41+ // eslint-disable-next-line no-console
42+ console . log ( error ) ;
43+ } ) ;
3244
3345const PARSING_OPTIONS : Partial < ParsingOptions > = {
3446 onLoadProcessing : { autoProcessing : true } ,
@@ -37,73 +49,57 @@ const PARSING_OPTIONS: Partial<ParsingOptions> = {
3749 logger,
3850} ;
3951
40- async function loadSpectraFromFiles ( files : File [ ] ) {
52+ async function loadSpectraFromNMRium ( nmrium : object ) : Promise < CoreReadReturn > {
53+ return core . readNMRiumObject ( nmrium , PARSING_OPTIONS ) ;
54+ }
55+
56+ async function loadSpectraFromFiles ( files : File [ ] ) : Promise < CoreReadReturn > {
4157 const fileCollection = await new FileCollection ( ) . appendFileList ( files ) ;
42- const {
43- nmriumState : { data, version } ,
44- } = await core . read ( fileCollection , PARSING_OPTIONS ) ;
45- return { data, version } as NMRiumData ;
58+ return core . read ( fileCollection , PARSING_OPTIONS ) ;
4659}
4760
48- async function loadSpectraFromURLs ( urls : string [ ] ) {
61+ async function loadSpectraFromURLs ( urls : string [ ] ) : Promise < CoreReadReturn > {
4962 const entries = urls . map ( ( url ) => {
5063 const refURL = new URL ( url ) ;
5164 const name = getFileNameFromURL ( url ) ;
5265 let path = refURL . pathname ;
53- const hasExtension = name ?. includes ( '.' ) ;
54- if ( ! hasExtension ) {
66+
67+ if ( ! name ?. includes ( '.' ) ) {
5568 path = `${ path } .zip` ;
5669 }
57- return { relativePath : path , baseURL : refURL . origin } ;
58- } , [ ] ) ;
59-
60- const [ { data, version } ] = await core . readFromWebSource (
61- { entries } ,
62- PARSING_OPTIONS ,
63- ) ;
64- return { data, version } as NMRiumData ;
65- }
66-
67- type LoadOptions =
68- | { urls : string [ ] ; activeTab ?: string }
69- | { files : File [ ] ; activeTab ?: string } ;
7070
71- export type NMRiumData = Pick < NMRiumState , 'data' | 'version' > ;
71+ return { relativePath : path , baseURL : refURL . origin } ;
72+ } ) ;
7273
73- interface UseLoadSpectraResult {
74- data : NMRiumData ;
75- load : ( options : LoadOptions ) => void ;
76- setData : ( data : NMRiumData ) => void ;
77- isLoading : boolean ;
74+ return core . readFromWebSource ( { entries } , PARSING_OPTIONS ) ;
7875}
7976
8077export function useLoadSpectra ( ) : UseLoadSpectraResult {
81- const [ data , setData ] = useState < NMRiumData > ( {
82- data : { spectra : [ ] , molecules : [ ] } ,
83- version : CURRENT_EXPORT_VERSION ,
84- } ) ;
85- const [ activeTab , setActiveTab ] = useState < string > ( ) ;
86- const [ isLoading , setLoading ] = useState < boolean > ( false ) ;
78+ const [ result , setResult ] = useState < CoreReadReturn | null > ( null ) ;
79+ const [ activeTab , setActiveTab ] = useState < string | undefined > ( ) ;
80+ const [ isLoading , setLoading ] = useState ( false ) ;
8781
8882 const load = useCallback ( async ( options : LoadOptions ) => {
8983 setLoading ( true ) ;
9084 try {
91- if ( 'urls' in options ) {
92- if ( isArrayOfString ( options . urls ) ) {
93- const result = await loadSpectraFromURLs ( options . urls ) ;
94- setData ( result ) ;
95- setActiveTab ( options ?. activeTab ) ;
96- } else {
85+ if ( 'nmrium' in options ) {
86+ const nmriumResult = await loadSpectraFromNMRium ( options . nmrium ) ;
87+ setResult ( nmriumResult ) ;
88+ setActiveTab (
89+ options . activeTab ?? nmriumResult . state . view ?. spectra ?. activeTab ,
90+ ) ;
91+ } else if ( 'urls' in options ) {
92+ if ( ! isArrayOfString ( options . urls ) ) {
9793 throw new Error ( 'The input must be a valid urls array of string[]' ) ;
9894 }
99- } else if ( 'files' in options ) {
100- const result = await loadSpectraFromFiles ( options . files ) ;
101- setData ( result ) ;
102- setActiveTab ( options ?. activeTab ) ;
95+ setResult ( await loadSpectraFromURLs ( options . urls ) ) ;
96+ setActiveTab ( options . activeTab ) ;
97+ } else {
98+ setResult ( await loadSpectraFromFiles ( options . files ) ) ;
99+ setActiveTab ( options . activeTab ) ;
103100 }
104101 } catch ( error : unknown ) {
105- const loadError = error as Error ;
106- events . trigger ( 'error' , loadError ) ;
102+ events . trigger ( 'error' , error as Error ) ;
107103 // eslint-disable-next-line no-console
108104 console . log ( error ) ;
109105 } finally {
@@ -112,14 +108,19 @@ export function useLoadSpectra(): UseLoadSpectraResult {
112108 } , [ ] ) ;
113109
114110 return useMemo ( ( ) => {
115- let view : DeepPartial < ViewState > = { } ;
116- view = { spectra : { activeTab } } ;
117- const { version, ...other } = data ;
118- return {
119- data : { version : version ?? CURRENT_EXPORT_VERSION , ...other , view } ,
120- load,
121- isLoading,
122- setData,
123- } ;
124- } , [ activeTab , data , isLoading , load ] ) ;
111+ const view = { spectra : { activeTab } } as unknown as ViewState ;
112+
113+ const data : NMRiumData | null = result
114+ ? {
115+ ...result ,
116+ state : {
117+ version : result . state . version ?? CURRENT_EXPORT_VERSION ,
118+ ...result . state ,
119+ view,
120+ } ,
121+ }
122+ : null ;
123+
124+ return { data, load, isLoading } ;
125+ } , [ activeTab , result , isLoading , load ] ) ;
125126}
0 commit comments