Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@zenfs/core

Package Overview
Dependencies
Maintainers
1
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zenfs/core - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

3

dist/backends/AsyncMirror.d.ts

@@ -38,5 +38,2 @@ import { FileSystem, FileSystemMetadata } from '../filesystem.js';

createFile(path: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;
/**
* @internal
*/
openFile(path: string, flag: FileFlag, cred: Cred): Promise<File>;

@@ -43,0 +40,0 @@ unlink(path: string, cred: Cred): Promise<void>;

@@ -83,2 +83,3 @@ import { Cred } from '../cred.js';

declare const AsyncStoreFileSystem_base: (abstract new (...args: any[]) => {
readonly metadata: FileSystemMetadata;
renameSync(oldPath: string, newPath: string, cred: Cred): void;

@@ -94,16 +95,2 @@ statSync(path: string, cred: Cred): Stats;

syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
readonly metadata: FileSystemMetadata;
ready(): Promise<any>;
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
stat(path: string, cred: Cred): Promise<Stats>;
openFile(path: string, flag: FileFlag, cred: Cred): Promise<File>;
createFile(path: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;
unlink(path: string, cred: Cred): Promise<void>;
rmdir(path: string, cred: Cred): Promise<void>;
mkdir(path: string, mode: number, cred: Cred): Promise<void>;
readdir(path: string, cred: Cred): Promise<string[]>;
exists(path: string, cred: Cred): Promise<boolean>;
existsSync(path: string, cred: Cred): boolean;
link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
}) & typeof FileSystem;

@@ -110,0 +97,0 @@ /**

1

dist/backends/AsyncStore.js

@@ -76,2 +76,3 @@ import { dirname, basename, join, resolve } from '../emulation/path.js';

}
// @ts-expect-error 2611
get metadata() {

@@ -78,0 +79,0 @@ return {

@@ -157,2 +157,3 @@ import type { Cred } from './cred.js';

declare const FileIndexFS_base: (abstract new (...args: any[]) => {
readonly metadata: import("./filesystem.js").FileSystemMetadata;
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;

@@ -172,12 +173,2 @@ renameSync(oldPath: string, newPath: string, cred: Cred): void;

syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
readonly metadata: import("./filesystem.js").FileSystemMetadata;
ready(): Promise<any>;
stat(path: string, cred: Cred): Promise<Stats>;
statSync(path: string, cred: Cred): Stats;
openFile(path: string, flag: FileFlag, cred: Cred): Promise<import("./file.js").File>;
openFileSync(path: string, flag: FileFlag, cred: Cred): import("./file.js").File;
readdir(path: string, cred: Cred): Promise<string[]>;
readdirSync(path: string, cred: Cred): string[];
exists(path: string, cred: Cred): Promise<boolean>;
existsSync(path: string, cred: Cred): boolean;
}) & typeof FileSystem;

@@ -229,2 +220,3 @@ export declare abstract class FileIndexFS<TIndex> extends FileIndexFS_base {

declare const AsyncFileIndexFS_base: (abstract new (...args: any[]) => {
readonly metadata: import("./filesystem.js").FileSystemMetadata;
renameSync(oldPath: string, newPath: string, cred: Cred): void;

@@ -240,16 +232,2 @@ statSync(path: string, cred: Cred): Stats;

syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
readonly metadata: import("./filesystem.js").FileSystemMetadata;
ready(): Promise<any>;
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
stat(path: string, cred: Cred): Promise<Stats>;
openFile(path: string, flag: FileFlag, cred: Cred): Promise<import("./file.js").File>;
createFile(path: string, flag: FileFlag, mode: number, cred: Cred): Promise<import("./file.js").File>;
unlink(path: string, cred: Cred): Promise<void>;
rmdir(path: string, cred: Cred): Promise<void>;
mkdir(path: string, mode: number, cred: Cred): Promise<void>;
readdir(path: string, cred: Cred): Promise<string[]>;
exists(path: string, cred: Cred): Promise<boolean>;
existsSync(path: string, cred: Cred): boolean;
link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
}) & (abstract new (index: ListingTree) => FileIndexFS<unknown>);

@@ -256,0 +234,0 @@ export declare abstract class AsyncFileIndexFS<TIndex> extends AsyncFileIndexFS_base {

@@ -157,11 +157,7 @@ import { ApiError } from './ApiError.js';

/**
* Implements the asynchronous API in terms of the synchronous API.
*
* @example ```ts
* class SyncFS extends Sync(FileSystem) {}
* ```
* @internal
*/
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => {
readonly metadata: FileSystemMetadata;
ready(): Promise<any>;
declare abstract class SyncFileSystem extends FileSystem {
get metadata(): FileSystemMetadata;
ready(): Promise<this>;
exists(path: string, cred: Cred): Promise<boolean>;

@@ -178,57 +174,15 @@ rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;

sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
/**
* Synchronous rename.
*/
}
/**
* Implements the asynchronous API in terms of the synchronous API.
*/
export declare function Sync<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => SyncFileSystem) & T;
/**
* @internal
*/
declare abstract class AsyncFileSystem {
get metadata(): FileSystemMetadata;
renameSync(oldPath: string, newPath: string, cred: Cred): void;
/**
* Synchronous `stat`.
*/
statSync(path: string, cred: Cred): Stats;
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
* @return A File object corresponding to the opened file.
*/
openFileSync(path: string, flag: FileFlag, cred: Cred): File;
/**
* Create the file at path p with the given mode. Then, open it with the given
* flag.
*/
createFileSync(path: string, flag: FileFlag, mode: number, cred: Cred): File;
/**
* Synchronous `unlink`.
*/
unlinkSync(path: string, cred: Cred): void;
/**
* Synchronous `rmdir`.
*/
rmdirSync(path: string, cred: Cred): void;
/**
* Synchronous `mkdir`.
* @param mode Mode to make the directory using. Can be ignored if
* the filesystem doesn't support permissions.
*/
mkdirSync(path: string, mode: number, cred: Cred): void;
/**
* Synchronous `readdir`. Reads the contents of a directory.
*/
readdirSync(path: string, cred: Cred): string[];
/**
* Test whether or not the given path exists by checking with the file system.
*/
existsSync(path: string, cred: Cred): boolean;
/**
* Synchronous `link`.
*/
linkSync(srcpath: string, dstpath: string, cred: Cred): void;
/**
* Synchronize the data and stats for path synchronously
*/
syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
}) & T;
export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => {
renameSync(oldPath: string, newPath: string, cred: Cred): void;
statSync(path: string, cred: Cred): Stats;
createFileSync(path: string, flag: FileFlag, mode: number, cred: Cred): File;
openFileSync(path: string, flag: FileFlag, cred: Cred): File;

@@ -241,64 +195,10 @@ unlinkSync(path: string, cred: Cred): void;

syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
readonly metadata: FileSystemMetadata;
ready(): Promise<any>;
/**
* Asynchronous rename. No arguments other than a possible exception
* are given to the completion callback.
*/
}
export declare function Async<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => AsyncFileSystem) & T;
/**
* @internal
*/
declare abstract class ReadonlyFileSystem {
get metadata(): FileSystemMetadata;
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
/**
* Asynchronous `stat`.
*/
stat(path: string, cred: Cred): Promise<Stats>;
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
*/
openFile(path: string, flag: FileFlag, cred: Cred): Promise<File>;
/**
* Create the file at path p with the given mode. Then, open it with the given
* flag.
*/
createFile(path: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;
/**
* Asynchronous `unlink`.
*/
unlink(path: string, cred: Cred): Promise<void>;
/**
* Asynchronous `rmdir`.
*/
rmdir(path: string, cred: Cred): Promise<void>;
/**
* Asynchronous `mkdir`.
* @param mode Mode to make the directory using. Can be ignored if
* the filesystem doesn't support permissions.
*/
mkdir(path: string, mode: number, cred: Cred): Promise<void>;
/**
* Asynchronous `readdir`. Reads the contents of a directory.
*
* The callback gets two arguments `(err, files)` where `files` is an array of
* the names of the files in the directory excluding `'.'` and `'..'`.
*/
readdir(path: string, cred: Cred): Promise<string[]>;
/**
* Test whether or not the given path exists by checking with the file system.
*/
exists(path: string, cred: Cred): Promise<boolean>;
/**
* Test whether or not the given path exists by checking with the file system.
*/
existsSync(path: string, cred: Cred): boolean;
/**
* Asynchronous `link`.
*/
link(srcpath: string, dstpath: string, cred: Cred): Promise<void>;
/**
* Synchronize the data and stats for path asynchronously
*/
sync(path: string, data: Uint8Array, stats: Readonly<Stats>): Promise<void>;
}) & T;
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => {
rename(oldPath: string, newPath: string, cred: Cred): Promise<void>;
renameSync(oldPath: string, newPath: string, cred: Cred): void;

@@ -317,44 +217,4 @@ createFile(path: string, flag: FileFlag, mode: number, cred: Cred): Promise<File>;

syncSync(path: string, data: Uint8Array, stats: Readonly<Stats>): void;
readonly metadata: FileSystemMetadata;
ready(): Promise<any>;
/**
* Asynchronous `stat`.
*/
stat(path: string, cred: Cred): Promise<Stats>;
/**
* Synchronous `stat`.
*/
statSync(path: string, cred: Cred): Stats;
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
*/
openFile(path: string, flag: FileFlag, cred: Cred): Promise<File>;
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
* @return A File object corresponding to the opened file.
*/
openFileSync(path: string, flag: FileFlag, cred: Cred): File;
/**
* Asynchronous `readdir`. Reads the contents of a directory.
*
* The callback gets two arguments `(err, files)` where `files` is an array of
* the names of the files in the directory excluding `'.'` and `'..'`.
*/
readdir(path: string, cred: Cred): Promise<string[]>;
/**
* Synchronous `readdir`. Reads the contents of a directory.
*/
readdirSync(path: string, cred: Cred): string[];
/**
* Test whether or not the given path exists by checking with the file system.
*/
exists(path: string, cred: Cred): Promise<boolean>;
/**
* Test whether or not the given path exists by checking with the file system.
*/
existsSync(path: string, cred: Cred): boolean;
}) & T;
}
export declare function Readonly<T extends abstract new (...args: any[]) => FileSystem>(FS: T): (abstract new (...args: any[]) => ReadonlyFileSystem) & T;
export {};

@@ -54,6 +54,2 @@ import { ApiError, ErrorCode } from './ApiError.js';

* Implements the asynchronous API in terms of the synchronous API.
*
* @example ```ts
* class SyncFS extends Sync(FileSystem) {}
* ```
*/

@@ -64,3 +60,3 @@ export function Sync(FS) {

*/
class SyncFileSystem extends FS {
class _SyncFileSystem extends FS {
get metadata() {

@@ -106,6 +102,9 @@ return { ...super.metadata, synchronous: true };

}
return SyncFileSystem;
return _SyncFileSystem;
}
export function Async(FS) {
class AsyncFileSystem extends FS {
class _AsyncFileSystem extends FS {
get metadata() {
return { ...super.metadata, synchronous: false };
}
/* eslint-disable @typescript-eslint/no-unused-vars */

@@ -144,6 +143,9 @@ renameSync(oldPath, newPath, cred) {

/* eslint-enable @typescript-eslint/no-unused-vars */
return AsyncFileSystem;
return _AsyncFileSystem;
}
export function Readonly(FS) {
class ReadonlyFileSystem extends FS {
class _ReadonlyFileSystem extends FS {
get metadata() {
return { ...super.metadata, readonly: true };
}
/* eslint-disable @typescript-eslint/no-unused-vars */

@@ -193,3 +195,3 @@ async rename(oldPath, newPath, cred) {

}
return ReadonlyFileSystem;
return _ReadonlyFileSystem;
}
{
"name": "@zenfs/core",
"version": "0.3.0",
"version": "0.3.1",
"description": "A filesystem in your browser",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -7,3 +7,3 @@ # ZenFS

ZenFS is highly extensible, and includes many builtin filesystem backends:
ZenFS is highly extensible, and includes a few built-in backends:

@@ -13,6 +13,8 @@ - `InMemory`: Stores files in-memory. It is a temporary file store that clears when the user navigates away.

- `AsyncMirror`: Use an asynchronous backend synchronously. Invaluable for Emscripten; let your Emscripten applications write to larger file stores with no additional effort!
- `AsyncMirror` loads the entire contents of the async file system into a synchronous backend during construction. It performs operations synchronous file system and then queues them to be mirrored onto the asynchronous backend.
More backends can be defined by separate libraries, so long as they extend they implement `ZenFS.FileSystem`. Multiple backends can be active at once at different locations in the directory hierarchy.
> [!NOTE]
> When constructed, `AsyncMirror` loads the entire contents of the async file system into a synchronous backend. It performs operations on the synchronous file system and then queues them to be mirrored onto the asynchronous backend.
More backends can be defined by separate libraries, as long as they implement `FileSystem`.
ZenFS supports a number of other backends (many are provided as seperate packages under `@zenfs`).

@@ -30,3 +32,4 @@

> 🛈 The examples are written in ESM. If you are using CJS, you can `require` the package. If running in a browser you can add a script tag to your HTML pointing to the `browser.min.js` and use ZenFS via the global `ZenFS` object.
> [!NOTE]
> The examples are written in ESM. If you are using CJS, you can `require` the package. If running in a browser you can add a script tag to your HTML pointing to the `browser.min.js` and use ZenFS via the global `ZenFS` object.

@@ -42,24 +45,12 @@ ```js

#### Using different backends
#### Using different and/or different backends
A `InMemory` backend is created by default. If you would like to use a different one, you must configure ZenFS. It is recommended to do so using the `configure` function. Here is an example using the `Storage` backend from `@zenfs/dom`:
A single `InMemory` backend is created by default, mounted on `/`.
```js
import { configure, fs } from '@zenfs/core';
import { StorageStore } from '@zenfs/dom';
You can configure ZenFS to use a different backend and mount multiple backends. It is strongly recommended to do so using the `configure` function.
await configure({ backend: StorageStore });
You can use multiple backends by passing an object to `configure` which maps paths to file systems.
if (!fs.existsSync('/test.txt')) {
fs.writeFileSync('/test.txt', 'This will persist across reloads!');
}
The following example mounts a zip file to `/zip`, in-memory storage to `/tmp`, and IndexedDB to `/home`. Note that `/` has the default in-memory backend.
const contents = fs.readFileSync('/test.txt', 'utf-8');
console.log(contents);
```
#### Using multiple backends
You can use multiple backends by passing an object to `configure` which maps paths to file systems. The following example mounts a zip file to `/zip`, in-memory storage to `/tmp`, and IndexedDB storage to `/home` (note that `/` has the default in-memory backend):
```js

@@ -73,6 +64,3 @@ import { configure } from '@zenfs/core';

await configure({
'/mnt/zip': {
backend: Zip,
zipData: zipData,
},
'/mnt/zip': { backend: Zip, zipData },
'/tmp': 'InMemory',

@@ -83,4 +71,23 @@ '/home': IndexedDB,

#### FS Promises API
> [!TIP]
> When configuring a mount point, you can pass in 1. A string that maps to a built-in backend 2. A `Backend` object, if the backend has no required options 3. An object that has a `backend` property which is a `Backend` or a string that maps to a built-in backend and the options accepted by the backend
Here is an example that mounts the `Storage` backend from `@zenfs/dom` on `/`:
```js
import { configure, fs } from '@zenfs/core';
import { Storage } from '@zenfs/dom';
await configure({ backend: Storage });
if (!fs.existsSync('/test.txt')) {
fs.writeFileSync('/test.txt', 'This will persist across reloads!');
}
const contents = fs.readFileSync('/test.txt', 'utf-8');
console.log(contents);
```
#### FS Promises
The FS promises API is exposed as `promises`.

@@ -100,7 +107,11 @@

ZenFS does _not_ provide a seperate public import for importing promises in its built form. If you are using ESM, you can import promises functions from `dist/emulation/promises`, though this may change at any time and is not recommended.
> [!NOTE]
> You can import the promises API using `promises`, or using `fs.promises` on the exported `fs`.
> [!IMPORTANT]
> ZenFS does _not_ provide a seperate public import for importing promises like `fs/promises`. If you are using ESM, you can import promises functions like `fs/promises` from the `dist/emulation/promises.ts` file, though this may change at any time and is **not recommended**.
#### Using asynchronous backends synchronously
You may have noticed that attempting to use a synchronous function on an asynchronous backend (e.g. IndexedDB) results in a "not supplied" error (`ENOTSUP`). If you wish to use an asynchronous backend synchronously you need to wrap it in an `AsyncMirror`:
You may have noticed that attempting to use a synchronous function on an asynchronous backend (e.g. `IndexedDB`) results in a "not supplied" error (`ENOTSUP`). If you would like to use an asynchronous backend synchronously you need to wrap it in an `AsyncMirror`:

@@ -119,45 +130,13 @@ ```js

fs.writeFileSync('/persistant.txt', 'My persistant data'); // This fails if you configure with only IndexedDB
fs.writeFileSync('/persistant.txt', 'My persistant data');
```
### Advanced usage
#### Mounting and unmounting, creating backends
#### Creating backends
If you would like to create backends without configure (e.g. to do something dynamic at runtime), you may do so by importing the backend and calling `createBackend` with it.
If you would like to create backends without configure, you may do so by importing the backend and calling `createBackend` with it. You can import the backend directly or with `backends`:
You can then mount and unmount the backend instance by using `mount` and `umount`.
```js
import { configure, backends, InMemory } from '@zenfs/core';
console.log(backends.InMemory === InMemory); // they are the same
const internalInMemoryFS = await createBackend(InMemory);
```
> ⚠ Instances of backends follow the **_internal_** ZenFS API. You should never use a backend's methods unless you are extending a backend.
```js
import { configure, InMemory } from '@zenfs/core';
const internalInMemoryFS = new InMemory();
await internalInMemoryFS.ready();
```
#### Mounting
If you would like to mount and unmount backends, you can do so using the `mount` and `umount` functions:
```js
import { fs, InMemory } from '@zenfs/core';
const internalInMemoryFS = await createBackend(InMemory); // create an FS instance
fs.mount('/tmp', internalInMemoryFS); // mount
fs.umount('/tmp'); // unmount /tmp
```
This could be used in the "multiple backends" example like so:
```js
import { configure, createBackend } from '@zenfs/core';
import { IndexedDB } from '@zenfs/dom';

@@ -168,3 +147,3 @@ import { Zip } from '@zenfs/zip';

'/tmp': 'InMemory',
'/home': 'IndexedDB',
'/home': IndexedDB,
};

@@ -183,2 +162,5 @@

> [!WARNING]
> Instances of backends follow the **internal** ZenFS API. You should never use a backend's methods unless you are extending a backend.
## Using with bundlers

@@ -198,5 +180,1 @@

Run unit tests with `npm test`.
### License
ZenFS is licensed under the MIT License.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc