UNPKG

@tokenizer/s3

Version:
63 lines 2.15 kB
import { parseContentRange } from '@tokenizer/range'; import { GetObjectCommand } from '@aws-sdk/client-s3'; import { Readable } from 'node:stream'; /** * Use S3-client to execute actual HTTP-requests. */ export class S3Request { constructor(s3, objRequest) { this.s3 = s3; this.objRequest = objRequest; this.abortController = new AbortController(); } /** * Concatenate given array of Uint8Arrays * @param arrays Array of Uint8Arrays */ static mergeUint8Arrays(...arrays) { const totalSize = arrays.reduce((acc, e) => acc + e.length, 0); const merged = new Uint8Array(totalSize); arrays.forEach((array, i, arrays) => { const offset = arrays.slice(0, i).reduce((acc, e) => acc + e.length, 0); merged.set(array, offset); }); return merged; } async buildArrayBuffer(response) { const buffers = []; if (response.Body instanceof Readable) { for await (const chunk of response.Body) { buffers.push(chunk); } return S3Request.mergeUint8Arrays(...buffers); } throw new Error('body expected to be an instance of Readable '); } async getResponse(method, range) { const response = await this.getRangedRequest(range); const contentRange = parseContentRange(response.ContentRange); return { size: contentRange?.instanceLength, mimeType: response.ContentType, contentRange, acceptPartialRequests: true, arrayBuffer: () => this.buildArrayBuffer(response), }; } /** * Do a ranged request * @param range Range request */ getRangedRequest(range) { const rangedRequest = { ...this.objRequest, Range: `bytes=${range[0]}-${range[1]}`, }; const command = new GetObjectCommand(rangedRequest); return this.s3.send(command, { abortSignal: this.abortController.signal }); } abort() { this.abortController.abort(); } } //# sourceMappingURL=s3-request.js.map