/** * `isolateFunction` — the Blob-URL escape hatch: run a single plain function inside a throwaway, * source-rehydrated Worker, without the caller ever writing a guest script file. * * @remarks * **This is a `new Function`-based eval trust surface. Read this before using it.** * * Every other seam in this battery (`spawnIsolated`/`serveIsolated`/the Node child_process backend) runs a guest * script the CALLER wrote, deployed, and controls the provenance of. `isolateFunction` is the opposite: * it takes an in-memory function VALUE, serializes it via `fn.toString()` (through * `@nhtio/encoder/function_serializer`'s `FunctionSerializer.dehydrate`), embeds that source text * verbatim into a synthesized classic-Worker script, and has the Worker rehydrate it with `new * Function(...)` at guest-side startup — there is no way to run source-rehydration without `new * Function` (or `eval`), and this module does not attempt to pretend otherwise. That is why the single * call site that opts into this is a literal, non-optional `{ allowSourceRehydration: true }` — both a * TypeScript literal-type requirement (passing `false` or a widened `boolean` fails to compile) AND a * runtime check (so a caller that reaches this through untyped JS, or an `as any` cast, still cannot * skip the acknowledgement). Treat any function handed to `isolateFunction` exactly as you would treat a * string handed to `eval`: only ever pass functions whose source your own process produced/controls. * `fn.toString()` captures no closures — only named, module-scope-free source is portable across the * Blob boundary (see {@link https://github.com/nhtio/nhtio-encoder | @nhtio/encoder}'s * `FunctionSerializer` for exactly which shapes round-trip). * * Design, deliberately MINI rather than the full `protocol.ts` envelope: * * - Host → guest: `{ id: string; args: WireValue[] }`. Each argument is encoded via `codec.ts`'s * {@link encodeArgument} in `'auto'` mode (so plain JSON-safe arguments cost nothing — they cross as * `enc: 'raw'` and the guest's inline unwrap is a no-op property read). If an argument contains an * exotic leaf (a function/Error/custom-encodable) `encodeArgument` would need to escalate past `raw` * — but the guest Blob has no module imports, so it cannot load `@nhtio/encoder` to decode an `enc: * 'nhtio'` value. Rather than ship a doomed message, {@link isolateFunction}'s `invoke` rejects such * calls up front with {@link E_ISOLATE_FUNCTION_ARG_UNSUPPORTED}. * - Guest → host: `{ id: string; ok: true; value: { enc: 'raw'; v: unknown } } | { id: string; ok: * false; error: { message: string; name: string; stack?: string } }` — hand-rolled inline in the Blob * source (no `codec.ts` import there either), but shaped compatibly with `protocol.ts`'s `WireValue`/ * `WireError` so the HOST side can decode results via the SAME {@link decodeArgument}/`fromWireError` * helpers the shared isolation protocol already defines, rather than a third, bespoke decode path. * * `dispose()` terminates the Worker and revokes the Blob URL; every in-flight `invoke()` call, and every * call made afterward, rejects with {@link @nhtio/adk/batteries/isolation!E_ISOLATED_TERMINATED}. An * uncaught top-level error in the guest (e.g. `FunctionSerializer`'s rehydrator itself throwing) surfaces * as a Worker `'error'` event, at which point every in-flight call rejects with * {@link @nhtio/adk/batteries/isolation!E_ISOLATED_CRASHED} and the instance is marked crashed permanently * (no auto-respawn — this is a one-shot escape hatch, not a managed service; construct a new * {@link isolateFunction} instance to try again). */ /** * Thrown when {@link isolateFunction} is called without the literal `{ allowSourceRehydration: true }` * acknowledgement. Fatal: this is a configuration/call-site error, caught before anything is spawned. */ export declare const E_ISOLATE_FUNCTION_REQUIRES_SOURCE_REHYDRATION: import("../../factories").CreatedException<[ string ]>; /** * Thrown when the function passed to {@link isolateFunction} cannot be serialized — * `@nhtio/encoder/function_serializer`'s `FunctionSerializer.canSerialize` rejects native functions * (`fn.toString()` containing `[native code]`) and bound functions (which stringify the same way). * Fatal: detected before any Worker is spawned; there is no fallback representation to fall back to. */ export declare const E_ISOLATE_FUNCTION_UNSERIALIZABLE: import("../../factories").CreatedException<[ string ]>; /** * Thrown when an `invoke()` argument contains an exotic leaf (a function/Error/custom-encodable) that * `codec.ts`'s tiered encoder would need to escalate past the `'raw'` tier. The isolated Blob guest has * no module imports (by design — no bare specifiers survive a Blob URL) and therefore cannot load * `@nhtio/encoder` to decode an `enc: 'nhtio'` value; `isolateFunction` only ever supports plain, * structured-cloneable arguments. Non-fatal: a caller can pass different, plain arguments instead. */ export declare const E_ISOLATE_FUNCTION_ARG_UNSUPPORTED: import("../../factories").CreatedException<[ string ]>; /** * Options accepted by {@link isolateFunction}. * * @remarks * `allowSourceRehydration` MUST be the literal `true` — both at the type level (a widened `boolean` * fails to type-check) and at runtime (checked explicitly, so an untyped/`as any` call site cannot skip * the acknowledgement). See this module's doc comment for what that acknowledgement means. */ export interface IsolateFunctionOptions { /** Explicit, non-optional acknowledgement that this function's source will be rehydrated via `new * Function` inside a Worker — an eval-equivalent trust surface. Must be the literal `true`. */ allowSourceRehydration: true; /** A developer-facing name, used in thrown exception messages and the Worker's `name` option. * Defaults to `fn.name` (or `'anonymous'` when the function itself has no name). */ name?: string; } /** The live handle returned by {@link isolateFunction}. */ export interface IsolatedFunctionHandle { /** * Invoke the isolated function with `args`, returning its result (or rejecting with whatever it * threw/rejected with, reconstructed as a plain `Error`). Lazily spawns the guest Worker on the first * call; subsequent calls reuse it. * * @throws {@link E_ISOLATE_FUNCTION_ARG_UNSUPPORTED} when an argument cannot cross into the guest. * @throws {@link @nhtio/adk/batteries/isolation!E_ISOLATION_UNSUPPORTED_ENV} when no browser `Worker` * global is present. * @throws {@link @nhtio/adk/batteries/isolation!E_ISOLATED_CRASHED} when the guest has crashed. * @throws {@link @nhtio/adk/batteries/isolation!E_ISOLATED_TERMINATED} after `dispose()`. */ invoke: (...args: A) => Promise; /** Terminate the guest Worker and revoke its Blob URL. Every in-flight (and future) `invoke()` call * rejects with {@link @nhtio/adk/batteries/isolation!E_ISOLATED_TERMINATED}. Idempotent. */ dispose: () => void; } /** * Run `fn` inside a throwaway, source-rehydrated Worker. See this module's doc comment for the full * design and the trust-boundary implications of `allowSourceRehydration`. * * @throws {@link E_ISOLATE_FUNCTION_REQUIRES_SOURCE_REHYDRATION} when `allowSourceRehydration` is not * the literal `true`. */ export declare const isolateFunction: (fn: (...args: A) => R | Promise, options: IsolateFunctionOptions) => IsolatedFunctionHandle;