UNPKG

hakojs

Version:

A secure, embeddable JavaScript engine that runs untrusted code inside WebAssembly sandboxes with fine-grained permissions and resource limits

606 lines 21.7 kB
import type { HakoRuntime } from "../host/runtime"; import type { DisposableResult } from "../mem/lifetime"; import type { CModuleInitializer } from "../vm/cmodule"; import type { VMContext } from "../vm/context"; import type { VMValue } from "../vm/value"; import type { VmCallResult } from "../vm/vm-interface"; /** * Opaque type helper that wraps a basic type with a specific string tag * for type safety while maintaining the underlying type's functionality. * * @template T - The underlying type (e.g., string, number) * @template K - A string literal used as a type tag */ type Opaque<T, K extends string> = T & { __typename: K; }; /** * Base64-encoded string type. Uses the Opaque type pattern to differentiate * from regular strings at the type level while maintaining string compatibility. */ export type Base64 = Opaque<string, "base64">; /** * Pointer to a JavaScript runtime instance in WebAssembly memory. * Maps to LEPUSRuntime* in C code. */ export type JSRuntimePointer = number; /** * Pointer to a JavaScript execution context in WebAssembly memory. * Maps to LEPUSContext* in C code. */ export type JSContextPointer = number; /** * Pointer to a mutable JavaScript value in WebAssembly memory. * Maps to LEPUSValue* in C code. */ export type JSValuePointer = number; /** * Pointer to a constant JavaScript value in WebAssembly memory. * Maps to LEPUSValueConst* in C code. */ export type JSValueConstPointer = number; /** * A numerical value representing the JavaScript type of a value. */ export type HAKOTypeOf = number; /** * JavaScript property atom identifier. Represents a property name * that has been interned for faster property lookups. * Maps to LEPUSAtom in C code. */ export type JSAtom = number; /** * Pointer to a null-terminated C string in WebAssembly memory. * Maps to CString in C code. */ export type CString = number; /** * Pointer to heap-allocated character data that must be freed. * Maps to OwnedHeapChar in C code. */ export type OwnedHeapChar = number; /** * Pointer to opaque data in WebAssembly memory. */ export type JSVoid = number; /** * Boolean type used in the LEPUS/QuickJS C API. * -1: Exception occurred * 0: False * 1: True */ export type LEPUS_BOOL = -1 | 0 | 1; /** * LEPUS_BOOL constant representing an exception state. */ export declare const LEPUS_EXCEPTION: LEPUS_BOOL; /** * LEPUS_BOOL constant representing false. */ export declare const LEPUS_FALSE: LEPUS_BOOL; /** * LEPUS_BOOL constant representing true. */ export declare const LEPUS_TRUE: LEPUS_BOOL; export type LEPUSModuleDef = number; /** * Converts a LEPUS_BOOL value to a JavaScript boolean. * * @param value - The LEPUS_BOOL value to convert * @returns The corresponding JavaScript boolean * @throws {PrimJSError} If the value is not a valid LEPUS_BOOL */ export declare function LEPUS_BOOLToBoolean(value: LEPUS_BOOL): boolean; /** * Host function type that can be called from the JavaScript environment. * * @template VmHandle - Type representing a VM value handle * @param this - The 'this' value for the function call * @param args - Arguments passed to the function from JavaScript * @returns A VM value handle, VM call result, or void */ export type HostCallbackFunction<VmHandle> = (this: VmHandle, ...args: VmHandle[]) => VmHandle | VmCallResult<VmHandle> | void; export type ModuleLoaderResult = { type: "source"; data: string; } | { type: "precompiled"; data: number; } | { type: "error"; } | null; /** * Function used to load JavaScript module source code. * * @param moduleName - The name of the module to load * @param attributes - Import attributes object (e.g., { type: "json" }) * @returns The module source code as a string, null if not found */ export type ModuleLoaderFunction = (moduleName: string, attributes?: Record<string, string>) => ModuleLoaderResult; /** * Function used to normalize module specifiers to absolute module names. * * @param baseName - The base module name (typically the importing module's name) * @param moduleName - The module specifier to normalize * @returns The normalized module name */ export type ModuleNormalizerFunction = (baseName: string, moduleName: string) => string; /** * Function used to resolve module names (import.meta.resolve). * * @param moduleName - The module name to resolve * @param currentModule - The current module context * @returns The fully qualified path to the module, or undefined if not found */ export type ModuleResolverFunction = (moduleName: string, currentModule?: string) => string | undefined; /** * Function used to initialize a C module. * This is called when the module is loaded into the runtime. * * @param module - The CModuleInitializer instance representing the module * @returns A status code indicating success (0) or failure (non-zero) */ export type ModuleInitFunction = (module: CModuleInitializer) => number; /** * Function used to finalize a C classes */ export type ClassConstructorHandler = (context: VMContext, newTarget: VMValue, args: VMValue[], classId: number) => VMValue; export type ClassFinalizerHandler = (runtime: HakoRuntime, opaque: number, classId: number) => void; export interface ClassOptions { finalizer?: ClassFinalizerHandler; methods?: Record<string, HostCallbackFunction<VMValue>>; staticMethods?: Record<string, HostCallbackFunction<VMValue>>; } /** * Basic interrupt handler function signature for C callbacks. * This is the low-level function called by the C side. * * @returns `true` to interrupt JavaScript execution, `false` to continue */ export type InterruptHandlerFunction = () => boolean; /** * Enhanced interrupt handler that receives the runtime object. * Determines if JavaScript execution inside the VM should be interrupted. * * @param runtime - The Hako runtime instance that is executing JavaScript * @param context - The VM context in which the JavaScript is executing * @param opaque - Opaque pointer data passed through from the enableInterruptHandler call * @returns `true` to interrupt JS execution, `false` or `undefined` to continue */ export type InterruptHandler = (runtime: HakoRuntime, context: VMContext, opaque: JSVoid) => boolean | undefined; /** * Phase type for the trace events we're tracking */ export type TraceEventPhase = "B" | "E"; /** * Structure of a trace event for function profiling */ export type TraceEvent = { /** Function name */ name: string; /** Category - always "js" for our events */ cat: "js"; /** Phase - 'B' for begin or 'E' for end */ ph: TraceEventPhase; /** Timestamp in microseconds */ ts: number; /** Process ID - always 1 for our events */ pid: 1; /** Thread ID - always 1 for our events */ tid: 1; }; /** * Handler for function profiling events */ export type ProfilerEventHandler = { /** * Handler for function start event * @param context - The VM context in which the function is executing * @param event - The trace event for the function start * @param opaque - Opaque pointer data passed through from the caller */ onFunctionStart: (context: VMContext, event: TraceEvent, opaque: JSVoid) => void; /** * Handler for function end event * @param context - The VM context in which the function is executing * @param event - The trace event for the function end * @param opaque - Opaque pointer data passed through from the caller */ onFunctionEnd: (context: VMContext, event: TraceEvent, opaque: JSVoid) => void; }; /** * Result type for executing pending Promise jobs (microtasks). * On success, contains the number of jobs executed. * On failure, contains the error value and associated context. */ export type ExecutePendingJobsResult = DisposableResult< /** Number of jobs successfully executed. */ number, /** The error that occurred. */ VMValue & { /** The context where the error occurred. */ context: VMContext; }>; export declare const INTRINSIC_BASE_OBJECTS: number; export declare const INTRINSIC_DATE: number; export declare const INTRINSIC_EVAL: number; export declare const INTRINSIC_STRING_NORMALIZE: number; export declare const INTRINSIC_REGEXP: number; export declare const INTRINSIC_REGEXP_COMPILER: number; export declare const INTRINSIC_JSON: number; export declare const INTRINSIC_PROXY: number; export declare const INTRINSIC_MAP_SET: number; export declare const INTRINSIC_TYPED_ARRAYS: number; export declare const INTRINSIC_PROMISE: number; export declare const INTRINSIC_BIGINT: number; export declare const INTRINSIC_BIGFLOAT: number; export declare const INTRINSIC_BIGDECIMAL: number; export declare const INTRINSIC_OPERATOR_OVERLOADING: number; export declare const INTRINSIC_BIGNUM_EXT: number; export declare const INTRINSIC_PERFORMANCE: number; export declare const INTRINSIC_CRYPTO: number; declare const INTRINSIC_FLAG_MAP: { readonly BaseObjects: number; readonly Date: number; readonly Eval: number; readonly StringNormalize: number; readonly RegExp: number; readonly RegExpCompiler: number; readonly JSON: number; readonly Proxy: number; readonly MapSet: number; readonly TypedArrays: number; readonly Promise: number; readonly BigInt: number; readonly BigFloat: number; readonly BigDecimal: number; readonly OperatorOverloading: number; readonly BignumExt: number; readonly Performance: number; readonly Crypto: number; }; export type Intrinsics = { [K in keyof typeof INTRINSIC_FLAG_MAP]?: boolean; }; /** * The default set of JavaScript language features enabled in a new context. * @see {@link ContextOptions} */ export declare const DefaultIntrinsics: Readonly<{ readonly BaseObjects: true; readonly Date: true; readonly Eval: true; readonly StringNormalize: true; readonly RegExp: true; readonly JSON: true; readonly Proxy: true; readonly MapSet: true; readonly TypedArrays: true; readonly Promise: true; }>; /** * Converts an Intrinsics object into the corresponding bitfield value. * * @param intrinsics - The Intrinsics configuration object * @returns A combined value representing all enabled features */ export declare function intrinsicsToFlags(intrinsics: Intrinsics): number; /** * Configuration options for creating a JavaScript execution context. * Pass to {@link HakoRuntime#newContext}. */ export interface ContextOptions { /** * What built-in objects and language features to enable? * If unset, the default intrinsics will be used. * To omit all intrinsics, pass an empty array. * * To remove a specific intrinsic, but retain the other defaults, * override it from {@link DefaultIntrinsics} * ```ts * const contextWithoutDateOrEval = runtime.newContext({ * intrinsics: { * ...DefaultIntrinsics, * Date: false, * } * }) * ``` */ intrinsics?: Intrinsics; /** * Wrap the provided context instead of constructing a new one. * @private Used internally, not intended for direct use */ contextPointer?: JSContextPointer; /** * Maximum stack size for JavaScript execution in this context, in bytes. * Helps prevent stack overflow attacks in untrusted code. */ maxStackSizeBytes?: number; } export declare const EVAL_FLAG_GLOBAL = 0; export declare const EVAL_FLAG_MODULE: number; export declare const EVAL_FLAG_DIRECT: number; export declare const EVAL_FLAG_INDIRECT: number; export declare const EVAL_FLAG_TYPE_MASK: number; export declare const EVAL_FLAG_STRICT: number; export declare const EVAL_FLAG_RESERVED: number; export declare const EVAL_FLAG_COMPILE_ONLY: number; export declare const EVAL_FLAG_DEBUGGER_NO_PERSIST_SCRIPT: number; /** * Type for evaluation flag values */ export type EvalFlag = number; /** * Bit flag for stripping source code * @internal */ export declare const JS_STRIP_SOURCE: number; /** * Bit flag for stripping all debug information including source code * @internal */ export declare const JS_STRIP_DEBUG: number; /** * Options for configuring code stripping behavior */ export interface StripOptions { /** * When true, source code will be stripped from the compiled output */ stripSource?: boolean; /** * When true, all debug information including source code will be stripped * Setting this to true automatically enables stripSource as well */ stripDebug?: boolean; } /** * Options for evaluating JavaScript code in a context. */ export interface ContextEvalOptions { /** * Global code (default), or "module" code? * * - When type is `"global"`, the code is evaluated in the global scope of the context, * and the return value is the result of the last expression. * - When type is `"module"`, the code is evaluated as a module scope, may use `import`, * `export`, and top-level `await`. The return value is the module's exports, * or a promise for the module's exports. */ type?: "global" | "module"; /** Force "strict" mode */ strict?: boolean; /** * Compile but do not run the code. The result is an object with a * JS_TAG_FUNCTION_BYTECODE or JS_TAG_MODULE tag. It can be executed * with JS_EvalFunction(). */ compileOnly?: boolean; /** Don't persist script in debugger */ noPersist?: boolean; /** Filename for error reporting */ fileName?: string; /** Automatically detect if code should be treated as a module */ detectModule?: boolean; } /** * Converts evaluation options to the corresponding bitfield flags. * * @param evalOptions - Options object, number (raw flags), or undefined * @returns The combined EvalFlag bitfield */ export declare function evalOptionsToFlags(evalOptions: ContextEvalOptions | number | undefined): EvalFlag; /** * JavaScript Promise states. */ export type PromiseState = /** Promise has not been resolved or rejected yet */ "pending" /** Promise has been resolved with a value */ | "fulfilled" /** Promise has been rejected with a reason */ | "rejected"; export declare const PROPERTY_ENUM_STRING: number; export declare const PROPERTY_ENUM_SYMBOL: number; export declare const PROPERTY_ENUM_PRIVATE: number; export declare const PROPERTY_ENUM_ENUMERABLE: number; export declare const PROPERTY_ENUM_NON_ENUMERABLE: number; export declare const PROPERTY_ENUM_CONFIGURABLE: number; export declare const PROPERTY_ENUM_NON_CONFIGURABLE: number; export declare const PROPERTY_ENUM_NUMBER: number; export declare const PROPERTY_ENUM_COMPLIANT: number; /** * Type for property enumeration flag values */ export type PropertyEnumFlags = number; /** * String representation of JavaScript types, aligned with typeof operator results. */ export type JSType = "undefined" | "object" | "string" | "symbol" | "boolean" | "number" | "bigint" | "function"; /** * Lifecycle modes for JavaScript values. */ export type ValueLifecycle = "owned" | "borrowed" | "temporary"; /** * Memory usage statistics returned by HAKO_RuntimeComputeMemoryUsage. * Provides detailed information about memory consumption by different components. */ export interface MemoryUsage { /** Maximum memory limit in bytes, or -1 if no limit */ malloc_limit: number; /** Current memory usage in bytes */ memory_used_size: number; /** Number of active malloc allocations */ malloc_count: number; /** Total count of memory allocations */ memory_used_count: number; /** Number of interned property names (atoms) */ atom_count: number; /** Memory used by atoms in bytes */ atom_size: number; /** Number of string objects */ str_count: number; /** Memory used by strings in bytes */ str_size: number; /** Number of JavaScript objects */ obj_count: number; /** Memory used by objects in bytes */ obj_size: number; /** Number of object properties */ prop_count: number; /** Memory used by properties in bytes */ prop_size: number; /** Number of object shapes */ shape_count: number; /** Memory used by shapes in bytes */ shape_size: number; /** Number of JavaScript functions */ lepus_func_count: number; /** Memory used by functions in bytes */ lepus_func_size: number; /** Memory used by function bytecode in bytes */ lepus_func_code_size: number; /** Number of PC to line mappings for debugging */ lepus_func_pc2line_count: number; /** Memory used by PC to line mappings in bytes */ lepus_func_pc2line_size: number; /** Number of C functions exposed to JavaScript */ c_func_count: number; /** Number of arrays */ array_count: number; /** Number of fast arrays (optimized for numeric indices) */ fast_array_count: number; /** Number of elements in fast arrays */ fast_array_elements: number; /** Number of binary objects (ArrayBuffer, TypedArray) */ binary_object_count: number; /** Memory used by binary objects in bytes */ binary_object_size: number; } /** * Property descriptor for defining object properties. * Similar to the standard JavaScript Object.defineProperty descriptor. */ export interface PropertyDescriptor { /** Property value */ value?: VMValue; /** Whether the property can be changed and deleted */ configurable?: boolean; /** Whether the property shows up during enumeration */ enumerable?: boolean; /** Getter function */ get?: (this: VMValue) => VMValue; /** Setter function */ set?: (this: VMValue, value: VMValue) => void; } /** * Configuration options for resource-limited interrupt handlers. */ export interface ResourceLimitOptions { /** Maximum execution time in milliseconds */ maxTimeMs?: number; /** Maximum memory usage in bytes */ maxMemoryBytes?: number; /** Maximum number of steps to execute */ maxSteps?: number; /** How often to check memory usage (every N steps) */ memoryCheckInterval?: number; } /** Uses === operator semantics */ type EqualOpStrict = "strict"; /** Uses Object.is() semantics */ type EqualOpSame = "same"; /** Uses Array.prototype.includes() semantics (treats +0 and -0 as equal) */ type EqualOpSameZero = "same-zero"; export type EqualOp = EqualOpStrict | EqualOpSame | EqualOpSameZero; /** * Promise executor function type, compatible with standard JavaScript Promise. */ export type PromiseExecutor<ResolveT, RejectT> = (resolve: (value: ResolveT | PromiseLike<ResolveT>) => void, reject: (reason: RejectT) => void) => void; /** * Result type for VMContext operations. */ export type VMContextResult<S> = DisposableResult<S, VMValue>; /** * Interface for Error objects with an options property containing a cause. */ interface ErrorWithOptions extends Error { options?: { cause?: unknown; }; } /** * Type guard to check if an Error has options with a cause property. * * @param error - The error to check * @returns True if the error has options with a cause */ export declare function hasOptionsWithCause(error: Error): error is ErrorWithOptions; /** * Detects circular references within an object and throws a TypeError when found. * * @param obj - The object to check for circular references * @param path - Optional path string for error messaging (used internally) * @throws TypeError when circular reference is detected */ export declare function detectCircularReferences(obj: unknown, path?: string): void; /** * Information about the build configuration of the Hako WebAssembly module. */ export type HakoBuildInfo = { /** Version string of the Hako library */ version: string; /** Raw flags value representing build configuration */ flags: number; /** Date and time the module was built */ buildDate: string; /** Version of the WASI SDK used */ wasiSdkVersion: string; /** Version of WASI libc used */ wasiLibc: string; /** LLVM compiler used */ llvm: string; /** Version of LLVM used */ llvmVersion: string; /** Build configuration string */ config: string; /** Whether this is a debug build */ isDebug: boolean; /** Whether sanitizers are enabled */ hasSanitizer: boolean; /** Whether BigNum support is enabled */ hasBignum: boolean; /** Whether LepusNG (next-gen engine) is enabled */ hasLepusNG: boolean; /** Whether debugger support is enabled */ hasDebugger: boolean; /** Whether snapshot support is enabled */ hasSnapshot: boolean; /** Whether compatible memory management is enabled */ hasCompatibleMM: boolean; /** Whether NaN boxing is enabled */ hasNanbox: boolean; /** Whether code cache is enabled */ hasCodeCache: boolean; /** Whether cache profiling is enabled */ hasCacheProfile: boolean; /** Whether memory detection is enabled */ hasMemDetection: boolean; /** Whether atomics support is enabled */ hasAtomics: boolean; /** Whether force garbage collection is enabled */ hasForceGC: boolean; /** Whether Lynx simplification is enabled */ hasLynxSimplify: boolean; /** Whether builtin serialization is enabled */ hasBuiltinSerialize: boolean; /** Whether hako was compiled with profiling enabled */ hasHakoProfiler: boolean; }; /** * Type of JavaScript TypedArray. */ export type TypedArrayType = "Unknown" | "Uint8Array" | "Uint8ClampedArray" | "Int8Array" | "Uint16Array" | "Int16Array" | "Uint32Array" | "Int32Array" | "BigUint64Array" | "BigInt64Array" | "Float16Array" | "Float32Array" | "Float64Array"; export {}; //# sourceMappingURL=types.d.ts.map