@zenfs/core
Version:
A filesystem, anywhere
198 lines (197 loc) • 6.74 kB
TypeScript
import type { UUID } from 'node:crypto';
import { Resource } from 'utilium/cache';
import type { UsageInfo } from '../../internal/filesystem.js';
import '../../polyfills.js';
import type { StoreFS } from './fs.js';
/**
* @category Stores and Transactions
*/
export type StoreFlag =
/** The store supports partial reads and writes */
'partial';
/**
* Represents a key-value store.
* @category Stores and Transactions
*/
export interface Store {
/**
* @see FileSystem#id
*/
readonly type?: number;
/**
* What the file system using this store should be called.
* For example, tmpfs for an in memory store
*/
readonly name: string;
/**
* A name for this instance of the store.
* For example, you might use a share name for a network-based store
*/
readonly label?: string;
/**
* A UUID for this instance of the store.
*/
readonly uuid?: UUID;
/**
* Syncs the store
*/
sync(): Promise<void>;
/**
* Begins a new transaction.
*/
transaction(): Transaction;
/**
* Use for optimizations
*/
readonly flags?: readonly StoreFlag[];
/**
* Usage information for the store
*/
usage?(): UsageInfo;
/**
* @internal @hidden
*/
fs?: StoreFS;
}
/**
* A transaction for a store.
* @category Stores and Transactions
*/
export declare abstract class Transaction<T extends Store = Store> {
readonly store: T;
constructor(store: T);
/**
* Gets all of the keys
*/
abstract keys(): Promise<Iterable<number>>;
/**
* Retrieves data.
* @param id The key to look under for data.
*/
abstract get(id: number, offset: number, end?: number): Promise<Uint8Array | undefined>;
/**
* Retrieves data.
* Throws an error if an error occurs or if the key does not exist.
* @param id The key to look under for data.
* @return The data stored under the key, or undefined if not present.
*/
abstract getSync(id: number, offset: number, end?: number): Uint8Array | undefined;
/**
* Adds the data to the store under an id. Overwrites any existing data.
* @param id The key to add the data under.
* @param data The data to add to the store.
*/
abstract set(id: number, data: Uint8Array, offset: number): Promise<void>;
/**
* Adds the data to the store under and id.
* @param id The key to add the data under.
* @param data The data to add to the store.
*/
abstract setSync(id: number, data: Uint8Array, offset: number): void;
/**
* Deletes the data at `ino`.
* @param id The key to delete from the store.
*/
abstract remove(id: number): Promise<void>;
/**
* Deletes the data at `ino`.
* @param id The key to delete from the store.
*/
abstract removeSync(id: number): void;
}
/**
* Transaction that implements asynchronous operations with synchronous ones
* @category Stores and Transactions
*/
export declare abstract class SyncTransaction<T extends Store = Store> extends Transaction<T> {
get(id: number, offset: number, end?: number): Promise<Uint8Array | undefined>;
set(id: number, data: Uint8Array, offset: number): Promise<void>;
remove(id: number): Promise<void>;
}
/**
* @category Stores and Transactions
*/
export interface AsyncStore extends Store {
cache?: Map<number, Resource<number>>;
}
/**
* Transaction that implements synchronous operations with a cache
* Implementors: You *must* update the cache and wait for `store.asyncDone` in your asynchronous methods.
* @todo Make sure we handle abortions correctly, especially since the cache is shared between transactions.
* @category Stores and Transactions
*/
export declare abstract class AsyncTransaction<T extends AsyncStore = AsyncStore> extends Transaction<T> {
protected asyncDone: Promise<unknown>;
/**
* Run a asynchronous operation from a sync context. Not magic and subject to (race) conditions.
* @internal
*/
protected async(promise: Promise<unknown>): void;
/**
* Gets a cache resource
* If `info` is set and the resource doesn't exist, it will be created
* @internal
*/
_cached(id: number, info?: {
size: number;
}): Resource<number> | undefined;
getSync(id: number, offset: number, end?: number): Uint8Array | undefined;
setSync(id: number, data: Uint8Array, offset: number): void;
removeSync(id: number): void;
}
/**
* Wraps a transaction with the ability to roll-back changes, among other things.
* This is used by `StoreFS`
* @category Stores and Transactions
* @internal @hidden
*/
export declare class WrappedTransaction<T extends Store = Store> {
readonly raw: Transaction<T>;
protected fs: StoreFS<T>;
/**
* Whether the transaction was committed or aborted
*/
protected done: boolean;
flag(flag: StoreFlag): boolean;
constructor(raw: Transaction<T>, fs: StoreFS<T>);
/**
* Stores data in the keys we modify prior to modifying them.
* Allows us to roll back commits.
*/
protected originalData: Map<number, {
data?: Uint8Array;
offset: number;
}[]>;
/**TransactionEntry
* List of keys modified in this transaction, if any.
*/
protected modifiedKeys: Set<number>;
keys(): Promise<Iterable<number>>;
get(id: number, offset?: number, end?: number): Promise<Uint8Array | undefined>;
getSync(id: number, offset?: number, end?: number): Uint8Array | undefined;
set(id: number, view: Uint8Array | ArrayBufferView, offset?: number): Promise<void>;
setSync(id: number, view: Uint8Array | ArrayBufferView, offset?: number): void;
remove(id: number): Promise<void>;
removeSync(id: number): void;
commit(): Promise<void>;
commitSync(): void;
abort(): Promise<void>;
abortSync(): void;
[Symbol.asyncDispose](): Promise<void>;
[Symbol.dispose](): void;
/**
* Stashes given key value pair into `originalData` if it doesn't already exist.
* Allows us to stash values the program is requesting anyway to
* prevent needless `get` requests if the program modifies the data later
* on during the transaction.
*/
protected stash(id: number, data?: Uint8Array, offset?: number): void;
/**
* Marks an id as modified, and stashes its value if it has not been stashed already.
*/
protected markModified(id: number, offset: number, length?: number): Promise<void>;
/**
* Marks an id as modified, and stashes its value if it has not been stashed already.
*/
protected markModifiedSync(id: number, offset: number, length?: number): void;
}