UNPKG

@txikijs/types

Version:
1,565 lines (1,421 loc) 52.3 kB
/** * The main txiki.js APIs are exposed as a single `tjs` global object. * * ```js * // Read a file * const data = await tjs.readFile('hello.txt'); * console.log(new TextDecoder().decode(data)); * * // Start an HTTP server * const server = tjs.serve({ * fetch: () => new Response('Hello!'), * port: 3000, * }); * ``` * * @module global */ declare global { /** * The main global where txiki.js APIs are exposed. */ namespace tjs { /** * Array with the arguments passed to the binary. * * @category System */ const args: readonly string[]; /** * @category Process */ type Signal = 'SIGHUP' | 'SIGINT' | 'SIGQUIT' | 'SIGILL' | 'SIGTRAP' | 'SIGABRT' | 'SIGBUS' | 'SIGFPE' | 'SIGKILL' | 'SIGUSR1' | 'SIGSEGV' | 'SIGUSR2' | 'SIGPIPE' | 'SIGALRM' | 'SIGTERM' | 'SIGSTKFLT' | 'SIGCHLD' | 'SIGCONT' | 'SIGSTOP' | 'SIGTSTP' | 'SIGTTIN' | 'SIGTTOU' | 'SIGURG' | 'SIGXCPU' | 'SIGXFSZ' | 'SIGVTALRM' | 'SIGPROF' | 'SIGWINCH' | 'SIGPOLL' | 'SIGPWR' | 'SIGSYS'; /** * Signal listener function. * * @category Process */ type SignalListener = () => void; /** * Registers a listener for the given signal. * * ```js * tjs.addSignalListener('SIGINT', handleSigint); * ``` * * @category Process * @param sig Which signal to register a listener for. * @param listener Listener function. */ function addSignalListener(sig: Signal, listener: SignalListener): void; /** * Un-registers a listener for the given signal. * * ```js * tjs.removeSignalListener('SIGINT', handleSigint); * ``` * * @category Process * @param sig Which signal to un-register a listener for. * @param listener Listener function. */ function removeSignalListener(sig: Signal, listener: SignalListener): void; /** * Send a signal to a process. * * @category Process * @param pid The pid of the process to send a signal to. * @param sig The name of the signal to send. Defaults to "SIGTERM". */ function kill(pid: number, sig?: Signal): void; /** * @category Engine */ type CompiledCode = unknown; /** * @namespace * @category Engine */ const engine : { /** * Compiles the provided code into bytecode ready to be evaluated or serialized. * * @param code The code to be compiled. * @returns The compiled code. */ compile: (code: Uint8Array) => CompiledCode; /** * Serializes the compiled code into something that can be easily written to a file. * * @param compiledCode The compiled code that needs to be serialized. * @returns Serialized bytecode. */ serialize: (compiledCode: CompiledCode) => Uint8Array; /** * Deserializes the given bytecode. * * @param bytes The serialized bytecode. * @returns The de-serialized code. */ deserialize: (bytes: Uint8Array) => CompiledCode; /** * Executes the given compiled code. * * @param code Pre-compiled code that needs to be executed. * @returns A `Promise` resolving to the value returned by the code, if any. */ evalBytecode: (code: CompiledCode) => Promise<unknown>; /** * Management for the garbage collection. */ readonly gc: { /** * Force garbage collection now. */ run: () => void; /** * Enables / disables automatic garbage collection. */ enabled: boolean; /** * Sets / gets the threshold (in bytes) for automatic garbage collection. */ threshold: number; } /** * Versions of all included libraries and txiki.js itself. */ readonly versions: { readonly quickjs: string; readonly tjs: string; readonly uv: string; readonly lws: string; readonly wamr: string; readonly sqlite3: string; readonly mimalloc?: number; }; } /** * The txiki.js version. * * @category System */ const version: string; /** * Full path to the txiki.js running executable. * * @category System */ const exePath: string; /** * Object containing environment variables. * Setting and deleting properties on this object causes * environment variables to be set / deleted. * * @category System */ type Environment = { [index: string]: string }; /** * System environment variables. * * @category System */ const env: Environment; /** * Current system host name. * * @category System */ const hostName: string; /** * Exit the current running program. * * @category Process * @param code Program exit code. */ function exit(code: number): void; /** * Changes the current working directory. * * @category System */ function chdir(dir: string): void; /** * Current working directory. * * @category System */ const cwd: string; /** * Result type for {@link lookup}. * * @category Networking */ interface Addr { family: number; ip: string; } /** * @category Networking */ interface LookupOptions { /** * Resolve only the given family results. */ family?: number; /** * If set to `true` returns all the results, it just returns the first one otherwise (default). */ all?: boolean; } /** * Basic DNS resolution using [getaddrinfo(3)](https://man7.org/linux/man-pages/man3/getaddrinfo.3.html). * * @category Networking * @param host Hostname to be looked up. * @param options Criteria for selecting the results. */ function lookup(host: string, options?: LookupOptions): Promise<Addr|Addr[]>; /** * Error type. It mostly encapsulates the libuv errors. * * @category Utilities */ class Error { constructor(errno: number); /** * The system error code as a string. For example `EPERM`. */ code: string; /** * The error string representation in the form `code: description`. */ message: string; } /** * Returns the canonicalized absolute pathname. * * @category Filesystem * @param path Path to convert. */ function realPath(path: string): Promise<string>; /** * Renames the given path. * * @category Filesystem * @param path Current path. * @param newPath New desired path name. */ function rename(path: string, newPath: string): Promise<void>; /** * Create a unique temporary directory. The given template must end in XXXXXX, and the Xs will * be replaced to provide a unique directory name. * * ```js * const tmpDir = await tjs.makeTempDir('tmpDirXXXXXX'); * ``` * * @category Filesystem * @param template Template for the directory. */ function makeTempDir(template: string): Promise<string>; /** * Create a unique temporary file. The given template must end in XXXXXX, and the Xs will * be replaced to provide a unique file name. The returned object is an open file handle. * * @category Filesystem * @param template Template for the file name. */ function makeTempFile(template: string): Promise<FileHandle>; /** * @category Filesystem */ interface FileHandle extends AsyncDisposable { /** * Reads data into the given buffer at the given file offset. Returns * the amount of read data or null for EOF. * * @param buffer Buffer to read data into. * @param offset Offset in the file to read from. */ read(buffer: Uint8Array, offset?: number): Promise<number|null>; /** * Writes data from the given buffer at the given file offset. Returns * the amount of data written. * * @param buffer Buffer to write. * @param offset Offset in the file to write to. */ write(buffer: Uint8Array, offset?: number): Promise<number>; /** * Closes the file. Idempotent: closing an already-closed handle * resolves successfully. * * Aliased as `Symbol.asyncDispose`, so * `await using f = await tjs.open(...)` closes the handle at scope * exit. */ close(): Promise<void>; /** * Get the file status information. * See [stat(2)](https://man7.org/linux/man-pages/man2/lstat.2.html) */ stat(): Promise<StatResult>; /** * Truncates the file to the given length. * * @param offset Length to truncate the file to. */ truncate(offset?: number): Promise<void>; /** * See [fdatasync(2)](https://man7.org/linux/man-pages/man2/fdatasync.2.html) */ datasync(): Promise<void>; /** * See [fsync(2)](https://man7.org/linux/man-pages/man2/fdatasync.2.html) */ sync(): Promise<void>; /** * Change permissions of the file. * See [fchmod(2)](https://man7.org/linux/man-pages/man2/fchmod.2.html) * * @param mode The file mode consisting of permission, suid, sgid, and sticky bits. */ chmod(mode: number): Promise<void>; /** * Change the access and modification time of the file. * See [futimes(2)](https://man7.org/linux/man-pages/man2/futimes.2.html) * * @param atime The new file access time. * @param mtime The new file modification time. */ utime(atime: Date, mtime: Date): Promise<void>; /** * The file path. */ path: string; readable: ReadableStream<Uint8Array>; writable: WritableStream<Uint8Array>; } /** * @category Filesystem */ interface StatResult { dev: number; mode: number; nlink: number; uid: number; gid: number; rdev: number; ino: number; size: number; blksize: number; blocks: number; atim: Date; mtim: Date; ctim: Date; birthtim: Date; isBlockDevice: boolean; isCharacterDevice: boolean; isDirectory: boolean; isFIFO: boolean; isFile: boolean; isSocket: boolean; isSymbolicLink: boolean; } /** * Gets file status information. * See [stat(2)](https://man7.org/linux/man-pages/man2/stat.2.html) * * @category Filesystem * @param path Path to the file. */ function stat(path: string): Promise<StatResult>; /** * Gets file status information. If the path is a link it returns information * about the link itself. * See [stat(2)](https://man7.org/linux/man-pages/man2/stat.2.html) * * @category Filesystem * @param path Path to the file. */ function lstat(path: string): Promise<StatResult>; /** * @category Filesystem */ interface StatFsResult { type: number; bsize: number; blocks: number; bfree: number; bavail: number; files: number; ffree: number; } /** * Get file-system statistics. * See [statfs(2)](https://man7.org/linux/man-pages/man2/statfs.2.html) * * @category Filesystem * @param path Path to the mount point. */ function statFs(path: string): Promise<StatFsResult>; /** * Change permissions of a file. * See [chmod(2)](https://man7.org/linux/man-pages/man2/chmod.2.html) * * @category Filesystem * @param path Path to the file. * @param mode The file mode consisting of permission, suid, sgid, and sticky bits. */ function chmod(path: string, mode: number): Promise<void>; /** * Change the ownership of a file. * See [chown(2)](https://man7.org/linux/man-pages/man2/chown.2.html) * * @category Filesystem * @param path Path to the file. * @param owner The uid to change the file's owner to. * @param group The gid to change the file's group to. */ function chown(path: string, owner: number, group: number): Promise<void>; /** * Change the ownership of a file. If the path is a link it changes * the ownership of the link itself. * See [lchown(2)](https://man7.org/linux/man-pages/man2/lchown.2.html) * * @category Filesystem * @param path Path to the file. * @param owner The uid to change the file's owner to. * @param group The gid to change the file's group to. */ function lchown(path: string, owner: number, group: number): Promise<void>; /** * Change the access and modification time of a file. * See [futimes(2)](https://man7.org/linux/man-pages/man2/futimes.2.html) * * @category Filesystem * @param path Path to the file. * @param atime The new file access time. * @param mtime The new file modification time. */ function utime(path: string, atime: Date, mtime: Date): Promise<void>; /** * Change the access and modification time of a file. If the path is a link it changes * the ownership of the link itself. * See [futimes(2)](https://man7.org/linux/man-pages/man2/futimes.2.html) * * @category Filesystem * @param path Path to the file. * @param atime The new file access time. * @param mtime The new file modification time. */ function lutime(path: string, atime: Date, mtime: Date): Promise<void>; /** * Opens the file at the given path. Opening flags: * * - r: open for reading * - w: open for writing, truncating the file if it exists * - x: open with exclusive creation, will fail if the file exists * - a: open for writing, appending at the end if the file exists * - +: open for updating (reading and writing) * * ```js * const f = await tjs.open('file.txt', 'r'); * ``` * * @category Filesystem * @param path The path to the file to be opened. * @param flags Flags with which to open the file. * @param mode File mode bits applied if the file is created. Defaults to `0o666`. */ function open(path: string, flags: string, mode?: number): Promise<FileHandle>; /** * @category Filesystem */ interface MakeDirOptions { /* The file mode for the new directory. Defaults to `0o777`. */ mode?: number; /* Whether the directories will be created recursively or not. Default to `false`. */ recursive?: boolean; } /** * Create a directory at the given path. * * @category Filesystem * @param path The path to of the directory to be created. * @param options Options for making the directory. */ function makeDir(path: string, options?: MakeDirOptions): Promise<void>; /** * Copies the source file into the target. * * @category Filesystem * @param path Source path. * @param newPath Target path. */ function copyFile(path: string, newPath: string): Promise<void>; /** * @category Filesystem */ interface DirEnt { name: string; isBlockDevice: boolean; isCharacterDevice: boolean; isDirectory: boolean; isFIFO: boolean; isFile: boolean; isSocket: boolean; isSymbolicLink: boolean; } /** * Directory entries can be obtained through asynchronous iteration: * * ```js * const dirIter = await tjs.readDir('.'); * for await (const item of dirIter) { * console.log(item.name); * } * ``` * * @category Filesystem */ interface DirHandle extends AsyncIterableIterator<DirEnt>, AsyncDisposable { /** * Closes the directory handle. Idempotent: closing an already-closed * handle resolves successfully. * * Aliased as `Symbol.asyncDispose`, so * `await using d = await tjs.readDir(...)` closes the handle at * scope exit. */ close(): Promise<void>; /** * Path of the directory. */ path: string; } /** * Open the directory at the given path in order to navigate its content. * See [readdir(3)](https://man7.org/linux/man-pages/man3/readdir.3.html) * * @category Filesystem * @param path Path to the directory. */ function readDir(path: string): Promise<DirHandle>; /** * Reads the value of a symbolic link. * See [readlink(2)](https://man7.org/linux/man-pages/man2/readlink.2.html) * * @category Filesystem * @param path File path. */ function readLink(path: string): Promise<string>; /** * Reads the entire contents of a file. * * @category Filesystem * @param path File path. */ function readFile(path: string): Promise<Uint8Array>; /** * @category Filesystem */ interface WriteFileOptions { /** File mode (permissions) to set when creating the file. Defaults to `0o644`. */ mode?: number; } /** * Writes data to a file, replacing the file if it already exists. * * @category Filesystem * @param path File path. * @param data Data to write. Strings are encoded as UTF-8. * @param options Optional settings. */ function writeFile(path: string, data: string | Uint8Array, options?: WriteFileOptions): Promise<void>; /** * @category Filesystem */ interface RemoveOptions { /* Amount of times to retry the operation in case it fails. Defaults to 0. */ maxRetries?: number; /* Time (in milliseconds) to wait between retries. Defaults to 100. */ retryDelay?: number; } /** * Recursively delete files and directories at the given path. * Equivalent to POSIX "rm -rf". * * @category Filesystem * @param path Path to be removed. */ function remove(path: string, options?: RemoveOptions): Promise<void>; /** * Create a hard file link. * See [link(2)](https://man7.org/linux/man-pages/man2/link.2.html) * * @category Filesystem * @param path Source file path. * @param newPath Target file path. */ function link(path: string, newPath: string): Promise<void>; /** * @category Filesystem */ interface SymlinkOptions { /* TYpe of symbolic link to create. Applies to Windows only. */ type?: 'file' | 'directory' | 'junction'; } /** * Create a symbolic link. * See [symlink(2)](https://man7.org/linux/man-pages/man2/symlink.2.html) * * @category Filesystem * @param path Source file path. * @param newPath Target file path. * @param options Options for specifying the type (Windows only). */ function symlink(path: string, newPath: string, options?: SymlinkOptions): Promise<void>; /** * File watch event handler function. * * @category Filesystem */ type WatchEventHandler = (filename: string, event: 'change' | 'rename') => void; /** * @category Filesystem */ interface FileWatcher extends Disposable { /** * Closes the watcher. * * Aliased as `Symbol.dispose`, so `using w = tjs.watch(...)` closes * the watcher at scope exit. */ close(): void; /** * Path which is currently being watched. */ path: string; } /** * Watches the given path for changes. * * @category Filesystem * @param path The path to watch. * @param handler Function to be called when an event occurs. */ function watch(path: string, handler: WatchEventHandler): FileWatcher; /** * The current user's home directory. * * @category System */ const homeDir: string; /** * The path to the current temporary directory. * * @category System */ const tmpDir: string; /** * @category System */ type StdioType = 'tty' | 'pipe' | 'file'; /** * @category System */ interface StdioInputStream extends ReadableStream<Uint8Array> { isTerminal: boolean; type: StdioType; setRawMode(enable: boolean): void; } /** * @category System */ interface StdioOutputStream extends WritableStream<Uint8Array> { isTerminal: boolean; type: StdioType; height: number; width: number; } /** * Object providing access to standard input. * * @category System */ const stdin: StdioInputStream; /** * Object providing access to standard output. * * @category System */ const stdout: StdioOutputStream; /** * Object providing access to standard error. * * @category System */ const stderr: StdioOutputStream; /** * @category Process */ interface ProcessStatus { exit_status: number; term_signal: Signal|null; } /** * @category Process */ interface ProcessReadableStream extends ReadableStream<Uint8Array> { arrayBuffer(): Promise<ArrayBuffer>; bytes(): Promise<Uint8Array>; text(): Promise<string>; } /** * @category Process */ interface Process extends AsyncDisposable { kill(signal?: Signal): void; /** * Resolves once the subprocess has exited. * * The interface is also async-disposable: at the end of an * `await using p = tjs.spawn(...)` scope, `SIGTERM` is sent (best * effort) and {@link wait} is awaited. */ wait(): Promise<ProcessStatus>; pid: number; stdin: WritableStream<Uint8Array> | null; stdout: ProcessReadableStream | null; stderr: ProcessReadableStream | null; } /** * @category Process */ type ProcessStdio = 'inherit' | 'pipe' | 'ignore'; /** * @category Process */ interface ProcessOptions { env?: Environment; cwd?: string; uid?: number; gid?: number; stdin?: ProcessStdio; stdout?: ProcessStdio; stderr?: ProcessStdio; } /** * Spawn a child process. * * @category Process * @param args Command line arguments for the new process. * @param options Extra options. */ function spawn(args: string | string[], options?: ProcessOptions): Process; /** * Replace the current process image with a new process image. * This function does not return if successful. * * See [execvp(3)](https://man7.org/linux/man-pages/man3/execvp.3.html) * * @category Process * @param args Command argument list for the new process image. */ function exec(args: string | string[]): void; /** * @category Networking */ type Transport = 'tcp' | 'udp' | 'pipe'; /** * @category Networking */ interface ConnectOptions { noDelay?: boolean; keepAliveDelay?: number; dnsQueryType?: 'ipv4' | 'ipv6'; bindAddr?: { ip: string; port: number }; ipv6Only?: boolean; } /** * @category Networking */ interface TLSConnectOptions extends ConnectOptions { /** Server Name Indication hostname. Defaults to the host argument. */ sni?: string; /** ALPN protocol list to negotiate. */ alpn?: string[]; /** PEM-encoded CA certificate(s) to trust. Defaults to the embedded Mozilla CA bundle. */ ca?: string; /** PEM-encoded client certificate for mutual TLS. */ cert?: string; /** PEM-encoded client private key for mutual TLS. */ key?: string; /** Whether to verify the peer's certificate. Defaults to true for clients, false for servers. */ verifyPeer?: boolean; } /** * Creates a connection to the target host + port over the selected transport. * Returns the appropriate Direct Sockets object. * * @category Networking * @param transport Type of transport for the connection. * @param host Hostname for the connection. Basic lookup using {@link lookup} will be performed. * @param port Destination port (where applicable). * @param options Extra connection options. */ function connect(transport: 'tcp', host: string, port: number, options?: ConnectOptions): Promise<TCPSocket>; function connect(transport: 'tls', host: string, port: number, options?: TLSConnectOptions): Promise<TLSSocket>; function connect(transport: 'pipe', host: string): Promise<PipeSocket>; function connect(transport: 'udp', host: string, port: number, options?: ConnectOptions): Promise<UDPSocket>; /** * @category Networking */ interface ListenOptions { backlog?: number; ipv6Only?: boolean; reuseAddr?: boolean; } /** * @category Networking */ interface TLSListenOptions extends ListenOptions { /** PEM-encoded server certificate. Required. */ cert: string; /** PEM-encoded server private key. Required. */ key: string; /** PEM-encoded CA certificate(s) for client certificate verification (mutual TLS). */ ca?: string; /** Whether to verify the peer's certificate. Defaults to true for clients, false for servers. */ verifyPeer?: boolean; /** ALPN protocol list to offer. */ alpn?: string[]; } /** * Listens for incoming connections on the selected transport. * Returns the appropriate Direct Sockets object. * * @category Networking * @param transport Transport type. * @param host Hostname for listening on. * @param port Listening port (where applicable). * @param options Extra listen options. */ function listen(transport: 'tcp', host: string, port?: number, options?: ListenOptions): Promise<TCPServerSocket>; function listen(transport: 'tls', host: string, port?: number, options?: TLSListenOptions): Promise<TLSServerSocket>; function listen(transport: 'pipe', host: string, options?: ListenOptions): Promise<PipeServerSocket>; function listen(transport: 'udp', host?: string, port?: number, options?: ListenOptions): Promise<UDPSocket>; /** * Current process ID. * * @category Process */ const pid: number; /** * Parent process ID. * * @category Process */ const ppid: number; namespace system{ /** * @category System */ interface UserInfo { userName: string; userId: number; gorupId: number; shell: string | null; homeDir: string | null; } /** * @category System */ interface CpuTimes { user: number; nice: number; sys: number; idle: number; irq: number; } /** * @category System */ interface CpuInfo { model: string; speed: number; times: CpuTimes; } /** * @category System */ interface NetworkInterface { name: string; address: string; mac: string; scopeId?: number; netmask: string; internal: boolean; } } /** * @namespace * System information. * * @category System */ const system: { /** * Information about the CPUs in the system. */ readonly cpus: system.CpuInfo[]; /** * System load average. * See [getloadavg(3)](https://man7.org/linux/man-pages/man3/getloadavg.3.html) */ readonly loadAvg: [ number, number, number ]; /** * Information about the network interfaces in the system. */ readonly networkInterfaces: system.NetworkInterface[]; /** * System uptime. */ readonly uptime: number; /** * Current user information from the password database. */ readonly userInfo: system.UserInfo; } /** * @category Utilities */ interface ConsolePrinterOptions { /** output message to stderr instead of stdout */ isWarn?: boolean; /** how much to indent the message (level of groups) */ indent: number; } /** * Creates a custom `console` object. * * @category Utilities */ function createConsole(opts: { /** function to print messages to somewhere, see https://console.spec.whatwg.org/#printer */ printer: (logLevel: string, args: unknown[], options: ConsolePrinterOptions) => void, /** function to handle normal log messages, see https://console.spec.whatwg.org/#logger */ logger?: (logLevel: string, args: unknown[], options: ConsolePrinterOptions) => void, /** function to clear the console, e.g. send the ASCII ctrl character */ clearConsole?: () => void, /** format given values, either by using a format string as first param or otherwise display values in a well readable format, see https://console.spec.whatwg.org/#formatter */ formatter?: (args: unknown[]) => string, /** format js values to be well readable */ inspect?: (args: unknown[]) => string, }): typeof console; // HTTP Server API /** * Handler function for incoming HTTP requests. * * @category HTTP Server */ type FetchHandler = (request: Request, context: RequestContext) => Response | Promise<Response> | void; /** * Context object passed to the fetch handler alongside the request. * * @category HTTP Server */ interface RequestContext { /** The server instance, useful for WebSocket upgrades. */ server: Server; /** The remote client IP address. */ remoteAddress: string; } /** * TLS options for enabling HTTPS on the server. * * @category HTTP Server */ interface TlsOptions { /** TLS certificate chain in PEM format. */ cert: string; /** TLS private key in PEM format. */ key: string; /** CA certificate(s) in PEM format, for client certificate verification. */ ca?: string; /** Passphrase for an encrypted private key. */ passphrase?: string; /** If `true`, the server requires a valid client certificate. Implies use of {@link ca}. */ requestCert?: boolean; } /** * Options for configuring the HTTP server. * * @category HTTP Server */ interface ServeOptions { /** Handler function called for each incoming HTTP request. */ fetch: FetchHandler; /** Port to listen on. Defaults to `0` (random available port). */ port?: number; /** IP address to bind to. Defaults to `'0.0.0.0'`. */ listenIp?: string; /** Optional WebSocket event handlers for upgraded connections. */ websocket?: WebSocketHandlers; /** TLS options for enabling HTTPS. When provided, the server listens for HTTPS connections. */ tls?: TlsOptions; } /** * Event handlers for WebSocket connections upgraded via {@link Server.upgrade}. * * @category HTTP Server */ interface WebSocketHandlers { /** Called when a WebSocket connection is established. */ open?(ws: ServerWebSocket): void; /** Called when a message is received. */ message?(ws: ServerWebSocket, data: string): void; /** Called when the WebSocket connection is closed. */ close?(ws: ServerWebSocket, code: number, reason: string): void; /** Called when an error occurs on the WebSocket connection. */ error?(ws: ServerWebSocket, error: Error): void; } /** * A WebSocket connection created by upgrading an HTTP request via {@link Server.upgrade}. * * @category HTTP Server */ interface ServerWebSocket { /** Arbitrary data associated with this connection, set via {@link UpgradeOptions.data}. */ readonly data: unknown; /** Send a text message. */ sendText(data: string): void; /** Send a binary message. */ sendBinary(data: Uint8Array): void; /** Close the connection. */ close(code?: number, reason?: string): void; } /** * Options for upgrading an HTTP request to a WebSocket connection. * * @category HTTP Server */ interface UpgradeOptions { /** Arbitrary data to associate with the WebSocket connection, accessible as `ws.data`. */ data?: unknown; } /** * An HTTP server instance. * * @category HTTP Server */ interface Server extends AsyncDisposable { /** The port the server is listening on. */ readonly port: number; /** * Stop accepting new connections and close the server. The returned * promise resolves once the listening socket has been fully torn * down. Idempotent; subsequent calls return the same promise. * * Aliased as `Symbol.asyncDispose`, so * `await using server = tjs.serve(...)` closes it automatically at * scope exit. */ close(): Promise<void>; /** * Upgrade an HTTP request to a WebSocket connection. Must be called * synchronously inside the fetch handler. * * @param request The incoming request with an `Upgrade: websocket` header. * @param options Options for the WebSocket connection. * @returns `true` if the upgrade was successful, `false` otherwise. */ upgrade(request: Request, options?: UpgradeOptions): boolean; } /** * Start an HTTP server. * * ```js * const server = tjs.serve({ * fetch(request) { * return new Response('Hello World!'); * }, * port: 8080, * }); * ``` * * A shorthand is also available when only a fetch handler is needed: * * ```js * const server = tjs.serve((request) => new Response('Hello!')); * ``` * * To enable HTTPS, provide TLS certificate and key as PEM strings: * * ```js * const cert = new TextDecoder().decode(await tjs.readFile('cert.pem')); * const key = new TextDecoder().decode(await tjs.readFile('key.pem')); * * const server = tjs.serve({ * fetch(request) { * return new Response('Hello HTTPS!'); * }, * port: 8443, * tls: { cert, key }, * }); * ``` * * `close()` returns a promise that resolves once the server has fully * shut down; prefer `await server.close()` (or `await using`) when you * need to wait for the listening socket to be released: * * ```js * await using server = tjs.serve(request => new Response('ok')); * // ...use server... * // server.close() runs automatically at scope exit. * ``` * * @category HTTP Server * @param options Server options or a fetch handler function. * @returns The server instance. */ function serve(options: ServeOptions | FetchHandler): Server; /** * Mapping from a bare specifier (or a `/`-terminated prefix) to a path * or URL the specifier should resolve to. Paths starting with `./` or * `../` are resolved against the `baseDir` argument passed to * `tjs.setImportMap()`. Mapping a key to `null` blocks the import. * * @category Modules */ interface ImportMap { imports?: Record<string, string | null>; scopes?: Record<string, Record<string, string | null>>; } /** * Install an [import map](https://github.com/WICG/import-maps) that * remaps bare specifiers (e.g. `"lodash"`) and prefixes (e.g. * `"lodash/"`) to file paths or URLs. Equivalent to running with * `--import-map`, but driven from JavaScript. * * Must be called before the affected `import` / dynamic `import()` runs * — modules already loaded into the runtime are not retroactively * remapped. Only one import map is active at a time; calling * `setImportMap()` again replaces the previous one. * * @example * ```js * tjs.setImportMap({ * imports: { * 'lodash': './vendor/lodash/index.js', * 'lodash/': './vendor/lodash/', * 'blocked': null, * }, * scopes: { * './legacy/': { * 'pkg': './vendor/pkg-v1/index.js', * }, * }, * }, import.meta.dirname); * * const _ = await import('lodash'); * ``` * * @category Modules * @param map The import map. Relative targets resolve against `baseDir`. * @param baseDir Directory used to resolve relative paths in `map`. */ function setImportMap(map: ImportMap, baseDir: string): void; } // Direct Sockets API // See https://wicg.github.io/direct-sockets/ /** * @category Networking */ interface TCPSocketOpenInfo { readable: ReadableStream<Uint8Array>; writable: WritableStream<Uint8Array>; localAddress: string; localPort: number; remoteAddress: string; remotePort: number; } /** * @category Networking */ interface TCPSocketOptions { noDelay?: boolean; keepAliveDelay?: number; dnsQueryType?: 'ipv4' | 'ipv6'; } /** * @category Networking */ class TCPSocket { constructor(remoteAddress: string, remotePort: number, options?: TCPSocketOptions); readonly opened: Promise<TCPSocketOpenInfo>; readonly closed: Promise<void>; /** * Initiates close. Use {@link closed} to await full teardown. * * The class is also async-disposable: at the end of an * `await using s = new TCPSocket(...)` scope the socket is closed and * {@link closed} is awaited. */ close(): void; } interface TCPSocket extends AsyncDisposable {} /** * @category Networking */ interface TCPServerSocketOpenInfo { readable: ReadableStream<TCPSocket>; localAddress: string; localPort: number; } /** * @category Networking */ interface TCPServerSocketOptions { localPort?: number; backlog?: number; ipv6Only?: boolean; } /** * @category Networking */ class TCPServerSocket { constructor(localAddress: string, options?: TCPServerSocketOptions); readonly opened: Promise<TCPServerSocketOpenInfo>; readonly closed: Promise<void>; /** * Initiates close. Use {@link closed} to await full teardown. * * Also async-disposable: at the end of an * `await using s = new TCPServerSocket(...)` scope the listener is * closed and {@link closed} is awaited. */ close(): void; } interface TCPServerSocket extends AsyncDisposable {} /** * Information about an opened TLS socket connection. * * @category Networking */ interface TLSSocketOpenInfo { readable: ReadableStream<Uint8Array>; writable: WritableStream<Uint8Array>; localAddress: string; localPort: number; remoteAddress: string; remotePort: number; /** The ALPN protocol negotiated during the TLS handshake, or null. */ alpn: string | null; } /** * Options for creating a TLS client socket. * * @category Networking */ interface TLSSocketOptions { /** Server Name Indication hostname. Defaults to remoteAddress. */ sni?: string; /** ALPN protocol list to negotiate. */ alpn?: string[]; /** PEM-encoded CA certificate(s) to trust. Defaults to the embedded Mozilla CA bundle. */ ca?: string; /** PEM-encoded client certificate for mutual TLS. */ cert?: string; /** PEM-encoded client private key for mutual TLS. */ key?: string; /** Whether to verify the peer's certificate. Defaults to true for clients, false for servers. */ verifyPeer?: boolean; noDelay?: boolean; keepAliveDelay?: number; dnsQueryType?: 'ipv4' | 'ipv6'; } /** * A TLS client socket. Wraps a TCP connection with TLS encryption. * All data read from the readable stream and written to the writable stream is automatically * encrypted/decrypted — JS only sees plaintext. * * @category Networking */ class TLSSocket { constructor(remoteAddress: string, remotePort: number, options?: TLSSocketOptions); readonly opened: Promise<TLSSocketOpenInfo>; readonly closed: Promise<void>; /** * Initiates close. Use {@link closed} to await full teardown. * * Also async-disposable: at the end of an * `await using s = new TLSSocket(...)` scope the socket is closed and * {@link closed} is awaited. */ close(): void; } interface TLSSocket extends AsyncDisposable {} /** * Information about an opened TLS server socket. * * @category Networking */ interface TLSServerSocketOpenInfo { readable: ReadableStream<TLSSocket>; localAddress: string; localPort: number; } /** * Options for creating a TLS server socket. * * @category Networking */ interface TLSServerSocketOptions { localPort?: number; /** PEM-encoded server certificate. Required. */ cert: string; /** PEM-encoded server private key. Required. */ key: string; /** PEM-encoded CA certificate(s) for client certificate verification (mutual TLS). */ ca?: string; /** Whether to verify the peer's certificate. Defaults to true for clients, false for servers. */ verifyPeer?: boolean; /** ALPN protocol list to offer. */ alpn?: string[]; backlog?: number; ipv6Only?: boolean; } /** * A TLS server socket. Listens for incoming TLS connections. * Accepted clients are {@link TLSSocket} instances with TLS already negotiated. * * @category Networking */ class TLSServerSocket { constructor(localAddress: string, options: TLSServerSocketOptions); readonly opened: Promise<TLSServerSocketOpenInfo>; readonly closed: Promise<void>; /** * Initiates close. Use {@link closed} to await full teardown. * * Also async-disposable: at the end of an * `await using s = new TLSServerSocket(...)` scope the listener is * closed and {@link closed} is awaited. */ close(): void; } interface TLSServerSocket extends AsyncDisposable {} /** * @category Networking */ interface UDPMessage { data: Uint8Array; remoteAddress?: string; remotePort?: number; } /** * @category Networking */ interface UDPSocketOpenInfo { readable: ReadableStream<UDPMessage>; writable: WritableStream<UDPMessage>; localAddress: string; localPort: number; remoteAddress?: string; remotePort?: number; multicastController: MulticastController; } /** * @category Networking */ interface MulticastController { /** * Joins a multicast group. */ joinGroup(ipAddress: string): Promise<void>; /** * Leaves a multicast group. */ leaveGroup(ipAddress: string): Promise<void>; /** * A frozen array of currently joined multicast group addresses. */ readonly joinedGroups: readonly string[]; } /** * @category Networking */ interface UDPSocketOptions { remoteAddress?: string; remotePort?: number; localAddress?: string; localPort?: number; dnsQueryType?: 'ipv4' | 'ipv6'; reuseAddr?: boolean; ipv6Only?: boolean; /** * TTL for multicast packets. Each router hop decrements this value. Default is 1. */ multicastTimeToLive?: number; /** * Whether packets sent to the multicast group are looped back to the sender. Default is true. */ multicastLoopback?: boolean; /** * Permits address reuse, essential for multiple applications listening on the same multicast address/port. Default is false. */ multicastAllowAddressSharing?: boolean; } /** * @category Networking */ class UDPSocket { constructor(options: UDPSocketOptions)