Skip to content

Commit

Permalink
Add metadataForPartialUploads option to set metadata for partial up…
Browse files Browse the repository at this point in the history
…loads only (#703)

* Add partialMetadata to options.

* Add api docs for partialMetadata.

* Rename to `metadataForPartialUploads`

* Simplify implementation and tests

* Update documentation

---------

Co-authored-by: Marius Kleidl <[email protected]>
  • Loading branch information
loren-m-crawford and Acconut authored Sep 9, 2024
1 parent 1cef03e commit 580bf98
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 5 deletions.
14 changes: 13 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,18 @@ metadata: {
}
```

#### metadataForPartialUploads

_Default value:_ `{}`

An object with string values used as additional meta data for partial uploads. When parallel uploads are enabled via `parallelUploads`, tus-js-client creates multiple partial uploads. The values from `metadata` are not passed to these partial uploads but only passed to the final upload, which is the concatentation of the partial uploads. In contrast, the values from `metadataForPartialUploads` are only passed to the partial uploads and not the final upload. This option has no effect if parallel uploads are not enabled. Can be used to associate partial uploads to a user, for example:

```js
metadataForPartialUploads: {
userId: "1234567"
}
```

#### uploadUrl

_Default value:_ `null`
Expand Down Expand Up @@ -234,7 +246,7 @@ X-Request-ID: fe51f777-f23e-4ed9-97d7-2785cc69f961

_Default value:_ `1`

A number indicating how many parts should be uploaded in parallel. If this number is not `1`, the input file will be split into multiple parts, where each part is uploaded individually in parallel. The value of `parallelUploads` determines the number of parts. Using `parallelUploadBoundaries` the size of each part can be changed. After all parts have been uploaded, the [`concatenation` extension](https://tus.io/protocols/resumable-upload.html#concatenation) will be used to concatenate all the parts together on the server-side, so the tus server must support this extension. This option should not be used if the input file is a streaming resource.
A number indicating how many parts should be uploaded in parallel. If this number is not `1`, the input file will be split into multiple parts, where each part is uploaded individually in parallel. The value of `parallelUploads` determines the number of parts. Using `parallelUploadBoundaries` the size of each part can be changed. After all parts have been uploaded, the [`concatenation` extension](https://tus.io/protocols/resumable-upload.html#concatenation) will be used to concatenate all the parts together on the server-side, so the tus server must support this extension. This option should not be used if the input file is a streaming resource. By default, the values from `metadata` are not passed to the partial uploads and only used for the final upload where the parts are concatenated together again. The `metadataForPartialUploads` option can be used to set meta data specifically for partial uploads.

The idea behind this option is that you can use multiple HTTP requests in parallel to better utilize the full capacity of the network connection to the tus server. If you want to use it, please evaluate it under real world situations to see if it actually improves your upload performance. In common browser session, we were not able to find a performance improve for the average user.

Expand Down
1 change: 1 addition & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface UploadOptions {

uploadUrl?: string | null
metadata?: { [key: string]: string }
metadataForPartialUploads?: { [key: string]: string }
fingerprint?: (file: File, options: UploadOptions) => Promise<string>
uploadSize?: number | null

Expand Down
3 changes: 3 additions & 0 deletions lib/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const upload = new tus.Upload(file, {
metadata: {
filename: 'foo.txt',
},
metadataForPartialUploads: {
userId: 'foo123bar',
},
onProgress: (bytesSent: number, bytesTotal: number) => {
const percentage = ((bytesSent / bytesTotal) * 100).toFixed(2)
console.log(bytesSent, bytesTotal, `${percentage}%`)
Expand Down
3 changes: 2 additions & 1 deletion lib/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const defaultOptions = {

uploadUrl: null,
metadata: {},
metadataForPartialUploads: {},
fingerprint: null,
uploadSize: null,

Expand Down Expand Up @@ -331,7 +332,7 @@ class BaseUpload {
parallelUploads: 1,
// Reset this option as we are not doing a parallel upload.
parallelUploadBoundaries: null,
metadata: {},
metadata: this.options.metadataForPartialUploads,
// Add the header to indicate the this is a partial upload.
headers: {
...this.options.headers,
Expand Down
9 changes: 6 additions & 3 deletions test/spec/test-parallel-uploads.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ describe('tus', () => {
metadata: {
foo: 'hello',
},
metadataForPartialUploads: {
test: 'world',
},
onProgress() {},
onSuccess: waitableFunction(),
fingerprint: () => Promise.resolve('fingerprinted'),
Expand All @@ -92,7 +95,7 @@ describe('tus', () => {
expect(req.requestHeaders['Tus-Resumable']).toBe('1.0.0')
expect(req.requestHeaders['Upload-Length']).toBe('5')
expect(req.requestHeaders['Upload-Concat']).toBe('partial')
expect(req.requestHeaders['Upload-Metadata']).toBeUndefined()
expect(req.requestHeaders['Upload-Metadata']).toBe('test d29ybGQ=') // world

req.respondWith({
status: 201,
Expand All @@ -108,7 +111,7 @@ describe('tus', () => {
expect(req.requestHeaders['Tus-Resumable']).toBe('1.0.0')
expect(req.requestHeaders['Upload-Length']).toBe('6')
expect(req.requestHeaders['Upload-Concat']).toBe('partial')
expect(req.requestHeaders['Upload-Metadata']).toBeUndefined()
expect(req.requestHeaders['Upload-Metadata']).toBe('test d29ybGQ=') // world

req.respondWith({
status: 201,
Expand Down Expand Up @@ -188,7 +191,7 @@ describe('tus', () => {
expect(req.requestHeaders['Upload-Concat']).toBe(
'final;https://tus.io/uploads/upload1 https://tus.io/uploads/upload2',
)
expect(req.requestHeaders['Upload-Metadata']).toBe('foo aGVsbG8=')
expect(req.requestHeaders['Upload-Metadata']).toBe('foo aGVsbG8=') // hello

req.respondWith({
status: 201,
Expand Down

0 comments on commit 580bf98

Please sign in to comment.