@napuketto/loader 0.0.23 → 0.0.24

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.
@@ -851,6 +851,118 @@ function decodeIpcMessage(line) {
851
851
  }
852
852
  }
853
853
  //#endregion
854
+ //#region src/host/ipc/ipc-ob11.ts
855
+ /**
856
+ * ipc-ob11.ts:OB11 动作容器 IPC 桥(NAPUTO_IPC=1 可选装配,2026-08-27)。
857
+ *
858
+ * 触发条件:IPC 模式 && NAPUTO_ADAPTER_ENTRY + NAPUTO_NETWORK_ENTRY 已注入
859
+ * (koishi 插件 launcher 透传;未注入 = app 层不要 OB11 面,静默跳过)。
860
+ *
861
+ * 装配:动态 import adapter onebot11/core 子路径 + network 入口(assemble-
862
+ * protocols.ts 同款——loader 编译期零 adapter/network 静态依赖),实例化
863
+ * NapukettoOneBot11Adapter 后仅 subscribeOnly()(接收链路,零网络传输),
864
+ * 全部动作名平铺合并进共享 IPC 动作表(OB11 snake_case 与 kernel 点分
865
+ * 命名空间不冲突),OB11 事件经 broadcaster 桥适配器 → sendEvent("ob11")。
866
+ *
867
+ * fail-soft:import/构造失败只 log 降级为纯 kernel 动作面,不阻断登录链路。
868
+ */
869
+ /** Windows 反斜杠(file:// URL 化时替换)。 */
870
+ const BACKSLASH_RE$1 = /\\/g;
871
+ /** adapter 入口 index.mjs 后缀(子路径导出替换用)。 */
872
+ const INDEX_MJS_RE$1 = /index\.mjs$/;
873
+ /** 动态 import(file:// URL;全动态表达式,打包器不静态解析)。 */
874
+ async function importFileUrl(url) {
875
+ return import(url);
876
+ }
877
+ /**
878
+ * OB11 动作桥装配(bootstrap 登录成功、attachIpcServices 之后调用)。
879
+ * 返回停止函数(broadcaster 注销 + adapter 退订;进程级清理用)。
880
+ */
881
+ async function attachOb11IpcBridge(actions, services, deps = {}) {
882
+ const e = deps.env ?? {
883
+ adapterEntry: env.NAPUTO_ADAPTER_ENTRY,
884
+ networkEntry: env.NAPUTO_NETWORK_ENTRY,
885
+ qqVersion: env.NAPUTO_QQ_VERSION,
886
+ dataRoot: env.NAPKETTO_DATA,
887
+ cfgDir: env.NAPUTO_CFG_DIR
888
+ };
889
+ const noop = () => {};
890
+ if (e.adapterEntry === void 0 || e.adapterEntry === "") return noop;
891
+ if (e.networkEntry === void 0 || e.networkEntry === "") return noop;
892
+ const importModule = deps.importModule ?? importFileUrl;
893
+ const emit = deps.emitEvent ?? sendEvent;
894
+ try {
895
+ const toUrl = (p) => `file://${p.replace(BACKSLASH_RE$1, "/")}`;
896
+ const network = await importModule(toUrl(e.networkEntry));
897
+ const onebot11Entry = e.adapterEntry.replace(INDEX_MJS_RE$1, "onebot11/index.mjs");
898
+ const coreEntry = e.adapterEntry.replace(INDEX_MJS_RE$1, "core/index.mjs");
899
+ const adapter = await importModule(toUrl(onebot11Entry));
900
+ const adapterCore = await importModule(toUrl(coreEntry));
901
+ const broadcaster = new network.EventBroadcaster();
902
+ const protocolConfig = new adapterCore.ProtocolConfig({
903
+ path: (0, node_path.join)(e.cfgDir ?? ".", "ob11-ipc.toml"),
904
+ schema: adapter.ob11ConfigSchema,
905
+ defaults: adapter.ob11ConfigSchema.parse({}),
906
+ seed: adapter.ob11ConfigSchema.parse({})
907
+ });
908
+ const ob11 = new adapter.NapukettoOneBot11Adapter({
909
+ config: protocolConfig,
910
+ broadcaster,
911
+ msgChannel: services.channel,
912
+ msgApi: services.msgApi,
913
+ groupApi: services.groupApi,
914
+ groupNotifyApi: services.groupNotifyApi,
915
+ friendApi: services.friendApi,
916
+ ticketApi: services.ticketApi,
917
+ richMediaApi: services.richMediaApi,
918
+ profileApi: services.profileApi,
919
+ profileLikeApi: services.profileLikeApi,
920
+ webApi: services.webApi,
921
+ self: services.self,
922
+ system: {
923
+ appVersion: e.qqVersion || "unknown",
924
+ cleanCache: async () => {
925
+ new services.kernel.PathWrapper({
926
+ dataRoot: e.dataRoot,
927
+ account: services.self.uin
928
+ }).clearCache();
929
+ },
930
+ cacheDir: (0, node_path.join)(e.cfgDir ?? ".", "cache"),
931
+ exit: async () => {
932
+ log("ipc-ob11: bot_exit 触发,退出子进程");
933
+ node_process.default.exit(0);
934
+ },
935
+ restart: async () => {
936
+ log("ipc-ob11: set_restart 触发,退出子进程(driver 重启)");
937
+ node_process.default.exit(0);
938
+ }
939
+ },
940
+ groupCache: services.groupCache
941
+ });
942
+ await ob11.subscribeOnly();
943
+ let mounted = 0;
944
+ for (const name of ob11.registry.names) {
945
+ const act = ob11.registry.get(name);
946
+ if (act === void 0) continue;
947
+ actions.set(name, (params) => act.handle(params));
948
+ mounted++;
949
+ }
950
+ const bridgeAdapter = { send: (event) => {
951
+ const postType = event.post_type;
952
+ emit("ob11", typeof postType === "string" ? postType : "unknown", [event]);
953
+ } };
954
+ broadcaster.register(bridgeAdapter);
955
+ log(`ipc-ob11: OB11 动作桥已挂载(${mounted} 动作,事件经 ob11 通道透出)`);
956
+ return () => {
957
+ broadcaster.unregister(bridgeAdapter);
958
+ ob11.unsubscribeOnly();
959
+ };
960
+ } catch (err) {
961
+ log(`ipc-ob11: OB11 动作桥装配失败(降级纯 kernel 动作面): ${errMsg(err)}`);
962
+ return noop;
963
+ }
964
+ }
965
+ //#endregion
854
966
  //#region src/host/ipc/ipc-server.ts
855
967
  /**
856
968
  * ipc-server.ts:IPC 服务端(self-host 子进程侧)。
@@ -1690,7 +1802,10 @@ async function bootstrapWithCore(kernel, state, bootEnv, Appid) {
1690
1802
  if (env.NAPUTO_IPC === "1") sendStatus("sessioning");
1691
1803
  await runSmokeIfEnabled(kernel, ctx, loginResult);
1692
1804
  const services = await startProtocols(kernel, ctx, loginResult);
1693
- if (env.NAPUTO_IPC === "1" && services !== null && ipcActions !== null) attachIpcServices(ipcActions, services);
1805
+ if (env.NAPUTO_IPC === "1" && services !== null && ipcActions !== null) {
1806
+ attachIpcServices(ipcActions, services);
1807
+ await attachOb11IpcBridge(ipcActions, services);
1808
+ }
1694
1809
  runProbePhase(kernel, ctx);
1695
1810
  }
1696
1811
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napuketto/loader",
3
- "version": "0.0.23",
3
+ "version": "0.0.24",
4
4
  "description": "NapukettoQQ 引导组件:自建宿主(标准 Node + stub QQNT.dll)dlopen wrapper.node 并启动 kernel,不拉起 QQ / 不注入",
5
5
  "type": "module",
6
6
  "files": [