BREAKING CHANGE(SmartFileFactory): Refactor to in-memory file API and introduce SmartFileFactory; delegate filesystem operations to @push.rocks/smartfs; bump to 12.0.0
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import * as smartfileFs from './fs.js';
|
||||
import * as smartfileFsStream from './fsstream.js';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
type TStreamSource = (streamFile: StreamFile) => Promise<Readable | ReadableStream>;
|
||||
@@ -8,30 +6,36 @@ type TStreamSource = (streamFile: StreamFile) => Promise<Readable | ReadableStre
|
||||
/**
|
||||
* The StreamFile class represents a file as a stream.
|
||||
* It allows creating streams from a file path, a URL, or a buffer.
|
||||
* Use SmartFileFactory to create instances of this class.
|
||||
*/
|
||||
export class StreamFile {
|
||||
// STATIC
|
||||
|
||||
public static async fromPath(filePath: string): Promise<StreamFile> {
|
||||
const streamSource: TStreamSource = async (streamFileArg) =>
|
||||
smartfileFsStream.createReadStream(filePath);
|
||||
const streamFile = new StreamFile(streamSource, filePath);
|
||||
public static async fromPath(filePath: string, smartFs?: any): Promise<StreamFile> {
|
||||
if (!smartFs) {
|
||||
throw new Error('No SmartFs instance available. Create StreamFile through SmartFileFactory.');
|
||||
}
|
||||
|
||||
const streamSource: TStreamSource = async (streamFileArg) => {
|
||||
return await streamFileArg.smartFs.file(filePath).readStream();
|
||||
};
|
||||
const streamFile = new StreamFile(streamSource, filePath, smartFs);
|
||||
streamFile.multiUse = true;
|
||||
streamFile.byteLengthComputeFunction = async () => {
|
||||
const stats = await smartfileFs.stat(filePath);
|
||||
const stats = await smartFs.file(filePath).stat();
|
||||
return stats.size;
|
||||
};
|
||||
return streamFile;
|
||||
}
|
||||
|
||||
public static async fromUrl(url: string): Promise<StreamFile> {
|
||||
public static async fromUrl(url: string, smartFs?: any): Promise<StreamFile> {
|
||||
const streamSource: TStreamSource = async (streamFileArg) => {
|
||||
const response = await plugins.smartrequest.SmartRequest.create()
|
||||
.url(url)
|
||||
.get();
|
||||
return response.stream();
|
||||
};
|
||||
const streamFile = new StreamFile(streamSource);
|
||||
const streamFile = new StreamFile(streamSource, undefined, smartFs);
|
||||
streamFile.multiUse = true;
|
||||
streamFile.byteLengthComputeFunction = async () => {
|
||||
const response = await plugins.smartrequest.SmartRequest.create()
|
||||
@@ -47,6 +51,7 @@ export class StreamFile {
|
||||
public static fromBuffer(
|
||||
buffer: Buffer,
|
||||
relativeFilePath?: string,
|
||||
smartFs?: any
|
||||
): StreamFile {
|
||||
const streamSource: TStreamSource = async (streamFileArg) => {
|
||||
const stream = new Readable();
|
||||
@@ -54,7 +59,7 @@ export class StreamFile {
|
||||
stream.push(null); // End of stream
|
||||
return stream;
|
||||
};
|
||||
const streamFile = new StreamFile(streamSource, relativeFilePath);
|
||||
const streamFile = new StreamFile(streamSource, relativeFilePath, smartFs);
|
||||
streamFile.multiUse = true;
|
||||
streamFile.byteLengthComputeFunction = async () => buffer.length;
|
||||
return streamFile;
|
||||
@@ -65,12 +70,14 @@ export class StreamFile {
|
||||
* @param stream A Node.js Readable stream.
|
||||
* @param relativeFilePath Optional file path for the stream.
|
||||
* @param multiUse If true, the stream can be read multiple times, caching its content.
|
||||
* @param smartFs Optional SmartFs instance for filesystem operations
|
||||
* @returns A StreamFile instance.
|
||||
*/
|
||||
public static fromStream(
|
||||
stream: Readable,
|
||||
relativeFilePath?: string,
|
||||
multiUse: boolean = false,
|
||||
smartFs?: any
|
||||
): StreamFile {
|
||||
const streamSource: TStreamSource = (streamFileArg) => {
|
||||
if (streamFileArg.multiUse) {
|
||||
@@ -84,7 +91,7 @@ export class StreamFile {
|
||||
}
|
||||
};
|
||||
|
||||
const streamFile = new StreamFile(streamSource, relativeFilePath);
|
||||
const streamFile = new StreamFile(streamSource, relativeFilePath, smartFs);
|
||||
streamFile.multiUse = multiUse;
|
||||
|
||||
// If multi-use is enabled, cache the stream when it's first read
|
||||
@@ -106,6 +113,7 @@ export class StreamFile {
|
||||
// INSTANCE
|
||||
relativeFilePath?: string;
|
||||
private streamSource: TStreamSource;
|
||||
private smartFs?: any;
|
||||
|
||||
// enable stream based multi use
|
||||
private cachedStreamBuffer?: Buffer;
|
||||
@@ -113,9 +121,10 @@ export class StreamFile {
|
||||
public used: boolean = false;
|
||||
public byteLengthComputeFunction: () => Promise<number>;
|
||||
|
||||
private constructor(streamSource: TStreamSource, relativeFilePath?: string) {
|
||||
private constructor(streamSource: TStreamSource, relativeFilePath?: string, smartFs?: any) {
|
||||
this.streamSource = streamSource;
|
||||
this.relativeFilePath = relativeFilePath;
|
||||
this.smartFs = smartFs;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
@@ -148,9 +157,13 @@ export class StreamFile {
|
||||
* @param filePathArg The file path where the stream should be written.
|
||||
*/
|
||||
public async writeToDisk(filePathArg: string): Promise<void> {
|
||||
if (!this.smartFs) {
|
||||
throw new Error('No SmartFs instance available. Create StreamFile through SmartFileFactory.');
|
||||
}
|
||||
|
||||
this.checkMultiUse();
|
||||
const readStream = await this.createReadStream();
|
||||
const writeStream = smartfileFsStream.createWriteStream(filePathArg);
|
||||
const writeStream = await this.smartFs.file(filePathArg).writeStream();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
readStream.pipe(writeStream);
|
||||
@@ -161,9 +174,14 @@ export class StreamFile {
|
||||
}
|
||||
|
||||
public async writeToDir(dirPathArg: string) {
|
||||
if (!this.smartFs) {
|
||||
throw new Error('No SmartFs instance available. Create StreamFile through SmartFileFactory.');
|
||||
}
|
||||
|
||||
this.checkMultiUse();
|
||||
const filePath = plugins.path.join(dirPathArg, this.relativeFilePath);
|
||||
await smartfileFs.ensureDir(plugins.path.parse(filePath).dir);
|
||||
const dirPath = plugins.path.parse(filePath).dir;
|
||||
await this.smartFs.directory(dirPath).create({ recursive: true });
|
||||
return this.writeToDisk(filePath);
|
||||
}
|
||||
|
||||
@@ -196,4 +214,17 @@ export class StreamFile {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the StreamFile to a SmartFile by loading content into memory
|
||||
*/
|
||||
public async toSmartFile(): Promise<any> {
|
||||
const { SmartFile } = await import('./classes.smartfile.js');
|
||||
const buffer = await this.getContentAsBuffer();
|
||||
return new SmartFile({
|
||||
path: this.relativeFilePath || 'stream',
|
||||
contentBuffer: buffer,
|
||||
base: process.cwd()
|
||||
}, this.smartFs);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user