@mainnet-pat/indexeddb-fs
v2.1.12
Published
An 'fs' kind of library dedicated to the browser
Downloads
134
Maintainers
Readme
indexeddb-fs
An fs library for the browser that lets you store data using an API similar to Node's fs module. It's powered by IndexedDB, a browser database.
Motivation
Other solutions I found didn't work well. They lacked validation and didn't create directories properly.
Installation
npm install indexeddb-fs
A simple example of how you can use indexeddb-fs
import fs from 'indexeddb-fs';
async function main() {
// Check if a directory exists
const directoryExists = await fs.isDirectory('my_directory');
// Create a new directory if it doesn't exist
if (!directoryExists) {
await fs.createDirectory('my_directory');
}
// Write data to a file
const content = 'Hello, world!';
await fs.writeFile('my_directory/my_file.txt', content);
// Read data from the file
const readContent = await fs.readFile('my_directory/my_file.txt');
console.log(readContent); // "Hello, world!"
// Remove the directory and all files within it
await fs.removeDirectory('my_directory');
}
main();
A more complex example that demonstrates the use of all the functions
import fs from 'indexeddb-fs';
async function main() {
// Create a new directory and subdirectories
await fs.createDirectory('my_directory');
await fs.createDirectory('my_directory/subdirectory');
await fs.createDirectory('my_directory/another_subdirectory');
// Write some content to a file
const content = 'Hello, world!';
await fs.writeFile('my_directory/my_file.txt', content);
// Check if a file exists and if it's a file
const fileExists = await fs.exists('my_directory/my_file.txt');
const isAFile = await fs.isFile('my_directory/my_file.txt');
console.log('File exists:', fileExists); // true
console.log('Is a file:', isAFile); // true
// Copy the file to a new location
await fs.copyFile('my_directory/my_file.txt', 'my_directory/another_subdirectory/my_file_copy.txt');
// Rename and move the original file to a new location
await fs.renameFile('my_directory/my_file.txt', 'my_directory/new_file_name.txt');
await fs.moveFile('my_directory/new_file_name.txt', 'my_directory/subdirectory/new_location.txt');
// Read the contents of a directory and count the number of files and subdirectories
const { filesCount, directoriesCount } = await fs.readDirectory('my_directory');
console.log('Number of files:', filesCount); // 0
console.log('Number of subdirectories:', directoriesCount); // 2
// Remove the directory and all files within it
await fs.removeDirectory('my_directory');
// Read the contents of the copied file
const copiedFileContent = await fs.readFile('my_directory/another_subdirectory/my_file_copy.txt');
console.log('Copied file content:', copiedFileContent); // "Hello, world!"
}
main();
Custom fs object
import { createFs } from 'indexeddb-fs';
const fs = createFs({
databaseVersion: 'indexeddb version (default "1")',
objectStoreName: 'store name in indexeddb (default "files")',
rootDirectoryName: 'your root directory name (default "root") ',
databaseName: 'indexeddb database name (default "indexeddb-fs")',
});
Api
- All methods in indexeddb-fs return a Promise since IndexedDB is an asynchronous API.
- Each method can reject the returned Promise with an
Error
object when an error occurs. - It's important to handle errors appropriately in your code to ensure your application is robust and doesn't break unexpectedly.
Fields
The indexeddb-fs library contains several configuration fields that can be accessed after importing the library. These fields include:
databaseName
: the name of the IndexedDB database used by the library.databaseVersion
: the version number of the IndexedDB database used by the library.objectStoreName
: the name of the object store used by the library to store data.rootDirectoryName
: the name of the root directory used by the library.
To access these fields, import them from the indexeddb-fs
module as shown in the example code above. These fields contain configuration information for the library and can also be used to access default values.
Common functions
fs.exists(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<boolean>
- Description: Returns a promise that resolves to
true
if the file or directory at the givenfullPath
exists, andfalse
otherwise.
Example of usage:
// Check if a file exists
const fileExists = await fs.exists('path/to/file.txt');
if (fileExists) {
console.log('The file exists!');
} else {
console.log('The file does not exist.');
}
// Check if a directory exists
const dirExists = await fs.exists('path/to/directory');
if (dirExists) {
console.log('The directory exists!');
} else {
console.log('The directory does not exist.');
}
fs.remove(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<void>
- Description: Removes the file or directory at the given
fullPath
. The method does not remove directories recursively, so it will throw an error if the path is not empty.
Example of usage:
// Remove a file
await fs.writeFile('file1.txt', 'test content');
await fs.remove('file1.txt');
await fs.exists('file1.txt').then((result) => {
console.log(!result);
});
// Remove an empty directory
await fs.createDirectory('directory1');
await fs.remove('directory1');
await fs.exists('directory1').then((result) => {
console.log(!result);
});
// Attempt to remove a non-empty directory
await fs.createDirectory('directory2');
await fs.writeFile('directory2/file2.txt', 'test content');
await fs.remove('directory2').catch((error) => {
console.error(error.message);
});
await fs.exists('directory2').then((result) => {
console.log(result);
});
fs.details(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<FileEntry<any> | DirectoryEntry>
- Description: Returns an object containing details about the file or directory at the given
fullPath
. The object contains the following properties:type
: The type of the entry (file or directory).name
: The name of the entry.directory
: The name of the directory that contains the entry.fullPath
: The full path of the entry, including the directory.
- Throws an error when the path does not contain anything.
Example of usage:
// Get details of a newly created directory
const createdDirectory = await fs.createDirectory('directory');
const createdDirectoryDetails = await fs.details(createdDirectory.fullPath);
console.log('Type:', createdDirectoryDetails.type); // directory
console.log('Name:', createdDirectoryDetails.name); // directory
console.log('Directory:', createdDirectoryDetails.directory); // root
console.log('Full Path:', createdDirectoryDetails.fullPath); // root/directory
Example result for FileEntry<any>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
Example result for DirectoryEntry
type:
{
isRoot: false,
directory: 'root',
type: 'directory',
name: 'directory',
createdAt: 1626882291087,
fullPath: 'root/directory'
}
File functions
fs.isFile(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<boolean>
- Description: Returns a promise that resolves to
true
if a file exists at the givenfullPath
, andfalse
otherwise. If the path does not contain anything, an error is thrown.
Example of usage:
import fs from 'indexeddb-fs';
// Create directories for testing
await fs.createDirectory('files');
await fs.createDirectory('directories');
// Check if directories are files
await fs.isFile('files').then((result) => {
console.log(result);
});
await fs.isFile('directories').then((result) => {
console.log(result);
});
// Create a file and check if it is a file
await fs.writeFile('file', 'content');
await fs.isFile('file').then((result) => {
console.log(result);
});
// Create a file in the 'files' directory and check if it is a file
await fs.writeFile('files/file', 'content');
await fs.isFile('files/file').then((result) => {
console.log(result);
});
Example result for FileEntry<TData>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
fs.writeFile(fullPath, data)
- Parameters: [
fullPath
: string,data
: TData] - Returns:
Promise<FileEntry<TData>>
- Description: Writes
data
to the file specified byfullPath
, replacing the file if it already exists. Thedata
parameter can be any data you want to write to the file, and is usually a string or an object that can be serialized to JSON. The method returns a promise that resolves to aFileEntry
object representing the file that was written. - Throws an error when the destination directory of the file does not exist. This can happen if the path to the file contains one or more directories that do not exist yet. You can use the
createDirectory
method to create the missing directories. - Throws an error when the path contains a directory with the same name as the file. For example, if a directory named "file.txt" exists, you cannot create a file with the same name in the same directory.
Example of usage:
import fs from 'indexeddb-fs';
// Create a directory to write the file to
await fs.createDirectory('my_directory');
// Write some data to a file
const fileEntry = await fs.writeFile('my_directory/my_file.txt', 'Hello, world!');
console.log(fileEntry); // FileEntry object representing the file that was written
Example result for FileEntry<TData>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
fs.fileDetails(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<FileEntry<TData>>
- Description: Returns a promise that resolves to a
FileEntry
object containing details about the file specified byfullPath
. TheFileEntry
object includes information such as the file's name, size, modification date, and type. If the file does not exist, or if the path contains directories that do not exist, the method will throw an error. - Throws an error when the path does not contain anything. This can happen if the
fullPath
parameter is an empty string ornull
. - Throws an error when the destination file is not a file. For example, if the path points to a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Get details about a file
const fileEntry = await fs.fileDetails('my_directory/my_file.txt');
console.log(fileEntry); // FileEntry object representing the file
fs.readFile(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<TData>
- Description: Returns a promise that resolves to the contents of the file specified by
fullPath
. The returned data type is the same type with which it was saved. For example, if the file was saved as a string using thewriteFile
method, the returned data type will also be a string. If the file was saved as an object using thewriteFile
method, the returned data type will also be an object. - Throws an error when the destination file does not exist. This can happen if the file was deleted or if the
fullPath
parameter points to a file that does not exist yet. - Throws an error when the destination file is not a file. For example, if the path points to a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Read the contents of a file
const fileContents = await fs.readFile('my_directory/my_file.txt');
console.log(fileContents); // Contents of the file
fs.removeFile(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<void>
- Description: Removes the file specified by
fullPath
. The method returns a promise that resolves once the file has been successfully removed. - Throws an error when the path does not contain anything. This can happen if the
fullPath
parameter is an empty string ornull
. - Throws an error when the destination file is not a file. For example, if the path points to a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Remove a file
await fs.removeFile('my_directory/my_file.txt');
fs.renameFile(fullPath, newFilename)
- Parameters: [
fullPath
: string,newFilename
: string] - Returns:
Promise<FileEntry<TData>>
- Description: Renames the file specified by
fullPath
to the new filename provided asnewFilename
. The method returns a promise that resolves to aFileEntry
object representing the renamed file. - Throws an error when the path does not contain anything. This can happen if the
fullPath
parameter is an empty string ornull
. - Throws an error when the
fullPath
is not a file. For example, if the path points to a directory, the method will throw an error. - Throws an error when the
fullPath
with anewFilename
is already taken. For example, if a file namednewFilename
already exists in the same directory as the original file, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Rename a file
const renamedFile = await fs.renameFile('my_directory/my_file.txt', 'new_file.txt');
console.log(renamedFile); // FileEntry object representing the renamed file
Example result for FileEntry<TData>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
fs.copyFile(fullPath, destinationPath)
- Parameters: [
fullPath
: string,destinationPath
: string] - Returns:
Promise<FileEntry<TData>>
- Description: Copies the file specified by
fullPath
to the destination path specified bydestinationPath
. The method returns a promise that resolves to aFileEntry
object representing the copied file at the newdestinationPath
. - Throws an error when the path does not contain anything. This can happen if the
fullPath
ordestinationPath
parameters are empty strings ornull
. - Throws an error when the
fullPath
is not a file. For example, if the path points to a directory, the method will throw an error. - Throws an error when the
destinationPath
is already taken. For example, if a file or directory already exists at thedestinationPath
, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Copy a file
const copiedFile = await fs.copyFile('my_directory/my_file.txt', 'my_directory/copied_file.txt');
console.log(copiedFile); // FileEntry object representing the copied file
Example result for FileEntry<TData>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
fs.moveFile(fullPath, destinationPath)
- Parameters: [
fullPath
: string,destinationPath
: string] - Returns:
Promise<FileEntry<TData>>
- Description: Moves the file specified by
fullPath
to the destination path specified bydestinationPath
. The method returns a promise that resolves to aFileEntry
object representing the moved file at the newdestinationPath
. - Throws an error when the path does not contain anything. This can happen if the
fullPath
ordestinationPath
parameters are empty strings ornull
. - Throws an error when the
fullPath
is not a file. For example, if the path points to a directory, the method will throw an error. - Throws an error when the
destinationPath
is already taken. For example, if a file or directory already exists at thedestinationPath
, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Move a file
const movedFile = await fs.moveFile('my_directory/my_file.txt', 'my_directory/moved_file.txt');
console.log(movedFile); // FileEntry object representing the moved file
Example result for FileEntry<TData>
type:
{
type: 'file',
name: 'file.txt',
directory: 'root',
data: 'test 2 content',
createdAt: 1626882161631,
fullPath: 'root/file.txt'
}
Directory functions
fs.isDirectory(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<boolean>
- Description: Returns
true
if the path specified byfullPath
contains a directory,false
otherwise. - Throws an error when the path does not contain anything. This can happen if the
fullPath
parameter is an empty string ornull
.
Example of usage:
import fs from 'indexeddb-fs';
// Check if a path is a directory
const isDirectory = await fs.isDirectory('my_directory');
console.log(isDirectory); // true if 'my_directory' is a directory, false otherwise
fs.createDirectory(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<DirectoryEntry>
- Description: Creates a new directory at the path specified by
fullPath
and returns a Promise that resolves to aDirectoryEntry
object representing the new directory. - Throws an error when the destination directory of the directory does not exist. For example, if the
fullPath
parameter specifies a nested directory structure, the method will throw an error if any of the parent directories do not already exist. - Throws an error when the path contains a file with the same name. For example, if a file called
'my_directory'
already exists in the specified path, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Create a new directory
const newDirectory = await fs.createDirectory('my_directory');
console.log(newDirectory); // DirectoryEntry object representing the new directory
Example result for DirectoryEntry
type:
{
isRoot: false,
directory: 'root',
type: 'directory',
name: 'directory',
createdAt: 1626882291087,
fullPath: 'root/directory'
}
fs.readDirectory(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<ReadDirectoryInstanceOutput>
- Description: Reads the entire contents of the directory specified by
fullPath
and returns a Promise that resolves to an object containing an array ofDirectoryEntry
andFileEntry
objects representing the contents of the directory, as well as a count of the number of directories and files in the directory. - Throws an error when the destination directory does not exist. For example, if the
fullPath
parameter specifies a nested directory structure, the method will throw an error if any of the parent directories do not exist. - Throws an error when the destination directory is not a directory. For example, if the
fullPath
parameter specifies a file rather than a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Read the contents of a directory
const directoryContents = await fs.readDirectory('my_directory');
console.log(directoryContents);
// { files: [...], directories: [...], filesCount: 2, directoriesCount: 1 }
Example result for ReadDirectoryInstanceOutput
type:
{
files: [],
filesCount: 0,
isEmpty: true,
directories: [],
directoriesCount: 0,
}
fs.directoryDetails(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<DirectoryEntry>
- Description: Returns an object with details about the directory specified by
fullPath
. The method returns a Promise that resolves to aDirectoryEntry
object representing the directory. - Throws an error when the path does not contain anything. For example, if the
fullPath
parameter is an empty string or undefined, the method will throw an error. - Throws an error when the destination directory is not a directory. For example, if the
fullPath
parameter specifies a file rather than a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Get details about a directory
const directory = await fs.directoryDetails('my_directory');
console.log(directory);
// DirectoryEntry object representing the directory
Example result for DirectoryEntry
type:
{
isRoot: false,
directory: 'root',
type: 'directory',
name: 'directory',
createdAt: 1626882291087,
fullPath: 'root/directory'
}
fs.removeDirectory(fullPath)
- Parameters: [
fullPath
: string] - Returns:
Promise<void>
- Description: Removes the directory specified by
fullPath
, recursively removing any files/subdirectories contained within. The method returns a Promise that resolves once the directory has been removed. - Throws an error when the destination directory does not exist. For example, if the
fullPath
parameter specifies a nested directory structure, the method will throw an error if any of the parent directories do not exist. - Throws an error when the destination directory is not a directory. For example, if the
fullPath
parameter specifies a file rather than a directory, the method will throw an error.
Example of usage:
import fs from 'indexeddb-fs';
// Remove a directory
await fs.removeDirectory('my_directory');
License
This project is licensed under the MIT License - see the LICENSE file for details.