@napuketto/loader 0.0.6 → 0.0.8
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/host/self-host.cjs +213 -62
- package/package.json +4 -2
package/dist/host/self-host.cjs
CHANGED
|
@@ -287,8 +287,135 @@ function createIpcActions(ctx) {
|
|
|
287
287
|
return ctx.groupCache.listGroupsRefreshed();
|
|
288
288
|
});
|
|
289
289
|
actions.set("friend.getFriendList", async () => ctx.friendApi.getFriendList());
|
|
290
|
+
actions.set("diag.richMediaTmpPaths", async () => runRichMediaDiag(ctx.session));
|
|
291
|
+
actions.set("diag.flashCall", async (params) => {
|
|
292
|
+
const sess = ctx.session;
|
|
293
|
+
if (sess === void 0) return { error: "session 未注入" };
|
|
294
|
+
const flash = typeof sess.getFlashTransferService === "function" ? sess.getFlashTransferService() : null;
|
|
295
|
+
if (flash === null || flash === void 0) return { error: "flash 服务为 null" };
|
|
296
|
+
return callDiagnosticMethod(flash, params);
|
|
297
|
+
});
|
|
298
|
+
actions.set("diag.sessionCall", async (params) => {
|
|
299
|
+
if (ctx.session === void 0) return { error: "session 未注入" };
|
|
300
|
+
return callDiagnosticMethod(ctx.session, params);
|
|
301
|
+
});
|
|
302
|
+
actions.set("diag.engineCall", async (params) => {
|
|
303
|
+
if (ctx.engine === void 0) return { error: "engine 未注入" };
|
|
304
|
+
return callDiagnosticMethod(ctx.engine, params);
|
|
305
|
+
});
|
|
306
|
+
actions.set("diag.richMediaCall", async (params) => {
|
|
307
|
+
const sess = ctx.session;
|
|
308
|
+
if (sess === void 0) return { error: "session 未注入" };
|
|
309
|
+
const svc = typeof sess.getRichMediaService === "function" ? sess.getRichMediaService() : null;
|
|
310
|
+
if (svc === null || svc === void 0) return { error: "richMedia 服务为 null" };
|
|
311
|
+
return callDiagnosticMethod(svc, params);
|
|
312
|
+
});
|
|
313
|
+
actions.set("diag.msgServiceCall", async (params) => {
|
|
314
|
+
const sess = ctx.session;
|
|
315
|
+
if (sess === void 0) return { error: "session 未注入" };
|
|
316
|
+
const svc = typeof sess.getMsgService === "function" ? sess.getMsgService() : null;
|
|
317
|
+
if (svc === null || svc === void 0) return { error: "msgService 为 null" };
|
|
318
|
+
return callDiagnosticMethod(svc, params);
|
|
319
|
+
});
|
|
320
|
+
actions.set("diag.utilCall", async (params) => {
|
|
321
|
+
const util = ctx.util;
|
|
322
|
+
if (util === void 0) return { error: "util 未注入" };
|
|
323
|
+
const instance = typeof util.get === "function" ? util.get() : util;
|
|
324
|
+
if (instance === null || instance === void 0) return { error: "util 实例为 null" };
|
|
325
|
+
return callDiagnosticMethod(instance, params);
|
|
326
|
+
});
|
|
290
327
|
return actions;
|
|
291
328
|
}
|
|
329
|
+
/** 诊断:按方法名 + 参数数组调用对象任意方法(返回结构化结果,不抛)。
|
|
330
|
+
* ⚠️ NAPI 对象方法挂在实例自身(非原型),__methods 须枚举实例 ownKeys。 */
|
|
331
|
+
async function callDiagnosticMethod(obj, params) {
|
|
332
|
+
const method = typeof params["method"] === "string" ? params["method"] : "";
|
|
333
|
+
const args = Array.isArray(params["args"]) ? params["args"] : [];
|
|
334
|
+
const target = obj;
|
|
335
|
+
if (method === "__methods") {
|
|
336
|
+
const own = Object.getOwnPropertyNames(obj);
|
|
337
|
+
const proto = Object.getOwnPropertyNames(Object.getPrototypeOf(obj) ?? {});
|
|
338
|
+
return { methods: [.../* @__PURE__ */ new Set([...own, ...proto])] };
|
|
339
|
+
}
|
|
340
|
+
const fn = target[method];
|
|
341
|
+
if (typeof fn !== "function") return { error: `方法不存在: ${method}` };
|
|
342
|
+
try {
|
|
343
|
+
return {
|
|
344
|
+
ok: true,
|
|
345
|
+
ret: await fn.apply(obj, args)
|
|
346
|
+
};
|
|
347
|
+
} catch (e) {
|
|
348
|
+
return {
|
|
349
|
+
ok: false,
|
|
350
|
+
err: e instanceof Error ? e.message : String(e)
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/** 诊断:枚举富媒体临时路径(getPicTmpPath 等 0 参方法)。 */
|
|
355
|
+
async function enumerateTmpPaths(svc) {
|
|
356
|
+
const tmp = {};
|
|
357
|
+
for (const name of [
|
|
358
|
+
"getPicTmpPath",
|
|
359
|
+
"getRichMeidaTmpPath",
|
|
360
|
+
"getPttTmpPath",
|
|
361
|
+
"getVideoTmpPath",
|
|
362
|
+
"getFileTmpPath",
|
|
363
|
+
"getTransferingTmpPath"
|
|
364
|
+
]) {
|
|
365
|
+
const fn = svc[name];
|
|
366
|
+
if (typeof fn === "function") try {
|
|
367
|
+
tmp[name] = await fn.call(svc);
|
|
368
|
+
} catch (e) {
|
|
369
|
+
tmp[name] = `调用失败: ${e instanceof Error ? e.message : String(e)}`;
|
|
370
|
+
}
|
|
371
|
+
else tmp[name] = "方法缺失";
|
|
372
|
+
}
|
|
373
|
+
return tmp;
|
|
374
|
+
}
|
|
375
|
+
/** 诊断:闪传服务候选 side-effect 触发(§5.3 候选动作 1,参数宽松猜测)。 */
|
|
376
|
+
async function probeFlashSideEffects(flash) {
|
|
377
|
+
const flashObj = flash;
|
|
378
|
+
const sideEffects = {};
|
|
379
|
+
const candidates = [
|
|
380
|
+
["addFileSetSimpleStatusListener", [() => void 0]],
|
|
381
|
+
["setFlashTransferDir", [""]],
|
|
382
|
+
["setFileSetDownloadDir", [""]],
|
|
383
|
+
["getFileSetIdByCode", [""]]
|
|
384
|
+
];
|
|
385
|
+
for (const [name, args] of candidates) {
|
|
386
|
+
const fn = flashObj[name];
|
|
387
|
+
if (typeof fn === "function") try {
|
|
388
|
+
sideEffects[name] = {
|
|
389
|
+
ok: true,
|
|
390
|
+
ret: await fn.apply(flash, args)
|
|
391
|
+
};
|
|
392
|
+
} catch (e) {
|
|
393
|
+
sideEffects[name] = {
|
|
394
|
+
ok: false,
|
|
395
|
+
err: e instanceof Error ? e.message : String(e)
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
else sideEffects[name] = { missing: true };
|
|
399
|
+
}
|
|
400
|
+
return sideEffects;
|
|
401
|
+
}
|
|
402
|
+
/** 诊断主流程:session → 富媒体服务 + 闪传服务的方法面与触发结果。 */
|
|
403
|
+
async function runRichMediaDiag(session) {
|
|
404
|
+
const sess = session;
|
|
405
|
+
if (sess === void 0) return { error: "session 未注入(IPC 上下文缺 session)" };
|
|
406
|
+
const out = {};
|
|
407
|
+
const svc = typeof sess.getRichMediaService === "function" ? sess.getRichMediaService() : null;
|
|
408
|
+
if (svc !== null && svc !== void 0) {
|
|
409
|
+
out["richMediaTmpPaths"] = await enumerateTmpPaths(svc);
|
|
410
|
+
out["richMediaMethods"] = Object.getOwnPropertyNames(Object.getPrototypeOf(svc));
|
|
411
|
+
} else out["richMediaService"] = "null";
|
|
412
|
+
const flash = typeof sess.getFlashTransferService === "function" ? sess.getFlashTransferService() : null;
|
|
413
|
+
if (flash !== null && flash !== void 0) {
|
|
414
|
+
out["flashMethods"] = Object.getOwnPropertyNames(Object.getPrototypeOf(flash));
|
|
415
|
+
out["flashSideEffects"] = await probeFlashSideEffects(flash);
|
|
416
|
+
} else out["flashService"] = "null";
|
|
417
|
+
return out;
|
|
418
|
+
}
|
|
292
419
|
/** 统一动作调用:查找动作表 → 执行 → 返回结果或错误(不抛,调用方转 result)。 */
|
|
293
420
|
async function callIpcAction(actions, action, params) {
|
|
294
421
|
const handler = actions.get(action);
|
|
@@ -510,6 +637,9 @@ function startIpcMode(services) {
|
|
|
510
637
|
groupCache: services.groupCache,
|
|
511
638
|
friendApi: services.friendApi,
|
|
512
639
|
self: services.self,
|
|
640
|
+
session: services.session,
|
|
641
|
+
engine: services.engine,
|
|
642
|
+
util: services.util,
|
|
513
643
|
...groupApi.uinToUid !== void 0 ? { uinToUid: groupApi.uinToUid } : {}
|
|
514
644
|
}) });
|
|
515
645
|
const stops = [];
|
|
@@ -612,6 +742,10 @@ function loadProtocolSections(kernel, uin) {
|
|
|
612
742
|
* assemble-protocols.ts:OB11 / Satori 协议装配(非 IPC 模式,cli pnpm start)。
|
|
613
743
|
* 2026-08-08:从 protocols.ts 拆分——protocols.ts 只留入口 + IPC 分支。
|
|
614
744
|
*/
|
|
745
|
+
/** Windows 反斜杠(file:// URL 化时替换)。 */
|
|
746
|
+
const BACKSLASH_RE = /\\/g;
|
|
747
|
+
/** adapter 入口 index.mjs 后缀(子路径导出替换用)。 */
|
|
748
|
+
const INDEX_MJS_RE = /index\.mjs$/;
|
|
615
749
|
/** 装配 OB11 + Satori 适配器(登录成功后,非 IPC 模式)。 */
|
|
616
750
|
async function assembleOb11AndSatori(kernel, services, loginResult) {
|
|
617
751
|
const adapterEntry = env.NAPUTO_ADAPTER_ENTRY;
|
|
@@ -621,13 +755,13 @@ async function assembleOb11AndSatori(kernel, services, loginResult) {
|
|
|
621
755
|
return;
|
|
622
756
|
}
|
|
623
757
|
try {
|
|
624
|
-
const network = await import(`file://${networkEntry.replace(
|
|
625
|
-
const onebot11Entry = adapterEntry.replace(
|
|
626
|
-
const satoriEntry = adapterEntry.replace(
|
|
627
|
-
const coreEntry = adapterEntry.replace(
|
|
628
|
-
const adapter = await import(`file://${onebot11Entry.replace(
|
|
629
|
-
const satoriAdapter = await import(`file://${satoriEntry.replace(
|
|
630
|
-
const adapterCore = await import(`file://${coreEntry.replace(
|
|
758
|
+
const network = await import(`file://${networkEntry.replace(BACKSLASH_RE, "/")}`);
|
|
759
|
+
const onebot11Entry = adapterEntry.replace(INDEX_MJS_RE, "onebot11/index.mjs");
|
|
760
|
+
const satoriEntry = adapterEntry.replace(INDEX_MJS_RE, "satori/index.mjs");
|
|
761
|
+
const coreEntry = adapterEntry.replace(INDEX_MJS_RE, "core/index.mjs");
|
|
762
|
+
const adapter = await import(`file://${onebot11Entry.replace(BACKSLASH_RE, "/")}`);
|
|
763
|
+
const satoriAdapter = await import(`file://${satoriEntry.replace(BACKSLASH_RE, "/")}`);
|
|
764
|
+
const adapterCore = await import(`file://${coreEntry.replace(BACKSLASH_RE, "/")}`);
|
|
631
765
|
const { channel, groupCache } = services;
|
|
632
766
|
const broadcaster = new network.EventBroadcaster();
|
|
633
767
|
const { cfgFile, ob11Section, satoriSection } = loadProtocolSections(kernel, loginResult.uin);
|
|
@@ -772,7 +906,8 @@ async function createKernelServices(kernel, ctx, loginResult) {
|
|
|
772
906
|
new kernel.MsgBridge(session, channel).register();
|
|
773
907
|
setupMsgLogging(kernel, channel, logger);
|
|
774
908
|
const groupApi = new kernel.GroupApi(session);
|
|
775
|
-
const
|
|
909
|
+
const util = ctx.exports?.NodeQQNTWrapperUtil;
|
|
910
|
+
const msgApi = new kernel.MsgApi(session, channel, util);
|
|
776
911
|
const friendApi = new kernel.FriendApi(session, { uidToUin: (uids) => groupApi.uidToUin(uids) });
|
|
777
912
|
const groupChannel = new kernel.NTEventChannel("Group");
|
|
778
913
|
new kernel.GroupBridge(session, groupChannel).register();
|
|
@@ -802,7 +937,10 @@ async function createKernelServices(kernel, ctx, loginResult) {
|
|
|
802
937
|
self: {
|
|
803
938
|
uin: loginResult.uin,
|
|
804
939
|
nickname: loginResult.nick ?? ""
|
|
805
|
-
}
|
|
940
|
+
},
|
|
941
|
+
session,
|
|
942
|
+
engine: ctx.engine,
|
|
943
|
+
util: ctx.exports?.NodeQQNTWrapperUtil
|
|
806
944
|
};
|
|
807
945
|
}
|
|
808
946
|
//#endregion
|
|
@@ -855,32 +993,32 @@ function isSessionUsable(s) {
|
|
|
855
993
|
return false;
|
|
856
994
|
}
|
|
857
995
|
}
|
|
996
|
+
/** 描述单个 session 对象(探测日志用;无效对象返回带断言信息的占位)。 */
|
|
997
|
+
function describeSession(s) {
|
|
998
|
+
if (!s) return "null";
|
|
999
|
+
try {
|
|
1000
|
+
const sess = s;
|
|
1001
|
+
const id = typeof sess.getSessionId === "function" ? String(sess.getSessionId()) : "?";
|
|
1002
|
+
const svc = typeof sess.getMsgService === "function" ? sess.getMsgService() : null;
|
|
1003
|
+
return `id=${id} msgSvc=${svc !== null && svc !== void 0 ? "READY" : "null"}`;
|
|
1004
|
+
} catch (e) {
|
|
1005
|
+
return `id=? msgSvc=断言(${errMsg(e).slice(0, 60)})`;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
/** 非空候选才追加探测描述。 */
|
|
1009
|
+
function pushProbe(out, label, candidate) {
|
|
1010
|
+
if (candidate) out.push(`${label}[${describeSession(candidate)}]`);
|
|
1011
|
+
}
|
|
858
1012
|
/** session 就绪探测(5s 间隔,60s 上限)——观察 qqSession / get() 状态。 */
|
|
859
1013
|
function startSessionProbe(state, _ctx, durationMs = 6e4) {
|
|
860
1014
|
const sessionProbe = setInterval(() => {
|
|
861
1015
|
try {
|
|
862
1016
|
const S2 = state.wrapperExports?.["NodeIQQNTWrapperSession"];
|
|
863
1017
|
const out = [];
|
|
864
|
-
const
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const id = typeof sess.getSessionId === "function" ? String(sess.getSessionId()) : "?";
|
|
869
|
-
const svc = typeof sess.getMsgService === "function" ? sess.getMsgService() : null;
|
|
870
|
-
return `id=${id} msgSvc=${svc !== null && svc !== void 0 ? "READY" : "null"}`;
|
|
871
|
-
} catch (e) {
|
|
872
|
-
return `id=? msgSvc=断言(${errMsg(e).slice(0, 60)})`;
|
|
873
|
-
}
|
|
874
|
-
};
|
|
875
|
-
if (state.qqSession && typeof state.qqSession.getMsgService === "function") out.push(`qqSession[${describe(state.qqSession)}]`);
|
|
876
|
-
if (S2 && typeof S2.get === "function") {
|
|
877
|
-
const got = S2.get();
|
|
878
|
-
out.push(`get()[${describe(got)}]`);
|
|
879
|
-
}
|
|
880
|
-
if (S2 && typeof S2.getNTWrapperSession === "function") {
|
|
881
|
-
const gotNT = S2.getNTWrapperSession("Session");
|
|
882
|
-
if (gotNT) out.push(`getNT("Session")[${describe(gotNT)}]`);
|
|
883
|
-
}
|
|
1018
|
+
const qqSession = state.qqSession;
|
|
1019
|
+
if (qqSession && typeof qqSession.getMsgService === "function") pushProbe(out, "qqSession", qqSession);
|
|
1020
|
+
if (S2 && typeof S2.get === "function") pushProbe(out, "get()", S2.get());
|
|
1021
|
+
if (S2 && typeof S2.getNTWrapperSession === "function") pushProbe(out, "getNT(\"Session\")", S2.getNTWrapperSession("Session"));
|
|
884
1022
|
log(`BOOT: session 探测: ${out.join(" | ")}`);
|
|
885
1023
|
} catch (e) {
|
|
886
1024
|
log(`BOOT: session 探测失败: ${errMsg(e)}`);
|
|
@@ -1129,11 +1267,13 @@ function buildLoginOpts(Appid, forcedUin, ref) {
|
|
|
1129
1267
|
};
|
|
1130
1268
|
const ipcMode = env.NAPUTO_IPC === "1";
|
|
1131
1269
|
opts["onLoginProgress"] = (progress) => {
|
|
1132
|
-
if (progress.qr !== void 0)
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1270
|
+
if (progress.qr !== void 0) {
|
|
1271
|
+
if (ipcMode) sendQr(progress.qr.pngBase64, progress.qr.qrcodeUrl);
|
|
1272
|
+
else node_process.default.stdout.write(`${QR_LINE_PREFIX}${JSON.stringify({
|
|
1273
|
+
pngBase64: progress.qr.pngBase64,
|
|
1274
|
+
qrcodeUrl: progress.qr.qrcodeUrl
|
|
1275
|
+
})}\n`);
|
|
1276
|
+
}
|
|
1137
1277
|
if (ipcMode && isLoginState(progress.state)) sendLogin(progress.state, progress.selfInfo);
|
|
1138
1278
|
};
|
|
1139
1279
|
return opts;
|
|
@@ -1284,6 +1424,43 @@ async function bootstrapWithCore(kernel, state, bootEnv, Appid) {
|
|
|
1284
1424
|
function resolveAppid(kernel, bootEnv) {
|
|
1285
1425
|
return typeof kernel.parseAppidFromMajor === "function" && bootEnv.wrapperPath && kernel.parseAppidFromMajor((0, node_path.join)((0, node_path.dirname)(bootEnv.wrapperPath), "major.node")) || typeof kernel.resolveAppidQua === "function" && kernel.resolveAppidQua(bootEnv.qqVersion || "").appid || "537237765";
|
|
1286
1426
|
}
|
|
1427
|
+
/** 快速登录 + session 初始化(kernel lifecycle 路径;生命周期方法缺失则跳过)。 */
|
|
1428
|
+
async function quickLoginAndStartSession(kernel, ctx, Appid, bootEnv) {
|
|
1429
|
+
if (typeof kernel.quickLogin !== "function" || typeof kernel.initAndStartSession !== "function") {
|
|
1430
|
+
log("bootstrap: kernel missing lifecycle fns (quickLogin/initAndStartSession)");
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
if (typeof kernel.buildLoginConfig === "function" && ctx.loginService) {
|
|
1434
|
+
const loginCfg = kernel.buildLoginConfig(Appid, bootEnv.qqVersion || "", bootEnv.dataDir || ".");
|
|
1435
|
+
if (typeof ctx.loginService.initConfig === "function") {
|
|
1436
|
+
ctx.loginService.initConfig(loginCfg);
|
|
1437
|
+
log("bootstrap: loginService.initConfig OK");
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
const loginResult = await kernel.quickLogin(ctx, {});
|
|
1441
|
+
log(`bootstrap: quickLogin OK, uin=${loginResult.uin}, uid=${loginResult.uid}`);
|
|
1442
|
+
const sessionConfig = kernel.buildSessionConfig({
|
|
1443
|
+
appid: Appid,
|
|
1444
|
+
fullVersion: bootEnv.qqVersion || "",
|
|
1445
|
+
selfUin: loginResult.uin,
|
|
1446
|
+
selfUid: loginResult.uid,
|
|
1447
|
+
accountPath: bootEnv.dataDir || ".",
|
|
1448
|
+
downloadPath: (0, node_path.join)(bootEnv.dataDir || ".", "temp")
|
|
1449
|
+
});
|
|
1450
|
+
const listener = kernel.createLifecycleSessionListener();
|
|
1451
|
+
await kernel.initAndStartSession(ctx, sessionConfig, listener, { timeoutMs: 2e4 });
|
|
1452
|
+
log("bootstrap: session init + startNT OK!");
|
|
1453
|
+
}
|
|
1454
|
+
/** 冒烟探测(NAPUTO_PROBE=1 时运行)。 */
|
|
1455
|
+
async function probeRuntime(kernel, ctx) {
|
|
1456
|
+
if (env.NAPUTO_PROBE !== "1" || typeof kernel.probeRuntime !== "function") return;
|
|
1457
|
+
try {
|
|
1458
|
+
const probe = kernel.probeRuntime(ctx);
|
|
1459
|
+
log(`bootstrap: probe done, session=${probe.session ? "ok" : "null"}, services=${Object.keys(probe.services ?? {}).length}`);
|
|
1460
|
+
} catch (e) {
|
|
1461
|
+
log(`bootstrap: probe error: ${errMsg(e)}`);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1287
1464
|
/** 回退:旧装配路径(startNapuketto + 手工 lifecycle)。 */
|
|
1288
1465
|
async function bootstrapFallback(kernel, state, bootEnv, Appid) {
|
|
1289
1466
|
log("bootstrap: kernel has no NapukettoCore, falling back");
|
|
@@ -1296,34 +1473,8 @@ async function bootstrapFallback(kernel, state, bootEnv, Appid) {
|
|
|
1296
1473
|
return;
|
|
1297
1474
|
}
|
|
1298
1475
|
log(`bootstrap: startNapuketto OK, engine=${typeof ctx.engine}, session=${ctx.session !== null}`);
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
const loginCfg = kernel.buildLoginConfig(Appid, bootEnv.qqVersion || "", bootEnv.dataDir || ".");
|
|
1302
|
-
if (typeof ctx.loginService.initConfig === "function") {
|
|
1303
|
-
ctx.loginService.initConfig(loginCfg);
|
|
1304
|
-
log("bootstrap: loginService.initConfig OK");
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
const loginResult = await kernel.quickLogin(ctx, {});
|
|
1308
|
-
log(`bootstrap: quickLogin OK, uin=${loginResult.uin}, uid=${loginResult.uid}`);
|
|
1309
|
-
const sessionConfig = kernel.buildSessionConfig({
|
|
1310
|
-
appid: Appid,
|
|
1311
|
-
fullVersion: bootEnv.qqVersion || "",
|
|
1312
|
-
selfUin: loginResult.uin,
|
|
1313
|
-
selfUid: loginResult.uid,
|
|
1314
|
-
accountPath: bootEnv.dataDir || ".",
|
|
1315
|
-
downloadPath: (0, node_path.join)(bootEnv.dataDir || ".", "temp")
|
|
1316
|
-
});
|
|
1317
|
-
const listener = kernel.createLifecycleSessionListener();
|
|
1318
|
-
await kernel.initAndStartSession(ctx, sessionConfig, listener, { timeoutMs: 2e4 });
|
|
1319
|
-
log("bootstrap: session init + startNT OK!");
|
|
1320
|
-
} else log("bootstrap: kernel missing lifecycle fns (quickLogin/initAndStartSession)");
|
|
1321
|
-
if (env.NAPUTO_PROBE === "1" && typeof kernel.probeRuntime === "function") try {
|
|
1322
|
-
const probe = kernel.probeRuntime(ctx);
|
|
1323
|
-
log(`bootstrap: probe done, session=${probe.session ? "ok" : "null"}, services=${Object.keys(probe.services ?? {}).length}`);
|
|
1324
|
-
} catch (e) {
|
|
1325
|
-
log(`bootstrap: probe error: ${errMsg(e)}`);
|
|
1326
|
-
}
|
|
1476
|
+
await quickLoginAndStartSession(kernel, ctx, Appid, bootEnv);
|
|
1477
|
+
await probeRuntime(kernel, ctx);
|
|
1327
1478
|
}
|
|
1328
1479
|
/** 核心引导:import kernel → 装配 → 登录 → 替换 session → 等待就绪 → 协议装配。 */
|
|
1329
1480
|
async function bootstrap(state) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napuketto/loader",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "NapukettoQQ 引导组件:自建宿主(标准 Node + stub QQNT.dll)dlopen wrapper.node 并启动 kernel,不拉起 QQ / 不注入",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/index.d.mts",
|
|
16
|
-
"import": "./dist/index.mjs"
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"require": "./dist/index.mjs",
|
|
18
|
+
"default": "./dist/index.mjs"
|
|
17
19
|
}
|
|
18
20
|
},
|
|
19
21
|
"devDependencies": {
|