@napuketto/loader 0.0.11 → 0.0.12

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.
@@ -223,6 +223,14 @@ function createState() {
223
223
  * workspace 依赖——见 types.ts 注释)。错误码提取用宽松结构判断。
224
224
  */
225
225
  /**
226
+ * 注册 login.refreshQr 动作(登录期即可用——不依赖 session 服务,只依赖
227
+ * core.refreshQr)。bootstrap 提前启动 IPC 服务端时先注册本动作,登录完成后
228
+ * 再把 kernel 服务的完整动作并入同一张表。
229
+ */
230
+ function registerLoginRefreshAction(actions, refreshQr) {
231
+ actions.set("login.refreshQr", async () => refreshQr());
232
+ }
233
+ /**
226
234
  * 从宽松 params 构造 Peer(缺省 chatType=1 群聊)。
227
235
  * 优先 peerUid(uid 直通);缺省时 peerUin 经 uinToUid 转换。
228
236
  *
@@ -500,13 +508,14 @@ function sendStatus(phase, message, error) {
500
508
  });
501
509
  }
502
510
  /** 登录状态(QR 状态机 idle/waiting_scan/scanned/logged_in/failed)。 */
503
- function sendLogin(state, selfInfo) {
511
+ function sendLogin(state, selfInfo, message) {
504
512
  sendIpc({
505
513
  v: 1,
506
514
  type: "login",
507
515
  payload: {
508
516
  state,
509
- ...selfInfo !== void 0 ? { selfInfo } : {}
517
+ ...selfInfo !== void 0 ? { selfInfo } : {},
518
+ ...message !== void 0 ? { message } : {}
510
519
  }
511
520
  });
512
521
  }
@@ -557,6 +566,51 @@ function sendPing() {
557
566
  });
558
567
  }
559
568
  //#endregion
569
+ //#region src/host/ipc/ipc-bootstrap.ts
570
+ /** 订阅事件通道 → event 消息转发(事件名 "Service/method" 拆分)。 */
571
+ function forwardChannel(channel, stops) {
572
+ if (typeof channel.onAny !== "function") return;
573
+ const off = channel.onAny((event, ...args) => {
574
+ const slash = event.indexOf("/");
575
+ sendEvent(slash >= 0 ? event.slice(0, slash) : event, slash >= 0 ? event.slice(slash + 1) : "", args);
576
+ });
577
+ if (typeof off === "function") stops.push(off);
578
+ }
579
+ /**
580
+ * 登录期动作表:只含 login.refreshQr(依赖 core.refreshQr,不依赖 session 服务)。
581
+ * bootstrap-core 在登录前用它启动 IPC 服务端——登录中前端即可刷新二维码。
582
+ */
583
+ function createIpcActionsForCore(core) {
584
+ const actions = /* @__PURE__ */ new Map();
585
+ if (typeof core.refreshQr === "function") registerLoginRefreshAction(actions, () => core.refreshQr?.() ?? false);
586
+ return actions;
587
+ }
588
+ /**
589
+ * 把 kernel 服务动作并入共享动作表 + 事件通道转发(登录成功后调用)。
590
+ * 返回停止函数(清理事件转发订阅;stdin 服务端由 bootstrap-core 独立管理)。
591
+ */
592
+ function attachIpcServices(actions, services) {
593
+ const groupApi = services.groupApi;
594
+ const full = createIpcActions({
595
+ msgApi: services.msgApi,
596
+ groupApi: services.groupApi,
597
+ groupCache: services.groupCache,
598
+ friendApi: services.friendApi,
599
+ self: services.self,
600
+ session: services.session,
601
+ engine: services.engine,
602
+ util: services.util,
603
+ ...groupApi.uinToUid !== void 0 ? { uinToUid: groupApi.uinToUid } : {}
604
+ });
605
+ for (const [name, handler] of full) actions.set(name, handler);
606
+ const stops = [];
607
+ forwardChannel(services.channel, stops);
608
+ forwardChannel(services.groupChannel, stops);
609
+ return () => {
610
+ for (const stop of stops) stop();
611
+ };
612
+ }
613
+ //#endregion
560
614
  //#region src/host/ipc/ipc-codec.ts
561
615
  /**
562
616
  * ipc-codec.ts:IPC 消息编解码(JSON 行协议,与 koishi 插件侧 src/ipc/codec.ts 对齐)。
@@ -617,40 +671,6 @@ function handleControl(payload, onExit) {
617
671
  if (payload.command === "stop" || payload.command === "restart") onExit();
618
672
  }
619
673
  //#endregion
620
- //#region src/host/ipc/ipc-bootstrap.ts
621
- /** 订阅事件通道 → event 消息转发(事件名 "Service/method" 拆分)。 */
622
- function forwardChannel(channel, stops) {
623
- if (typeof channel.onAny !== "function") return;
624
- const off = channel.onAny((event, ...args) => {
625
- const slash = event.indexOf("/");
626
- sendEvent(slash >= 0 ? event.slice(0, slash) : event, slash >= 0 ? event.slice(slash + 1) : "", args);
627
- });
628
- if (typeof off === "function") stops.push(off);
629
- }
630
- /** IPC 模式装配(enableIpc + 动作表 + 服务端 + 事件转发)。返回停止函数。 */
631
- function startIpcMode(services) {
632
- enableIpc();
633
- const groupApi = services.groupApi;
634
- const stopServer = startIpcServer({ actions: createIpcActions({
635
- msgApi: services.msgApi,
636
- groupApi: services.groupApi,
637
- groupCache: services.groupCache,
638
- friendApi: services.friendApi,
639
- self: services.self,
640
- session: services.session,
641
- engine: services.engine,
642
- util: services.util,
643
- ...groupApi.uinToUid !== void 0 ? { uinToUid: groupApi.uinToUid } : {}
644
- }) });
645
- const stops = [];
646
- forwardChannel(services.channel, stops);
647
- forwardChannel(services.groupChannel, stops);
648
- return () => {
649
- stopServer();
650
- for (const stop of stops) stop();
651
- };
652
- }
653
- //#endregion
654
674
  //#region src/host/core/login.ts
655
675
  /** 打印可用快速登录账号 + 返回目标账号(启动横幅)。forcedUin(cli `-q` / NAPUTO_QUICK_UIN)优先。 */
656
676
  async function pickLoginAccount(kernel, ctx, loginResultRef, forcedUin) {
@@ -1274,7 +1294,7 @@ function buildLoginOpts(Appid, forcedUin, ref) {
1274
1294
  qrcodeUrl: progress.qr.qrcodeUrl
1275
1295
  })}\n`);
1276
1296
  }
1277
- if (ipcMode && isLoginState(progress.state)) sendLogin(progress.state, progress.selfInfo);
1297
+ if (ipcMode && isLoginState(progress.state)) sendLogin(progress.state, progress.selfInfo, progress.message);
1278
1298
  };
1279
1299
  return opts;
1280
1300
  }
@@ -1363,6 +1383,11 @@ async function bootstrapWithCore(kernel, state, bootEnv, Appid) {
1363
1383
  paths: { dataRoot: bootEnv.dataDir },
1364
1384
  logLevel: "info"
1365
1385
  });
1386
+ let ipcActions = null;
1387
+ if (env.NAPUTO_IPC === "1") {
1388
+ ipcActions = createIpcActionsForCore(core);
1389
+ startIpcServer({ actions: ipcActions });
1390
+ }
1366
1391
  const ctx = core.attachWrapper(state.wrapperExports, { ...bootEnv });
1367
1392
  log(`bootstrap: attachWrapper OK, engine=${typeof ctx.engine}, session=${ctx.session !== null}`);
1368
1393
  probeCreatedSession(state, ctx);
@@ -1396,7 +1421,7 @@ async function bootstrapWithCore(kernel, state, bootEnv, Appid) {
1396
1421
  if (env.NAPUTO_IPC === "1") sendStatus("sessioning");
1397
1422
  await runSmokeIfEnabled(kernel, ctx, loginResult);
1398
1423
  const services = await startProtocols(kernel, ctx, loginResult);
1399
- if (env.NAPUTO_IPC === "1" && services !== null) startIpcMode(services);
1424
+ if (env.NAPUTO_IPC === "1" && services !== null && ipcActions !== null) attachIpcServices(ipcActions, services);
1400
1425
  runProbePhase(kernel, ctx);
1401
1426
  }
1402
1427
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napuketto/loader",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "NapukettoQQ 引导组件:自建宿主(标准 Node + stub QQNT.dll)dlopen wrapper.node 并启动 kernel,不拉起 QQ / 不注入",
5
5
  "type": "module",
6
6
  "files": [