Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metadataForPartialUploads option to set metadata for partial uploads only #703

Merged
merged 6 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading