@uppy/transloadit
Version:
The Transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and more
134 lines (106 loc) • 3.59 kB
text/typescript
import type { Body, Meta, Uppy } from '@uppy/core'
import Emitter from 'component-emitter'
import type { AssemblyResponse } from './index.js'
/**
* Track completion of multiple assemblies.
*
* Emits 'assembly-complete' when an assembly completes.
* Emits 'assembly-error' when an assembly fails.
* Exposes a `.promise` property that resolves when all assemblies have
* completed (or failed).
*/
class TransloaditAssemblyWatcher<
M extends Meta,
B extends Body,
> extends Emitter {
#assemblyIDs
#remaining: number
promise: Promise<void>
#resolve!: () => void
#reject!: (reason?: string) => void
#uppy
constructor(uppy: Uppy<M, B>, assemblyIDs: string[]) {
super()
this.#uppy = uppy
this.#assemblyIDs = assemblyIDs
this.#remaining = assemblyIDs.length
this.promise = new Promise<void>((resolve, reject) => {
this.#resolve = resolve
this.#reject = reject
})
this.#addListeners()
}
/**
* Are we watching this assembly ID?
*/
#watching(id: string) {
return this.#assemblyIDs.indexOf(id) !== -1
}
#onAssemblyComplete = (assembly: AssemblyResponse) => {
const assemblyId = assembly.assembly_id
if (assemblyId == null || !this.#watching(assemblyId)) {
return
}
this.#uppy.log(
`[Transloadit] AssemblyWatcher: Got Assembly finish ${assemblyId}`,
)
this.emit('assembly-complete', assemblyId)
this.#checkAllComplete()
}
#onAssemblyCancel = (assembly: AssemblyResponse) => {
const assemblyId = assembly.assembly_id
if (assemblyId == null || !this.#watching(assemblyId)) {
return
}
this.#checkAllComplete()
}
#onAssemblyError = (assembly: AssemblyResponse, error: Error) => {
const assemblyId = assembly.assembly_id
if (assemblyId == null || !this.#watching(assemblyId)) {
return
}
this.#uppy.log(
`[Transloadit] AssemblyWatcher: Got Assembly error ${assemblyId}`,
)
this.#uppy.log(error)
this.emit('assembly-error', assemblyId, error)
this.#checkAllComplete()
}
#onImportError = (
assembly: AssemblyResponse,
fileID: string,
error: Error,
) => {
const assemblyId = assembly.assembly_id
if (assemblyId == null || !this.#watching(assemblyId)) {
return
}
// Not sure if we should be doing something when it's just one file failing.
// ATM, the only options are 1) ignoring or 2) failing the entire upload.
// I think failing the upload is better than silently ignoring.
// In the future we should maybe have a way to resolve uploads with some failures,
// like returning an object with `{ successful, failed }` uploads.
this.#onAssemblyError(assembly, error)
}
#checkAllComplete() {
this.#remaining -= 1
if (this.#remaining === 0) {
// We're done, these listeners can be removed
this.#removeListeners()
this.#resolve()
}
}
#removeListeners() {
this.#uppy.off('transloadit:complete', this.#onAssemblyComplete)
this.#uppy.off('transloadit:assembly-cancel', this.#onAssemblyCancel)
this.#uppy.off('transloadit:assembly-error', this.#onAssemblyError)
this.#uppy.off('transloadit:import-error', this.#onImportError)
}
#addListeners() {
this.#uppy.on('transloadit:complete', this.#onAssemblyComplete)
this.#uppy.on('transloadit:assembly-cancel', this.#onAssemblyCancel)
this.#uppy.on('transloadit:assembly-error', this.#onAssemblyError)
this.#uppy.on('transloadit:import-error', this.#onImportError)
}
}
export default TransloaditAssemblyWatcher