@zenfs/core
Version:
A filesystem, anywhere
146 lines (145 loc) • 5.05 kB
TypeScript
import type { MountConfiguration } from '../config.js';
import type { CreationOptions } from '../internal/filesystem.js';
import type { InodeLike } from '../internal/inode.js';
import type { Backend, FilesystemOf } from './backend.js';
import { FileSystem } from '../internal/filesystem.js';
import { Inode } from '../internal/inode.js';
import * as RPC from '../internal/rpc.js';
import '../polyfills.js';
export { RPC };
/**
* @category Backends and Configuration
*/
export interface PortOptions {
/**
* The target port that you want to connect to, or the current port if in a port context.
*/
port: RPC.Channel;
/**
* How long to wait for a request to complete
*/
timeout?: number;
}
declare const PortFS_base: import("../index.js").Mixin<typeof FileSystem, import("../mixins/async.js").AsyncMixin>;
/**
* PortFS lets you access an FS instance that is running in a port, or the other way around.
*
* Note that *direct* synchronous operations are not permitted on the PortFS,
* regardless of the configuration option of the remote FS.
* @category Internals
* @internal
*/
export declare class PortFS<T extends RPC.Channel = RPC.Channel> extends PortFS_base {
readonly channel: T;
readonly timeout: number;
readonly port: RPC.Port<T>;
/**
* @hidden
*/
_sync: import("./index.js").StoreFS<import("./memory.js").InMemoryStore>;
/**
* Constructs a new PortFS instance that connects with the FS running on `options.port`.
*/
constructor(channel: T, timeout?: number);
protected rpc<const T extends RPC.Method>(method: T, ...args: Parameters<RPC.Methods[T]>): Promise<Awaited<ReturnType<RPC.Methods[T]>>>;
ready(): Promise<void>;
rename(oldPath: string, newPath: string): Promise<void>;
stat(path: string): Promise<Inode>;
touch(path: string, metadata: InodeLike | Inode): Promise<void>;
sync(): Promise<void>;
createFile(path: string, options: CreationOptions): Promise<Inode>;
unlink(path: string): Promise<void>;
rmdir(path: string): Promise<void>;
mkdir(path: string, options: CreationOptions): Promise<Inode>;
readdir(path: string): Promise<string[]>;
exists(path: string): Promise<boolean>;
link(srcpath: string, dstpath: string): Promise<void>;
read(path: string, buffer: Uint8Array, start: number, end: number): Promise<void>;
write(path: string, buffer: Uint8Array, offset: number): Promise<void>;
}
export declare function attachFS(channel: RPC.Channel | RPC.Port, fs: FileSystem): void;
export declare function detachFS(channel: RPC.Channel | RPC.Port, fs: FileSystem): void;
declare const _Port: {
name: string;
options: {
port: {
type: ({
new (): EventTarget;
prototype: EventTarget;
} | ((e: any) => boolean))[];
required: true;
};
timeout: {
type: string;
required: false;
};
};
create(opt: PortOptions): PortFS<RPC.Channel>;
};
type _Port = typeof _Port;
/**
* @category Backends and Configuration
*/
export interface Port extends _Port {
}
/**
* A backend for usage with ports and workers. See the examples below.
*
* #### Accessing an FS on a remote Worker from the main thread
*
* Main:
*
* ```ts
* import { configure } from '@zenfs/core';
* import { Port } from '@zenfs/port';
* import { Worker } from 'node:worker_threads';
*
* const worker = new Worker('worker.js');
*
* await configure({
* mounts: {
* '/worker': {
* backend: Port,
* port: worker,
* },
* },
* });
* ```
*
* Worker:
*
* ```ts
* import { InMemory, resolveRemoteMount, attachFS } from '@zenfs/core';
* import { parentPort } from 'node:worker_threads';
*
* await resolveRemoteMount(parentPort, { backend: InMemory, name: 'tmp' });
* ```
*
* If you are using using web workers, you would use `self` instead of importing `parentPort` in the worker, and would not need to import `Worker` in the main thread.
*
* #### Using with multiple ports on the same thread
*
* ```ts
* import { InMemory, fs, resolveMountConfig, resolveRemoteMount, Port } from '@zenfs/core';
* import { MessageChannel } from 'node:worker_threads';
*
* const { port1: localPort, port2: remotePort } = new MessageChannel();
*
* fs.mount('/remote', await resolveRemoteMount(remotePort, { backend: InMemory, name: 'tmp' }));
* fs.mount('/port', await resolveMountConfig({ backend: Port, port: localPort }));
*
* const content = 'FS is in a port';
*
* await fs.promises.writeFile('/port/test', content);
*
* fs.readFileSync('/remote/test', 'utf8'); // FS is in a port
* await fs.promises.readFile('/port/test', 'utf8'); // FS is in a port
* ```
*
* @category Backends and Configuration
*/
export declare const Port: Port;
/**
* @category Backends and Configuration
*/
export declare function resolveRemoteMount<T extends Backend>(channel: RPC.Channel | RPC.Port, config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>;