import { Fd } from '@bjorn3/browser_wasi_shim'; import { wait_async_polyfill } from './polyfill.js'; import { wasi } from '@bjorn3/browser_wasi_shim'; import { default as worker_background_worker } from './shared_array_buffer/worker_background/worker_background_worker_minify.js'; /** * AllocatorUseArrayBuffer provides a simple shared memory allocator built on top of `SharedArrayBuffer`. * * It uses atomic operations for thread-safe memory management and a First-Fit-like * simplified allocation strategy. * * Memory Layout: * - [0..3]: Lock flag (0 = unlocked, 1 = locked) * - [4..7]: Active user count * - [8..11]: Current offset for the next allocation * - [12..]: Data storage */ declare class AllocatorUseArrayBuffer { share_arrays_memory: SharedArrayBuffer; /** * Creates an allocator and initializes its shared-memory headers. * * @param share_arrays_memory The shared memory buffer to manage. Defaults to a 10MB buffer. * @param initialize Whether to initialize the buffer headers. Attachments pass false to preserve shared state. */ constructor(share_arrays_memory?: SharedArrayBuffer, initialize?: boolean); /** * Attaches an allocator to transferred shared state without resetting headers. * * @param sl The serialized allocator state. * @returns A new AllocatorUseArrayBuffer instance. */ static init_self(sl: AllocatorUseArrayBufferObject): AllocatorUseArrayBuffer; /** * Asynchronously writes data to the shared memory. * * @param data The data to write. * @param memory The guest memory buffer to update with the pointer and length. * @param ret_ptr The offset in guest memory where the pointer and length should be stored. * @returns A promise that resolves to a tuple containing the shared memory offset and the data length. */ async_write(data: Uint8Array | Uint32Array, memory: SharedArrayBuffer, ret_ptr: number): Promise<[number, number]>; block_write(data: Uint8Array | Uint32Array, memory: SharedArrayBuffer, ret_ptr: number): [number, number]; write_inner(data: Uint8Array | Uint32Array, memory: SharedArrayBuffer, ret_ptr: number): [number, number]; /** * Releases an allocation, decrementing the active user count. * * @param _pointer The offset of the allocation. * @param _len The length of the allocation. */ free(_pointer: number, _len: number): void; /** * Retrieves data from the shared memory. * * @param ptr The offset in shared memory. * @param len The length of the data. * @returns A new ArrayBuffer containing the data. */ get_memory(ptr: number, len: number): ArrayBuffer; take_memory(ptr: number, len: number): ArrayBuffer; use_defined_memory(ptr: number, len: number, data: ArrayBufferLike): void; /** * Returns a serializable representation of this allocator. * * @returns An AllocatorUseArrayBufferObject containing the shared state. */ get_object(): AllocatorUseArrayBufferObject; } /** * Represents the serialized state of an AllocatorUseArrayBuffer for thread transfer. */ declare type AllocatorUseArrayBufferObject = { share_arrays_memory: SharedArrayBuffer; }; /** * Raised when user slots are temporarily exhausted or when user or reserved * system-slot capacity has been permanently retired. */ export declare class BaseCallCapacityError extends Error { constructor(); } /** Coordinates destruction through a shared worker lifecycle capability. */ export declare class DestroyerHandle { private readonly sender; private readonly destroy_status; private readonly requester_animal_id?; private requester_shutdown?; constructor(sender: WorkerBackgroundRef, destroy_status: SharedArrayBuffer, requester_animal_id?: number | undefined); /** Reconstructs an unbound handle for an external controller. */ static init_self(obj: DestroyerHandleObject): DestroyerHandle; /** Reconstructs a handle bound to a managed requester's local Animal ID. */ static init_bound(obj: DestroyerHandleObject, requesterAnimalId: number): DestroyerHandle; get_object(): DestroyerHandleObject; /** Synchronously rejects new work and initiates runtime-wide teardown. */ destroy(): void; /** * Observes logical teardown and issued termination operations. * * An elected managed requester resolves after every other managed Worker has * received termination and its own close has been scheduled. Browser hosts * do not provide a physical thread join. */ async_destroy(): Promise; private schedule_requester_shutdown; } /** Represents the serialized state of a DestroyerHandle for thread transfer. */ export declare interface DestroyerHandleObject { sender: WorkerBackgroundRefObject; destroy_status: SharedArrayBuffer; } /** * FdCloseSender defines the interface for broadcasting file descriptor closures * to multiple worker threads. */ declare interface FdCloseSender { /** * Sends a closure notification to target worker IDs. * * @param targets The list of worker IDs to notify. * @param fd The file descriptor index that was closed. */ send(targets: Array, fd: number): Promise; /** * Retrieves the list of closed FDs for a specific worker ID. * * @param id The worker ID. * @returns An array of closed FD indices, or undefined if none. */ get(id: number): Array | undefined; } /** * The entry point for thread spawning on a worker. * * It handles the message from the parent thread and initializes the WASI environment * and WebAssembly instance for the new thread. * * @param msg The message containing thread initialization data. * @param instantiate An optional custom WebAssembly instantiation function. * @returns A promise that resolves to the created WASIFarmAnimal. */ export declare const thread_spawn_on_worker: (msg: { this_is_thread_spawn: boolean; worker_id?: number; start_arg: number; worker_background_ref: WorkerBackgroundRefObject; sl_object: ThreadSpawnerObject; thread_spawn_wasm: WebAssembly.Module; args: Array; env: Array; fd_map: [number, number][]; this_is_start?: boolean; animal_id: number; }, instantiate?: (thread_spawn_wasm: WebAssembly.Module, imports: { env: { [key: string]: WebAssembly.Memory; }; wasi: { "thread-spawn": (start_arg: number) => number; }; wasi_snapshot_preview1: { [key: string]: (...args: any[]) => unknown; }; }) => Promise, callback?: (wasi: WASIFarmAnimal) => void | Promise) => Promise; /** * ThreadSpawner manages the spawning and lifecycle of WebAssembly threads. * * It coordinates with a background worker to manage thread resources, * shared memory, and synchronization primitives. */ declare class ThreadSpawner { private share_memory; private wasi_farm_refs_object; private worker_url; private worker_background_ref; private worker_background_ref_object; private destroy_status; private animal_id_counter; private worker_background_worker?; private worker_background_worker_promise; private worker_background_ready; private worker_background_ready_settled; private worker_background_readiness_error?; private reject_worker_background_worker?; private destroy_promise?; private readonly destroyer_handles; private coordinator_failure?; readonly owns_worker_background_worker: boolean; /** * Initializes a new ThreadSpawner. * * @param worker_url The URL of the worker script. * @param wasi_farm_refs_object The serialized state of WASI farm references. * @param share_memory The shared WebAssembly memories. * @param MIN_STACK The minimum stack size for spawned threads. Defaults to 16MB. * @param worker_background_ref_object The serialized state of the background worker reference. * @param thread_spawn_wasm The WebAssembly module used for thread spawning. * @param worker_background_worker_url Optional custom URL for the background worker. * @param destroy_status Shared buffer for tracking destruction status. * @param animal_id_counter Shared buffer for generating unique process IDs. */ constructor(worker_url: string, wasi_farm_refs_object: Array, share_memory?: { [key: string]: WebAssembly.Memory; }, MIN_STACK?: number, worker_background_ref_object?: WorkerBackgroundRefObject, thread_spawn_wasm?: WebAssembly.Module, worker_background_worker_url?: string, destroy_status?: SharedArrayBuffer, animal_id_counter?: SharedArrayBuffer); wait_worker_background_worker(): Promise; check_worker_background_worker(): void; /** * Spawns a new thread. * * @param start_arg The argument passed to the thread start function. * @param args The command line arguments for the thread. * @param env The environment variables for the thread. * @param fd_map A mapping of file descriptors for the thread. * @returns The ID of the spawned thread. */ thread_spawn(start_arg: number, args: Array, env: Array, fd_map: Array<[number, number]>): number; create_destroyer(requesterAnimalId?: number): DestroyerHandle; is_managed_worker_context(): boolean; generate_animal_id(): number; async_start_on_thread(args: Array, env: Array, fd_map: Array<[number, number]>): Promise; block_start_on_thread(args: Array, env: Array, fd_map: Array<[number, number]>): void; static init_self(sl: ThreadSpawnerObject): ThreadSpawner; static init_self_with_worker_background_ref(sl: ThreadSpawnerObject, worker_background_ref_object: WorkerBackgroundRefObject): ThreadSpawner; get_share_memory(): { [key: string]: WebAssembly.Memory; }; get_object(): ThreadSpawnerObject; done_notify(code: number): void; async_wait_done_or_error(): Promise; block_wait_done_or_error(): number; destroy(requesterAnimalId?: number): void; async_destroy(requesterAnimalId?: number): Promise; private start_destroy_finalization; private observe_destroy; private finish_destroy; kill_animal(id: number): void; } /** * Represents the serialized state of a ThreadSpawner for thread transfer. */ declare type ThreadSpawnerObject = { share_memory: { [key: string]: WebAssembly.Memory; }; wasi_farm_refs_object: Array; worker_url: string; worker_background_ref_object: WorkerBackgroundRefObject; destroy_status: SharedArrayBuffer; animal_id_counter: SharedArrayBuffer; }; export { wait_async_polyfill } /** * WASIFarm is the central manager for a virtualized WASI environment. * * It coordinates file descriptors and provides a "park" backend that handles * system calls via shared memory across multiple worker threads. */ export declare class WASIFarm { private fds; private park; private can_array_buffer; /** * Initializes a new WASIFarm. * * @param stdin The standard input file descriptor. * @param stdout The standard output file descriptor. * @param stderr The standard error file descriptor. * @param fds Additional file descriptors to include in the farm. * @param options Configuration for shared allocation, descriptor capacity, * base-call capacity, and the host callback. `max_base_calls_limit` defaults * to 128 and must be an integer from 1 through 1024. Construction starts the * non-blocking Park listener; Animals and external Workers are not created. */ constructor(stdin?: Fd, stdout?: Fd, stderr?: Fd, fds?: Array, options?: { allocator_size?: number; /** * Shared payload allocator size for multiplexed base calls, in bytes. * * Defaults to 10 MiB. This is independent from `allocator_size`; requests * and responses fail with `OutOfMemory` when the configured free capacity is * insufficient. */ base_call_allocator_size?: number; max_fds_limit?: number; /** Maximum concurrent user base calls, excluding one reserved system slot. */ max_base_calls_limit?: number; unknown_fn?: ((arg: unknown) => Promise | unknown) | null; }); private fds_ref; /** * Generates a reference object that can be transferred to a worker thread. * * @returns A serialized reference to the WASI farm. */ get_ref(): WASIFarmRefObject; /** * Destroys this farm and its exclusively owned Park. * * The operation is synchronous and idempotent. It rejects new base calls, * wakes blocked callers, and does not wait for unresolved user callbacks. It * does not destroy Animals or terminate external Workers holding a reference. */ destroy(): void; } /** * WASIFarmAnimal represents a WASI "process" or "worker" instance. * * It manages its own set of file descriptors (via references to the farm) * and provides the environment (args, env, memory) for a WebAssembly instance. * It also coordinates thread spawning if enabled. */ export declare class WASIFarmAnimal { args: Array; env: Array; private wasi_farm_refs; private id_in_wasi_farm_ref; inst: { exports: { memory: WebAssembly.Memory; }; } | undefined; wasiImport: { [key: string]: (...args: Array) => unknown; }; wasiThreadImport: { "thread-spawn": (start_arg: number) => number; }; animal_id?: number; private can_array_buffer; private sleepBuffer; private can_thread_spawn?; private thread_spawner?; private destroy_promise?; wait_worker_background_worker(): Promise; check_worker_background_worker(): void; protected fd_map: Array<[number, number]>; protected get_fd_and_wasi_ref(fd: number): [number | undefined, WASIFarmRef | undefined]; protected get_fd_and_wasi_ref_n(fd: number): [number | undefined, number | undefined]; /** Start a WASI command When this function is executed, the WebAssembly (Wasm) code runs on that thread. If the Wasm code throws an error or calls process_exit, the main thread would need to be forcibly terminated. However, since this is not possible, if the Wasm code aborts in a child thread, it will be thrown from the worker_background_worker function. By default, this function is hidden. For detailed usage, please refer to the examples/worker_background_worker.ts file. If you are dealing with programs that may abort, consider using async_start_on_thread or block_start_on_thread instead. */ start(instance: { exports: { memory: WebAssembly.Memory; _start: () => unknown; }; }): number; /** * This function is similar to start, but it does not handle error and exit code. */ start_only(instance: { exports: { memory: WebAssembly.Memory; _start: () => unknown; }; }): void; /** * * This function only initializes the instance and does not start the execution. */ initialize_only(instance: { exports: { memory: WebAssembly.Memory; }; }): void; /** Start a WASI command on a thread. If the module has child threads and one of them throws an error, the main thread should normally also be stopped. However, since there is no way to stop it, the entire worker will be stopped instead. Do not use this if it is not necessary. If you want to use custom imports, pass the optional instantiate function as an argument to the thread_spawn_on_worker function. */ async_start_on_thread(): Promise; /** Start a WASI command on a thread. If the module has child threads and one of them throws an error, the main thread should normally also be stopped. However, since there is no way to stop it, the entire worker will be stopped instead. Do not use this if it is not necessary. If you want to use custom imports, pass the optional instantiate function as an argument to the thread_spawn_on_worker function. */ block_start_on_thread(): number; wasi_thread_start(instance: { exports: { memory: WebAssembly.Memory; wasi_thread_start: (thread_id: number, start_arg: number) => void; }; }, thread_id: number, start_arg: number): void; initialize(instance: { exports: { memory: WebAssembly.Memory; _initialize?: () => unknown; }; }): void; private mapping_fds; private map_new_fd; private map_new_fd_and_notify; private check_fds; get_share_memory(): { [key: string]: WebAssembly.Memory; }; /** * DestroyerHandle を生成(スレッド間転送用) * Translation: Generate a DestroyerHandle (for cross-thread transfer). * * メインスレッド側で destroy_status を持つ DestroyerHandle を生成。 * Translation: Generate a DestroyerHandle with destroy_status on the main thread side. * A managed worker must reconstruct a transferred object with * WASIFarmAnimal.init_destroyer() so the receiving Animal is bound as the * requester. External controllers use DestroyerHandle.init_self() to create * an unbound handle. */ create_destroyer(): DestroyerHandle; /** Reconstructs a transferred destroy handle with this Animal's context. */ init_destroyer(obj: DestroyerHandleObject): DestroyerHandle; /** * Initiates runtime-wide teardown and observes its logical completion. * * An elected managed requester resolves after all other managed Workers have * received termination and its own close has been scheduled. External and * owner-side callers resolve after coordinator teardown and issued * termination operations; browser platforms do not provide a physical join. */ async_destroy(): Promise; /** * Synchronously initiates teardown of the entire shared worker runtime. * * New runtime work is rejected immediately. The method does not wait for * physical Worker exit or destroy any referenced Park. Repeated calls are * safe after the first call has cleared the Animal's owned state. */ destroy(): void; /** * Synchronously destroys the nth Park referenced by this Animal. * * The wire operation is idempotent. This method does not destroy the Animal, * its threads, or any other referenced Park, and rejects an invalid index. */ destroy_park(n: number): void; /** * Synchronously destroys every Park referenced by this Animal. * * Each wire operation is idempotent. The Animal and its owned threads remain * intact, so callers may still destroy them separately. */ destroy_park_all(): void; /** * Synchronously destroys every referenced Park and then this Animal. * * Park destruction is idempotent, and the final Animal cleanup is safe to * repeat. No unrelated Farm, Park, or external Worker is destroyed. */ destroy_with_park(): void; call_unknown_fn(idx: number, unknown: unknown): unknown; kill_animal(id: number): void; /** * Initializes a new WASIFarmAnimal. * * @param wasi_farm_refs The WASI farm references (or a single reference). * @param args The command line arguments. * @param env The environment variables. * @param options Configuration options for thread spawning and memory. * @param override_fd_maps Optional FD mappings to override defaults. * @param thread_spawner Optional existing ThreadSpawner instance. */ constructor(wasi_farm_refs: WASIFarmRefObject[] | WASIFarmRefObject, args: Array, env: Array, options?: { can_thread_spawn?: boolean; thread_spawn_worker_url?: string; thread_spawn_wasm?: WebAssembly.Module; hand_override_fd_map?: Array<[number, number]>; worker_background_worker_url?: string; share_memory?: { [key: string]: WebAssembly.Memory; }; }, override_fd_maps?: Array, thread_spawner?: ThreadSpawner, assigned_animal_id?: number); } /** * 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 declare abstract class WASIFarmRef { abstract get_fds_len(): number; protected stdin: number | undefined; protected stdout: number | undefined; protected stderr: number | undefined; protected id: number; fd_close_receiver: FdCloseSender; default_fds: Array; send(targets: Array, fd: number): Promise; get(id: number): Array | undefined; /** * 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); get_stdin(): number | undefined; get_stdout(): number | undefined; get_stderr(): number | undefined; 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_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; } /** * 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 declare type WASIFarmRefObject = { stdin: number | undefined; stdout: number | undefined; stderr: number | undefined; fd_close_receiver: FdCloseReceiverObject; default_fds: Array; }; export { worker_background_worker } export declare const worker_background_worker_url: string; /** * WorkerBackgroundRef provides a thread-safe interface for communicating with * the background worker coordination layer. * * It uses shared memory and atomic operations to request new workers, * start threads, and manage thread lifecycles. */ declare class WorkerBackgroundRef { private allocator; private lock; private signature_input; private destroy_status; /** * Initializes a new WorkerBackgroundRef. * * @param allocator The shared memory allocator. * @param lock The shared buffer for locking the coordination channel. * @param signature_input The shared buffer for system call signatures and parameters. */ constructor(allocator: AllocatorUseArrayBuffer, lock: SharedArrayBuffer, signature_input: SharedArrayBuffer, destroy_status: SharedArrayBuffer); private block_lock_base_func; private async_lock_base_func; private call_base_func; private block_wait_base_func; private async_wait_base_func; private release_base_func; private encode_post_object; get_object(): WorkerBackgroundRefObject; notify_destroy(): void; private lifecycle_error; private assert_running; private block_allocate; private async_allocate; private block_allocate_worker_request; private async_allocate_worker_request; private read_worker_request; private block_wait_worker_request; private async_wait_worker_request; /** * Requests the creation of a new worker thread. * * @param url The URL of the worker script. * @param options Configuration options for the worker. * @param post_obj Optional initialization data to send to the worker. * @returns A WorkerRef representing the newly created worker. */ new_worker(url: string, options?: WorkerOptions_2, post_obj?: unknown): WorkerRef; private block_create_worker; async_start_on_thread(url: string, options: WorkerOptions_2 | undefined, post_obj: unknown): Promise; block_start_on_thread(url: string, options: WorkerOptions_2 | undefined, post_obj: unknown): void; /** * Reconstructs a reference from a transferred object. * * @param sl The serialized reference state. * @returns A new WorkerBackgroundRef instance. */ static init_self(sl: WorkerBackgroundRefObject): WorkerBackgroundRef; done_notify(code: number, owner?: boolean): void; cancel_runtime_completion(): boolean; async_wait_done_or_error(): Promise; block_wait_done_or_error(): number; private read_runtime_completion; private cancel_command_request; private acknowledge_failed_command; recover_failed_coordinator_command(): Promise; terminate_all_workers(): void; kill_animal(id: number): void; } /** * Represents the serialized state of a WorkerBackgroundRef for thread transfer. */ declare type WorkerBackgroundRefObject = { allocator: AllocatorUseArrayBufferObject; lock: SharedArrayBuffer; signature_input: SharedArrayBuffer; destroy_status: SharedArrayBuffer; }; export declare class WorkerDestroyError extends Error { readonly code: WorkerDestroyFailureCode; constructor(code: WorkerDestroyFailureCode); } export declare enum WorkerDestroyFailureCode { None = 0, CoordinatorBootstrap = 1, CoordinatorRuntime = 2, WorkerBootstrap = 3, Protocol = 4 } declare type WorkerOptions_2 = { type: "module" | ""; }; /** * WorkerRef represents a handle to a worker thread managed by the background * coordination layer. */ declare class WorkerRef { private id; constructor(id: number); get_id(): number; } export { }