npm package: @suraimu/fs
Description: The best high-level FS
Author: @suraimu
Latest version: 1.4.1

# WHAT IS SuraimuFS (SlimeFS)
SuraimuFS, also known as SlimeFS, is a custom file system implementation. It includes fallback mechanisms to handle different scenarios and provides custom implementations for most file system methods.
[![Package quality](https://packagequality.com/badge/yourpackage.png)](https://packagequality.com/#?package=@suraimu/fs)

# CHANGELOGS
[SOURCE CODE IN REPLIT (DEVELOPMENT)](https://replit.com/@incarnatorx/fs)
## v1.4.0 - The directory update
- Added `sync` method to create sync version from `callback-based` method. (Because sometime the author forgot to add the sync-version)
- Added `readdir` method to read a directory
## v1.3.0 - The synchronous update
- Added sync version of all functions
## v1.2.0 - The statistic update
- Added `isDirectory`, `exists` and `stat`
- Added options to `remove`. Options: recursive (default: false), force (default: false), retries (default: 0), retryDelay (default: 90)
- Better performance
## v1.1.0 - Refined edition
- Split callback and promise-based methods for improved handling.
- Added `remove` method for file or directory removal.
- Removed `asyncMode` global setting.
- Introduced `sfs.promises` and `sfs.promise` as aliases for promise-based methods.
## v1.0.0 - The birth
- Introduced `sfs.asyncMode` as a global setting to determine whether methods return promises or use callbacks.
- Added `writeFile`, `readFile`, and `copy` methods.
- All methods now return promises or use callbacks based on the `asyncMode`.

# USAGE
## Installation
```sh
npm install suraimufs
```

## Importing
```js
const sfs = require('sfs');
```

## Callback-based methods
SuraimuFS provides callback-based methods for file system operations. You can use them by passing a callback function as the last argument. This approach allows you to handle the results and potential errors in a callback function. Callbacks are useful in scenarios where you need precise control over the flow of execution or when working with older codebases.

Here's an example of how to use the callback-based version of the `readFile` method:
```js
sfs.readFile('file.txt', 'utf-8', (err, data) => {
  if (err) {
    console.error('Error reading file:', err);
  } else {
    console.log('File content:', data);
  }
});
```

## Promise-based methods
Starting from version 1.1.0, SuraimuFS also offers promise-based methods. You can use them by chaining `.then()` and `.catch()` on the method call. This approach provides a more modern and convenient way to handle asynchronous operations using promises. Additionally, you can use `async/await` with promise-based methods for even more concise and readable code.

Here's an example of how to use the promise-based version of the `writeFile` method:
```js
sfs.promises.writeFile('newfile.txt', 'Hello, SlimeFS!')
  .then(() => {
    console.log('File written successfully.');
  })
  .catch((err) => {
    console.error('Error writing file:', err);
  });
```
or by using `async/await`:
```js
async function writeFile() {
  try {
    await sfs.promises.writeFile('newfile.txt', 'Hello, SlimeFS!')
    console.log('File written successfully.');
  } catch(err) {
    console.error('Error writing file:', err);
  }
}

writeFile();
```

## Synchronous methods
Starting from version 1.3.0, SuraimuFS offers synchronous methods, providing an alternative way to perform file system operations in a synchronous manner. You can use these methods by adding `Sync` at the end of the method name. This allows you to perform operations in a blocking way, which may be useful in certain scenarios.

Keep in mind that using synchronous methods may cause the main thread to block, so it's essential to consider the potential impact on performance and responsiveness, especially in environments that require non-blocking operations.

Here's an example of how to use the synchronous version of the `exists` method:
```js
try {
  const isexist = sfs.existsSync('file1.txt')
  console.log('File1 exist:', isexist)
} catch(err) {
  console.error(err)
}
```

## Methods usage
### Removing file and directory
SuraimuFS provides a remove method to delete files or directories. It supports both callback and promise-based usage. For example:
#### sfs.remove(filepath: string, options?: object, callback?: function(err)): void
```js
sfs.remove('file.txt', (err) => {
  if (err) {
    console.error('Error removing file:', err);
  } else {
    console.log('File removed successfully.');
  }
});
```
#### sfs.promises.remove(filepath: string, options?: object): Promise<Void, Error>
```js
sfs.promises.remove('dir', { force: true })
  .then(() => {
    console.log('Directory removed.');
  })
  .catch((err) => {
    console.error('Error removing directory:', err);
  });
```
#### sfs.removeSync(filepath: string, options?: object): void
```js
sfs.removeSync('file.txt')
```
#### Option:
- `recursive` -> `boolean`
  Whether should remove directory recursively. default: false
- `force` -> `boolean`
  Whether should not throw error if ENOENT error throwed (buggy). default: false
- `retries` -> `integer`
  How many retry if removing fail. default: 0
- `retryDelay` -> `integer`
  The delay beteeen each retry. default: 90

### Writing to file
SuraimuFS provides a writeFile method to write content to file. It supports both callback and promise-based usage. For example:
#### sfs.writeFile(filepath: string, content: string|Buffer|Uint8Array, encoding?: string, callback?: function(err)): void
```js
sfs.writeFile('file.txt', 'Hello, Slime!', (err) => {
  if (err) {
    console.error('Error writing file:', err);
  } else {
    console.log('File written successfully.');
  }
});
```
#### sfs.promises.writeFile(filepath: string, content: string|Buffer|Uint8Array, encoding?: string): Promise<Void, Error>
```js
sfs.promises.writeFile('file.txt', 'Hello, Slime!')
  .then(() => {
    console.log('File written successfully.');
  })
  .catch((err) => {
    console.error('Error writing file:', err);
  });
```
#### sfs.writeFileSync(filepath: string, content: string): void
```js
sfs.writeFileSync('file.txt', 'Hello, Slime!')
```
### Reading a file
SuraimuFS provides a readFile method to read content of a file. It supports both callback and promise-based usage. For example:
#### sfs.readFile(filepath: string, encoding?: string, callback?: function(err: Error, content: string)): void
```js
sfs.readFile('file.txt', (err, content) => {
  if (err) {
    console.error('Error reading file:', err);
  } else {
    console.log(content);
  }
});
```
#### sfs.promises.readFile(filepath: string, encoding?: string): Promise<string, Error>
```js
sfs.promises.readFile('file.txt')
  .then((content) => {
    console.log(content);
  })
  .catch((err) => {
    console.error('Error reading file:', err);
  });
```
#### sfs.readFileSync(filepath: string): string
```js
const d = sfs.readFileSync('file.txt')
```
### Copying a file
SuraimuFS provides a copyFile method to copy the content of a file to another file. It supports both callback and promise-based usage. For example:
#### sfs.copy(filepath: string, targetfilepath: string, callback?: function(err: Error)): void
```js
sfs.copy('file.txt', 'file.copy', (err) => {
  if (err) {
    console.error('Error copying file:', err);
  } else {
    console.log('File copied successfully.');
  }
});
```
#### sfs.promises.copy(filepath: string, targetfilepath: string): Promise<Void, Error>
```js
sfs.promises.copy('file.txt', 'file.copy')
  .then(() => {
    console.log('File copied successfully.');
  })
  .catch((err) => {
    console.error('Error copying file:', err);
  });
```
#### sfs.copySync(filepath: string, targetfilepath: string): void
```js
sfs.copySync('file.txt', 'file.copy')
```
### Stating file
SuraimuFS provides a stat method to get the stat of a file. It supports both callback and promise-based usage. For example:
#### sfs.stat(filepath: string, callback?: function(err: Error, stat: FD?)): void
```js
sfs.stat('file.txt', (err, stat) => {
  if (err) {
    console.error('Error stating file:', err);
  } else {
    console.log('File stated successfully:', stat);
  }
});
```
#### sfs.promises.stat(filepath: string): Promise<FD, Error>
```js
sfs.promises.stat('file.txt')
  .then(() => {
    console.log('File stated successfully:', stat);
  })
  .catch((err) => {
    console.error('Error stating file:', err);
  });
```
#### sfs.statSync(filepath: string): FD?
```js
const stat = sfs.statSync('file.txt')
```
### See whether file is a directory
SuraimuFS provides a isDirectory method to get if a file is a directory. It supports both callback and promise-based usage. For example:
#### sfs.isDirectory(filepath: string, callback?: function(err: Error, isdirectory: bool)): void
```js
sfs.isDirectory('file.txt', (err, isdirectory) => {
  if (err) {
    console.error('Error stating file:', err);
  } else {
    console.log('file1.txt is a directory:', isdirectory); // false
  }
});
```
#### sfs.promises.isDirectory(filepath: string): Promise<bool, Error>
```js
sfs.promises.isDirectory('dir1')
  .then((isdirectory) => {
    console.log('dir1 is a directory:', isdirectory); // true
  })
  .catch((err) => {
    console.error('Error stating file:', err);
  });
```
#### sfs.isDirectorySync(filepath: string): bool
```js
const isdir = sfs.isDirectorySync('dir2')
```
### List files from a directory
SuraimuFS provides a readdir method to get all files from a directory. For example:
#### sfs.readdir(filepath: string, option?: object, callback?: function(err: Error, files: string[])): void
```js
sfs.readdir('dir1', { recursive: true }, (err, files) => {
  if (err) {
    console.error('Error reading directory:', err);
  } else {
    console.log('Files:', files);
  }
});
```
#### sfs.promises.readdir(filepath: string, option?: object): Promise<string[], Error>
```js
sfs.promises.readdir('not/a/dir')
  .then((files) => {
    console.log('Files:', files);
  })
  .catch((err) => {
    console.error('Error readig directory:', err);
  });
```
#### sfs.readdirSync(filepath: string, option?: object): bool
```js
try {
  const files = sfs.readdirSync('dir2', {
    recursive: true,
    filter: '**/*.{js,txt,ts}'
  })
  console.log('Files:', files)
} catch(err) {
  console.error('Error reading directory:', err)
}
```
#### Option:
- `recursive` -> `boolean`
  Whether should read directory recursively. default: false
- `force` -> `boolean`
  Whether should not throw error if ENOENT error throwed (buggy). default: false
- `filter` -> `string`
  How should files filtered. default: false, example: `**/*.txt`