@zenfs/core
Advanced tools
Comparing version 0.16.0 to 0.16.1
@@ -9,5 +9,13 @@ /// <reference types="node" resolution-mode="require"/> | ||
import { Stats, type FileType } from '../../stats.js'; | ||
import type { Backend, FilesystemOf } from '../backend.js'; | ||
import * as RPC from './rpc.js'; | ||
import { type MountConfiguration } from '../../config.js'; | ||
type FileMethods = Omit<ExtractProperties<File, (...args: any[]) => Promise<any>>, typeof Symbol.asyncDispose>; | ||
type FileMethod = keyof FileMethods; | ||
interface FileRequest<TMethod extends FileMethod = FileMethod> extends RPC.Request { | ||
fd: number; | ||
scope: 'file'; | ||
method: TMethod; | ||
args: Parameters<FileMethods[TMethod]>; | ||
} | ||
export declare class PortFile extends File { | ||
@@ -44,2 +52,7 @@ readonly fs: PortFS; | ||
type FSMethod = keyof FSMethods; | ||
interface FSRequest<TMethod extends FSMethod = FSMethod> extends RPC.Request { | ||
scope: 'fs'; | ||
method: TMethod; | ||
args: Parameters<FSMethods[TMethod]>; | ||
} | ||
declare const PortFS_base: import("../../filesystem.js").Mixin<typeof FileSystem, { | ||
@@ -93,2 +106,10 @@ _sync?: FileSystem | undefined; | ||
} | ||
/** | ||
* @internal | ||
*/ | ||
export type FileOrFSRequest = FSRequest | FileRequest; | ||
/** | ||
* @internal | ||
*/ | ||
export declare function handleRequest(port: RPC.Port, fs: FileSystem, request: FileOrFSRequest): Promise<void>; | ||
export declare function attachFS(port: RPC.Port, fs: FileSystem): void; | ||
@@ -114,2 +135,3 @@ export declare function detachFS(port: RPC.Port, fs: FileSystem): void; | ||
}; | ||
export declare function resolveRemoteMount<T extends Backend>(port: RPC.Port, config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>; | ||
export {}; |
@@ -7,2 +7,3 @@ import { Errno, ErrnoError } from '../../error.js'; | ||
import * as RPC from './rpc.js'; | ||
import { resolveMountConfig } from '../../config.js'; | ||
export class PortFile extends File { | ||
@@ -163,3 +164,6 @@ constructor(fs, fd, path, position) { | ||
const descriptors = new Map(); | ||
async function handleRequest(port, fs, request) { | ||
/** | ||
* @internal | ||
*/ | ||
export async function handleRequest(port, fs, request) { | ||
if (!RPC.isMessage(request)) { | ||
@@ -238,1 +242,8 @@ return; | ||
}; | ||
export async function resolveRemoteMount(port, config, _depth = 0) { | ||
const stopAndReplay = RPC.catchMessages(port); | ||
const fs = await resolveMountConfig(config, _depth); | ||
attachFS(port, fs); | ||
stopAndReplay(fs); | ||
return fs; | ||
} |
/// <reference types="node" resolution-mode="require"/> | ||
import { type ErrnoErrorJSON } from '../../error.js'; | ||
import type { Backend, FilesystemOf } from '../backend.js'; | ||
import { type PortFS } from './fs.js'; | ||
@@ -65,1 +66,2 @@ type _MessageEvent<T = any> = T | { | ||
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>) => void; |
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Errno, ErrnoError } from '../../error.js'; | ||
import { PortFile } from './fs.js'; | ||
import { handleRequest, PortFile } from './fs.js'; | ||
function isFileData(value) { | ||
@@ -75,1 +75,13 @@ return typeof value == 'object' && value != null && 'fd' in value && 'path' in value && 'position' in value; | ||
} | ||
export function catchMessages(port) { | ||
const events = []; | ||
const handler = events.push.bind(events); | ||
attach(port, handler); | ||
return function (fs) { | ||
detach(port, handler); | ||
for (const event of events) { | ||
const request = 'data' in event ? event.data : event; | ||
handleRequest(port, fs, request); | ||
} | ||
}; | ||
} |
@@ -12,3 +12,3 @@ import type { Backend, BackendConfiguration, FilesystemOf, SharedConfig } from './backends/backend.js'; | ||
export declare function resolveMountConfig<T extends Backend>(config: MountConfiguration<T>, _depth?: number): Promise<FilesystemOf<T>>; | ||
type ConfigMounts = { | ||
export type ConfigMounts = { | ||
[K in AbsolutePath]: Backend; | ||
@@ -44,2 +44,1 @@ }; | ||
export declare function configure<T extends ConfigMounts>(config: Partial<Configuration<T>>): Promise<void>; | ||
export {}; |
{ | ||
"name": "@zenfs/core", | ||
"version": "0.16.0", | ||
"version": "0.16.1", | ||
"description": "A filesystem, anywhere", | ||
@@ -54,2 +54,7 @@ "main": "dist/index.js", | ||
}, | ||
"lint-staged": { | ||
"*": [ | ||
"prettier --write" | ||
] | ||
}, | ||
"dependencies": { | ||
@@ -74,2 +79,3 @@ "@types/node": "^20.12.12", | ||
"jest": "^29.7.0", | ||
"lint-staged": "^15.2.7", | ||
"prettier": "^3.2.5", | ||
@@ -76,0 +82,0 @@ "ts-jest": "^29.1.5", |
@@ -10,4 +10,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { InMemory } from '../memory.js'; | ||
import type { Backend } from '../backend.js'; | ||
import type { Backend, FilesystemOf } from '../backend.js'; | ||
import * as RPC from './rpc.js'; | ||
import { type MountConfiguration, resolveMountConfig } from '../../config.js'; | ||
@@ -227,5 +228,11 @@ type FileMethods = Omit<ExtractProperties<File, (...args: any[]) => Promise<any>>, typeof Symbol.asyncDispose>; | ||
type FileOrFSRequest = FSRequest | FileRequest; | ||
/** | ||
* @internal | ||
*/ | ||
export type FileOrFSRequest = FSRequest | FileRequest; | ||
async function handleRequest(port: RPC.Port, fs: FileSystem, request: FileOrFSRequest): Promise<void> { | ||
/** | ||
* @internal | ||
*/ | ||
export async function handleRequest(port: RPC.Port, fs: FileSystem, request: FileOrFSRequest): Promise<void> { | ||
if (!RPC.isMessage(request)) { | ||
@@ -313,1 +320,9 @@ return; | ||
} satisfies Backend<PortFS, RPC.Options>; | ||
export async function resolveRemoteMount<T extends Backend>(port: RPC.Port, config: MountConfiguration<T>, _depth = 0): Promise<FilesystemOf<T>> { | ||
const stopAndReplay = RPC.catchMessages(port); | ||
const fs = await resolveMountConfig(config, _depth); | ||
attachFS(port, fs); | ||
stopAndReplay(fs); | ||
return fs; | ||
} |
@@ -29,8 +29,6 @@ # Port Backend | ||
```ts | ||
import { InMemory, resolveMountConfig } from '@zenfs/core'; | ||
import { attachFS } from '@zenfs/port'; | ||
import { InMemory, resolveRemoteMount, attachFS } from '@zenfs/core'; | ||
import { parentPort } from 'node:worker_threads'; | ||
const tmpfs = await resolveMountConfig({ backend: InMemory, name: 'tmp' }); | ||
attachFS(parentPort, tmpfs); | ||
await resolveRemoteMount(parentPort, { backend: InMemory, name: 'tmp' }); | ||
``` | ||
@@ -43,12 +41,9 @@ | ||
```ts | ||
import { InMemory, fs, resolveMountConfig } from '@zenfs/core'; | ||
import { Port, attachFS } from '@zenfs/port'; | ||
import { InMemory, fs, resolveMountConfig, resolveRemoteMount, Port } from '@zenfs/core'; | ||
import { MessageChannel } from 'node:worker_threads'; | ||
const { port1, port2 } = new MessageChannel(); | ||
const { port1: localPort, port2: remotePort } = new MessageChannel(); | ||
const tmpfs = await resolveMountConfig({ backend: InMemory, name: 'tmp' }); | ||
attachFS(port2, tmpfs); | ||
fs.mount('/port', await resolveMountConfig({ backend: Port, port: port1 })); | ||
console.log('/port'); | ||
fs.mount('/remote', await resolveRemoteMount(remotePort, { backend: InMemory, name: 'tmp' })); | ||
fs.mount('/port', await resolveMountConfig({ backend: Port, port: localPort })); | ||
@@ -59,4 +54,4 @@ const content = 'FS is in a port'; | ||
fs.readFileSync('/tmp/test', 'utf8'); // FS is in a port | ||
fs.readFileSync('/remote/test', 'utf8'); // FS is in a port | ||
await fs.promises.readFile('/port/test', 'utf8'); // FS is in a port | ||
``` |
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Errno, ErrnoError, type ErrnoErrorJSON } from '../../error.js'; | ||
import { PortFile, type PortFS } from './fs.js'; | ||
import type { Backend, FilesystemOf } from '../backend.js'; | ||
import { handleRequest, PortFile, type PortFS } from './fs.js'; | ||
import type { FileOrFSRequest } from './fs.js'; | ||
@@ -151,1 +153,14 @@ type _MessageEvent<T = any> = T | { data: T }; | ||
} | ||
export function catchMessages<T extends Backend>(port: Port): (fs: FilesystemOf<T>) => void { | ||
const events: _MessageEvent[] = []; | ||
const handler = events.push.bind(events); | ||
attach(port, handler); | ||
return function (fs: any) { | ||
detach(port, handler); | ||
for (const event of events) { | ||
const request: FileOrFSRequest = 'data' in event ? event.data : event; | ||
handleRequest(port, fs, request); | ||
} | ||
}; | ||
} |
@@ -70,3 +70,3 @@ import type { Backend, BackendConfiguration, FilesystemOf, SharedConfig } from './backends/backend.js'; | ||
type ConfigMounts = { [K in AbsolutePath]: Backend }; | ||
export type ConfigMounts = { [K in AbsolutePath]: Backend }; | ||
@@ -73,0 +73,0 @@ /** |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1896145
21233
15