UNPKG

@nasriya/cachify

Version:

A lightweight, extensible in-memory caching library for storing anything, with built-in TTL and customizable cache types.

88 lines (87 loc) 3.07 kB
import atomix from "@nasriya/atomix"; import PersistanceService from "../../../core/persistence/PersistanceService.js"; import { PassThrough } from "stream"; class S3StorageDriver extends PersistanceService { #_manager; #_client; #_PutObjectCommand; #_GetObjectCommand; constructor(persistenceManager, configs) { super('s3', configs); this.#_manager = persistenceManager; } async #_init() { if (this.#_client) { return; } const moduleName = '@aws-sdk/client-s3'; let mod; try { mod = await atomix.runtime.loadModule(moduleName); } catch (error) { const newErr = new Error(`S3 driver requires "${moduleName}". Please install it with "npm i ${moduleName}".`); newErr.cause = error; throw newErr; } this.#_client = new mod.S3Client(this.configs); this.#_GetObjectCommand = mod.GetObjectCommand; this.#_PutObjectCommand = mod.PutObjectCommand; } /** * Uploads a readable stream to the specified S3 bucket. * * @throws {Error} Throws an error if initialization fails or the S3 client is not available. * @returns {Promise<void>} A promise that resolves when the upload is complete. */ async backup(...args) { const [_, backupStream, key] = args; try { await this.#_init(); const stream = new PassThrough(); const command = new this.#_PutObjectCommand({ Bucket: this.configs.bucket, Key: key, Body: stream }); const sendPromise = this.#_client.send(command); await backupStream.streamTo(stream); await sendPromise; } catch (err) { if (err instanceof Error) { err.message = `Failed to upload to S3: ${err.message}`; } throw err; } } /** * Downloads an object from the specified S3 bucket. * * @throws {Error} Throws an error if initialization fails or the S3 client is not available. * @returns {Promise<Buffer>} A promise that resolves with the content of the downloaded object. */ async restore(...args) { const [key] = args; try { await this.#_init(); const command = new this.#_GetObjectCommand({ Bucket: this.configs.bucket, Key: key, }); const response = await this.#_client.send(command); if (!response.Body) { throw new Error(`S3 object "${key}" not found`); } const restoreStream = this.#_manager.createRestoreStream(); return await restoreStream.streamFrom(response.Body); } catch (error) { if (error instanceof Error) { error.message = `Failed to download from S3: ${error.message}`; } throw error; } } } export default S3StorageDriver;