UNPKG

@zenfs/core

Version:

A filesystem, anywhere

144 lines (143 loc) 5.26 kB
import type { ExceptionJSON } from 'kerium'; import type { TransferListItem } from 'node:worker_threads'; import type { WithOptional } from 'utilium'; import type { Backend, FilesystemOf } from '../backends/backend.js'; import type { PortFS } from '../backends/port.js'; import type { CreationOptions, FileSystem, UsageInfo } from '../internal/filesystem.js'; import '../polyfills.js'; export interface WebMessagePort { postMessage(value: unknown, transfer?: TransferListItem[]): void; addEventListener(type: 'message', listener: (ev: { data: any; }) => void): void; removeEventListener(type: 'message', listener: (ev: { data: any; }) => void): void; } export interface NodeMessagePort { postMessage(value: unknown, transfer?: TransferListItem[]): void; on(type: 'message', listener: (ev: any) => void): void; off(type: 'message', listener: (ev: any) => void): void; } export type Channel = NodeMessagePort | WebMessagePort | WebSocket; /** @internal */ export interface Port<T extends Channel = Channel> { readonly channel: T; /** Send a request */ send<M extends Message>(message: M, transfer?: TransferListItem[]): void; /** Add a response handler */ addHandler<M extends Message>(handler: (message: M) => void): void; /** Remove a response handler */ removeHandler<M extends Message>(handler: (message: M) => void): void; /** Remove all handlers */ disconnect?(): void; } export declare function isPort<T extends Channel>(port: unknown): port is Port<T>; /** * Creates a new RPC port from a `Worker` or `MessagePort` that extends `EventTarget` */ export declare function fromWeb<T extends WebMessagePort>(port: T): Port<T>; /** * Creates a new RPC port from a Node.js `Worker` or `MessagePort`. */ export declare function fromNode<T extends NodeMessagePort>(port: T): Port<T>; /** * Creates a new RPC port from a WebSocket. * @experimental */ export declare function fromWebSocket<T extends WebSocket>(ws: T): Port<T>; export declare function from<T extends Channel>(port: T | Port<T>): Port<T>; /** * The options for the RPC options * @category Backends and Configuration */ export interface Options { /** * The target port that you want to connect to, or the current port if in a port context. */ port: Port; /** * How long to wait for a request to complete */ timeout?: number; } /** * The API for remote procedure calls * @category Internals * @internal */ export interface Methods { usage(): UsageInfo; ready(): void; rename(oldPath: string, newPath: string): void; createFile(path: string, options: CreationOptions): Uint8Array; unlink(path: string): void; rmdir(path: string): void; mkdir(path: string, options: CreationOptions): Uint8Array; readdir(path: string): string[]; touch(path: string, metadata: Uint8Array): void; exists(path: string): boolean; link(target: string, link: string): void; sync(): void; read(path: string, buffer: Uint8Array, start: number, end: number): Uint8Array; write(path: string, buffer: Uint8Array, offset: number): void; stat(path: string): Uint8Array; } /** * The methods that can be called on the RPC port * @category Internals * @internal */ export type Method = keyof Methods; /** * An RPC message * @category Internals * @internal */ export interface Message { _zenfs: true; id: string; method: Method; stack: string; } export interface Request<TMethod extends Method = Method> extends Message { method: TMethod; args: Parameters<Methods[TMethod]>; } export interface Response<TMethod extends Method = Method> extends Message { error?: WithOptional<ExceptionJSON, 'code' | 'errno'>; method: TMethod; value: ReturnType<Methods[TMethod]>; } /** * Encode a RPC message as a string using JSON. * This is only done when structured cloning is not available. * @internal */ export declare function encodeMessage(message: Message): string; /** * Decode a RPC message from a string using JSON. * This is only done when structured cloning is not available. * @internal */ export declare function decodeMessage<T extends Message>(message: string): T; export declare function isMessage(arg: unknown): arg is Message; /** * An RPC executor * @internal @hidden */ export interface Executor extends PromiseWithResolvers<any> { fs: PortFS; timeout: ReturnType<typeof setTimeout>; } export declare function request<const TRequest extends Request, TValue>(request: Omit<TRequest, 'id' | 'stack' | '_zenfs'>, { port, timeout: ms, fs }: Partial<Options> & { fs: PortFS; }): Promise<TValue>; export declare function handleResponse<const TMethod extends Method>(response: Response<TMethod>): void; export declare function attach<T extends Message>(port: Port, handler: (message: T) => unknown): void; export declare function detach<T extends Message>(port: Port, handler: (message: T) => unknown): void; export declare function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => Promise<void>; /** @internal */ export declare function handleRequest(port: Port, fs: FileSystem & { _descriptors?: Map<number, File>; }, request: Request): Promise<void>;