diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc63a6a2..c3000c36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: matrix: project: - helia-101 + - helia-browser-verified-fetch - helia-cjs - helia-electron - helia-esbuild @@ -86,6 +87,7 @@ jobs: project: - helia-101 - helia-cjs + - helia-browser-verified-fetch - helia-electron - helia-esbuild - helia-jest diff --git a/examples/helia-browser-verified-fetch/.gitignore b/examples/helia-browser-verified-fetch/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/examples/helia-browser-verified-fetch/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/helia-browser-verified-fetch/README.md b/examples/helia-browser-verified-fetch/README.md new file mode 100644 index 00000000..3a117ea4 --- /dev/null +++ b/examples/helia-browser-verified-fetch/README.md @@ -0,0 +1,34 @@ +

+ + Helia logo + +

+ +

Browser Verified Retrieval with @helia/verified-fetch

+ +

+ +
+ Explore the docs + ยท + + ยท + Report Bug + ยท + Request Feature/Example +

+ + +## Table of Contents + +- [Getting Started](#getting-started) + - [Installation and Running example](#installation-and-running-example) + +## Getting Started + +### Installation and Running example + +```console +npm install +npm run dev +``` diff --git a/examples/helia-browser-verified-fetch/index.html b/examples/helia-browser-verified-fetch/index.html new file mode 100644 index 00000000..314ad51a --- /dev/null +++ b/examples/helia-browser-verified-fetch/index.html @@ -0,0 +1,13 @@ + + + + + + + Verified Retrieval with @helia/verified-fetch + + +
+ + + diff --git a/examples/helia-browser-verified-fetch/package.json b/examples/helia-browser-verified-fetch/package.json new file mode 100644 index 00000000..4c319c1a --- /dev/null +++ b/examples/helia-browser-verified-fetch/package.json @@ -0,0 +1,29 @@ +{ + "name": "helia-browser-verified-fetch", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "clean": "rimraf ./dist", + "start": "vite", + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "test": "vite build -c ./test/vite.config.js && test-browser-example test" + }, + "dependencies": { + "@helia/verified-fetch": "^1.3.2", + "@sgtpooki/file-type": "^1.0.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@playwright/test": "^1.42.1", + "@types/react": "^18.2.72", + "@types/react-dom": "^18.2.22", + "@vitejs/plugin-react": "^4.2.1", + "test-ipfs-example": "^1.0.0", + "typescript": "^5.4.3", + "vite": "^5.2.6" + } +} diff --git a/examples/helia-browser-verified-fetch/src/App.tsx b/examples/helia-browser-verified-fetch/src/App.tsx new file mode 100644 index 00000000..4854bf3c --- /dev/null +++ b/examples/helia-browser-verified-fetch/src/App.tsx @@ -0,0 +1,273 @@ +import { verifiedFetch } from '@helia/verified-fetch' +import { fileTypeFromBuffer } from '@sgtpooki/file-type' +import { useCallback, useState } from 'react' +import { Output } from './Output' +import { helpText } from './constants' + +function App (): JSX.Element { + const [path, setPath] = useState('') + const [output, setOutput] = useState('') + const [err, setErr] = useState('') + const [loading, setLoadingTo] = useState('') + const [controller, setController] = useState(null) + + const setSuccess = useCallback((message: string | JSX.Element) => { + setOutput(message) + setLoadingTo('') + setErr('') + }, []) + const setError = useCallback((message: string) => { + setOutput('') + setLoadingTo('') + setErr(message) + }, []) + const setLoading = useCallback((message: string) => { + setErr('') + setLoadingTo(message) + }, []) + + const handleImageType = useCallback(async (resp: Response) => { + try { + setLoading('Waiting for full image data...') + const blob = await resp.blob() + const url = URL.createObjectURL(blob) + setSuccess(fetched image content) + } catch (err) { + setError((err as Error).message) + } + }, []) + + const handleJsonType = useCallback(async (resp: Response) => { + try { + setLoading('Waiting for full JSON data...') + const json = await resp.json() + setSuccess(JSON.stringify(json, null, 2)) + } catch (err) { + setError((err as Error).message) + } + }, []) + + const handleVideoType = useCallback(async (resp: Response) => { + try { + controller?.abort() // abort any ongoing requests + setLoading('Waiting for full video data...') + const blob = await resp.blob() + const url = URL.createObjectURL(blob) + setSuccess(