Coder Social home page Coder Social logo

kqito / use-tus Goto Github PK

View Code? Open in Web Editor NEW
96.0 3.0 8.0 2.29 MB

React hooks for resumable file uploads using tus

Home Page: https://kqito.github.io/use-tus/?path=/story/usetus--basic

License: MIT License

JavaScript 8.63% Shell 0.08% TypeScript 91.14% CSS 0.15%
react react-hooks tus tus-js-client hooks

use-tus's Introduction

use-tus

React hooks for resumable file uploads using tus.

Build status Npm version License

Features

  • Resumable file uploads on react.
  • Lightweight and simple interface hooks.
  • Managing the Upload by using context.
  • TypeScript support.

Demo

You can try the use-tus demo.

Installation

You can install the package from npm.

npm install use-tus tus-js-client

or

yarn add use-tus tus-js-client

Usage

We can use useTus as following.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload, isSuccess, error, remove } = useTus();

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );

  const handleStart = useCallback(() => {
    if (!upload) {
      return;
    }

    // Start to upload the file.
    upload.start();
  }, [upload]);

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
      <button type="button" onClick={handleStart}>
        Upload
      </button>
    </div>
  );
};

API

useTus hooks

const { upload, setUpload, isSuccess, isAborted, isUploading, error, remove } = useTus({ autoAbort, autoStart, uploadOptions, Upload });

useTus is a hooks that creates an object to perform Resumable file upload.

Arguments

  • autoAbort (type: boolean | undefined) (default: true)

    • Whether or not to automatically abort uploads when useTus hooks is unmounted.
  • autoStart (type: boolean | undefined) (default: false)

    • Whether or not to start upload the file after setUpload function.
  • uploadOptions (type: TusHooksUploadFnOptions | undefined) (default: undefined)

    • Option to used by upload object that generated by that hooks.
  • Upload (type: Upload | undefined) (default: undefined)

    • Option to specify customized own Upload class with this hooks.

About uploadOptions

This option extends the UploadOptions provided by tus-js-client, but it has been extended so that every callback can receive the upload instance as the final argument.

For detail type information of UploadOptions, please see here.

e.g.

setUplaod(file, {
  onSuccess: (upload) => {
    console.log(upload.url)
  },
  onError: (error, upload) => {
    console.log(error)

    setTimeout(() => {
      upload.start()
    }, 1000)
  }
})

Returns

  • upload (type: tus.Upload | undefined)

    • Object to be used when performing Resumable file upload.
    • This value is undefined unless the setUpload function called.
    • For detail usage, please see here
  • setUpload (type: (file: tus.Upload['file'], options?: TusHooksUploadFnOptions) => void)

    • Function to create an Upload.
    • The property specified in uploadOptions will be overwritten if property of options are speicified.
  • isSuccess (type: boolean)

    • Whether the upload was successful or not.
  • isAborted (type: boolean)

    • Whether the upload was aborted or not.
  • isUploading (type: boolean)

    • Indicates if an uploading is in progress or not.
  • error (type: Error | undefined)

    • Error when upload fails.
  • remove (type: () => void)

    • Function to reset states.

useTusStore hooks

const { upload, setUpload, isSuccess, isAborted, isUploading, error, remove } = useTusStore(cacheKey, { autoAbort, autoStart, uploadOptions, Upload  });

useTusStore is a hooks that creates an object for resumable file upload and stores it in a context.

This hooks is useful when you want to handle uploads across pages or components.

Note that using useTusStore hooks, the TusClientProvider must be specified as the parent or higher element.

Arguments

  • cacheKey (type: string)

    • Specify the key associated with the Upload object is created by setUpload function.
  • autoAbort (type: boolean | undefined) (default: true)

    • Whether or not to automatically abort uploads when useTusStore hooks is unmounted.
  • autoStart (type: boolean | undefined) (default: false)

    • Whether or not to start upload the file after setUpload function.
  • uploadOptions (type: TusHooksUploadFnOptions | undefined) (default: undefined)

    • Option to used by upload object that generated by that hooks.
    • For detail type information of TusHooksUploadFnOptions, please see here.
  • Upload (type: Upload | undefined) (default: undefined)

    • Option to specify customized own Upload class with this hooks.

Returns

  • upload (type: tus.Upload | undefined)
    • Object to be used when performing Resumable file upload.
    • This value is undefined unless the setUpload function called.

Returns

  • upload (type: tus.Upload | undefined)

    • Object to be used when performing Resumable file upload.
    • This value of the Upload associated with the cacheKey in the TusClientProvider. If not present, undefined.
    • For detail usage, please see here
  • setUpload (type: (file: tus.Upload['file'], options?: tus.Upload['options']) => void)

    • Function to create an Upload.
    • The property specified in uploadOptions will be overwritten if property of options are speicified.
  • isSuccess (type: boolean)

    • Whether the upload was successful or not.
  • isAborted (type: boolean)

    • Whether the upload was aborted or not.
  • isUploading (type: boolean)

    • Indicates if an uploading is in progress or not.
  • error (type: Error | undefined)

    • Error when upload fails.
  • remove (type: () => void)

    • Function to delete the Upload associated with cacheKey.

TusClientProvider

() => (
  <TusClientProvider defaultOptions={defaultOptions}>
    {children}
  </TusClientProvider>
)

TusClientProvider is the provider that stores the Upload with useTusStore hooks.

Props

  • defaultOptions (type: (file: tus.Upload['file']) => TusHooksUploadFnOptions | undefined)
    • An object containing the default options used when creating a new upload. detail

useTusClient

const { state, removeUpload, reset } = useTusClient();

useTusClient is a hooks that can be used to retrieve and reset the state of a TusClientProvider.

Returns

  • state (type: { [cacheKey: string]: UploadState | undefined })

    • Upload information associated with cacheKey
  • removeUpload (type: (cacheKey: string) => void)

    • Remove the upload instance associated with the specified cacheKey.
  • reset (type: () => void)

    • Initialize the value of TusClientProvider

Examples

The following are some example of how to use use-tus.

Uploading a file

The setUpload and upload.start functions can be used to perform resumable file uploads.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus();

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );

  const handleStart = useCallback(() => {
    if (!upload) {
      return;
    }

    // Start upload the file.
    upload.start();
  }, [upload]);

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
      <button type="button" onClick={handleStart}>
        Upload
      </button>
    </div>
  );
};

It is also possible to automatically upload files after setUpload by specifying the autoStart option.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus({ autoStart: true });

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      setUpload(file, {
        endpoint: 'https://tusd.tusdemo.net/files/',
        metadata: {
          filename: file.name,
          filetype: file.type,
        },
      });
    },
    [setUpload]
  );
  return (
    <input type="file" onChange={handleSetUpload} />
  );
};

Aborting a file upload

You can abort the upload by using the upload.abort function.

import { useTus } from 'use-tus'

const Aborter = () => {
  const { upload } = useTus();

  const handleAbort = useCallback(() => {
    if (!upload) {
      return;
    }

    upload.abort();
  }, [upload]);

  return (
    <div>
      <button type="button" onClick={handleAbort}>
        Abort
      </button>
    </div>
  );
};

You can also specify the autoAbort option to automatically stop uploads when unmounting hooks.

import { useTus } from 'use-tus'

const Uploader = () => {
  const { upload, setUpload } = useTus({ autoAbort: true });

  // omitted...
};

Default options of upload

You can specify default options in the defaultOptions props of the TusClientProvider.

import { useTusStore, DefaultOptions, TusClientProvider } from 'use-tus'

const defaultOptions: DefaultOptions = (contents) => {
  const file = contents instanceof File ? contents : undefined;

  return {
    endpoint: 'https://tusd.tusdemo.net/files/',
    metadata: file
      ? {
          filename: file.name,
          filetype: file.type,
        }
      : undefined,
  };
};

const App = () => (
  <TusClientProvider defaultOptions={defaultOptions}>
    <Uploader />
  </TusClientProvider>
);

const Uploader = () => {
  const { setUpload } = useTusStore('cacheKey', { autoStart: true });

  const handleSetUpload = useCallback((event: ChangeEvent<HTMLInputElement>) => {
      const file = event.target.files.item(0);

      if (!file) {
        return;
      }

      // You no longer need to specify the options associated with upload.
      // If specified, it will override defaultOptions.
      setUpload(file);
    },
    [setUpload]
  );

  return (
    <div>
      <input type="file" onChange={handleSetUpload} />
    </div>
  );
};

Specify upload key

If you specify cacheKey as an argument to useTusStore, you can get the upload associated with it. This is useful for cross-page file uploads.

const SelectFileComponent = (file: File) => {
  // Create upload accosiated with 'upload-thumbnail' key
  const { setUpload } = useTusStore('upload-thumbnail')

  setUpload(file)
}

const UploadFileComponent = () => {
  const { upload } = useTusStore('upload-thumbnail')

  upload.start()
}

License

MIT © kqito

use-tus's People

Contributors

kallebysantos avatar kqito avatar sasha95 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

use-tus's Issues

ReferenceError: regeneratorRuntime is not defined

The problem arise in useAutoAbort hook. After being bundled by babel, I suppose, the library throw this error.

Uncaught ReferenceError: regeneratorRuntime is not defined
    abortUploading index.esm.js:199
    useAutoAbort2 index.esm.js:226
    ....

retryDelays not working

I'm trying to set retryDelays to send request every 10seconds until it reaches to 10 mins then throw error. but it doesn't send multiple requests and throw error after a while on first reqest.
This is my code:

 setUpload(file, {
      endpoint: `https://upload.domain.com`,
      retryDelays: [
        0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000, 100000, 110000, 120000,
        130000, 140000, 150000, 160000, 170000, 180000, 190000, 200000, 210000, 220000, 230000,
        240000, 250000, 260000, 270000, 280000, 290000, 300000, 310000, 320000, 330000, 340000,
        350000, 360000, 370000, 380000, 390000, 400000, 410000, 420000, 430000, 440000, 450000,
        460000, 470000, 480000, 490000, 500000, 510000, 520000, 530000, 540000, 550000, 560000,
        570000, 580000, 590000, 600000,
      ],
      headers: {
        Authorization: `Bearer ${token}`,
      },
      metadata: {
        filename: file.name.split('.')[0],
        filetype: file.type.split('/')[1],
      },
      onProgress: function (bytesUploaded, bytesTotal) {
        const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2)

        setProgress(percentage)
      },
      onSuccess: function () {},
    })

Using upload url parameter on onSuccess function

When i try to access upload object on onSuccess function i get undefined error.

I need to get upload.url parameter to get file information after upload completed succesfully.

useEffect(() => {
  if (!upload) {
    return
  }

  setUrl(upload.url as string)
  console.log(upload.url)
}, [upload])

This sets url to null

onSuccess: () => {
  setUploading(false)
  console.log(upload)
  
  apiService.post("/upload_info", {
    key: upload.url
  })
}

This is also null.

Thanks for creating great library

Uploading multiple files - 1 file missing

Attempting to upload multiples files, i noticed all files are upload execpt 1, always.
If i select 5 files, only 4 are successfully uploaded.

These logs show the use state null
image

I modified your Basic.stories.tsx , added multiple on input type file.
Then, used all files instead of 1.

const files = event.target?.files;
for (let index = 0; index < files.length; index += 1) {
  const file = files[index];

Not sure what is happening. Can you upload multiple files using use-tus?

UPDATE: the problem was in the for loop. Implemented a queue to upload 1 file at a time, it works as expected.

bump the peer dependency to support react v18

  "peerDependencies": {
    "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
    "tus-js-client": "^2.2.0"
  },

we need to add || ^18.0.0.

As of today now, we have to force install via npm install --force.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.