/** * pendingFn 回调函数接收的参数 */ type PendingFnParams = { /** 解析后的 scope key */ scope: string; /** 获取当前等待中的 caller 数量(实时值) */ getPendingCount: () => number; }; declare class MountRemoteError extends Error { readonly prev?: unknown | undefined; constructor(message: string, prev?: unknown | undefined); } type MountRemoteResult = Record> = { type: string; scope: string; } & Result; /** * Handler 上下文,继承 PendingFnParams */ type MountHandlerContext = Record> = PendingFnParams & { type: string; } & Options; /** * DOM 类型 handler 的通用选项 */ type MountDomOptions = { url: string; attrs?: Record; onLoad?: (el: HTMLElement, res: MountRemoteResult) => void | Promise; onError?: (err: unknown, ctx: MountHandlerContext, opts: MountDomOptions) => void; }; /** * DOM handler 的扩展返回字段(不含 MountRemoteResult 的基础字段) */ type MountDomResult = MountDomOptions & { id: string; el: HTMLElement; }; /** * 类型安全的 handler 函数 */ type MountHandlerFn = Record, Result extends Record = Record> = (ctx: MountHandlerContext, opts: Options) => Promise> | MountRemoteResult; /** * Handler 类型映射表 * * 通过 interface 声明合并扩展: * ```ts * declare module '@zenstone/ts-utils/remote' { * interface MountHandlerMap { * wasm: MountHandlerFn<{ url: string; importObject?: WebAssembly.Imports }>; * } * } * ``` */ interface MountHandlerMap { js: MountHandlerFn; css: MountHandlerFn; mjs: MountHandlerFn; } /** * 注册挂载类型处理器 * * @param type 资源类型标识 * @param handler 处理函数 * * @example * ```ts * registerMountHandler('wasm', async (ctx, opts) => { * const response = await fetch(opts.url); * const module = await WebAssembly.instantiateStreaming(response, opts.importObject); * return { type: ctx.type, scope: ctx.scope, url: opts.url, module }; * }); * ``` */ declare const registerMountHandler: (type: K, handler: MountHandlerMap[K]) => void; /** * 创建基于 DOM 元素的挂载处理器 * * 适用于通过 script/link 等标签加载的资源。自动处理: * - `getElementById` 短路检查 * - 创建元素并设置属性 * - 设置 id(使用 scope) * - 监听 load/error 事件 * - 挂载到 document.head * * @param tagName 标签名 * @param setup 元素初始化函数 * * @example * ```ts * registerMountHandler('img', createDomHandler('img', (el, ctx) => { * el.setAttribute('src', ctx.url); * })); * ``` */ declare const createDomHandler: (tagName: string, setup: (el: HTMLElement, ctx: MountHandlerContext) => void) => MountHandlerFn; /** * 挂载远程资源 * * 基于 scope 做 inflight 去重:并发调用同 scope 只执行一次,结果共享。 * Options 类型由 `type` 字段决定,通过 {@link MountHandlerMap} 接口扩展。 * * 内置支持 `js`、`mjs`、`css` 三种类型,其他类型需通过 * {@link registerMountHandler} 注册处理器。 * * @param scope 去重标识,同时用作 DOM 元素 id(对于 DOM handler) * @param options 挂载选项,类型由 `type` 决定 * * @example * ```ts * await mountRemote('jquery', { * type: 'js', * url: 'https://cdn.example.com/jquery.min.js', * }); * ``` * * @example 并发去重 * ```ts * await Promise.all([ * mountRemote('lib', { type: 'js', url }), * mountRemote('lib', { type: 'js', url }), * ]); * // 只加载一次 * ``` */ declare function mountRemote(scope: string, options: { type: K; } & Parameters[1]): Promise; /** * 基于 id 移除已挂载的远程资源 * * @param id 元素 ID * @param onRemove 移除后回调 */ declare const unmountDomRemote: (id: string, onRemove?: () => void) => void; export { MountRemoteError, createDomHandler, mountRemote, registerMountHandler, unmountDomRemote }; export type { MountDomOptions, MountDomResult, MountHandlerContext, MountHandlerFn, MountHandlerMap, MountRemoteResult };