@dlient/plugin-sdk 3.0.6 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -151,8 +151,13 @@ function createWorkerRpc(pluginId, generation, options) {
151
151
  if (!handler) {
152
152
  response.error = `Method "${msg.method}" not found`;
153
153
  } else {
154
+ const ctx = {
155
+ from_plugin_id: msg.from_plugin_id ?? "",
156
+ request_id: msg.id,
157
+ signal: new AbortController().signal
158
+ };
154
159
  try {
155
- const result = handler(msg.args);
160
+ const result = handler(msg.args, ctx);
156
161
  if (result instanceof Promise) {
157
162
  result.then(
158
163
  (value) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/types.ts","../src/worker.ts"],"sourcesContent":["/**\n * 领域模型:PluginManifest / PluginPermission / PluginRuntime / PluginInstalled / PluginType。\n * manifest 对应插件 package.json 的 `dlient` 子对象。\n * 该文件是类型与工具函数的事实来源(自 core 迁入),core 反向引用本包。\n */\n\n/** 本地化文案:字符串(默认值)或多语言映射(键为 locale,如 'zh-CN'/'en-US';'default' 键兜底) */\nexport type LocalizedText = string | Record<string, string>\n\n/**\n * expose 方法调用权限(docs/v3/plugin-view.md §2.2):\n * - private 仅本插件自己;\n * - default(缺省) 宿主(主进程侧)+ 本插件自己;\n * - system system 插件可默认调用,非 system 插件不可调;\n * - public 所有插件,无需 dependencies 声明;\n * - install-confirm 安装时用户确认(永久有效),须在 dependencies 中声明;\n * - runtime-confirm 使用时用户确认(1 天内有效),须在 dependencies 中声明。\n * 支持组合表达式:'|' = 或(满足任一),'&' = 且(需全部满足)。\n * 例:`runtime-confirm | system` = system 直接调用,其它插件需运行时确认。\n */\nexport type ExposeAccess =\n | 'private'\n | 'default'\n | 'system'\n | 'public'\n | 'install-confirm'\n | 'runtime-confirm'\n\n/** expose 方法条目 */\nexport interface PluginExposeMethod {\n /** 方法说明(确认框 / 上传校验文案用) */\n description?: string\n /** 调用权限表达式(缺省 'default') */\n access?: string\n}\n\nexport interface PluginManifest {\n id: string // 插件唯一 ID\n version: string // semver\n /** 显示名:字符串或多语言映射(键为 locale,如 'zh-CN'/'en-US';'default' 兜底) */\n name: LocalizedText\n /** 描述:字符串或多语言映射(同上) */\n description?: LocalizedText\n /** dist 目录相对插件根目录的路径(默认 'dist';开发插件可为任意外部目录的构建输出) */\n dist?: string\n /**\n * 产物打包方式(方案 build.md 2.3):\n * - 'plain'(缺省):多文件 dist 目录,dlientV3:// 协议直接读磁盘文件;\n * - 'asar':发布时 dist 打成 <pluginDir>/plugin.asar,协议与 worker fork 从 asar 内读取。\n */\n packaging?: 'plain' | 'asar'\n /**\n * 插件类型:\n * - app:独立应用,可在基座中直接启动(启动后打开页面);\n * - full / worker / ui:提供能力给其它插件调用的常规插件。\n * 缺省 'ui'。\n */\n type?: PluginType\n /** 是否为系统级插件(不可卸载;基座首次启动时从服务器下载并安装) */\n system?: boolean\n /** 来源:market=市场;local=本地;dev=开发中(缺省由加载上下文决定) */\n source?: PluginSource\n /** 图标:相对插件根目录的路径(如 \"icon.svg\" / \"assets/icon.svg\") */\n icon?: string\n /** 插件标签(市场展示 / 检索;如 [\"ai\", \"chat\"]) */\n tags?: string[]\n /** 所属组织(组织标识,形如 \"@xxx\") */\n organization?: string\n requires?: string[] // 依赖的插件 ID\n platforms?: PluginPlatform[] // 支持平台(缺省=全平台)\n permissions?: PluginPermission[] // 申请的宿主能力\n /** 对外暴露给其它插件调用的方法(plugin.invoke 校验;access 见 ExposeAccess) */\n expose?: Record<string, PluginExposeMethod>\n /** 声明要调用的其它插件方法(plugin.invoke 校验) */\n dependencies?: Record<string, string[]>\n engines?: {\n dlient?: string\n electron?: string\n }\n author?: string\n homepage?: string\n repository?: string\n}\n\nexport type PluginPlatform = 'darwin' | 'win32' | 'linux'\n\nexport type PluginPermission =\n | 'webview.create'\n | 'webview.navigate'\n | 'fs.read'\n | 'fs.write'\n | 'fs.delete'\n | 'os.openExternal'\n | 'clipboard.read'\n | 'clipboard.write'\n | 'notifications'\n | 'system.getIdleState'\n // app.* 宿主能力\n | 'app.data' // 插件数据隔离存储(USER_DATA/plugin-data/<pluginId>/)\n | 'app.setAutoLaunch' // 开机自启动\n | 'app.shortcut.register' // 快捷键注册\n | 'app.crypt' // 每插件独立密钥加解密(主进程内部派生,插件间隔离)\n | 'app.window' // 窗口控制(无头模式自绘标题栏:关闭窗口等)\n | 'plugins.dev' // 开发插件管理(外部目录注册 / 移除 / 热重载)\n\nexport interface PluginRuntime {\n id: string\n version: string\n status: 'stopped' | 'starting' | 'running' | 'error' | 'stopping'\n generation: number\n enabled: boolean\n error?: string\n startTime?: number\n}\n\nexport interface PluginInstalled {\n id: string\n version: string\n installedAt: number\n enabled: boolean\n updateAvailable?: string\n}\n\nexport type PluginType = 'full' | 'worker' | 'ui' | 'app'\n\n/** 插件来源:market=市场安装;local=本地导入;dev=开发中 */\nexport type PluginSource = 'market' | 'local' | 'dev'\n\n/** 缺省推断:显式声明优先;未声明按 'ui'(无 worker 依赖,最安全) */\nexport function inferPluginType(manifest: PluginManifest): PluginType {\n return manifest.type ?? 'ui'\n}\n\n/** 解析本地化文案:locale 无匹配时回退 'default' 键 → 字符串本身 → fallback */\nexport function localizeText(text: LocalizedText | undefined, locale: string, fallback = ''): string {\n if (!text) return fallback\n if (typeof text === 'string') return text\n return text[locale] ?? text['default'] ?? fallback\n}\n","/**\n * createWorkerRpc - 插件 worker(utilityProcess)端辅助。\n * 双通道:\n * - parentPort 主通道:init / rpc-call(主进程 invokePlugin 转发)/ host-api / 心跳 / port-setup\n * - directPort 直连通道(MessageChannelMain):渲染层 preload 直连\n * request/listen → 执行 registerHandler/registerStreamHandler → 自动按 request_id 回传\n * 插件开发者不感知 port 与 request_id:handler(args, ctx) 即可。\n */\n\nimport type {\n PluginMessage,\n RpcResponseMessage,\n HostApiCallMessage,\n HostApiResponseMessage,\n PushMessage,\n DirectRequestMessage,\n DirectListenMessage,\n DirectPortMessage,\n SnapshotRequestMessage,\n SnapshotResponseMessage,\n SnapshotRestoreMessage,\n} from './protocol'\n\n/** Electron utilityProcess 的 parentPort(Node 全局 Process 类型无此成员,此处扩展) */\ninterface UtilityParentPort {\n postMessage(message: unknown, transfer?: unknown[]): void\n on(event: 'message', listener: (message: unknown) => void): void\n}\n\ndeclare global {\n namespace NodeJS {\n interface Process {\n parentPort?: UtilityParentPort\n }\n }\n}\n\n/**\n * 通道(控制面 / 直连):兼容 Electron MessagePortMain 与 utilityProcess parentPort。\n * 共享池模式下控制/直连通道由池运行时注入(见 pool-worker.ts),独立进程模式用 process.parentPort。\n */\ninterface RpcChannel {\n postMessage(message: unknown, transfer?: unknown[]): void\n on(event: 'message', listener: (event: { data: unknown; ports?: unknown[] }) => void): void\n start?(): void\n}\n\n/** 池上下文:pool-worker 加载插件前设置,createWorkerRpc 同步读取 */\ninterface PoolContext {\n pluginId?: string\n controlPort?: RpcChannel\n directPort?: RpcChannel\n}\n\n/** 池运行时读写全局键(与 pool-worker.ts 一致) */\nconst POOL_CTX_KEY = '__dlientPoolCtx'\nconst RPC_TABLE_KEY = '__dlientRpcTable'\n\ntype WorkerRpcHandler = (args: unknown[], ctx?: HandlerContext) => unknown | Promise<unknown>\n\n/** handler 执行上下文(directPort 直连调用时填充) */\nexport interface HandlerContext {\n from_plugin_id: string\n request_id: string\n /** 请求携带的大块数据(transfer 零拷贝) */\n data?: ArrayBuffer\n /** 流式发射(仅 registerStreamHandler / listen 模式可用) */\n emit?: (chunk?: unknown, opts?: { data?: ArrayBuffer }) => void\n /** 取消信号(UI 发 cancel 时 abort) */\n signal: AbortSignal\n}\n\n/** rpc.api:按模块分层的宿主能力调用入口(Proxy 动态生成,无需预先枚举) */\nexport type HostApi = Record<string, Record<string, (...args: unknown[]) => Promise<unknown>>>\n\nexport interface WorkerRpc {\n registerHandler: (method: string, handler: WorkerRpcHandler) => void\n /** 流式 handler:ctx.emit(chunk) 多次,return 后自动发 stream-done */\n registerStreamHandler: (method: string, handler: WorkerRpcHandler) => void\n /** 跨插件调用:经主进程 plugin.invoke(expose + dependencies 校验) */\n callPlugin: (pluginId: string, method: string, args?: unknown[]) => Promise<unknown>\n /** 宿主能力调用(字符串方法名方式) */\n callHostApi: (method: string, args?: unknown[]) => Promise<unknown>\n /**\n * 宿主能力分层调用:rpc.api.{module}.{method}(...args),\n * 等价 rpc.callHostApi('{module}.{method}', args)。\n * 参数格式与 Electron 官方 API 一致(模块与接口见 docs/v3/worker_api.md)。\n */\n api: HostApi\n /** 推送事件给绑定本插件的渲染层 view(经主进程转发) */\n push: (event: string, data?: unknown) => void\n /** 业务状态快照:热重载/重启前主进程请求(1s 窗口),插件实现返回可序列化状态 */\n registerSnapshotHandler: (handler: () => unknown | Promise<unknown>) => void\n /** 业务状态恢复:重启后主进程回灌快照,插件据此恢复状态 */\n registerRestoreHandler: (handler: (snapshot: unknown) => void | Promise<void>) => void\n getPluginId: () => string\n getGeneration: () => number\n log: (level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: unknown) => void\n}\n\nexport function createWorkerRpc(\n pluginId: string,\n generation: number,\n options?: { controlPort?: RpcChannel; directPort?: RpcChannel },\n): WorkerRpc {\n const handlers = new Map<string, WorkerRpcHandler>()\n const streamHandlers = new Set<string>()\n let messageId = 0\n const pending = new Map<string, { resolve: (value: unknown) => void; reject: (err: Error) => void }>()\n /** directPort(渲染层直连通道);池注入或 port-setup 消息时设置 */\n let directPort: RpcChannel | null = null\n /** 在途流式/请求的 AbortController(cancel 时 abort) */\n const inFlight = new Map<string, AbortController>()\n /** 业务状态快照/恢复 handler(热重载/重启用;未注册则跳过快照) */\n let snapshotHandler: (() => unknown | Promise<unknown>) | undefined\n let restoreHandler: ((snapshot: unknown) => void | Promise<void>) | undefined\n\n // 通道解析:池上下文(pool-worker 注入)优先,其次显式 options,最后 process.parentPort(独立进程)\n const poolCtx = (globalThis as unknown as Record<string, unknown>)[POOL_CTX_KEY] as PoolContext | undefined\n const ctl: RpcChannel | undefined =\n options?.controlPort ??\n poolCtx?.controlPort ??\n (typeof process !== 'undefined' ? (process.parentPort as RpcChannel | undefined) : undefined)\n\n const sendMessage = (msg: PluginMessage) => {\n ctl?.postMessage(msg)\n }\n\n // ---- directPort 直连消息处理(渲染层 preload 发出)----\n\n /**\n * 注意:utilityProcess 下发的 directPort 是 Electron MessagePortMain,\n * 其 postMessage 的 transfer 仅接受 MessagePortMain[](不支持 ArrayBuffer),\n * 且传 undefined 第二参也会抛 \"transferables must be an array of MessagePorts\"。\n * 因此 data 字段一律随消息结构化克隆(深拷贝),不启用 transfer。\n */\n const sendDirect = (msg: DirectPortMessage) => {\n if (!directPort) return\n directPort.postMessage(msg)\n }\n\n const handleDirectMessage = (event: { data: DirectPortMessage }) => {\n const msg = event.data\n switch (msg.type) {\n case 'request':\n runDirectHandler(msg, false)\n break\n case 'listen':\n runDirectHandler(msg, true)\n break\n case 'cancel':\n inFlight.get(msg.request_id)?.abort()\n inFlight.delete(msg.request_id)\n break\n }\n }\n\n /** 设置并监听直连通道(池注入 directPort / port-setup 消息 / reattach-direct 共用) */\n const setupDirectPort = (port: RpcChannel) => {\n directPort = port\n port.on('message', (payload: unknown) => handleDirectMessage(payload as { data: DirectPortMessage }))\n port.start?.()\n sendMessage({ type: 'direct-port-ready', pluginId })\n }\n\n // 池模式直连通道注入(pool-worker 随 load-plugin transfer 的 direct port;同步生效)\n const directInit = options?.directPort ?? poolCtx?.directPort\n if (directInit) setupDirectPort(directInit)\n\n // 注册到池 rpc 表:池运行时重建直连通道(reattach-direct 消息)时按 pluginId 调用\n // (独立进程模式无 pool-worker,表仅被池运行时消费;全局键与 pool-worker.ts 一致)\n const rpcTable = ((globalThis as unknown as Record<string, unknown>)[RPC_TABLE_KEY] ??= {}) as Record<\n string,\n { setDirectPort?: (port: RpcChannel) => void }\n >\n rpcTable[pluginId] = { setDirectPort: setupDirectPort }\n\n /** 执行 directPort 请求并自动按 request_id 回传(并发:每条消息独立 Promise,不互相等待) */\n function runDirectHandler(msg: DirectRequestMessage | DirectListenMessage, isStream: boolean): void {\n const handler = handlers.get(msg.method)\n if (!handler) {\n sendDirect({ type: 'error', request_id: msg.request_id, error: `Method \"${msg.method}\" not found` })\n return\n }\n const ac = new AbortController()\n inFlight.set(msg.request_id, ac)\n\n const emit = (chunk?: unknown, opts?: { data?: ArrayBuffer }) => {\n sendDirect({ type: 'stream', request_id: msg.request_id, chunk, data: opts?.data })\n }\n\n const ctx: HandlerContext = {\n from_plugin_id: msg.from_plugin_id,\n request_id: msg.request_id,\n data: msg.data,\n signal: ac.signal,\n emit: isStream ? emit : undefined,\n }\n\n Promise.resolve()\n .then(() => handler(msg.args, ctx))\n .then((result) => {\n if (ac.signal.aborted) return\n const data = (result as { data?: ArrayBuffer } | null | undefined)?.data\n const value = data !== undefined ? (result as { result?: unknown }).result : result\n sendDirect(\n isStream\n ? { type: 'stream-done', request_id: msg.request_id, result: value }\n : { type: 'response', request_id: msg.request_id, result: value, data },\n )\n })\n .catch((err) => {\n if (ac.signal.aborted) return\n sendDirect({ type: 'error', request_id: msg.request_id, error: err instanceof Error ? err.message : String(err) })\n })\n .finally(() => {\n inFlight.delete(msg.request_id)\n })\n }\n\n if (ctl) {\n // 主进程最近一次有消息的时间(心跳 / rpc-call / host-api-response 等均代表主进程存活)\n let lastSeenAt = Date.now()\n\n ctl.on('message', (event: unknown) => {\n const e = event as { data: PluginMessage; ports?: unknown[] }\n const msg = e.data\n lastSeenAt = Date.now()\n switch (msg.type) {\n case 'init': {\n sendMessage({ type: 'ready', pluginId, generation, capabilities: Array.from(handlers.keys()) })\n break\n }\n case 'port-setup': {\n // 独立进程模式:主进程下发直连 port → 复用 setupDirectPort(池模式经 load-plugin 直接注入)\n const [port] = (e.ports ?? []) as RpcChannel[]\n if (port) setupDirectPort(port)\n break\n }\n case 'rpc-call':\n handleRpcCall(msg as never)\n break\n case 'host-api-response':\n handleHostApiResponse(msg as HostApiResponseMessage)\n break\n case 'snapshot-request': {\n // 主进程重启前请求快照:1s 窗口内回 snapshot-response;未注册 handler 则静默不回\n const req = msg as SnapshotRequestMessage\n if (snapshotHandler) {\n Promise.resolve()\n .then(() => snapshotHandler!())\n .then((snapshot) => {\n const res: SnapshotResponseMessage = { type: 'snapshot-response', pluginId, request_id: req.request_id, snapshot }\n sendMessage(res)\n })\n .catch((err) => {\n const res: SnapshotResponseMessage = {\n type: 'snapshot-response',\n pluginId,\n request_id: req.request_id,\n error: err instanceof Error ? err.message : String(err),\n }\n sendMessage(res)\n })\n }\n break\n }\n case 'snapshot-restore': {\n // 重启后主进程回灌快照(消息保序:先于后续 rpc-call 到达)\n const res = msg as SnapshotRestoreMessage\n if (restoreHandler) {\n void Promise.resolve()\n .then(() => restoreHandler!(res.snapshot))\n .catch((err) => console.error(`[plugin:${pluginId}] snapshot restore failed:`, err))\n }\n break\n }\n case 'heartbeat':\n // 主进程存活信号:仅刷新 lastSeenAt(已在开头统一处理)\n break\n }\n })\n // 池模式:ctl 是注入的 MessagePortMain,必须显式 start() 才会开始接收消息\n //(独立进程模式为 process.parentPort,无 start 方法,可选链安全跳过)。\n // 缺少 start 时 worker 收不到主进程 heartbeat / host-api-response → watchdog 误报\n // 「Main process lost (no message for 30s)」,所有 host-api 调用与渲染层请求全部超时。\n ctl.start?.()\n\n // worker → 主进程心跳:每 10s 上报一次,主进程据此判定 worker 是否失联\n setInterval(() => {\n sendMessage({ type: 'heartbeat', pluginId, ts: Date.now() })\n }, 10000)\n\n // worker 侧失联 watchdog:主进程心跳每 10s 一条,超过 30s 未收到任何消息\n setInterval(() => {\n if (Date.now() - lastSeenAt > 30000) {\n const error = new Error('Main process lost (no message for 30s)')\n for (const { reject } of pending.values()) reject(error)\n pending.clear()\n }\n }, 5000)\n }\n\n const handleRpcCall = (msg: { id: string; method: string; args: unknown[] }) => {\n const handler = handlers.get(msg.method)\n const response: RpcResponseMessage = { type: 'rpc-response', id: msg.id, pluginId }\n if (!handler) {\n response.error = `Method \"${msg.method}\" not found`\n } else {\n try {\n const result = handler(msg.args)\n if (result instanceof Promise) {\n result.then(\n (value) => { response.result = value; sendMessage(response) },\n (err) => { response.error = err.message; sendMessage(response) },\n )\n return\n }\n response.result = result\n } catch (err) {\n response.error = err instanceof Error ? err.message : String(err)\n }\n }\n sendMessage(response)\n }\n\n const handleHostApiResponse = (msg: HostApiResponseMessage) => {\n const pendingItem = pending.get(msg.id)\n if (pendingItem) {\n pending.delete(msg.id)\n if (msg.error) {\n pendingItem.reject(new Error(msg.error))\n } else {\n pendingItem.resolve(msg.result)\n }\n }\n }\n\n // ---- 内建 webview 能力转发(Webview 组件经「承载插件」worker 调用 hostApi)----\n // 任何插件的 worker 都自动带这些 handler:前端 <Webview>(@dlient/ui)用 useDientApi 请求\n // 自己插件的 webview:* → 这里转发到主进程 webview-manager。hostApi 侧按 manifest.permissions\n //(webview.create / webview.navigate)鉴权,未声明权限的插件调用会被主进程拒绝。\n // 插件可用 registerHandler 显式注册同名方法覆盖内建实现(显式优先)。\n handlers.set('webview:create', ([opts]) => callHostApiImpl('webview.create', [opts]))\n handlers.set('webview:update', ([opts]) => callHostApiImpl('webview.update', [opts]))\n handlers.set('webview:destroy', ([viewId]) => callHostApiImpl('webview.destroy', [String(viewId ?? '')]))\n handlers.set('webview:webContents:call', ([opts]) => callHostApiImpl('webview.webContentsCall', [opts]))\n // 主进程 webview-manager 按 owner 插件转发 webContents 白名单事件 → 推送承载插件前端组件\n handlers.set('onWebContentsEvent', ([payload]) => {\n const { viewId, name, args } = (payload ?? {}) as { viewId?: string; name?: string; args?: unknown[] }\n if (!viewId || !name) return\n const msg: PushMessage = { type: 'push', pluginId, event: 'webview:event', data: { viewId, name, args } }\n sendMessage(msg)\n })\n\n return {\n getPluginId: () => pluginId,\n getGeneration: () => generation,\n\n registerHandler: (method: string, handler: WorkerRpcHandler) => {\n handlers.set(method, handler)\n streamHandlers.delete(method)\n },\n\n registerSnapshotHandler: (handler: () => unknown | Promise<unknown>) => {\n snapshotHandler = handler\n },\n\n registerRestoreHandler: (handler: (snapshot: unknown) => void | Promise<void>) => {\n restoreHandler = handler\n },\n\n registerStreamHandler: (method: string, handler: WorkerRpcHandler) => {\n handlers.set(method, handler)\n streamHandlers.add(method)\n },\n\n callHostApi: (method: string, args: unknown[] = []) => callHostApiImpl(method, args),\n\n /** rpc.api.{module}.{method}(...args) → callHostApi('{module}.{method}', args) */\n api: createApiProxy(),\n\n callPlugin: (targetPluginId: string, method: string, args: unknown[] = []) =>\n callHostApiImpl('plugin.invoke', [targetPluginId, method, args]),\n\n push: (event: string, data?: unknown) => {\n const msg: PushMessage = { type: 'push', pluginId, event, data }\n sendMessage(msg)\n },\n\n log: (level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: unknown) => {\n sendMessage({ type: 'log', pluginId, level, message, data })\n },\n }\n\n function callHostApiImpl(method: string, args: unknown[]): Promise<unknown> {\n const id = `host-api-${pluginId}-${generation}-${++messageId}`\n const msg: HostApiCallMessage = { type: 'host-api-call', id, method, args, pluginId }\n return new Promise<unknown>((resolve, reject) => {\n pending.set(id, { resolve, reject })\n sendMessage(msg)\n })\n }\n\n /**\n * 分层 api 代理:访问 rpc.api.{module}.{method} 时动态生成调用函数。\n * 模块与方法名直接拼成 host-api 方法 id(\"{module}.{method}\"),与主进程方法表一致;\n * 参数原样透传,格式与 Electron 官方 API 一致。\n */\n function createApiProxy(): HostApi {\n const moduleProxies = new Map<string, Record<string, (...args: unknown[]) => Promise<unknown>>>()\n return new Proxy({} as HostApi, {\n get: (_target, module) => {\n const mod = String(module)\n let modProxy = moduleProxies.get(mod)\n if (!modProxy) {\n modProxy = new Proxy({} as Record<string, (...args: unknown[]) => Promise<unknown>>, {\n get: (_t, method) => (...args: unknown[]) => callHostApiImpl(`${mod}.${String(method)}`, args),\n })\n moduleProxies.set(mod, modProxy)\n }\n return modProxy\n },\n })\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/types.ts","../src/worker.ts"],"sourcesContent":["/**\n * 领域模型:PluginManifest / PluginPermission / PluginRuntime / PluginInstalled / PluginType。\n * manifest 对应插件 package.json 的 `dlient` 子对象。\n * 该文件是类型与工具函数的事实来源(自 core 迁入),core 反向引用本包。\n */\n\n/** 本地化文案:字符串(默认值)或多语言映射(键为 locale,如 'zh-CN'/'en-US';'default' 键兜底) */\nexport type LocalizedText = string | Record<string, string>\n\n/**\n * expose 方法调用权限(docs/v3/plugin-view.md §2.2):\n * - private 仅本插件自己;\n * - default(缺省) 宿主(主进程侧)+ 本插件自己;\n * - system system 插件可默认调用,非 system 插件不可调;\n * - public 所有插件,无需 dependencies 声明;\n * - install-confirm 安装时用户确认(永久有效),须在 dependencies 中声明;\n * - runtime-confirm 使用时用户确认(1 天内有效),须在 dependencies 中声明。\n * 支持组合表达式:'|' = 或(满足任一),'&' = 且(需全部满足)。\n * 例:`runtime-confirm | system` = system 直接调用,其它插件需运行时确认。\n */\nexport type ExposeAccess =\n | 'private'\n | 'default'\n | 'system'\n | 'public'\n | 'install-confirm'\n | 'runtime-confirm'\n\n/** expose 方法条目 */\nexport interface PluginExposeMethod {\n /** 方法说明(确认框 / 上传校验文案用) */\n description?: string\n /** 调用权限表达式(缺省 'default') */\n access?: string\n}\n\nexport interface PluginManifest {\n id: string // 插件唯一 ID\n version: string // semver\n /** 显示名:字符串或多语言映射(键为 locale,如 'zh-CN'/'en-US';'default' 兜底) */\n name: LocalizedText\n /** 描述:字符串或多语言映射(同上) */\n description?: LocalizedText\n /** dist 目录相对插件根目录的路径(默认 'dist';开发插件可为任意外部目录的构建输出) */\n dist?: string\n /**\n * 产物打包方式(方案 build.md 2.3):\n * - 'plain'(缺省):多文件 dist 目录,dlientV3:// 协议直接读磁盘文件;\n * - 'asar':发布时 dist 打成 <pluginDir>/plugin.asar,协议与 worker fork 从 asar 内读取。\n */\n packaging?: 'plain' | 'asar'\n /**\n * 插件类型:\n * - app:独立应用,可在基座中直接启动(启动后打开页面);\n * - full / worker / ui:提供能力给其它插件调用的常规插件。\n * 缺省 'ui'。\n */\n type?: PluginType\n /** 是否为系统级插件(不可卸载;基座首次启动时从服务器下载并安装) */\n system?: boolean\n /** 来源:market=市场;local=本地;dev=开发中(缺省由加载上下文决定) */\n source?: PluginSource\n /** 图标:相对插件根目录的路径(如 \"icon.svg\" / \"assets/icon.svg\") */\n icon?: string\n /** 插件标签(市场展示 / 检索;如 [\"ai\", \"chat\"]) */\n tags?: string[]\n /** 所属组织(组织标识,形如 \"@xxx\") */\n organization?: string\n requires?: string[] // 依赖的插件 ID\n platforms?: PluginPlatform[] // 支持平台(缺省=全平台)\n /**\n * 是否包含原生模块(.node 二进制,经 @electron/rebuild 针对 Electron ABI 编译)。\n * true 时必须同时声明 platforms(原生模块为平台二进制,仅允许在声明的平台上下载安装),\n * 且产物中必须实际包含 .node 文件(服务端上传时校验二者一致性)。\n */\n native?: boolean\n permissions?: PluginPermission[] // 申请的宿主能力\n /** 对外暴露给其它插件调用的方法(plugin.invoke 校验;access 见 ExposeAccess) */\n expose?: Record<string, PluginExposeMethod>\n /** 声明要调用的其它插件方法(plugin.invoke 校验) */\n dependencies?: Record<string, string[]>\n engines?: {\n dlient?: string\n electron?: string\n }\n author?: string\n homepage?: string\n repository?: string\n}\n\nexport type PluginPlatform = 'darwin' | 'win32' | 'linux'\n\nexport type PluginPermission =\n | 'webview.create'\n | 'webview.navigate'\n | 'fs.read'\n | 'fs.write'\n | 'fs.delete'\n | 'os.openExternal'\n | 'clipboard.read'\n | 'clipboard.write'\n | 'notifications'\n | 'system.getIdleState'\n // app.* 宿主能力\n | 'app.data' // 插件数据隔离存储(USER_DATA/plugin-data/<pluginId>/)\n | 'app.setAutoLaunch' // 开机自启动\n | 'app.shortcut.register' // 快捷键注册\n | 'app.crypt' // 每插件独立密钥加解密(主进程内部派生,插件间隔离)\n | 'app.window' // 窗口控制(无头模式自绘标题栏:关闭窗口等)\n | 'plugins.dev' // 开发插件管理(外部目录注册 / 移除 / 热重载)\n\nexport interface PluginRuntime {\n id: string\n version: string\n status: 'stopped' | 'starting' | 'running' | 'error' | 'stopping'\n generation: number\n enabled: boolean\n error?: string\n startTime?: number\n}\n\nexport interface PluginInstalled {\n id: string\n version: string\n installedAt: number\n enabled: boolean\n updateAvailable?: string\n}\n\nexport type PluginType = 'full' | 'worker' | 'ui' | 'app'\n\n/** 插件来源:market=市场安装;local=本地导入;dev=开发中 */\nexport type PluginSource = 'market' | 'local' | 'dev'\n\n/** 缺省推断:显式声明优先;未声明按 'ui'(无 worker 依赖,最安全) */\nexport function inferPluginType(manifest: PluginManifest): PluginType {\n return manifest.type ?? 'ui'\n}\n\n/** 解析本地化文案:locale 无匹配时回退 'default' 键 → 字符串本身 → fallback */\nexport function localizeText(text: LocalizedText | undefined, locale: string, fallback = ''): string {\n if (!text) return fallback\n if (typeof text === 'string') return text\n return text[locale] ?? text['default'] ?? fallback\n}\n","/**\n * createWorkerRpc - 插件 worker(utilityProcess)端辅助。\n * 双通道:\n * - parentPort 主通道:init / rpc-call(主进程 invokePlugin 转发)/ host-api / 心跳 / port-setup\n * - directPort 直连通道(MessageChannelMain):渲染层 preload 直连\n * request/listen → 执行 registerHandler/registerStreamHandler → 自动按 request_id 回传\n * 插件开发者不感知 port 与 request_id:handler(args, ctx) 即可。\n */\n\nimport type {\n PluginMessage,\n RpcResponseMessage,\n HostApiCallMessage,\n HostApiResponseMessage,\n PushMessage,\n DirectRequestMessage,\n DirectListenMessage,\n DirectPortMessage,\n SnapshotRequestMessage,\n SnapshotResponseMessage,\n SnapshotRestoreMessage,\n} from './protocol'\n\n/** Electron utilityProcess 的 parentPort(Node 全局 Process 类型无此成员,此处扩展) */\ninterface UtilityParentPort {\n postMessage(message: unknown, transfer?: unknown[]): void\n on(event: 'message', listener: (message: unknown) => void): void\n}\n\ndeclare global {\n namespace NodeJS {\n interface Process {\n parentPort?: UtilityParentPort\n }\n }\n}\n\n/**\n * 通道(控制面 / 直连):兼容 Electron MessagePortMain 与 utilityProcess parentPort。\n * 共享池模式下控制/直连通道由池运行时注入(见 pool-worker.ts),独立进程模式用 process.parentPort。\n */\ninterface RpcChannel {\n postMessage(message: unknown, transfer?: unknown[]): void\n on(event: 'message', listener: (event: { data: unknown; ports?: unknown[] }) => void): void\n start?(): void\n}\n\n/** 池上下文:pool-worker 加载插件前设置,createWorkerRpc 同步读取 */\ninterface PoolContext {\n pluginId?: string\n controlPort?: RpcChannel\n directPort?: RpcChannel\n}\n\n/** 池运行时读写全局键(与 pool-worker.ts 一致) */\nconst POOL_CTX_KEY = '__dlientPoolCtx'\nconst RPC_TABLE_KEY = '__dlientRpcTable'\n\ntype WorkerRpcHandler = (args: unknown[], ctx?: HandlerContext) => unknown | Promise<unknown>\n\n/** handler 执行上下文(directPort 直连调用时填充) */\nexport interface HandlerContext {\n from_plugin_id: string\n request_id: string\n /** 请求携带的大块数据(transfer 零拷贝) */\n data?: ArrayBuffer\n /** 流式发射(仅 registerStreamHandler / listen 模式可用) */\n emit?: (chunk?: unknown, opts?: { data?: ArrayBuffer }) => void\n /** 取消信号(UI 发 cancel 时 abort) */\n signal: AbortSignal\n}\n\n/** rpc.api:按模块分层的宿主能力调用入口(Proxy 动态生成,无需预先枚举) */\nexport type HostApi = Record<string, Record<string, (...args: unknown[]) => Promise<unknown>>>\n\nexport interface WorkerRpc {\n registerHandler: (method: string, handler: WorkerRpcHandler) => void\n /** 流式 handler:ctx.emit(chunk) 多次,return 后自动发 stream-done */\n registerStreamHandler: (method: string, handler: WorkerRpcHandler) => void\n /** 跨插件调用:经主进程 plugin.invoke(expose + dependencies 校验) */\n callPlugin: (pluginId: string, method: string, args?: unknown[]) => Promise<unknown>\n /** 宿主能力调用(字符串方法名方式) */\n callHostApi: (method: string, args?: unknown[]) => Promise<unknown>\n /**\n * 宿主能力分层调用:rpc.api.{module}.{method}(...args),\n * 等价 rpc.callHostApi('{module}.{method}', args)。\n * 参数格式与 Electron 官方 API 一致(模块与接口见 docs/v3/worker_api.md)。\n */\n api: HostApi\n /** 推送事件给绑定本插件的渲染层 view(经主进程转发) */\n push: (event: string, data?: unknown) => void\n /** 业务状态快照:热重载/重启前主进程请求(1s 窗口),插件实现返回可序列化状态 */\n registerSnapshotHandler: (handler: () => unknown | Promise<unknown>) => void\n /** 业务状态恢复:重启后主进程回灌快照,插件据此恢复状态 */\n registerRestoreHandler: (handler: (snapshot: unknown) => void | Promise<void>) => void\n getPluginId: () => string\n getGeneration: () => number\n log: (level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: unknown) => void\n}\n\nexport function createWorkerRpc(\n pluginId: string,\n generation: number,\n options?: { controlPort?: RpcChannel; directPort?: RpcChannel },\n): WorkerRpc {\n const handlers = new Map<string, WorkerRpcHandler>()\n const streamHandlers = new Set<string>()\n let messageId = 0\n const pending = new Map<string, { resolve: (value: unknown) => void; reject: (err: Error) => void }>()\n /** directPort(渲染层直连通道);池注入或 port-setup 消息时设置 */\n let directPort: RpcChannel | null = null\n /** 在途流式/请求的 AbortController(cancel 时 abort) */\n const inFlight = new Map<string, AbortController>()\n /** 业务状态快照/恢复 handler(热重载/重启用;未注册则跳过快照) */\n let snapshotHandler: (() => unknown | Promise<unknown>) | undefined\n let restoreHandler: ((snapshot: unknown) => void | Promise<void>) | undefined\n\n // 通道解析:池上下文(pool-worker 注入)优先,其次显式 options,最后 process.parentPort(独立进程)\n const poolCtx = (globalThis as unknown as Record<string, unknown>)[POOL_CTX_KEY] as PoolContext | undefined\n const ctl: RpcChannel | undefined =\n options?.controlPort ??\n poolCtx?.controlPort ??\n (typeof process !== 'undefined' ? (process.parentPort as RpcChannel | undefined) : undefined)\n\n const sendMessage = (msg: PluginMessage) => {\n ctl?.postMessage(msg)\n }\n\n // ---- directPort 直连消息处理(渲染层 preload 发出)----\n\n /**\n * 注意:utilityProcess 下发的 directPort 是 Electron MessagePortMain,\n * 其 postMessage 的 transfer 仅接受 MessagePortMain[](不支持 ArrayBuffer),\n * 且传 undefined 第二参也会抛 \"transferables must be an array of MessagePorts\"。\n * 因此 data 字段一律随消息结构化克隆(深拷贝),不启用 transfer。\n */\n const sendDirect = (msg: DirectPortMessage) => {\n if (!directPort) return\n directPort.postMessage(msg)\n }\n\n const handleDirectMessage = (event: { data: DirectPortMessage }) => {\n const msg = event.data\n switch (msg.type) {\n case 'request':\n runDirectHandler(msg, false)\n break\n case 'listen':\n runDirectHandler(msg, true)\n break\n case 'cancel':\n inFlight.get(msg.request_id)?.abort()\n inFlight.delete(msg.request_id)\n break\n }\n }\n\n /** 设置并监听直连通道(池注入 directPort / port-setup 消息 / reattach-direct 共用) */\n const setupDirectPort = (port: RpcChannel) => {\n directPort = port\n port.on('message', (payload: unknown) => handleDirectMessage(payload as { data: DirectPortMessage }))\n port.start?.()\n sendMessage({ type: 'direct-port-ready', pluginId })\n }\n\n // 池模式直连通道注入(pool-worker 随 load-plugin transfer 的 direct port;同步生效)\n const directInit = options?.directPort ?? poolCtx?.directPort\n if (directInit) setupDirectPort(directInit)\n\n // 注册到池 rpc 表:池运行时重建直连通道(reattach-direct 消息)时按 pluginId 调用\n // (独立进程模式无 pool-worker,表仅被池运行时消费;全局键与 pool-worker.ts 一致)\n const rpcTable = ((globalThis as unknown as Record<string, unknown>)[RPC_TABLE_KEY] ??= {}) as Record<\n string,\n { setDirectPort?: (port: RpcChannel) => void }\n >\n rpcTable[pluginId] = { setDirectPort: setupDirectPort }\n\n /** 执行 directPort 请求并自动按 request_id 回传(并发:每条消息独立 Promise,不互相等待) */\n function runDirectHandler(msg: DirectRequestMessage | DirectListenMessage, isStream: boolean): void {\n const handler = handlers.get(msg.method)\n if (!handler) {\n sendDirect({ type: 'error', request_id: msg.request_id, error: `Method \"${msg.method}\" not found` })\n return\n }\n const ac = new AbortController()\n inFlight.set(msg.request_id, ac)\n\n const emit = (chunk?: unknown, opts?: { data?: ArrayBuffer }) => {\n sendDirect({ type: 'stream', request_id: msg.request_id, chunk, data: opts?.data })\n }\n\n const ctx: HandlerContext = {\n from_plugin_id: msg.from_plugin_id,\n request_id: msg.request_id,\n data: msg.data,\n signal: ac.signal,\n emit: isStream ? emit : undefined,\n }\n\n Promise.resolve()\n .then(() => handler(msg.args, ctx))\n .then((result) => {\n if (ac.signal.aborted) return\n const data = (result as { data?: ArrayBuffer } | null | undefined)?.data\n const value = data !== undefined ? (result as { result?: unknown }).result : result\n sendDirect(\n isStream\n ? { type: 'stream-done', request_id: msg.request_id, result: value }\n : { type: 'response', request_id: msg.request_id, result: value, data },\n )\n })\n .catch((err) => {\n if (ac.signal.aborted) return\n sendDirect({ type: 'error', request_id: msg.request_id, error: err instanceof Error ? err.message : String(err) })\n })\n .finally(() => {\n inFlight.delete(msg.request_id)\n })\n }\n\n if (ctl) {\n // 主进程最近一次有消息的时间(心跳 / rpc-call / host-api-response 等均代表主进程存活)\n let lastSeenAt = Date.now()\n\n ctl.on('message', (event: unknown) => {\n const e = event as { data: PluginMessage; ports?: unknown[] }\n const msg = e.data\n lastSeenAt = Date.now()\n switch (msg.type) {\n case 'init': {\n sendMessage({ type: 'ready', pluginId, generation, capabilities: Array.from(handlers.keys()) })\n break\n }\n case 'port-setup': {\n // 独立进程模式:主进程下发直连 port → 复用 setupDirectPort(池模式经 load-plugin 直接注入)\n const [port] = (e.ports ?? []) as RpcChannel[]\n if (port) setupDirectPort(port)\n break\n }\n case 'rpc-call':\n handleRpcCall(msg as never)\n break\n case 'host-api-response':\n handleHostApiResponse(msg as HostApiResponseMessage)\n break\n case 'snapshot-request': {\n // 主进程重启前请求快照:1s 窗口内回 snapshot-response;未注册 handler 则静默不回\n const req = msg as SnapshotRequestMessage\n if (snapshotHandler) {\n Promise.resolve()\n .then(() => snapshotHandler!())\n .then((snapshot) => {\n const res: SnapshotResponseMessage = { type: 'snapshot-response', pluginId, request_id: req.request_id, snapshot }\n sendMessage(res)\n })\n .catch((err) => {\n const res: SnapshotResponseMessage = {\n type: 'snapshot-response',\n pluginId,\n request_id: req.request_id,\n error: err instanceof Error ? err.message : String(err),\n }\n sendMessage(res)\n })\n }\n break\n }\n case 'snapshot-restore': {\n // 重启后主进程回灌快照(消息保序:先于后续 rpc-call 到达)\n const res = msg as SnapshotRestoreMessage\n if (restoreHandler) {\n void Promise.resolve()\n .then(() => restoreHandler!(res.snapshot))\n .catch((err) => console.error(`[plugin:${pluginId}] snapshot restore failed:`, err))\n }\n break\n }\n case 'heartbeat':\n // 主进程存活信号:仅刷新 lastSeenAt(已在开头统一处理)\n break\n }\n })\n // 池模式:ctl 是注入的 MessagePortMain,必须显式 start() 才会开始接收消息\n //(独立进程模式为 process.parentPort,无 start 方法,可选链安全跳过)。\n // 缺少 start 时 worker 收不到主进程 heartbeat / host-api-response → watchdog 误报\n // 「Main process lost (no message for 30s)」,所有 host-api 调用与渲染层请求全部超时。\n ctl.start?.()\n\n // worker → 主进程心跳:每 10s 上报一次,主进程据此判定 worker 是否失联\n setInterval(() => {\n sendMessage({ type: 'heartbeat', pluginId, ts: Date.now() })\n }, 10000)\n\n // worker 侧失联 watchdog:主进程心跳每 10s 一条,超过 30s 未收到任何消息\n setInterval(() => {\n if (Date.now() - lastSeenAt > 30000) {\n const error = new Error('Main process lost (no message for 30s)')\n for (const { reject } of pending.values()) reject(error)\n pending.clear()\n }\n }, 5000)\n }\n\n const handleRpcCall = (msg: { id: string; method: string; args: unknown[]; from_plugin_id?: string }) => {\n const handler = handlers.get(msg.method)\n const response: RpcResponseMessage = { type: 'rpc-response', id: msg.id, pluginId }\n if (!handler) {\n response.error = `Method \"${msg.method}\" not found`\n } else {\n // 跨插件调用(主进程 plugin.invoke 转发)携带 from_plugin_id:handler 经 ctx 识别请求方,\n // 用于多租户隔离(如 sqlite 插件按调用方建库);渲染层直连不经过此通道(见 runDirectHandler)。\n const ctx: HandlerContext = {\n from_plugin_id: msg.from_plugin_id ?? '',\n request_id: msg.id,\n signal: new AbortController().signal,\n }\n try {\n const result = handler(msg.args, ctx)\n if (result instanceof Promise) {\n result.then(\n (value) => { response.result = value; sendMessage(response) },\n (err) => { response.error = err.message; sendMessage(response) },\n )\n return\n }\n response.result = result\n } catch (err) {\n response.error = err instanceof Error ? err.message : String(err)\n }\n }\n sendMessage(response)\n }\n\n const handleHostApiResponse = (msg: HostApiResponseMessage) => {\n const pendingItem = pending.get(msg.id)\n if (pendingItem) {\n pending.delete(msg.id)\n if (msg.error) {\n pendingItem.reject(new Error(msg.error))\n } else {\n pendingItem.resolve(msg.result)\n }\n }\n }\n\n // ---- 内建 webview 能力转发(Webview 组件经「承载插件」worker 调用 hostApi)----\n // 任何插件的 worker 都自动带这些 handler:前端 <Webview>(@dlient/ui)用 useDientApi 请求\n // 自己插件的 webview:* → 这里转发到主进程 webview-manager。hostApi 侧按 manifest.permissions\n //(webview.create / webview.navigate)鉴权,未声明权限的插件调用会被主进程拒绝。\n // 插件可用 registerHandler 显式注册同名方法覆盖内建实现(显式优先)。\n handlers.set('webview:create', ([opts]) => callHostApiImpl('webview.create', [opts]))\n handlers.set('webview:update', ([opts]) => callHostApiImpl('webview.update', [opts]))\n handlers.set('webview:destroy', ([viewId]) => callHostApiImpl('webview.destroy', [String(viewId ?? '')]))\n handlers.set('webview:webContents:call', ([opts]) => callHostApiImpl('webview.webContentsCall', [opts]))\n // 主进程 webview-manager 按 owner 插件转发 webContents 白名单事件 → 推送承载插件前端组件\n handlers.set('onWebContentsEvent', ([payload]) => {\n const { viewId, name, args } = (payload ?? {}) as { viewId?: string; name?: string; args?: unknown[] }\n if (!viewId || !name) return\n const msg: PushMessage = { type: 'push', pluginId, event: 'webview:event', data: { viewId, name, args } }\n sendMessage(msg)\n })\n\n return {\n getPluginId: () => pluginId,\n getGeneration: () => generation,\n\n registerHandler: (method: string, handler: WorkerRpcHandler) => {\n handlers.set(method, handler)\n streamHandlers.delete(method)\n },\n\n registerSnapshotHandler: (handler: () => unknown | Promise<unknown>) => {\n snapshotHandler = handler\n },\n\n registerRestoreHandler: (handler: (snapshot: unknown) => void | Promise<void>) => {\n restoreHandler = handler\n },\n\n registerStreamHandler: (method: string, handler: WorkerRpcHandler) => {\n handlers.set(method, handler)\n streamHandlers.add(method)\n },\n\n callHostApi: (method: string, args: unknown[] = []) => callHostApiImpl(method, args),\n\n /** rpc.api.{module}.{method}(...args) → callHostApi('{module}.{method}', args) */\n api: createApiProxy(),\n\n callPlugin: (targetPluginId: string, method: string, args: unknown[] = []) =>\n callHostApiImpl('plugin.invoke', [targetPluginId, method, args]),\n\n push: (event: string, data?: unknown) => {\n const msg: PushMessage = { type: 'push', pluginId, event, data }\n sendMessage(msg)\n },\n\n log: (level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: unknown) => {\n sendMessage({ type: 'log', pluginId, level, message, data })\n },\n }\n\n function callHostApiImpl(method: string, args: unknown[]): Promise<unknown> {\n const id = `host-api-${pluginId}-${generation}-${++messageId}`\n const msg: HostApiCallMessage = { type: 'host-api-call', id, method, args, pluginId }\n return new Promise<unknown>((resolve, reject) => {\n pending.set(id, { resolve, reject })\n sendMessage(msg)\n })\n }\n\n /**\n * 分层 api 代理:访问 rpc.api.{module}.{method} 时动态生成调用函数。\n * 模块与方法名直接拼成 host-api 方法 id(\"{module}.{method}\"),与主进程方法表一致;\n * 参数原样透传,格式与 Electron 官方 API 一致。\n */\n function createApiProxy(): HostApi {\n const moduleProxies = new Map<string, Record<string, (...args: unknown[]) => Promise<unknown>>>()\n return new Proxy({} as HostApi, {\n get: (_target, module) => {\n const mod = String(module)\n let modProxy = moduleProxies.get(mod)\n if (!modProxy) {\n modProxy = new Proxy({} as Record<string, (...args: unknown[]) => Promise<unknown>>, {\n get: (_t, method) => (...args: unknown[]) => callHostApiImpl(`${mod}.${String(method)}`, args),\n })\n moduleProxies.set(mod, modProxy)\n }\n return modProxy\n },\n })\n }\n}\n"],"names":[],"mappings":"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"}
@@ -21,6 +21,11 @@ export interface RpcCallMessage {
21
21
  method: string;
22
22
  args: unknown[];
23
23
  pluginId: string;
24
+ /**
25
+ * 调用方插件 id(跨插件 invoke 时由主进程填入;渲染层直连不经过此通道)。
26
+ * worker 端 handler 据此识别请求方身份,实现多租户隔离。
27
+ */
28
+ from_plugin_id?: string;
24
29
  }
25
30
  export interface RpcResponseMessage {
26
31
  type: 'rpc-response';
package/dist/types.d.ts CHANGED
@@ -58,6 +58,12 @@ export interface PluginManifest {
58
58
  organization?: string;
59
59
  requires?: string[];
60
60
  platforms?: PluginPlatform[];
61
+ /**
62
+ * 是否包含原生模块(.node 二进制,经 @electron/rebuild 针对 Electron ABI 编译)。
63
+ * true 时必须同时声明 platforms(原生模块为平台二进制,仅允许在声明的平台上下载安装),
64
+ * 且产物中必须实际包含 .node 文件(服务端上传时校验二者一致性)。
65
+ */
66
+ native?: boolean;
61
67
  permissions?: PluginPermission[];
62
68
  /** 对外暴露给其它插件调用的方法(plugin.invoke 校验;access 见 ExposeAccess) */
63
69
  expose?: Record<string, PluginExposeMethod>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dlient/plugin-sdk",
3
- "version": "3.0.6",
3
+ "version": "3.0.7",
4
4
  "private": false,
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",