@zenfs/core
Advanced tools
Comparing version 0.15.2 to 0.16.0
@@ -10,3 +10,3 @@ /// <reference types="node" resolution-mode="require"/> | ||
import * as RPC from './rpc.js'; | ||
type FileMethods = ExtractProperties<File, (...args: any[]) => Promise<any>>; | ||
type FileMethods = Omit<ExtractProperties<File, (...args: any[]) => Promise<any>>, typeof Symbol.asyncDispose>; | ||
type FileMethod = keyof FileMethods; | ||
@@ -13,0 +13,0 @@ export declare class PortFile extends File { |
@@ -198,14 +198,6 @@ import { Errno, ErrnoError } from '../../error.js'; | ||
catch (e) { | ||
value = e; | ||
value = e instanceof ErrnoError ? e.toJSON() : e.toString(); | ||
error = true; | ||
} | ||
port.postMessage({ | ||
_zenfs: true, | ||
scope, | ||
id, | ||
error, | ||
method, | ||
stack, | ||
value: value instanceof ErrnoError ? value.toJSON() : value, | ||
}); | ||
port.postMessage({ _zenfs: true, scope, id, error, method, stack, value }); | ||
} | ||
@@ -212,0 +204,0 @@ export function attachFS(port, fs) { |
/// <reference types="node" resolution-mode="require"/> | ||
/// <reference types="node" resolution-mode="require"/> | ||
import type { TransferListItem } from 'worker_threads'; | ||
import { type ErrnoErrorJSON } from '../../error.js'; | ||
import { type PortFS } from './fs.js'; | ||
@@ -9,7 +8,7 @@ type _MessageEvent<T = any> = T | { | ||
export interface Port { | ||
postMessage(value: unknown, transferList?: ReadonlyArray<TransferListItem>): void; | ||
postMessage(value: unknown): void; | ||
on?(event: 'message', listener: (value: unknown) => void): this; | ||
off?(event: 'message', listener: (value: unknown) => void): this; | ||
addEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void; | ||
removeEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void; | ||
addEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void; | ||
removeEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void; | ||
} | ||
@@ -29,16 +28,21 @@ export interface Options { | ||
*/ | ||
export interface Message<TScope extends string = string, TMethod extends string = string> { | ||
export interface Message { | ||
_zenfs: true; | ||
scope: TScope; | ||
scope: 'fs' | 'file'; | ||
id: string; | ||
method: TMethod; | ||
method: string; | ||
stack: string; | ||
} | ||
export interface Request<TScope extends string = string, TMethod extends string = string, TArgs extends unknown[] = unknown[]> extends Message<TScope, TMethod> { | ||
args: TArgs; | ||
export interface Request extends Message { | ||
args: unknown[]; | ||
} | ||
export interface Response<TScope extends string = string, TMethod extends string = string, TValue = unknown> extends Message<TScope, TMethod> { | ||
error: boolean; | ||
value: Awaited<TValue> extends File ? FileData : Awaited<TValue>; | ||
interface _ResponseWithError extends Message { | ||
error: true; | ||
value: ErrnoErrorJSON | string; | ||
} | ||
interface _ResponseWithValue<T> extends Message { | ||
error: false; | ||
value: Awaited<T> extends File ? FileData : Awaited<T>; | ||
} | ||
export type Response<T = unknown> = _ResponseWithError | _ResponseWithValue<T>; | ||
export interface FileData { | ||
@@ -50,3 +54,3 @@ fd: number; | ||
export { FileData as File }; | ||
export declare function isMessage(arg: unknown): arg is Message<string, string>; | ||
export declare function isMessage(arg: unknown): arg is Message; | ||
type _Executor = Parameters<ConstructorParameters<typeof Promise<any>>[0]>; | ||
@@ -53,0 +57,0 @@ export interface Executor { |
@@ -1,2 +0,3 @@ | ||
import { ErrnoError, Errno } from '../../error.js'; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { Errno, ErrnoError } from '../../error.js'; | ||
import { PortFile } from './fs.js'; | ||
@@ -41,3 +42,3 @@ function isFileData(value) { | ||
if (error) { | ||
const e = ErrnoError.fromJSON(value); | ||
const e = typeof value == 'string' ? new Error(value) : ErrnoError.fromJSON(value); | ||
e.stack += stack; | ||
@@ -44,0 +45,0 @@ reject(e); |
@@ -5,3 +5,3 @@ import type { Cred } from '../../cred.js'; | ||
import { type Ino, Inode } from '../../inode.js'; | ||
import { type Stats, FileType } from '../../stats.js'; | ||
import type { FileType, Stats } from '../../stats.js'; | ||
import type { Store, Transaction } from './store.js'; | ||
@@ -8,0 +8,0 @@ /** |
@@ -1,9 +0,8 @@ | ||
import { W_OK, R_OK } from '../../emulation/constants.js'; | ||
import { dirname, basename, join, resolve } from '../../emulation/path.js'; | ||
import { ErrnoError, Errno } from '../../error.js'; | ||
import { R_OK, S_IFDIR, S_IFREG, W_OK } from '../../emulation/constants.js'; | ||
import { basename, dirname, join, resolve } from '../../emulation/path.js'; | ||
import { Errno, ErrnoError } from '../../error.js'; | ||
import { PreloadFile, flagToMode } from '../../file.js'; | ||
import { FileSystem } from '../../filesystem.js'; | ||
import { Inode, rootIno, randomIno } from '../../inode.js'; | ||
import { FileType } from '../../stats.js'; | ||
import { encodeDirListing, encode, decodeDirListing } from '../../utils.js'; | ||
import { Inode, randomIno, rootIno } from '../../inode.js'; | ||
import { decodeDirListing, encode, encodeDirListing } from '../../utils.js'; | ||
const maxInodeAllocTries = 5; | ||
@@ -202,7 +201,7 @@ /** | ||
const data = new Uint8Array(0); | ||
const file = await this.commitNew(this.store.transaction(), path, FileType.FILE, mode, cred, data); | ||
const file = await this.commitNew(this.store.transaction(), path, S_IFREG, mode, cred, data); | ||
return new PreloadFile(this, path, flag, file.toStats(), data); | ||
} | ||
createFileSync(path, flag, mode, cred) { | ||
this.commitNewSync(path, FileType.FILE, mode, cred); | ||
this.commitNewSync(path, S_IFREG, mode, cred); | ||
return this.openFileSync(path, flag, cred); | ||
@@ -255,6 +254,6 @@ } | ||
const tx = this.store.transaction(), data = encode('{}'); | ||
await this.commitNew(tx, path, FileType.DIRECTORY, mode, cred, data); | ||
await this.commitNew(tx, path, S_IFDIR, mode, cred, data); | ||
} | ||
mkdirSync(path, mode, cred) { | ||
this.commitNewSync(path, FileType.DIRECTORY, mode, cred, encode('{}')); | ||
this.commitNewSync(path, S_IFDIR, mode, cred, encode('{}')); | ||
} | ||
@@ -383,3 +382,3 @@ async readdir(path, cred) { | ||
const inode = new Inode(); | ||
inode.mode = 0o777 | FileType.DIRECTORY; | ||
inode.mode = 0o777 | S_IFDIR; | ||
// If the root doesn't exist, the first random ID shouldn't exist either. | ||
@@ -400,3 +399,3 @@ await tx.set(inode.ino, encode('{}')); | ||
const inode = new Inode(); | ||
inode.mode = 0o777 | FileType.DIRECTORY; | ||
inode.mode = 0o777 | S_IFDIR; | ||
// If the root doesn't exist, the first random ID shouldn't exist either. | ||
@@ -403,0 +402,0 @@ tx.setSync(inode.ino, encode('{}')); |
@@ -17,2 +17,3 @@ /// <reference types="node" resolution-mode="require"/> | ||
import type { FileContents } from '../filesystem.js'; | ||
import '../polyfills.js'; | ||
import { BigIntStats, type Stats } from '../stats.js'; | ||
@@ -22,3 +23,2 @@ import { Dir, Dirent } from './dir.js'; | ||
export * as constants from './constants.js'; | ||
import '../polyfills.js'; | ||
export declare class FileHandle implements promises.FileHandle { | ||
@@ -25,0 +25,0 @@ /** |
@@ -49,3 +49,4 @@ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) { | ||
import { isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js'; | ||
import { BigIntStats, FileType } from '../stats.js'; | ||
import '../polyfills.js'; | ||
import { BigIntStats } from '../stats.js'; | ||
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js'; | ||
@@ -58,3 +59,2 @@ import * as constants from './constants.js'; | ||
export * as constants from './constants.js'; | ||
import '../polyfills.js'; | ||
export class FileHandle { | ||
@@ -673,3 +673,3 @@ constructor(fdOrFile) { | ||
const handle = await _open(path, 'r+', 0o644, false); | ||
await handle.file._setType(FileType.SYMLINK); | ||
await handle.file._setType(constants.S_IFLNK); | ||
} | ||
@@ -676,0 +676,0 @@ symlink; |
@@ -49,3 +49,3 @@ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) { | ||
import { isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../file.js'; | ||
import { BigIntStats, FileType } from '../stats.js'; | ||
import { BigIntStats } from '../stats.js'; | ||
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js'; | ||
@@ -529,3 +529,3 @@ import { COPYFILE_EXCL, F_OK, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } from './constants.js'; | ||
const file = _openSync(path, 'r+', 0o644, false); | ||
file._setTypeSync(FileType.SYMLINK); | ||
file._setTypeSync(S_IFLNK); | ||
} | ||
@@ -532,0 +532,0 @@ symlinkSync; |
/// <reference types="node" resolution-mode="require"/> | ||
import type * as Node from 'fs'; | ||
import type { Cred } from './cred.js'; | ||
import { S_IFDIR, S_IFLNK, S_IFREG } from './emulation/constants.js'; | ||
/** | ||
* Indicates the type of the given file. Applied to 'mode'. | ||
*/ | ||
export declare enum FileType { | ||
FILE = 32768, | ||
DIRECTORY = 16384, | ||
SYMLINK = 40960 | ||
} | ||
export type FileType = typeof S_IFREG | typeof S_IFDIR | typeof S_IFLNK; | ||
/** | ||
@@ -13,0 +10,0 @@ * |
import { S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK, S_IRWXG, S_IRWXO, S_IRWXU } from './emulation/constants.js'; | ||
import { size_max } from './inode.js'; | ||
/** | ||
* Indicates the type of the given file. Applied to 'mode'. | ||
*/ | ||
export var FileType; | ||
(function (FileType) { | ||
FileType[FileType["FILE"] = 32768] = "FILE"; | ||
FileType[FileType["DIRECTORY"] = 16384] = "DIRECTORY"; | ||
FileType[FileType["SYMLINK"] = 40960] = "SYMLINK"; | ||
})(FileType || (FileType = {})); | ||
/** | ||
* Provides information about a particular entry in the file system. | ||
@@ -88,19 +79,5 @@ * Common code used by both Stats and BigIntStats. | ||
this.ino = this._convert(ino ?? 0); | ||
const itemType = Number(mode) & S_IFMT || FileType.FILE; | ||
if (mode) { | ||
this.mode = this._convert(mode); | ||
} | ||
else { | ||
switch (itemType) { | ||
case FileType.FILE: | ||
this.mode = this._convert(0o644); | ||
break; | ||
case FileType.DIRECTORY: | ||
default: | ||
this.mode = this._convert(0o777); | ||
} | ||
} | ||
// Check if mode also includes top-most bits, which indicate the file's type. | ||
this.mode = this._convert(mode ?? 0o644 & S_IFREG); | ||
if ((this.mode & S_IFMT) == 0) { | ||
this.mode = (this.mode | this._convert(itemType)); | ||
this.mode = (this.mode | this._convert(S_IFREG)); | ||
} | ||
@@ -107,0 +84,0 @@ } |
{ | ||
"name": "@zenfs/core", | ||
"version": "0.15.2", | ||
"version": "0.16.0", | ||
"description": "A filesystem, anywhere", | ||
@@ -24,3 +24,3 @@ "main": "dist/index.js", | ||
"homepage": "https://github.com/zen-fs/core", | ||
"author": "James P. <jp@drvortex.dev> (https://drvortex.dev)", | ||
"author": "James Prevett <jp@jamespre.dev> (https://jamespre.dev)", | ||
"contributors": [ | ||
@@ -27,0 +27,0 @@ "John Vilk <jvilk@cs.umass.edu>" |
@@ -13,6 +13,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
type FileMethods = ExtractProperties<File, (...args: any[]) => Promise<any>>; | ||
type FileMethods = Omit<ExtractProperties<File, (...args: any[]) => Promise<any>>, typeof Symbol.asyncDispose>; | ||
type FileMethod = keyof FileMethods; | ||
interface FileRequest<TMethod extends FileMethod & string = FileMethod & string> extends RPC.Request<'file', TMethod, Parameters<FileMethods[TMethod]>> { | ||
interface FileRequest<TMethod extends FileMethod = FileMethod> extends RPC.Request { | ||
fd: number; | ||
scope: 'file'; | ||
method: TMethod; | ||
args: Parameters<FileMethods[TMethod]>; | ||
} | ||
@@ -130,3 +133,7 @@ | ||
type FSMethod = keyof FSMethods; | ||
type FSRequest<TMethod extends FSMethod = FSMethod> = RPC.Request<'fs', TMethod, Parameters<FSMethods[TMethod]>>; | ||
interface FSRequest<TMethod extends FSMethod = FSMethod> extends RPC.Request { | ||
scope: 'fs'; | ||
method: TMethod; | ||
args: Parameters<FSMethods[TMethod]>; | ||
} | ||
@@ -260,16 +267,8 @@ /** | ||
} | ||
} catch (e) { | ||
value = e; | ||
} catch (e: any) { | ||
value = e instanceof ErrnoError ? e.toJSON() : e.toString(); | ||
error = true; | ||
} | ||
port.postMessage({ | ||
_zenfs: true, | ||
scope, | ||
id, | ||
error, | ||
method, | ||
stack, | ||
value: value instanceof ErrnoError ? value.toJSON() : value, | ||
}); | ||
port.postMessage({ _zenfs: true, scope, id, error, method, stack, value }); | ||
} | ||
@@ -276,0 +275,0 @@ |
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/// !<reference lib="DOM" /> | ||
import type { TransferListItem } from 'worker_threads'; | ||
import { ErrnoError, Errno, type ErrnoErrorJSON } from '../../error.js'; | ||
import { Errno, ErrnoError, type ErrnoErrorJSON } from '../../error.js'; | ||
import { PortFile, type PortFS } from './fs.js'; | ||
@@ -10,7 +8,7 @@ | ||
export interface Port { | ||
postMessage(value: unknown, transferList?: ReadonlyArray<TransferListItem>): void; | ||
postMessage(value: unknown): void; | ||
on?(event: 'message', listener: (value: unknown) => void): this; | ||
off?(event: 'message', listener: (value: unknown) => void): this; | ||
addEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void; | ||
removeEventListener?(type: 'message', listener: (this: Port, ev: _MessageEvent) => void): void; | ||
addEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void; | ||
removeEventListener?(type: 'message', listener: (ev: _MessageEvent) => void): void; | ||
} | ||
@@ -32,19 +30,26 @@ | ||
*/ | ||
export interface Message<TScope extends string = string, TMethod extends string = string> { | ||
export interface Message { | ||
_zenfs: true; | ||
scope: TScope; | ||
scope: 'fs' | 'file'; | ||
id: string; | ||
method: TMethod; | ||
method: string; | ||
stack: string; | ||
} | ||
export interface Request<TScope extends string = string, TMethod extends string = string, TArgs extends unknown[] = unknown[]> extends Message<TScope, TMethod> { | ||
args: TArgs; | ||
export interface Request extends Message { | ||
args: unknown[]; | ||
} | ||
export interface Response<TScope extends string = string, TMethod extends string = string, TValue = unknown> extends Message<TScope, TMethod> { | ||
error: boolean; | ||
value: Awaited<TValue> extends File ? FileData : Awaited<TValue>; | ||
interface _ResponseWithError extends Message { | ||
error: true; | ||
value: ErrnoErrorJSON | string; | ||
} | ||
interface _ResponseWithValue<T> extends Message { | ||
error: false; | ||
value: Awaited<T> extends File ? FileData : Awaited<T>; | ||
} | ||
export type Response<T = unknown> = _ResponseWithError | _ResponseWithValue<T>; | ||
export interface FileData { | ||
@@ -64,3 +69,3 @@ fd: number; | ||
export function isMessage(arg: unknown): arg is Message<string, string> { | ||
export function isMessage(arg: unknown): arg is Message { | ||
return typeof arg == 'object' && arg != null && '_zenfs' in arg && !!arg._zenfs; | ||
@@ -112,3 +117,3 @@ } | ||
if (error) { | ||
const e = ErrnoError.fromJSON(value as ErrnoErrorJSON); | ||
const e = typeof value == 'string' ? new Error(value) : ErrnoError.fromJSON(value); | ||
e.stack += stack; | ||
@@ -115,0 +120,0 @@ reject(e); |
import type { Cred } from '../../cred.js'; | ||
import { W_OK, R_OK } from '../../emulation/constants.js'; | ||
import { dirname, basename, join, resolve } from '../../emulation/path.js'; | ||
import { ErrnoError, Errno } from '../../error.js'; | ||
import { R_OK, S_IFDIR, S_IFREG, W_OK } from '../../emulation/constants.js'; | ||
import { basename, dirname, join, resolve } from '../../emulation/path.js'; | ||
import { Errno, ErrnoError } from '../../error.js'; | ||
import { PreloadFile, flagToMode } from '../../file.js'; | ||
import { FileSystem, type FileSystemMetadata } from '../../filesystem.js'; | ||
import { type Ino, Inode, rootIno, randomIno } from '../../inode.js'; | ||
import { type Stats, FileType } from '../../stats.js'; | ||
import { encodeDirListing, encode, decodeDirListing } from '../../utils.js'; | ||
import { type Ino, Inode, randomIno, rootIno } from '../../inode.js'; | ||
import type { FileType, Stats } from '../../stats.js'; | ||
import { decodeDirListing, encode, encodeDirListing } from '../../utils.js'; | ||
import type { Store, Transaction } from './store.js'; | ||
@@ -230,3 +230,3 @@ | ||
const data = new Uint8Array(0); | ||
const file = await this.commitNew(this.store.transaction(), path, FileType.FILE, mode, cred, data); | ||
const file = await this.commitNew(this.store.transaction(), path, S_IFREG, mode, cred, data); | ||
return new PreloadFile(this, path, flag, file.toStats(), data); | ||
@@ -236,3 +236,3 @@ } | ||
public createFileSync(path: string, flag: string, mode: number, cred: Cred): PreloadFile<this> { | ||
this.commitNewSync(path, FileType.FILE, mode, cred); | ||
this.commitNewSync(path, S_IFREG, mode, cred); | ||
return this.openFileSync(path, flag, cred); | ||
@@ -296,7 +296,7 @@ } | ||
data = encode('{}'); | ||
await this.commitNew(tx, path, FileType.DIRECTORY, mode, cred, data); | ||
await this.commitNew(tx, path, S_IFDIR, mode, cred, data); | ||
} | ||
public mkdirSync(path: string, mode: number, cred: Cred): void { | ||
this.commitNewSync(path, FileType.DIRECTORY, mode, cred, encode('{}')); | ||
this.commitNewSync(path, S_IFDIR, mode, cred, encode('{}')); | ||
} | ||
@@ -453,3 +453,3 @@ | ||
const inode = new Inode(); | ||
inode.mode = 0o777 | FileType.DIRECTORY; | ||
inode.mode = 0o777 | S_IFDIR; | ||
// If the root doesn't exist, the first random ID shouldn't exist either. | ||
@@ -471,3 +471,3 @@ await tx.set(inode.ino, encode('{}')); | ||
const inode = new Inode(); | ||
inode.mode = 0o777 | FileType.DIRECTORY; | ||
inode.mode = 0o777 | S_IFDIR; | ||
// If the root doesn't exist, the first random ID shouldn't exist either. | ||
@@ -474,0 +474,0 @@ tx.setSync(inode.ino, encode('{}')); |
@@ -13,3 +13,4 @@ import { Buffer } from 'buffer'; | ||
import type { FileContents } from '../filesystem.js'; | ||
import { BigIntStats, FileType, type Stats } from '../stats.js'; | ||
import '../polyfills.js'; | ||
import { BigIntStats, type Stats } from '../stats.js'; | ||
import { normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js'; | ||
@@ -22,3 +23,2 @@ import * as constants from './constants.js'; | ||
export * as constants from './constants.js'; | ||
import '../polyfills.js'; | ||
@@ -753,3 +753,3 @@ export class FileHandle implements promises.FileHandle { | ||
const handle = await _open(path, 'r+', 0o644, false); | ||
await handle.file._setType(FileType.SYMLINK); | ||
await handle.file._setType(constants.S_IFLNK); | ||
} | ||
@@ -756,0 +756,0 @@ symlink satisfies typeof promises.symlink; |
@@ -580,3 +580,3 @@ import { Buffer } from 'buffer'; | ||
const file = _openSync(path, 'r+', 0o644, false); | ||
file._setTypeSync(FileType.SYMLINK); | ||
file._setTypeSync(S_IFLNK); | ||
} | ||
@@ -583,0 +583,0 @@ symlinkSync satisfies typeof fs.symlinkSync; |
@@ -9,7 +9,3 @@ import type * as Node from 'fs'; | ||
*/ | ||
export enum FileType { | ||
FILE = S_IFREG, | ||
DIRECTORY = S_IFDIR, | ||
SYMLINK = S_IFLNK, | ||
} | ||
export type FileType = typeof S_IFREG | typeof S_IFDIR | typeof S_IFLNK; | ||
@@ -192,19 +188,6 @@ /** | ||
this.ino = this._convert(ino ?? 0); | ||
const itemType: FileType = Number(mode) & S_IFMT || FileType.FILE; | ||
this.mode = this._convert(mode ?? 0o644 & S_IFREG); | ||
if (mode) { | ||
this.mode = this._convert(mode); | ||
} else { | ||
switch (itemType) { | ||
case FileType.FILE: | ||
this.mode = this._convert(0o644); | ||
break; | ||
case FileType.DIRECTORY: | ||
default: | ||
this.mode = this._convert(0o777); | ||
} | ||
} | ||
// Check if mode also includes top-most bits, which indicate the file's type. | ||
if ((this.mode & S_IFMT) == 0) { | ||
this.mode = (this.mode | this._convert(itemType)) as T; | ||
this.mode = (this.mode | this._convert(S_IFREG)) as T; | ||
} | ||
@@ -211,0 +194,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1891417
21158