-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(idea/frontend): metadata fetch on program/code upload and pr…
…ogram init (#1579)
- Loading branch information
1 parent
1426dd0
commit f571ad5
Showing
29 changed files
with
328 additions
and
414 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const WASM_FILE_TYPE = { | ||
PROGRAM: 'program', | ||
CODE: 'code', | ||
} as const; | ||
|
||
export { WASM_FILE_TYPE }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { WASM_FILE_TYPE } from './file'; | ||
|
||
export { WASM_FILE_TYPE }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { useWasmFileHandler } from './use-wasm-file-handler'; | ||
import { useWasmFile } from './use-wasm-file'; | ||
|
||
export { useWasmFileHandler, useWasmFile }; |
47 changes: 47 additions & 0 deletions
47
idea/frontend/src/features/code/hooks/use-wasm-file-handler.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { HexString, generateCodeHash } from '@gear-js/api'; | ||
import { useApi, useAlert } from '@gear-js/react-hooks'; | ||
import { generatePath } from 'react-router-dom'; | ||
|
||
import { FileTypes, routes } from '@/shared/config'; | ||
import { CustomLink } from '@/shared/ui/customLink'; | ||
|
||
import { WasmFileType } from '../types'; | ||
import { WASM_FILE_TYPE } from '../consts'; | ||
|
||
type OnChange = (value: File | undefined, buffer: Buffer | undefined) => void; | ||
|
||
// upload-code feature? | ||
function useWasmFileHandler(type: WasmFileType, onChange: OnChange = () => {}) { | ||
const { api, isApiReady } = useApi(); | ||
const alert = useAlert(); | ||
|
||
const renderCodeExistsAlert = (codeId: HexString) => ( | ||
<> | ||
<p>Code already exists</p> | ||
<p> | ||
ID: <CustomLink to={generatePath(routes.code, { codeId })} text={codeId} /> | ||
</p> | ||
</> | ||
); | ||
|
||
return async (value: File | undefined) => { | ||
if (!value) return onChange(undefined, undefined); | ||
if (value.type !== FileTypes.Wasm) return alert.error('Invalid file type'); | ||
|
||
const arrayBuffer = await value.arrayBuffer(); | ||
const buffer = Buffer.from(arrayBuffer); | ||
|
||
if (type === WASM_FILE_TYPE.CODE) { | ||
if (!isApiReady) throw new Error('API is not initialized'); | ||
|
||
const codeId = generateCodeHash(buffer); | ||
const isCodeExists = await api.code.exists(codeId); | ||
|
||
if (isCodeExists) return alert.error(renderCodeExistsAlert(codeId)); | ||
} | ||
|
||
onChange(value, buffer); | ||
}; | ||
} | ||
|
||
export { useWasmFileHandler }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useState } from 'react'; | ||
import { useLocation } from 'react-router-dom'; | ||
|
||
import { WASM_FILE_TYPE } from '../consts'; | ||
import { WasmFileType } from '../types'; | ||
import { useWasmFileHandler } from './use-wasm-file-handler'; | ||
|
||
type Location = { | ||
state: { | ||
file: File | undefined; | ||
buffer: Buffer | undefined; | ||
} | null; | ||
}; | ||
|
||
// upload-code/program feature? | ||
function useWasmFile(type: WasmFileType = WASM_FILE_TYPE.PROGRAM) { | ||
const { state } = useLocation() as Location; | ||
|
||
const [file, setFile] = useState(state?.file); | ||
const [buffer, setBuffer] = useState(state?.buffer); | ||
|
||
const handleFileChange = useWasmFileHandler(type, (value, bufferValue) => { | ||
setFile(value); | ||
setBuffer(bufferValue); | ||
}); | ||
|
||
const resetFile = () => { | ||
setFile(undefined); | ||
setBuffer(undefined); | ||
}; | ||
|
||
return { value: file, buffer, reset: resetFile, handleChange: handleFileChange }; | ||
} | ||
|
||
export { useWasmFile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { CodeTable } from './ui'; | ||
import { useWasmFileHandler, useWasmFile } from './hooks'; | ||
|
||
export { CodeTable }; | ||
export { CodeTable, useWasmFileHandler, useWasmFile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { WASM_FILE_TYPE } from '../consts'; | ||
|
||
type WasmFileType = typeof WASM_FILE_TYPE[keyof typeof WASM_FILE_TYPE]; | ||
|
||
export type { WasmFileType }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { WasmFileType } from './file'; | ||
|
||
export type { WasmFileType }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
import { useMetadata } from './use-metadata'; | ||
import { useMetadataHash } from './use-metadata-hash'; | ||
import { useMetadataWithFile } from './use-metadata-with-file'; | ||
|
||
export { useMetadata }; | ||
export { useMetadata, useMetadataHash, useMetadataWithFile }; |
39 changes: 39 additions & 0 deletions
39
idea/frontend/src/features/metadata/hooks/use-metadata-hash.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { HexString } from '@gear-js/api'; | ||
import { useApi } from '@gear-js/react-hooks'; | ||
import { isHex } from '@polkadot/util'; | ||
import { useQuery } from '@tanstack/react-query'; | ||
|
||
import { isString } from '@/shared/helpers'; | ||
|
||
const NO_METAHASH_ERROR = 'metahash function not found in exports'; | ||
|
||
function useMetadataHash(codeIdOrBuffer: HexString | Buffer | undefined) { | ||
const { api, isApiReady } = useApi(); | ||
const queryKey = ['metadataHash', codeIdOrBuffer]; | ||
|
||
const getMetadataHash = async () => { | ||
if (!isApiReady) throw new Error('API is not initialized'); | ||
if (!codeIdOrBuffer) throw new Error('Code ID or buffer is not provided'); | ||
|
||
try { | ||
return await (isHex(codeIdOrBuffer) | ||
? api.code.metaHash(codeIdOrBuffer) | ||
: api.code.metaHashFromWasm(codeIdOrBuffer)); | ||
} catch (error) { | ||
// mock the behavior of the meta-storage api. useMetadata hook is relying on this, maybe worth to refactor | ||
if (isString(error) && error === NO_METAHASH_ERROR) return null; | ||
|
||
throw error; | ||
} | ||
}; | ||
|
||
const { data } = useQuery({ | ||
queryKey, | ||
queryFn: getMetadataHash, | ||
enabled: isApiReady && Boolean(codeIdOrBuffer), | ||
}); | ||
|
||
return data; | ||
} | ||
|
||
export { useMetadataHash }; |
28 changes: 28 additions & 0 deletions
28
idea/frontend/src/features/metadata/hooks/use-metadata-with-file.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { HexString, ProgramMetadata } from '@gear-js/api'; | ||
import { useState, useMemo } from 'react'; | ||
|
||
import { useMetadata } from './use-metadata'; | ||
|
||
// upload-metadata feature? | ||
function useMetadataWithFile(hash: HexString | null | undefined) { | ||
const { metadataHex: storageMetadataHex, isMetadataReady: isStorageMetadataReady } = useMetadata(hash); | ||
|
||
const [fileMetadataHex, setFileMetadataHex] = useState<HexString>(); | ||
const resetFileMetadataHex = () => setFileMetadataHex(undefined); | ||
|
||
const metadataHex = fileMetadataHex || storageMetadataHex; | ||
const metadata = useMemo(() => (metadataHex ? ProgramMetadata.from(metadataHex) : undefined), [metadataHex]); | ||
const isMetadataReady = isStorageMetadataReady || Boolean(fileMetadataHex); | ||
const isStorageMetadata = Boolean(storageMetadataHex); | ||
|
||
return { | ||
value: metadata, | ||
hex: metadataHex, | ||
isReady: isMetadataReady, | ||
isFromStorage: isStorageMetadata, | ||
set: setFileMetadataHex, | ||
reset: resetFileMetadataHex, | ||
}; | ||
} | ||
|
||
export { useMetadataWithFile }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,38 @@ | ||
import { HexString, ProgramMetadata } from '@gear-js/api'; | ||
import { useAlert } from '@gear-js/react-hooks'; | ||
import { useEffect, useState } from 'react'; | ||
import { useEffect, useMemo, useState } from 'react'; | ||
|
||
import { fetchMetadata, getLocalMetadata } from '@/api'; | ||
import { RPCError, RPCErrorCode } from '@/shared/services/rpcService'; | ||
import { useChain } from '@/hooks'; | ||
|
||
function useMetadata(hash?: HexString | null | undefined) { | ||
const alert = useAlert(); | ||
|
||
const { isDevChain } = useChain(); | ||
|
||
const [metadata, setMetadata] = useState<ProgramMetadata>(); | ||
const [isMetadataReady, setIsMetadataReady] = useState(false); | ||
const [metadataHex, setMetadataHex] = useState<HexString>(); | ||
const metadata = useMemo(() => (metadataHex ? ProgramMetadata.from(metadataHex) : undefined), [metadataHex]); | ||
|
||
const defaultIsReady = hash === null; | ||
const [isMetadataReady, setIsMetadataReady] = useState(defaultIsReady); | ||
|
||
const getMetadata = (_hash: HexString) => | ||
isDevChain ? getLocalMetadata(_hash).catch(() => fetchMetadata(_hash)) : fetchMetadata(_hash); | ||
|
||
useEffect(() => { | ||
if (hash === null) return setIsMetadataReady(true); | ||
setMetadataHex(undefined); | ||
setIsMetadataReady(defaultIsReady); | ||
|
||
if (!hash) return; | ||
|
||
getMetadata(hash) | ||
.then(({ result }) => result.hex && setMetadata(ProgramMetadata.from(result.hex))) | ||
.then(({ result }) => result.hex && setMetadataHex(result.hex)) | ||
.catch(({ message, code }: RPCError) => code !== RPCErrorCode.MetadataNotFound && alert.error(message)) | ||
.finally(() => setIsMetadataReady(true)); | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [hash]); | ||
|
||
return { metadata, isMetadataReady, setMetadata, getMetadata }; | ||
return { metadata, metadataHex, isMetadataReady, setMetadataHex, getMetadata }; | ||
} | ||
|
||
export { useMetadata }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { useMetadata } from './hooks'; | ||
import { useMetadata, useMetadataHash, useMetadataWithFile } from './hooks'; | ||
import { MetadataTable } from './ui'; | ||
import { isHumanTypesRepr, isState } from './utils'; | ||
|
||
export { useMetadata, MetadataTable, isHumanTypesRepr, isState }; | ||
export { useMetadata, useMetadataHash, useMetadataWithFile, MetadataTable, isHumanTypesRepr, isState }; |
5 changes: 0 additions & 5 deletions
5
idea/frontend/src/features/uploadMetadata/ui/metadataInput/MetadataInput.module.scss
This file was deleted.
Oops, something went wrong.
35 changes: 0 additions & 35 deletions
35
idea/frontend/src/features/uploadMetadata/ui/metadataInput/MetadataInput.tsx
This file was deleted.
Oops, something went wrong.
3 changes: 0 additions & 3 deletions
3
idea/frontend/src/features/uploadMetadata/ui/metadataInput/index.ts
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.