import type { wasi } from "@bjorn3/browser_wasi_shim"; import type { FdCloseSender } from "./sender.js"; /** * Cloneable data required to reconstruct a `WASIFarmRef` in another agent. * * The object owns no payloads and may be structured-cloned repeatedly. The * generic receiver member lets concrete transports expose cloneable data * instead of a runtime class instance. */ export type WASIFarmRefObject = { stdin: number | undefined; stdout: number | undefined; stderr: number | undefined; fd_close_receiver: FdCloseReceiverObject; default_fds: Array; }; /** * WASIFarmRef is an abstract base class for guest-side file descriptor operations. * * It provides the interface for system calls like fd_read, fd_write, etc., * and handles communication with the farm backend. */ export abstract class WASIFarmRef { abstract get_fds_len(): number; // please implement this method // abstract init_self(sl: WASIFarmRef): WASIFarmRef; protected stdin: number | undefined; protected stdout: number | undefined; protected stderr: number | undefined; protected id!: number; fd_close_receiver: FdCloseSender; default_fds: Array = []; async send(targets: Array, fd: number): Promise { await this.fd_close_receiver.send(targets, fd); } get(id: number): Array | undefined { return this.fd_close_receiver.get(id); } /** * Synchronously registers this reference ID for the supplied Park fds. * * Duplicate registrations are ignored. The call blocks the current Worker * until the Park commits the mapping and may throw on destruction or transport * failure. It does not destroy this reference, its Animal, or its Park. */ abstract set_park_fds_map(fds: Array): void; abstract set_id(): number; /** * Initializes a new WASIFarmRef. * * @param stdin The standard input FD index. * @param stdout The standard output FD index. * @param stderr The standard error FD index. * @param fd_close_receiver The broadcast receiver for FD closures. * @param default_fds The list of FDs initially accessible. */ constructor( stdin: number | undefined, stdout: number | undefined, stderr: number | undefined, fd_close_receiver: FdCloseSender, default_fds?: Array, ) { this.stdin = stdin; this.stdout = stdout; this.stderr = stderr; this.fd_close_receiver = fd_close_receiver; if (default_fds !== undefined) { this.default_fds = default_fds; } } get_stdin(): number | undefined { return this.stdin; } get_stdout(): number | undefined { return this.stdout; } get_stderr(): number | undefined { return this.stderr; } abstract fd_advise(fd: number | undefined): number; abstract fd_allocate( fd: number | undefined, offset: bigint, len: bigint, ): number; abstract fd_close(fd: number | undefined): number; abstract fd_datasync(fd: number | undefined): number; abstract fd_fdstat_get( fd: number | undefined, ): [wasi.Fdstat | undefined, number]; abstract fd_fdstat_set_flags(fd: number | undefined, flags: number): number; abstract fd_fdstat_set_rights( fd: number | undefined, fs_rights_base: bigint, fs_rights_inheriting: bigint, ): number; abstract fd_filestat_get( fd: number | undefined, ): [wasi.Filestat | undefined, number]; abstract fd_filestat_set_size(fd: number | undefined, size: bigint): number; abstract fd_filestat_set_times( fd: number | undefined, atim: bigint, mtim: bigint, fst_flags: number, ): number; abstract fd_pread( fd: number | undefined, iovs: Uint32Array, offset: bigint, ): [[number, Uint8Array] | undefined, number]; abstract fd_prestat_get( fd: number | undefined, ): [[number, number] | undefined, number]; abstract fd_prestat_dir_name( fd: number | undefined, path_len: number, ): [Uint8Array | undefined, number]; abstract fd_pwrite( fd: number | undefined, iovs: Uint8Array, offset: bigint, ): [number | undefined, number]; abstract fd_read( fd: number | undefined, iovs: Uint32Array, ): [[number, Uint8Array] | undefined, number]; abstract fd_readdir( fd: number | undefined, limit_buf_len: number, cookie: bigint, ): [[Uint8Array, number] | undefined, number]; // abstract fd_renumber(fd: number | undefined, to: number): number; abstract fd_seek( fd: number | undefined, offset: bigint, whence: number, ): [bigint | undefined, number]; abstract fd_sync(fd: number | undefined): number; abstract fd_tell(fd: number | undefined): [bigint | undefined, number]; abstract fd_write( fd: number | undefined, iovs: Uint8Array, ): [number | undefined, number]; abstract path_create_directory( fd: number | undefined, path: Uint8Array, ): number; abstract path_filestat_get( fd: number | undefined, flags: number, path: Uint8Array, ): [wasi.Filestat | undefined, number]; abstract path_filestat_set_times( fd: number | undefined, flags: number, path: Uint8Array, st_atim: bigint, st_mtim: bigint, fst_flags: number, ): number; abstract path_link( old_fd: number | undefined, old_flags: number, old_path: Uint8Array, new_fd: number | undefined, new_path: Uint8Array, ): number; abstract path_open( fd: number | undefined, dirflags: number, path: Uint8Array, oflags: number, fs_rights_base: bigint, fs_rights_inheriting: bigint, fs_flags: number, ): [number | undefined, number]; abstract path_readlink( fd: number | undefined, path: Uint8Array, buf_len: number, ): [Uint8Array | undefined, number]; abstract path_remove_directory( fd: number | undefined, path: Uint8Array, ): number; abstract path_rename( old_fd: number | undefined, old_path: Uint8Array, new_fd: number | undefined, new_path: Uint8Array, ): number; abstract path_symlink( old_path: Uint8Array, fd: number | undefined, new_path: Uint8Array, ): number; abstract path_unlink_file(fd: number | undefined, path: Uint8Array): number; /** * Synchronously requests destruction of this reference's Park. * * The operation is idempotent and blocks the current Worker through the * acknowledgement. It does not destroy the calling reference or its Animal. */ abstract destroy_park(): void; /** * Synchronously invokes the Park's configured unknown-function callback. * * The call blocks the current Worker and returns the strictly decoded result. * Capacity, callback, codec, cancellation, and destruction failures throw. It * does not destroy the reference, its Animal, or its Park. */ abstract call_unknown_fn(arg: unknown): unknown; }