diff --git a/apps/web/package.json b/apps/web/package.json index f65e12c..8caf4d9 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -10,13 +10,15 @@ }, "dependencies": { "@octokit/rest": "^21.0.0", - "@zk-kit/artifacts": "1.6.0", + "@zk-kit/artifacts": "1.9.0", "jotai": "^2.8.3", "preact": "^10.22.0", - "react-query": "^3.39.3" + "react-query": "^3.39.3", + "semver": "^7.6.2" }, "devDependencies": { "@preact/preset-vite": "^2.8.2", + "@types/semver": "^7.5.8", "typescript": "^5.2.2", "vite": "^5.3.1" } diff --git a/apps/web/src/constants.ts b/apps/web/src/constants.ts index d06a71b..5c8b83e 100644 --- a/apps/web/src/constants.ts +++ b/apps/web/src/constants.ts @@ -2,3 +2,4 @@ export const artifacts = ['wasm', 'zkey'] export const owner = 'privacy-scaling-explorations' export const repo = 'snark-artifacts' export const cdnUrl = 'https://snark-artifacts.pse.dev' +export const npmRegistryUrl = 'https://registry.npmjs.org' diff --git a/apps/web/src/containers/DownloadButton.tsx b/apps/web/src/containers/DownloadButton.tsx index e656496..da3c89f 100644 --- a/apps/web/src/containers/DownloadButton.tsx +++ b/apps/web/src/containers/DownloadButton.tsx @@ -1,13 +1,17 @@ -import { cdnUrl } from '../constants' -import { useStore } from '../hooks' +import { useDownloadUrl, useStore } from '../hooks' export function DownloadButton() { - const { selectedFile, selectedProject, selectedVersion } = useStore() + const { selectedFile, tickedDownloadAll } = useStore() + const disabled = !(selectedFile || tickedDownloadAll) + const downloadUrl = useDownloadUrl() const onClick = () => { - const url = `${cdnUrl}/${selectedProject}/${selectedVersion}/${selectedFile}` - window.location.href = url + window.location.href = downloadUrl } - return + return ( + + ) } diff --git a/apps/web/src/containers/FileSelect.tsx b/apps/web/src/containers/FileSelect.tsx index b4d0118..9ce563b 100644 --- a/apps/web/src/containers/FileSelect.tsx +++ b/apps/web/src/containers/FileSelect.tsx @@ -3,11 +3,11 @@ import { Options } from '../components' import { useFiles, useStore } from '../hooks' export function FileSelect() { - const { selectedFile, setSelectedFile } = useStore() + const { selectedFile, setSelectedFile, tickedDownloadAll, toggleTickedDownloadAll } = useStore() const { data: files, isLoading, isFetched, isSuccess, isError, error } = useFiles() - const onChange = (e: ChangeEvent) => { - const file = e.target as HTMLSelectElement - setSelectedFile(file.value) + const onSelectChange = (e: ChangeEvent) => { + const { value } = e.target as HTMLSelectElement + setSelectedFile(value) } if (isLoading) return
Loading...
@@ -17,13 +17,18 @@ export function FileSelect() { return (
- - { - /* - */ - } + + +
) } diff --git a/apps/web/src/containers/ProjectSelect.tsx b/apps/web/src/containers/ProjectSelect.tsx index ac5a58e..b614607 100644 --- a/apps/web/src/containers/ProjectSelect.tsx +++ b/apps/web/src/containers/ProjectSelect.tsx @@ -4,11 +4,9 @@ import { Options } from '../components' import { useStore } from '../hooks' export function ProjectSelect() { - const { selectedProject, setSelectedProject, resetSelectedFile, resetSelectedVersion } = useStore() + const { selectedProject, setSelectedProject } = useStore() const onChange = (e: ChangeEvent) => { - resetSelectedFile() - resetSelectedVersion() const target = e.target as HTMLSelectElement setSelectedProject(target.value) } diff --git a/apps/web/src/containers/VersionSelect.tsx b/apps/web/src/containers/VersionSelect.tsx index 2dc7fec..391e607 100644 --- a/apps/web/src/containers/VersionSelect.tsx +++ b/apps/web/src/containers/VersionSelect.tsx @@ -3,13 +3,12 @@ import { Options } from '../components' import { useStore, useVersions } from '../hooks' export function VersionSelect() { - const { selectedVersion, setSelectedVersion, resetSelectedFile } = useStore() + const { selectedVersion, setSelectedVersion } = useStore() const { data: versions, isSuccess, isFetched, isLoading, isError, error } = useVersions() const onChange = (e: ChangeEvent) => { - resetSelectedFile() - const target = e.target as HTMLSelectElement - setSelectedVersion(target.value) + const { value } = e.target as HTMLSelectElement + setSelectedVersion(value) } if (isLoading) return
Loading...
diff --git a/apps/web/src/hooks/index.ts b/apps/web/src/hooks/index.ts index 1555139..61cf2ba 100644 --- a/apps/web/src/hooks/index.ts +++ b/apps/web/src/hooks/index.ts @@ -1,3 +1,4 @@ +export * from './useDownloadUrl' export * from './useFiles' export * from './useStore' export * from './useVersions' diff --git a/apps/web/src/hooks/useDownloadUrl.ts b/apps/web/src/hooks/useDownloadUrl.ts new file mode 100644 index 0000000..4d1b51e --- /dev/null +++ b/apps/web/src/hooks/useDownloadUrl.ts @@ -0,0 +1,9 @@ +import { cdnUrl, npmRegistryUrl } from '../constants' +import { useStore } from './useStore' + +export const useDownloadUrl = () => { + const { selectedFile, selectedProject, selectedVersion, tickedDownloadAll } = useStore() + return tickedDownloadAll + ? `${npmRegistryUrl}/@zk-kit/${selectedProject}-artifacts/-/${selectedProject}-artifacts-${selectedVersion}.tgz` + : `${cdnUrl}/${selectedProject}/${selectedVersion}/${selectedFile}` +} diff --git a/apps/web/src/hooks/useStore.ts b/apps/web/src/hooks/useStore.ts index a78ca5a..8c860b9 100644 --- a/apps/web/src/hooks/useStore.ts +++ b/apps/web/src/hooks/useStore.ts @@ -3,20 +3,38 @@ import { atom, useAtom } from 'jotai' const selectedFileAtom = atom('') const selectedProjectAtom = atom('') const selectedVersionAtom = atom('') +const tickedDownloadAllAtom = atom(false) export const useStore = () => { const [selectedFile, setSelectedFile] = useAtom(selectedFileAtom) - const [selectedProject, setSelectedProject] = useAtom(selectedProjectAtom) - const [selectedVersion, setSelectedVersion] = useAtom(selectedVersionAtom) + const _resetSelectedFile = () => setSelectedFile('') + + const [tickedDownloadAll, _setTickedDownloadAll] = useAtom(tickedDownloadAllAtom) + const _resetTickedDownloadAll = () => _setTickedDownloadAll(false) + const toggleTickedDownloadAll = () => _setTickedDownloadAll(prev => !prev) + + const [selectedVersion, _setSelectedVersion] = useAtom(selectedVersionAtom) + const setSelectedVersion = (...args: Parameters) => { + _resetSelectedFile() + _resetTickedDownloadAll() + _setSelectedVersion(...args) + } + const _resetSelectedVersion = () => setSelectedVersion('') + + const [selectedProject, _setSelectedProject] = useAtom(selectedProjectAtom) + const setSelectedProject = (...args: Parameters) => { + _resetSelectedVersion() + _setSelectedProject(...args) + } return { selectedFile, - resetSelectedFile: () => setSelectedFile(''), setSelectedFile, selectedProject, setSelectedProject, selectedVersion, - resetSelectedVersion: () => setSelectedVersion(''), setSelectedVersion, + tickedDownloadAll, + toggleTickedDownloadAll, } } diff --git a/apps/web/src/hooks/useVersions.ts b/apps/web/src/hooks/useVersions.ts index ec403e9..a3528dd 100644 --- a/apps/web/src/hooks/useVersions.ts +++ b/apps/web/src/hooks/useVersions.ts @@ -1,4 +1,5 @@ import { useQuery } from 'react-query' +import rcompare from 'semver/functions/rcompare' import { owner, repo } from '../constants' import { gh } from '../gh' import { useStore } from './useStore' @@ -16,6 +17,10 @@ export function useVersions() { queryKey: ['versions', selectedProject], queryFn, select: (data) => - data.filter(tag => tag.includes(`@zk-kit/${selectedProject}-artifacts@`)).map(tag => tag.split('@')[2]), + data + .filter(tag => tag.includes(`@zk-kit/${selectedProject}-artifacts@`)) + .map(tag => tag.split('@')[2]) + .filter(version => version !== 'latest') + .sort(rcompare), }) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4a2916..91a0fd1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,8 +60,8 @@ importers: specifier: ^21.0.0 version: 21.0.0 '@zk-kit/artifacts': - specifier: 1.6.0 - version: 1.6.0 + specifier: 1.9.0 + version: 1.9.0 jotai: specifier: ^2.8.3 version: 2.8.3(react@18.3.1) @@ -71,10 +71,16 @@ importers: react-query: specifier: ^3.39.3 version: 3.39.3(react@18.3.1) + semver: + specifier: ^7.6.2 + version: 7.6.2 devDependencies: '@preact/preset-vite': specifier: ^2.8.2 version: 2.8.3(@babel/core@7.24.6)(preact@10.22.0)(vite@5.3.1(@types/node@20.14.0)(terser@5.31.1)) + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 typescript: specifier: ^5.2.2 version: 5.4.5 @@ -1123,6 +1129,9 @@ packages: '@zk-kit/artifacts@1.6.0': resolution: {integrity: sha512-vNhVvKy5EjLAZcfm0cHkbputecXgtoW9hpPGRc5aNmv94zGk9owNA+EuG7YghP88D/iNlvA+80rwlw5qMdSYlA==} + '@zk-kit/artifacts@1.9.0': + resolution: {integrity: sha512-Dl8bJLWnSw0NGT1/p5UKmp4Zgr+evyyvgyi2pwDzdPuT0RKMRkgNIC4ai1j58utwWR9tczGNQlDPdpdZNqFfmA==} + acorn-walk@8.3.2: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} @@ -4438,6 +4447,8 @@ snapshots: '@zk-kit/artifacts@1.6.0': {} + '@zk-kit/artifacts@1.9.0': {} + acorn-walk@8.3.2: {} acorn@8.11.3: {}