Use async api for upload
This commit is contained in:
parent
2330d34546
commit
88b2d8486a
|
@ -41,7 +41,7 @@
|
|||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codex-storage/sdk-js": "0.0.1",
|
||||
"@codex-storage/sdk-js": "0.0.2",
|
||||
"@tanstack/react-query": "^5.51.24",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
|
@ -1940,9 +1940,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@codex-storage/sdk-js": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codex-storage/sdk-js/-/sdk-js-0.0.1.tgz",
|
||||
"integrity": "sha512-Zhc7sBXjNKSEjRkqfSy9NG9r5gCulKiGpDZ8t19INVPJpn0VWhjqMSQLDYcCWdxkeBz/EJPS3+ktJ5kCieeeAQ==",
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@codex-storage/sdk-js/-/sdk-js-0.0.2.tgz",
|
||||
"integrity": "sha512-LCzEPZFOqjPz+cC03eyzp7YlfBLe6ixuG0Q3wt4RXw4Ib+iH3lqrTE1a2c4g71OVQicooXoyYZWkJpZabdmaNQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"valibot": "^0.36.0"
|
||||
|
@ -4353,21 +4353,6 @@
|
|||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/body-parser/node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"dev": true,
|
||||
|
@ -5455,9 +5440,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.20.0",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz",
|
||||
"integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==",
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
|
||||
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
|
@ -5472,7 +5457,7 @@
|
|||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.2.0",
|
||||
"finalhandler": "1.3.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"merge-descriptors": "1.0.3",
|
||||
|
@ -5481,11 +5466,11 @@
|
|||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.11.0",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "0.19.0",
|
||||
"serve-static": "1.16.0",
|
||||
"serve-static": "1.16.2",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
|
@ -5595,12 +5580,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.2.0",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
|
@ -5613,16 +5599,27 @@
|
|||
},
|
||||
"node_modules/finalhandler/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler/node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/find-cache-dir": {
|
||||
"version": "3.3.2",
|
||||
|
@ -7380,8 +7377,9 @@
|
|||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
|
@ -7700,12 +7698,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.4"
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
|
@ -8239,63 +8237,27 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.0.tgz",
|
||||
"integrity": "sha512-pDLK8zwl2eKaYrs8mrPZBJua4hMplRWJ1tIFksVC3FtBEBnl8dxgeHtsaMS8DhS9i4fLObaon6ABoc4/hQGdPA==",
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.18.0"
|
||||
"send": "0.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static/node_modules/debug/node_modules/ms": {
|
||||
"node_modules/serve-static/node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/serve-static/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/serve-static/node_modules/send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.3",
|
||||
"on-finished": "2.4.1",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"lucide-react": "^0.428.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codex-storage/sdk-js": "0.0.1",
|
||||
"@codex-storage/sdk-js": "0.0.2",
|
||||
"@tanstack/react-query": "^5.51.24",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
|
|
|
@ -60,7 +60,7 @@ type Props = {
|
|||
* If not provider is passed, the cid returned will be empty.
|
||||
* Default value: provider returning random cid.
|
||||
*/
|
||||
provider?: () => Promise<CodexData["upload"]>;
|
||||
codexData: CodexData;
|
||||
|
||||
/**
|
||||
* If true, the upload will run in a separate web worker.
|
||||
|
@ -81,21 +81,6 @@ type Props = {
|
|||
style?: CustomStyleCSS;
|
||||
};
|
||||
|
||||
const defaultProvider = () =>
|
||||
Promise.resolve(
|
||||
(_: File, onProgress: (loaded: number, total: number) => void) => {
|
||||
onProgress(100, 100);
|
||||
|
||||
return Promise.resolve({
|
||||
abort: () => {},
|
||||
result: Promise.resolve({
|
||||
error: false,
|
||||
data: Date.now().toString(),
|
||||
}),
|
||||
} satisfies UploadResponse);
|
||||
}
|
||||
);
|
||||
|
||||
export function Upload({
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
|
@ -105,7 +90,7 @@ export function Upload({
|
|||
editable = true,
|
||||
onDeleteItem,
|
||||
onSuccess,
|
||||
provider = defaultProvider,
|
||||
codexData,
|
||||
// useWorker = !!window.Worker,
|
||||
}: Props) {
|
||||
const { deleteFile, files, uploadFiles, warning } = useUploadStategy(
|
||||
|
@ -188,7 +173,7 @@ export function Upload({
|
|||
onClose={() => onClose(id)}
|
||||
id={id}
|
||||
onSuccess={onSuccess}
|
||||
provider={provider}
|
||||
codexData={codexData}
|
||||
// useWorker={useWorker}
|
||||
/>
|
||||
))}
|
||||
|
|
|
@ -23,7 +23,7 @@ type UploadFileProps = {
|
|||
onClose: (id: string) => void;
|
||||
id: string;
|
||||
onSuccess: ((cid: string, file: File) => void) | undefined;
|
||||
provider: () => Promise<CodexData["upload"]>;
|
||||
codexData: CodexData;
|
||||
// useWorker: boolean;
|
||||
};
|
||||
|
||||
|
@ -121,7 +121,7 @@ export function UploadFile({
|
|||
onClose,
|
||||
id,
|
||||
onSuccess,
|
||||
provider,
|
||||
codexData,
|
||||
// useWorker,
|
||||
}: UploadFileProps) {
|
||||
const abort = useRef<(() => void) | null>(null);
|
||||
|
@ -138,8 +138,8 @@ export function UploadFile({
|
|||
const { mutateAsync } = useMutation({
|
||||
mutationKey: ["upload"],
|
||||
mutationFn: (file: File) => {
|
||||
return provider()
|
||||
.then((upload) => upload(file, onProgress))
|
||||
return codexData
|
||||
.upload(file, onProgress)
|
||||
.then((res) => {
|
||||
abort.current = res.abort;
|
||||
return res.result;
|
||||
|
@ -152,7 +152,6 @@ export function UploadFile({
|
|||
},
|
||||
onError: (error) => {
|
||||
worker.current?.terminate();
|
||||
// TODO report to Sentry
|
||||
dispatch({ type: "error", error: error.message });
|
||||
},
|
||||
onSuccess: (cid: string) => {
|
||||
|
@ -242,7 +241,7 @@ export function UploadFile({
|
|||
// } else {
|
||||
// mutateAsync(file);
|
||||
// }
|
||||
}, [file, mutateAsync, onInternalSuccess, provider]);
|
||||
}, [file, mutateAsync, onInternalSuccess, codexData]);
|
||||
|
||||
const onCancel = () => {
|
||||
if (worker.current) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import type { Meta } from "@storybook/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { UploadResponse } from "@codex-storage/sdk-js";
|
||||
import { Codex, CodexData, UploadResponse } from "@codex-storage/sdk-js";
|
||||
import { Upload } from "../src/components/Upload/Upload";
|
||||
import { fn } from "@storybook/test";
|
||||
import "./Upload.stories.css";
|
||||
import { CodexDataSdk, CodexDataSlowSdk } from "./sdk";
|
||||
|
||||
const meta = {
|
||||
title: "Advanced/Upload",
|
||||
|
@ -42,50 +43,18 @@ type Props = {
|
|||
const Template = (p: Props) => {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{<Upload useWorker={false} multiple {...p} />}
|
||||
{<Upload multiple {...p} codexData={CodexDataSdk} />}
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Multiple = Template.bind({});
|
||||
|
||||
const slowProvider = () =>
|
||||
Promise.resolve(
|
||||
(_: File, onProgress: (loaded: number, total: number) => void) => {
|
||||
return new Promise<UploadResponse>((resolve) => {
|
||||
let timeout: number;
|
||||
|
||||
resolve({
|
||||
abort: () => {
|
||||
window.clearInterval(timeout);
|
||||
},
|
||||
result: new Promise((resolve) => {
|
||||
let count = 0;
|
||||
timeout = window.setInterval(() => {
|
||||
count++;
|
||||
|
||||
onProgress(500 * count, 1500);
|
||||
|
||||
if (count === 3) {
|
||||
window.clearInterval(timeout);
|
||||
|
||||
resolve({
|
||||
error: false,
|
||||
data: Date.now().toString(),
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
}),
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const SlowTemplate = (p: Props) => {
|
||||
return (
|
||||
<div className="demo">
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{<Upload useWorker={false} multiple provider={slowProvider} {...p} />}
|
||||
{<Upload multiple codexData={CodexDataSlowSdk} {...p} />}
|
||||
</QueryClientProvider>
|
||||
</div>
|
||||
);
|
||||
|
@ -99,10 +68,9 @@ const SingleTemplate = (p: Props) => {
|
|||
<QueryClientProvider client={queryClient}>
|
||||
{
|
||||
<Upload
|
||||
useWorker={false}
|
||||
multiple={false}
|
||||
editable={false}
|
||||
provider={slowProvider}
|
||||
codexData={CodexDataSlowSdk}
|
||||
{...p}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import { Codex } from "@codex-storage/sdk-js";
|
||||
import { CodexData, UploadResponse } from "@codex-storage/sdk-js";
|
||||
|
||||
class CodexDataMock extends CodexData {
|
||||
override upload(
|
||||
_: File,
|
||||
onProgress?: (loaded: number, total: number) => void
|
||||
): Promise<UploadResponse> {
|
||||
return new Promise<UploadResponse>((resolve) => {
|
||||
let timeout: number;
|
||||
|
||||
resolve({
|
||||
abort: () => {
|
||||
window.clearInterval(timeout);
|
||||
},
|
||||
result: new Promise((resolve) => {
|
||||
let count = 0;
|
||||
timeout = window.setInterval(() => {
|
||||
count++;
|
||||
|
||||
onProgress?.(500 * count, 1500);
|
||||
|
||||
if (count === 3) {
|
||||
window.clearInterval(timeout);
|
||||
|
||||
resolve({
|
||||
error: false,
|
||||
data: Date.now().toString(),
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
}),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const CodexDataSdk = new CodexDataMock("");
|
||||
|
||||
class CodexDataSlowMock extends CodexData {
|
||||
override upload(
|
||||
_: File,
|
||||
onProgress?: (loaded: number, total: number) => void
|
||||
): Promise<UploadResponse> {
|
||||
return new Promise<UploadResponse>((resolve) => {
|
||||
let timeout: number;
|
||||
|
||||
resolve({
|
||||
abort: () => {
|
||||
window.clearInterval(timeout);
|
||||
},
|
||||
result: new Promise((resolve) => {
|
||||
let count = 0;
|
||||
timeout = window.setInterval(() => {
|
||||
count++;
|
||||
|
||||
onProgress?.(500 * count, 1500);
|
||||
|
||||
if (count === 3) {
|
||||
window.clearInterval(timeout);
|
||||
|
||||
resolve({
|
||||
error: false,
|
||||
data: Date.now().toString(),
|
||||
});
|
||||
}
|
||||
}, 1500);
|
||||
}),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const CodexDataSlowSdk = new CodexDataSlowMock("");
|
Loading…
Reference in New Issue