@dimina-kit/devtools 0.4.0-dev.20260630070008 → 0.4.0-dev.20260630123203
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/main/index.bundle.js +158 -10
- package/dist/main/ipc/app-lifecycle.d.ts +32 -0
- package/dist/main/ipc/app-lifecycle.js +54 -0
- package/dist/main/ipc/bridge-router.js +173 -10
- package/dist/main/ipc/page-scroll.d.ts +14 -0
- package/dist/main/ipc/page-scroll.js +17 -0
- package/dist/main/windows/service-host-window/create.d.ts +7 -0
- package/dist/main/windows/service-host-window/create.js +5 -0
- package/dist/preload/windows/main.cjs +200 -0
- package/dist/preload/windows/main.cjs.map +3 -3
- package/dist/service-host/preload.cjs +11 -0
- package/dist/simulator/assets/{device-shell-BiFE9Otv.css → device-shell-CS1rqAQz.css} +1 -1
- package/dist/simulator/assets/device-shell-H3Bq5NgA.js +2 -0
- package/dist/simulator/assets/{jsx-runtime-P6ZegaOf.js → jsx-runtime-CDK-o-S0.js} +2 -2
- package/dist/simulator/assets/simulator-CYPhufF2.js +10 -0
- package/dist/simulator/simulator.html +2 -2
- package/package.json +5 -5
- package/dist/simulator/assets/device-shell-CPCnCp1L.js +0 -2
- package/dist/simulator/assets/simulator-gMBWKDeO.js +0 -10
|
@@ -4731,6 +4731,9 @@ function buildServiceHostSpawnUrl(opts) {
|
|
|
4731
4731
|
if (opts.hostEnvSnapshot) {
|
|
4732
4732
|
url.searchParams.set("hostEnv", encodeURIComponent(JSON.stringify(opts.hostEnvSnapshot)));
|
|
4733
4733
|
}
|
|
4734
|
+
if (opts.apiNamespaces && opts.apiNamespaces.length > 0) {
|
|
4735
|
+
url.searchParams.set("apiNamespaces", opts.apiNamespaces.join(","));
|
|
4736
|
+
}
|
|
4734
4737
|
return url.toString();
|
|
4735
4738
|
}
|
|
4736
4739
|
function navigateServiceHost(win, url) {
|
|
@@ -5624,6 +5627,52 @@ function findSimulatorWebContents() {
|
|
|
5624
5627
|
return null;
|
|
5625
5628
|
}
|
|
5626
5629
|
|
|
5630
|
+
// src/main/ipc/page-scroll.ts
|
|
5631
|
+
function buildPageScrollScript(params) {
|
|
5632
|
+
const rawTop = Number(params.scrollTop);
|
|
5633
|
+
const top = Number.isFinite(rawTop) ? rawTop : 0;
|
|
5634
|
+
const duration = params.duration === void 0 ? 300 : Number(params.duration);
|
|
5635
|
+
const behavior = Number.isFinite(duration) && duration > 0 ? "smooth" : "auto";
|
|
5636
|
+
return `window.scrollTo({ top: ${top}, left: 0, behavior: ${JSON.stringify(behavior)} })`;
|
|
5637
|
+
}
|
|
5638
|
+
|
|
5639
|
+
// src/main/ipc/app-lifecycle.ts
|
|
5640
|
+
function createAppLifecycleController() {
|
|
5641
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
5642
|
+
return {
|
|
5643
|
+
register(appSessionId, event, callbackId) {
|
|
5644
|
+
if (callbackId === void 0 || callbackId === null) return;
|
|
5645
|
+
let events = sessions.get(appSessionId);
|
|
5646
|
+
if (!events) {
|
|
5647
|
+
events = /* @__PURE__ */ new Map();
|
|
5648
|
+
sessions.set(appSessionId, events);
|
|
5649
|
+
}
|
|
5650
|
+
let ids = events.get(event);
|
|
5651
|
+
if (!ids) {
|
|
5652
|
+
ids = /* @__PURE__ */ new Set();
|
|
5653
|
+
events.set(event, ids);
|
|
5654
|
+
}
|
|
5655
|
+
ids.add(callbackId);
|
|
5656
|
+
},
|
|
5657
|
+
unregister(appSessionId, event, callbackId) {
|
|
5658
|
+
const events = sessions.get(appSessionId);
|
|
5659
|
+
if (!events) return;
|
|
5660
|
+
if (callbackId === void 0 || callbackId === null) {
|
|
5661
|
+
events.delete(event);
|
|
5662
|
+
return;
|
|
5663
|
+
}
|
|
5664
|
+
events.get(event)?.delete(callbackId);
|
|
5665
|
+
},
|
|
5666
|
+
listeners(appSessionId, event) {
|
|
5667
|
+
const ids = sessions.get(appSessionId)?.get(event);
|
|
5668
|
+
return ids ? Array.from(ids) : [];
|
|
5669
|
+
},
|
|
5670
|
+
dispose(appSessionId) {
|
|
5671
|
+
sessions.delete(appSessionId);
|
|
5672
|
+
}
|
|
5673
|
+
};
|
|
5674
|
+
}
|
|
5675
|
+
|
|
5627
5676
|
// src/main/ipc/bridge-router.ts
|
|
5628
5677
|
function rewriteSourceMappingUrl(source, scriptUrl) {
|
|
5629
5678
|
if (typeof source !== "string" || !source) return source;
|
|
@@ -5703,6 +5752,7 @@ function installBridgeRouter(ctx) {
|
|
|
5703
5752
|
},
|
|
5704
5753
|
connections: ctx.connections,
|
|
5705
5754
|
debugTap: createDebugTap({ enabled: resolveDebugTapEnabled() }),
|
|
5755
|
+
appLifecycle: createAppLifecycleController(),
|
|
5706
5756
|
evictAppDataBridges: (ap) => {
|
|
5707
5757
|
if (!ctx.appData) return;
|
|
5708
5758
|
for (const page of ap.pages.values()) ctx.appData.evictBridge(ap.appId, page.bridgeId);
|
|
@@ -5720,6 +5770,7 @@ function installBridgeRouter(ctx) {
|
|
|
5720
5770
|
ctx.registry.add(() => clearTimeout(warmTimer));
|
|
5721
5771
|
ctx.registry.add(() => state.pool?.dispose());
|
|
5722
5772
|
}
|
|
5773
|
+
installAppLifecycleDriver(ctx, state);
|
|
5723
5774
|
installResourceProtocolHandlers(ctx, state);
|
|
5724
5775
|
let currentDevice = null;
|
|
5725
5776
|
const onNativeHostQuery = (event) => {
|
|
@@ -5984,6 +6035,7 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
5984
6035
|
const workspaceProjectPath = typeof ctx.workspace.getProjectPath === "function" ? ctx.workspace.getProjectPath() : "";
|
|
5985
6036
|
const pkgRoot = path16.resolve(opts.pkgRoot || workspaceProjectPath || process.cwd());
|
|
5986
6037
|
const root = opts.root || "main";
|
|
6038
|
+
const apiNamespaces = ctx.apiNamespaces ?? [];
|
|
5987
6039
|
let resourceServer = null;
|
|
5988
6040
|
let resourceBaseUrl;
|
|
5989
6041
|
if (opts.resourceBaseUrl) {
|
|
@@ -6025,7 +6077,8 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
6025
6077
|
pkgRoot,
|
|
6026
6078
|
root,
|
|
6027
6079
|
resourceBaseUrl,
|
|
6028
|
-
hostEnvSnapshot: hostEnv
|
|
6080
|
+
hostEnvSnapshot: hostEnv,
|
|
6081
|
+
apiNamespaces
|
|
6029
6082
|
});
|
|
6030
6083
|
}
|
|
6031
6084
|
const appSession = {
|
|
@@ -6038,6 +6091,7 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
6038
6091
|
serviceWc: serviceWindow.webContents,
|
|
6039
6092
|
simulatorWc,
|
|
6040
6093
|
serviceLoaded: false,
|
|
6094
|
+
logicInjected: null,
|
|
6041
6095
|
resourceBaseUrl,
|
|
6042
6096
|
resourceServer,
|
|
6043
6097
|
hostEnv,
|
|
@@ -6059,6 +6113,7 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
6059
6113
|
renderWc: null,
|
|
6060
6114
|
renderLoaded: false,
|
|
6061
6115
|
resourceLoadedSent: false,
|
|
6116
|
+
renderLoadPending: false,
|
|
6062
6117
|
windowConfig: rootWindowConfig
|
|
6063
6118
|
};
|
|
6064
6119
|
state.appSessions.set(appSessionId, appSession);
|
|
@@ -6093,7 +6148,7 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
6093
6148
|
}
|
|
6094
6149
|
if (!serviceWindow.webContents.getURL().includes("service.html")) return;
|
|
6095
6150
|
serviceWindow.webContents.removeListener("did-finish-load", bootOnServiceLoad);
|
|
6096
|
-
void bootServiceHost(state, appSession);
|
|
6151
|
+
void bootServiceHost(state, appSession, ctx);
|
|
6097
6152
|
};
|
|
6098
6153
|
appSession.onServiceBoot = bootOnServiceLoad;
|
|
6099
6154
|
serviceWindow.webContents.on("did-finish-load", bootOnServiceLoad);
|
|
@@ -6106,12 +6161,13 @@ async function handleSpawn(state, ctx, event, opts) {
|
|
|
6106
6161
|
pkgRoot,
|
|
6107
6162
|
root,
|
|
6108
6163
|
resourceBaseUrl,
|
|
6109
|
-
hostEnvSnapshot: hostEnv
|
|
6164
|
+
hostEnvSnapshot: hostEnv,
|
|
6165
|
+
apiNamespaces
|
|
6110
6166
|
})
|
|
6111
6167
|
);
|
|
6112
6168
|
} else {
|
|
6113
6169
|
serviceWindow.webContents.once("did-finish-load", () => {
|
|
6114
|
-
void bootServiceHost(state, appSession);
|
|
6170
|
+
void bootServiceHost(state, appSession, ctx);
|
|
6115
6171
|
});
|
|
6116
6172
|
}
|
|
6117
6173
|
return {
|
|
@@ -6145,6 +6201,7 @@ async function handlePageOpen(state, event, opts) {
|
|
|
6145
6201
|
renderWc: null,
|
|
6146
6202
|
renderLoaded: false,
|
|
6147
6203
|
resourceLoadedSent: false,
|
|
6204
|
+
renderLoadPending: false,
|
|
6148
6205
|
windowConfig
|
|
6149
6206
|
};
|
|
6150
6207
|
state.pageSessions.set(bridgeId, page);
|
|
@@ -6191,23 +6248,49 @@ function handleNavCallback(state, sender, payload) {
|
|
|
6191
6248
|
}
|
|
6192
6249
|
sendCallback(ap, payload.callbacks.complete, result);
|
|
6193
6250
|
}
|
|
6194
|
-
async function bootServiceHost(state, ap) {
|
|
6251
|
+
async function bootServiceHost(state, ap, ctx) {
|
|
6195
6252
|
if (state.appSessions.get(ap.appSessionId) !== ap) return;
|
|
6196
|
-
await injectLogicBundle(ap);
|
|
6253
|
+
ap.logicInjected = await injectLogicBundle(ap);
|
|
6254
|
+
if (!ap.logicInjected) {
|
|
6255
|
+
reportLogicLoadFailure(ap, ctx);
|
|
6256
|
+
return;
|
|
6257
|
+
}
|
|
6197
6258
|
forwardToService(ap, makeLoadResource(ap, ap.pages.get(ap.appSessionId), "service"));
|
|
6259
|
+
for (const page of ap.pages.values()) {
|
|
6260
|
+
if (page.renderLoadPending) {
|
|
6261
|
+
page.renderLoadPending = false;
|
|
6262
|
+
sendRenderLoadResource(ap, page);
|
|
6263
|
+
}
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6266
|
+
function sendRenderLoadResource(ap, page) {
|
|
6267
|
+
if (page.renderWc && !page.renderWc.isDestroyed()) {
|
|
6268
|
+
page.renderWc.send(BRIDGE_CHANNELS.TO_RENDER, { msg: makeLoadResource(ap, page, "render") });
|
|
6269
|
+
}
|
|
6270
|
+
}
|
|
6271
|
+
function logicBundleUrl(ap) {
|
|
6272
|
+
return ap.resourceServer ? new URL("logic.js", ap.resourceBaseUrl).toString() : new URL(`${ap.appId}/${ap.root}/logic.js`, ap.resourceBaseUrl).toString();
|
|
6198
6273
|
}
|
|
6199
6274
|
async function injectLogicBundle(ap) {
|
|
6200
|
-
const logicUrl =
|
|
6275
|
+
const logicUrl = logicBundleUrl(ap);
|
|
6201
6276
|
try {
|
|
6202
6277
|
const res = await fetch(logicUrl);
|
|
6203
6278
|
if (!res.ok) throw new Error(`logic.js fetch ${res.status} at ${logicUrl}`);
|
|
6204
6279
|
const logicContent = rewriteSourceMappingUrl(await res.text(), logicUrl);
|
|
6205
6280
|
await ap.serviceWc.executeJavaScript(`${logicContent}
|
|
6206
6281
|
//# sourceURL=${logicUrl}`, true);
|
|
6282
|
+
return true;
|
|
6207
6283
|
} catch (error) {
|
|
6208
6284
|
console.warn("[bridge-router] unable to inject service logic.js:", error);
|
|
6285
|
+
return false;
|
|
6209
6286
|
}
|
|
6210
6287
|
}
|
|
6288
|
+
function reportLogicLoadFailure(ap, ctx) {
|
|
6289
|
+
const hint = ap.appId === "unknown" ? ' appId could not be resolved (it fell back to "unknown") \u2014 the mini-program likely failed to compile or its project manifest/app config is missing.' : "";
|
|
6290
|
+
const message = `[dimina-kit] Failed to load the mini-program logic bundle from ${logicBundleUrl(ap)}. The service runtime has no registered modules, so no page can mount.` + hint + ` Verify the project compiled successfully and that the resource server serves "${ap.appId}/${ap.root}/".`;
|
|
6291
|
+
console.error(message);
|
|
6292
|
+
ctx.guestConsole?.emit({ source: "service", level: "error", args: [message] });
|
|
6293
|
+
}
|
|
6211
6294
|
function maybeSendResourceLoaded(ap, page) {
|
|
6212
6295
|
if (page.resourceLoadedSent || !ap.serviceLoaded || !page.renderLoaded) return;
|
|
6213
6296
|
page.resourceLoadedSent = true;
|
|
@@ -6242,9 +6325,12 @@ function routeFromService(state, ap, defaultPage, msg, ctx) {
|
|
|
6242
6325
|
}
|
|
6243
6326
|
function routeFromRender(state, ap, page, msg, ctx) {
|
|
6244
6327
|
if (msg.type === "renderHostReady") {
|
|
6245
|
-
if (
|
|
6246
|
-
|
|
6328
|
+
if (ap.logicInjected === false) return;
|
|
6329
|
+
if (ap.logicInjected === null) {
|
|
6330
|
+
page.renderLoadPending = true;
|
|
6331
|
+
return;
|
|
6247
6332
|
}
|
|
6333
|
+
sendRenderLoadResource(ap, page);
|
|
6248
6334
|
return;
|
|
6249
6335
|
}
|
|
6250
6336
|
if (msg.type === "renderResourceLoaded") {
|
|
@@ -6281,9 +6367,15 @@ function handleContainerMsg(ap, page, msg, ctx, state) {
|
|
|
6281
6367
|
case "invokeAPI":
|
|
6282
6368
|
void handleSimulatorApi(state, ap, page, msg.body, ctx);
|
|
6283
6369
|
break;
|
|
6284
|
-
case "serviceHostError":
|
|
6370
|
+
case "serviceHostError": {
|
|
6285
6371
|
console.warn("[bridge-router] service host error:", msg.body);
|
|
6372
|
+
const errBody = msg.body;
|
|
6373
|
+
const errArg = errBody?.message ?? msg.body;
|
|
6374
|
+
for (const id of state.appLifecycle.listeners(ap.appSessionId, "onError")) {
|
|
6375
|
+
sendCallback(ap, id, errArg);
|
|
6376
|
+
}
|
|
6286
6377
|
break;
|
|
6378
|
+
}
|
|
6287
6379
|
case "consoleLog":
|
|
6288
6380
|
ctx.guestConsole?.emit(msg.body);
|
|
6289
6381
|
break;
|
|
@@ -6315,6 +6407,40 @@ var TAB_ACTION_NAMES = /* @__PURE__ */ new Set([
|
|
|
6315
6407
|
"showTabBarRedDot",
|
|
6316
6408
|
"hideTabBarRedDot"
|
|
6317
6409
|
]);
|
|
6410
|
+
function installAppLifecycleDriver(ctx, state) {
|
|
6411
|
+
const win = ctx.windows?.mainWindow;
|
|
6412
|
+
if (!win || typeof win.on !== "function") return;
|
|
6413
|
+
const emit = (serviceEvent, listenerEvent) => {
|
|
6414
|
+
for (const ap of state.appSessions.values()) {
|
|
6415
|
+
forwardToService(ap, { type: serviceEvent, target: "service", body: {} });
|
|
6416
|
+
for (const id of state.appLifecycle.listeners(ap.appSessionId, listenerEvent)) {
|
|
6417
|
+
sendCallback(ap, id, {});
|
|
6418
|
+
}
|
|
6419
|
+
}
|
|
6420
|
+
};
|
|
6421
|
+
const onHide = () => emit("appHide", "onAppHide");
|
|
6422
|
+
const onShow = () => emit("appShow", "onAppShow");
|
|
6423
|
+
win.on("hide", onHide);
|
|
6424
|
+
win.on("minimize", onHide);
|
|
6425
|
+
win.on("show", onShow);
|
|
6426
|
+
win.on("restore", onShow);
|
|
6427
|
+
ctx.registry.add(() => {
|
|
6428
|
+
win.off("hide", onHide);
|
|
6429
|
+
win.off("minimize", onHide);
|
|
6430
|
+
win.off("show", onShow);
|
|
6431
|
+
win.off("restore", onShow);
|
|
6432
|
+
});
|
|
6433
|
+
}
|
|
6434
|
+
var APP_LIFECYCLE_REGISTER = {
|
|
6435
|
+
onAppShow: "onAppShow",
|
|
6436
|
+
onAppHide: "onAppHide",
|
|
6437
|
+
onError: "onError"
|
|
6438
|
+
};
|
|
6439
|
+
var APP_LIFECYCLE_UNREGISTER = {
|
|
6440
|
+
offAppShow: "onAppShow",
|
|
6441
|
+
offAppHide: "onAppHide",
|
|
6442
|
+
offError: "onError"
|
|
6443
|
+
};
|
|
6318
6444
|
async function handleSimulatorApi(state, ap, page, body, ctx) {
|
|
6319
6445
|
const name = String(body.name ?? "");
|
|
6320
6446
|
const params = normalizeParams(body.params);
|
|
@@ -6365,6 +6491,27 @@ async function handleSimulatorApi(state, ap, page, body, ctx) {
|
|
|
6365
6491
|
}
|
|
6366
6492
|
return;
|
|
6367
6493
|
}
|
|
6494
|
+
const lifecycleRegister = APP_LIFECYCLE_REGISTER[name];
|
|
6495
|
+
if (lifecycleRegister) {
|
|
6496
|
+
state.appLifecycle.register(ap.appSessionId, lifecycleRegister, params.success);
|
|
6497
|
+
return;
|
|
6498
|
+
}
|
|
6499
|
+
const lifecycleUnregister = APP_LIFECYCLE_UNREGISTER[name];
|
|
6500
|
+
if (lifecycleUnregister) {
|
|
6501
|
+
state.appLifecycle.unregister(ap.appSessionId, lifecycleUnregister, params.success);
|
|
6502
|
+
return;
|
|
6503
|
+
}
|
|
6504
|
+
if (name === "pageScrollTo") {
|
|
6505
|
+
const renderWc = page.renderWc;
|
|
6506
|
+
if (renderWc && !renderWc.isDestroyed()) {
|
|
6507
|
+
void renderWc.executeJavaScript(buildPageScrollScript(params)).catch(() => {
|
|
6508
|
+
});
|
|
6509
|
+
}
|
|
6510
|
+
const successResult = { errMsg: "pageScrollTo:ok" };
|
|
6511
|
+
sendCallback(ap, params.success, successResult);
|
|
6512
|
+
sendCallback(ap, params.complete, successResult);
|
|
6513
|
+
return;
|
|
6514
|
+
}
|
|
6368
6515
|
if (ctx.storageApi && STORAGE_API_NAMES.has(name)) {
|
|
6369
6516
|
try {
|
|
6370
6517
|
const result = await ctx.storageApi.invoke(ap.appId, name, params);
|
|
@@ -6589,6 +6736,7 @@ async function disposeAppSession(state, appSessionId, opts = {}) {
|
|
|
6589
6736
|
const ap = state.appSessions.get(appSessionId);
|
|
6590
6737
|
if (!ap) return;
|
|
6591
6738
|
state.appSessions.delete(appSessionId);
|
|
6739
|
+
state.appLifecycle.dispose(appSessionId);
|
|
6592
6740
|
state.evictAppDataBridges(ap);
|
|
6593
6741
|
for (const [requestId, pending] of state.pendingApiCalls) {
|
|
6594
6742
|
if (pending.appSessionId !== appSessionId) continue;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-app-session registry for the app-level lifecycle listeners registered
|
|
3
|
+
* from the mini-program service layer: `wx.onAppShow` / `onAppHide` / `onError`
|
|
4
|
+
* (and their `off*` removers).
|
|
5
|
+
*
|
|
6
|
+
* These arrive as keep subscriptions — `wx.onAppShow(cb)` encodes `cb` as a
|
|
7
|
+
* persistent callback id in `params.success` (service `callback.store(fn,
|
|
8
|
+
* keep=true)`), so the router stores the id here and re-fires it via
|
|
9
|
+
* `sendCallback` on every app foreground / background / error.
|
|
10
|
+
*
|
|
11
|
+
* `wx.offAppShow(cb)` re-encodes the SAME `cb`: with `keep=true`,
|
|
12
|
+
* `callback.store` dedups by function and returns the original evtId, so `off*`
|
|
13
|
+
* carries that id and removes exactly that listener. `wx.offAppShow()` with no
|
|
14
|
+
* argument carries no id and clears every listener of the event (WeChat
|
|
15
|
+
* contract).
|
|
16
|
+
*/
|
|
17
|
+
export type AppLifecycleEvent = 'onAppShow' | 'onAppHide' | 'onError';
|
|
18
|
+
export interface AppLifecycleController {
|
|
19
|
+
/** Store a keep callback id for an event. Null/undefined ids are ignored. */
|
|
20
|
+
register(appSessionId: string, event: AppLifecycleEvent, callbackId: unknown): void;
|
|
21
|
+
/**
|
|
22
|
+
* Remove a listener. With `callbackId`, removes only that id; without one,
|
|
23
|
+
* clears every listener of the event for the session.
|
|
24
|
+
*/
|
|
25
|
+
unregister(appSessionId: string, event: AppLifecycleEvent, callbackId?: unknown): void;
|
|
26
|
+
/** Snapshot of the registered callback ids (empty for unknown session/event). */
|
|
27
|
+
listeners(appSessionId: string, event: AppLifecycleEvent): unknown[];
|
|
28
|
+
/** Drop all listeners for a torn-down session. */
|
|
29
|
+
dispose(appSessionId: string): void;
|
|
30
|
+
}
|
|
31
|
+
export declare function createAppLifecycleController(): AppLifecycleController;
|
|
32
|
+
//# sourceMappingURL=app-lifecycle.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-app-session registry for the app-level lifecycle listeners registered
|
|
3
|
+
* from the mini-program service layer: `wx.onAppShow` / `onAppHide` / `onError`
|
|
4
|
+
* (and their `off*` removers).
|
|
5
|
+
*
|
|
6
|
+
* These arrive as keep subscriptions — `wx.onAppShow(cb)` encodes `cb` as a
|
|
7
|
+
* persistent callback id in `params.success` (service `callback.store(fn,
|
|
8
|
+
* keep=true)`), so the router stores the id here and re-fires it via
|
|
9
|
+
* `sendCallback` on every app foreground / background / error.
|
|
10
|
+
*
|
|
11
|
+
* `wx.offAppShow(cb)` re-encodes the SAME `cb`: with `keep=true`,
|
|
12
|
+
* `callback.store` dedups by function and returns the original evtId, so `off*`
|
|
13
|
+
* carries that id and removes exactly that listener. `wx.offAppShow()` with no
|
|
14
|
+
* argument carries no id and clears every listener of the event (WeChat
|
|
15
|
+
* contract).
|
|
16
|
+
*/
|
|
17
|
+
export function createAppLifecycleController() {
|
|
18
|
+
const sessions = new Map();
|
|
19
|
+
return {
|
|
20
|
+
register(appSessionId, event, callbackId) {
|
|
21
|
+
if (callbackId === undefined || callbackId === null)
|
|
22
|
+
return;
|
|
23
|
+
let events = sessions.get(appSessionId);
|
|
24
|
+
if (!events) {
|
|
25
|
+
events = new Map();
|
|
26
|
+
sessions.set(appSessionId, events);
|
|
27
|
+
}
|
|
28
|
+
let ids = events.get(event);
|
|
29
|
+
if (!ids) {
|
|
30
|
+
ids = new Set();
|
|
31
|
+
events.set(event, ids);
|
|
32
|
+
}
|
|
33
|
+
ids.add(callbackId);
|
|
34
|
+
},
|
|
35
|
+
unregister(appSessionId, event, callbackId) {
|
|
36
|
+
const events = sessions.get(appSessionId);
|
|
37
|
+
if (!events)
|
|
38
|
+
return;
|
|
39
|
+
if (callbackId === undefined || callbackId === null) {
|
|
40
|
+
events.delete(event);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
events.get(event)?.delete(callbackId);
|
|
44
|
+
},
|
|
45
|
+
listeners(appSessionId, event) {
|
|
46
|
+
const ids = sessions.get(appSessionId)?.get(event);
|
|
47
|
+
return ids ? Array.from(ids) : [];
|
|
48
|
+
},
|
|
49
|
+
dispose(appSessionId) {
|
|
50
|
+
sessions.delete(appSessionId);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=app-lifecycle.js.map
|