@dimina-kit/devtools 0.4.0-dev.20260729062524 → 0.4.0-dev.20260801163345
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/app/app.js +7 -0
- package/dist/main/app/bootstrap.d.ts +8 -5
- package/dist/main/app/bootstrap.js +15 -15
- package/dist/main/index.bundle.js +2207 -5152
- package/dist/main/ipc/app-lifecycle.d.ts +1 -31
- package/dist/main/ipc/app-lifecycle.js +1 -53
- package/dist/main/ipc/bridge-router.d.ts +19 -152
- package/dist/main/ipc/bridge-router.js +28 -2186
- package/dist/main/ipc/page-scroll.d.ts +1 -13
- package/dist/main/ipc/page-scroll.js +1 -16
- package/dist/main/ipc/session-listener-bag.d.ts +1 -40
- package/dist/main/ipc/session-listener-bag.js +1 -39
- package/dist/main/services/console-forward/index.d.ts +1 -60
- package/dist/main/services/console-forward/index.js +1 -225
- package/dist/main/services/console-forward/internal-log.d.ts +1 -10
- package/dist/main/services/console-forward/internal-log.js +1 -22
- package/dist/main/services/diagnostics/index.d.ts +1 -58
- package/dist/main/services/diagnostics/index.js +1 -60
- package/dist/main/services/dimina-resource-server.d.ts +1 -6
- package/dist/main/services/dimina-resource-server.js +1 -98
- package/dist/main/services/mcp/target-manager.js +5 -1
- package/dist/main/services/network-forward/index.d.ts +15 -3
- package/dist/main/services/network-forward/index.js +30 -4
- package/dist/main/services/network-forward/websocket.d.ts +36 -0
- package/dist/main/services/network-forward/websocket.js +120 -0
- package/dist/main/services/service-host-pool/pool.d.ts +1 -196
- package/dist/main/services/service-host-pool/pool.js +1 -363
- package/dist/main/services/simulator/custom-apis.d.ts +1 -42
- package/dist/main/services/simulator/custom-apis.js +1 -46
- package/dist/main/services/simulator/referer.d.ts +1 -9
- package/dist/main/services/simulator/referer.js +1 -19
- package/dist/main/services/simulator-storage/service-storage-ops.d.ts +1 -39
- package/dist/main/services/simulator-storage/service-storage-ops.js +1 -66
- package/dist/main/services/simulator-temp-files/disk.d.ts +1 -54
- package/dist/main/services/simulator-temp-files/disk.js +1 -237
- package/dist/main/services/simulator-temp-files/fs-channels.d.ts +1 -68
- package/dist/main/services/simulator-temp-files/fs-channels.js +1 -107
- package/dist/main/services/simulator-temp-files/index.d.ts +1 -32
- package/dist/main/services/simulator-temp-files/index.js +1 -181
- package/dist/main/services/simulator-temp-files/request-handler.d.ts +1 -29
- package/dist/main/services/simulator-temp-files/request-handler.js +1 -177
- package/dist/main/services/simulator-temp-files/resolver.d.ts +1 -21
- package/dist/main/services/simulator-temp-files/resolver.js +1 -21
- package/dist/main/services/simulator-temp-files/store.d.ts +1 -13
- package/dist/main/services/simulator-temp-files/store.js +1 -23
- package/dist/main/services/views/miniapp-partition.d.ts +1 -89
- package/dist/main/services/views/miniapp-partition.js +1 -158
- package/dist/main/services/views/simulator-session-policy.d.ts +1 -27
- package/dist/main/services/views/simulator-session-policy.js +1 -98
- package/dist/main/services/workbench-context.d.ts +4 -1
- package/dist/main/services/workbench-context.js +17 -0
- package/dist/main/utils/ipc-registry.d.ts +21 -3
- package/dist/main/utils/ipc-registry.js +26 -23
- package/dist/main/utils/paths.d.ts +14 -0
- package/dist/main/utils/paths.js +14 -0
- package/dist/main/windows/service-host-window/create.d.ts +1 -92
- package/dist/main/windows/service-host-window/create.js +1 -154
- package/dist/native-host/common/common.js +154 -58
- package/dist/native-host/container/pageFrame.css +1 -1
- package/dist/native-host/render/render.js +6611 -3312
- package/dist/native-host/service/service.js +2 -2
- package/dist/preload/index.d.ts +2 -0
- package/dist/preload/index.js +1 -0
- package/dist/preload/runtime/clipboard.d.ts +6 -0
- package/dist/preload/runtime/clipboard.js +12 -0
- package/dist/preload/runtime/native-host.d.ts +2 -0
- package/dist/preload/runtime/native-host.js +5 -10
- package/dist/preload/runtime/node-bindings.d.ts +18 -0
- package/dist/preload/runtime/node-bindings.js +44 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
- package/dist/preload/windows/main.cjs +1195 -897
- package/dist/preload/windows/main.cjs.map +4 -4
- package/dist/preload/windows/simulator.cjs +149 -60
- package/dist/preload/windows/simulator.cjs.map +4 -4
- package/dist/preload/windows/simulator.js +149 -60
- package/dist/render-host/pageFrame.html +3 -3
- package/dist/shared/bridge-channels.d.ts +1 -419
- package/dist/shared/bridge-channels.js +1 -89
- package/dist/shared/dmb-resource-url.d.ts +2 -0
- package/dist/shared/dmb-resource-url.js +2 -0
- package/dist/shared/ipc-channels.d.ts +2 -32
- package/dist/shared/ipc-channels.js +2 -5
- package/dist/shared/node-bindings.d.ts +2 -0
- package/dist/shared/node-bindings.js +2 -0
- package/dist/shared/request-core.d.ts +1 -83
- package/dist/shared/request-core.js +1 -167
- package/dist/simulator/assets/device-shell-Cw7c-IkG.js +2 -0
- package/dist/simulator/assets/{device-shell-BHz1v3Yo.css → device-shell-DbC5ccs8.css} +1 -1
- package/dist/simulator/assets/{jsx-runtime-hBv-rHqQ.js → jsx-runtime-DkKmJyBb.js} +2 -2
- package/dist/simulator/assets/simulator-COIE6R49.js +10 -0
- package/dist/simulator/assets/simulator-mini-app-BLn7XV8e.js +2 -0
- package/dist/simulator/simulator.html +2 -2
- package/dist/simulator/temp-files.d.ts +29 -0
- package/dist/simulator/temp-files.js +79 -0
- package/dist/simulator/types.d.ts +43 -0
- package/dist/simulator/types.js +2 -0
- package/package.json +6 -5
- package/dist/shared/simulator-api-metadata.d.ts +0 -26
- package/dist/shared/simulator-api-metadata.js +0 -59
- package/dist/shared/vpath.d.ts +0 -42
- package/dist/shared/vpath.js +0 -105
- package/dist/simulator/assets/device-shell-CH_DMYaz.js +0 -2
- package/dist/simulator/assets/simulator-DXraYerh.js +0 -10
- package/dist/simulator/assets/simulator-mini-app-w1Bhwkld.js +0 -2
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Build the script that `wx.pageScrollTo` runs inside the page's render guest.
|
|
3
|
-
*
|
|
4
|
-
* The mini-program page scrolls the whole render document (the native iOS impl
|
|
5
|
-
* scrolls the WKWebView's scrollView; Android scrolls the page view), so the
|
|
6
|
-
* simulator scrolls `window`. `duration` is best-effort: a positive duration
|
|
7
|
-
* maps to smooth scrolling (the browser owns the easing — the exact ms is not
|
|
8
|
-
* controllable), and `0` jumps instantly.
|
|
9
|
-
*/
|
|
10
|
-
export declare function buildPageScrollScript(params: {
|
|
11
|
-
scrollTop?: unknown;
|
|
12
|
-
duration?: unknown;
|
|
13
|
-
}): string;
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/page-scroll';
|
|
14
2
|
//# sourceMappingURL=page-scroll.d.ts.map
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Build the script that `wx.pageScrollTo` runs inside the page's render guest.
|
|
3
|
-
*
|
|
4
|
-
* The mini-program page scrolls the whole render document (the native iOS impl
|
|
5
|
-
* scrolls the WKWebView's scrollView; Android scrolls the page view), so the
|
|
6
|
-
* simulator scrolls `window`. `duration` is best-effort: a positive duration
|
|
7
|
-
* maps to smooth scrolling (the browser owns the easing — the exact ms is not
|
|
8
|
-
* controllable), and `0` jumps instantly.
|
|
9
|
-
*/
|
|
10
|
-
export function buildPageScrollScript(params) {
|
|
11
|
-
const rawTop = Number(params.scrollTop);
|
|
12
|
-
const top = Number.isFinite(rawTop) ? rawTop : 0;
|
|
13
|
-
const duration = params.duration === undefined ? 300 : Number(params.duration);
|
|
14
|
-
const behavior = Number.isFinite(duration) && duration > 0 ? 'smooth' : 'auto';
|
|
15
|
-
return `window.scrollTo({ top: ${top}, left: 0, behavior: ${JSON.stringify(behavior)} })`;
|
|
16
|
-
}
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/page-scroll';
|
|
17
2
|
//# sourceMappingURL=page-scroll.js.map
|
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Session-scoped listener bookkeeping. An app session hangs lifecycle hooks on
|
|
3
|
-
* emitters it does NOT own — the shared simulator WebContentsView, a pooled
|
|
4
|
-
* service-host window — and those emitters outlive the session (one simulator
|
|
5
|
-
* wc soft-reloads through many sessions). Every such hook is registered
|
|
6
|
-
* through this bag so the session's single teardown chokepoint can detach them
|
|
7
|
-
* all with one `dispose()`; a hook left behind survives as a dead listener on
|
|
8
|
-
* the shared emitter, growing by one per soft reload until Node's MaxListeners
|
|
9
|
-
* warning fires.
|
|
10
|
-
*/
|
|
11
|
-
type Listener = (...args: unknown[]) => void;
|
|
12
|
-
/**
|
|
13
|
-
* Structural surface of the Node/Electron emitters the bag manages.
|
|
14
|
-
* `removeListener(event, fn)` also detaches a `once(event, fn)` registration:
|
|
15
|
-
* Node's once wrapper keeps a `.listener` back-reference to `fn` and
|
|
16
|
-
* removeListener matches through it. `isDestroyed` covers Electron objects
|
|
17
|
-
* (WebContents / BrowserWindow) whose methods throw once destroyed.
|
|
18
|
-
*/
|
|
19
|
-
export interface BagEmitter {
|
|
20
|
-
on(event: string, listener: Listener): unknown;
|
|
21
|
-
once(event: string, listener: Listener): unknown;
|
|
22
|
-
removeListener(event: string, listener: Listener): unknown;
|
|
23
|
-
isDestroyed?(): boolean;
|
|
24
|
-
}
|
|
25
|
-
export interface SessionListenerBag {
|
|
26
|
-
/** Attach `fn` via `emitter.on` and track it for dispose. No-op after dispose. */
|
|
27
|
-
on(emitter: BagEmitter, event: string, fn: Listener): void;
|
|
28
|
-
/** Attach `fn` via `emitter.once` and track it for dispose. No-op after dispose. */
|
|
29
|
-
once(emitter: BagEmitter, event: string, fn: Listener): void;
|
|
30
|
-
/**
|
|
31
|
-
* Detach every tracked listener that may still be attached. Emitters that
|
|
32
|
-
* report `isDestroyed()` are skipped — their listeners died with them, and
|
|
33
|
-
* touching a destroyed Electron object throws. Removing a `once` that
|
|
34
|
-
* already fired is a no-op, so dispose is safe to call FROM one of the
|
|
35
|
-
* bag's own hooks (teardown triggered by the hook itself). Idempotent.
|
|
36
|
-
*/
|
|
37
|
-
dispose(): void;
|
|
38
|
-
}
|
|
39
|
-
export declare function createSessionListenerBag(): SessionListenerBag;
|
|
40
|
-
export {};
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/session-listener-bag';
|
|
41
2
|
//# sourceMappingURL=session-listener-bag.d.ts.map
|
|
@@ -1,40 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Session-scoped listener bookkeeping. An app session hangs lifecycle hooks on
|
|
3
|
-
* emitters it does NOT own — the shared simulator WebContentsView, a pooled
|
|
4
|
-
* service-host window — and those emitters outlive the session (one simulator
|
|
5
|
-
* wc soft-reloads through many sessions). Every such hook is registered
|
|
6
|
-
* through this bag so the session's single teardown chokepoint can detach them
|
|
7
|
-
* all with one `dispose()`; a hook left behind survives as a dead listener on
|
|
8
|
-
* the shared emitter, growing by one per soft reload until Node's MaxListeners
|
|
9
|
-
* warning fires.
|
|
10
|
-
*/
|
|
11
|
-
export function createSessionListenerBag() {
|
|
12
|
-
const records = [];
|
|
13
|
-
let disposed = false;
|
|
14
|
-
return {
|
|
15
|
-
on(emitter, event, fn) {
|
|
16
|
-
if (disposed)
|
|
17
|
-
return;
|
|
18
|
-
emitter.on(event, fn);
|
|
19
|
-
records.push({ emitter, event, fn });
|
|
20
|
-
},
|
|
21
|
-
once(emitter, event, fn) {
|
|
22
|
-
if (disposed)
|
|
23
|
-
return;
|
|
24
|
-
emitter.once(event, fn);
|
|
25
|
-
records.push({ emitter, event, fn });
|
|
26
|
-
},
|
|
27
|
-
dispose() {
|
|
28
|
-
if (disposed)
|
|
29
|
-
return;
|
|
30
|
-
disposed = true;
|
|
31
|
-
for (const { emitter, event, fn } of records) {
|
|
32
|
-
if (emitter.isDestroyed?.())
|
|
33
|
-
continue;
|
|
34
|
-
emitter.removeListener(event, fn);
|
|
35
|
-
}
|
|
36
|
-
records.length = 0;
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/session-listener-bag';
|
|
40
2
|
//# sourceMappingURL=session-listener-bag.js.map
|
|
@@ -1,61 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import type { BridgeRouterHandle } from '../../ipc/bridge-router.js';
|
|
3
|
-
import type { DiagnosticsBus } from '../diagnostics/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* One console entry posted by a guest preload. Shape mirrors
|
|
6
|
-
* render-host/preload.cjs + service-host/preload.cjs `emitConsoleLog`:
|
|
7
|
-
* - `source` which layer it came from ('render' | 'service'); ONLY 'render'
|
|
8
|
-
* is forwarded into the service host (see loop-safety above).
|
|
9
|
-
* - `bridgeId` present for render entries; identifies the owning page so we
|
|
10
|
-
* can target the matching app's service host (multi-app safe).
|
|
11
|
-
* - `level` console method name ('log' | 'warn' | 'error' | 'info' | 'debug').
|
|
12
|
-
* - `args` already-`safeSerialize`d arguments (structured-cloneable).
|
|
13
|
-
*/
|
|
14
|
-
export interface GuestConsoleEntry {
|
|
15
|
-
source?: string;
|
|
16
|
-
bridgeId?: string;
|
|
17
|
-
level?: string;
|
|
18
|
-
args?: unknown[];
|
|
19
|
-
ts?: number;
|
|
20
|
-
}
|
|
21
|
-
/** A consumer of every guest console entry (render AND service). */
|
|
22
|
-
export type ConsoleSink = (entry: GuestConsoleEntry) => void;
|
|
23
|
-
export interface ConsoleForwarder extends Disposable {
|
|
24
|
-
/**
|
|
25
|
-
* The single sink bridge-router invokes (wired onto `ctx.guestConsole.emit`).
|
|
26
|
-
* Fans every entry out to subscribers, then runs the render→service forward.
|
|
27
|
-
*/
|
|
28
|
-
emit(entry: unknown): void;
|
|
29
|
-
/**
|
|
30
|
-
* Register an external sink (e.g. automation WS broadcast). Returns a
|
|
31
|
-
* Disposable that unregisters it. Sinks see EVERY entry (both layers) — the
|
|
32
|
-
* render→service forward is internal and not exposed as a sink.
|
|
33
|
-
*
|
|
34
|
-
* A bounded history buffer (200 entries, oldest dropped first — mirrors
|
|
35
|
-
* `DiagnosticsBus`'s `DEFAULT_BUFFER_CAP` ring-buffer style) records every
|
|
36
|
-
* entry regardless of whether anyone is subscribed. `opts.replay` (default
|
|
37
|
-
* `false`, UNLIKE `DiagnosticsBus` whose default is `true`) opts a new
|
|
38
|
-
* subscriber into draining that buffer, in order, before receiving live
|
|
39
|
-
* entries. Default stays non-replaying because the existing automation
|
|
40
|
-
* subscriber (`services/automation/index.ts`) wants only entries from the
|
|
41
|
-
* moment it subscribes — a history dump on an existing WS connection would
|
|
42
|
-
* be a surprise duplicate broadcast. `{replay:true}` exists for the global
|
|
43
|
-
* console mirror, whose whole point is to catch up a standalone debug
|
|
44
|
-
* window opened well after boot.
|
|
45
|
-
*/
|
|
46
|
-
subscribe(sink: ConsoleSink, opts?: {
|
|
47
|
-
replay?: boolean;
|
|
48
|
-
}): Disposable;
|
|
49
|
-
/**
|
|
50
|
-
* Flush any diagnostic queued for `appSessionId` (plus the global,
|
|
51
|
-
* session-less queue) into that session's now-ready service-host wc.
|
|
52
|
-
* Idempotent: entries are removed from their bucket as they flush, so a
|
|
53
|
-
* repeat call for the same session injects nothing further. Call once the
|
|
54
|
-
* session's service-host webContents has actually navigated/loaded (e.g.
|
|
55
|
-
* from `bootServiceHost`, after `did-finish-load`) — calling it earlier just
|
|
56
|
-
* finds nothing resolvable and leaves the queue intact for a later call.
|
|
57
|
-
*/
|
|
58
|
-
notifyServiceHostReady(appSessionId: string): void;
|
|
59
|
-
}
|
|
60
|
-
export declare function createConsoleForwarder(bridge: Pick<BridgeRouterHandle, 'getServiceWc' | 'getServiceWcForBridge'>, diagnostics?: DiagnosticsBus): ConsoleForwarder;
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/console-forward';
|
|
61
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,226 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { RENDER_FORWARD_SOURCE_URL } from '../service-console/console-api.js';
|
|
3
|
-
import { isInternalLogMessage } from './internal-log.js';
|
|
4
|
-
/** Console levels we re-emit into the service host. Anything else maps to 'log'. */
|
|
5
|
-
const FORWARDABLE_LEVELS = new Set(['log', 'warn', 'error', 'info', 'debug']);
|
|
6
|
-
/**
|
|
7
|
-
* Build the `executeJavaScript` source that re-emits a render entry inside the
|
|
8
|
-
* service host. Args are carried as a JSON string and parsed service-side, so no
|
|
9
|
-
* guest-controlled value is ever interpolated into executable JS — the only
|
|
10
|
-
* thing that reaches the parser is a JSON literal. The `[视图]` prefix lets the
|
|
11
|
-
* DevTools console filter isolate the render layer.
|
|
12
|
-
*/
|
|
13
|
-
function buildForwardScript(level, args) {
|
|
14
|
-
const method = FORWARDABLE_LEVELS.has(level) ? level : 'log';
|
|
15
|
-
// JSON.stringify('…') yields a valid JS string literal; embedding it and
|
|
16
|
-
// re-parsing keeps args as data, never code. JSON.stringify can throw on a
|
|
17
|
-
// value that slipped past safeSerialize (e.g. a BigInt) — caller guards.
|
|
18
|
-
const argsJson = JSON.stringify(args ?? []);
|
|
19
|
-
// `console[method]` (not `console.log`) preserves the original level so the
|
|
20
|
-
// DevTools severity filter still works on the forwarded line.
|
|
21
|
-
//
|
|
22
|
-
// The trailing `//# sourceURL` stamps this injected line with a sentinel URL.
|
|
23
|
-
// The service-console CDP capture (services/service-console) attached to THIS
|
|
24
|
-
// service host would otherwise re-capture this `console[...]` call as a fresh
|
|
25
|
-
// service entry and re-broadcast it to automation (duplicate). It skips any
|
|
26
|
-
// `consoleAPICalled` whose top frame URL === RENDER_FORWARD_SOURCE_URL.
|
|
27
|
-
return `(()=>{try{const a=JSON.parse(${JSON.stringify(argsJson)});console[${JSON.stringify(method)}]('[视图]',...a)}catch(_){}})()\n//# sourceURL=${RENDER_FORWARD_SOURCE_URL}`;
|
|
28
|
-
}
|
|
29
|
-
/** `Diagnostic.severity` → the literal `console.<method>` call to emit (dot form, not computed — kept greppable/CDP-attributable like a hand-written call site). */
|
|
30
|
-
const DIAGNOSTIC_CONSOLE_CALL = {
|
|
31
|
-
error: 'console.error',
|
|
32
|
-
warn: 'console.warn',
|
|
33
|
-
info: 'console.info',
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Build the `executeJavaScript` source that injects one diagnostic into the
|
|
37
|
-
* service host's console, prefixed `[dimina-kit]`. Args ride as a JSON string
|
|
38
|
-
* (same anti-injection shape as `buildForwardScript`) and the sourceURL is the
|
|
39
|
-
* SAME sentinel the render mirror uses, so this line is exempt from
|
|
40
|
-
* service-console's loop-safety skip too.
|
|
41
|
-
*/
|
|
42
|
-
function buildDiagnosticScript(severity, message) {
|
|
43
|
-
const call = DIAGNOSTIC_CONSOLE_CALL[severity];
|
|
44
|
-
const argsJson = JSON.stringify([`[dimina-kit] ${message}`]);
|
|
45
|
-
return `(()=>{try{const a=JSON.parse(${JSON.stringify(argsJson)});${call}(...a)}catch(_){}})()\n//# sourceURL=${RENDER_FORWARD_SOURCE_URL}`;
|
|
46
|
-
}
|
|
47
|
-
export function createConsoleForwarder(bridge, diagnostics) {
|
|
48
|
-
const sinks = new Set();
|
|
49
|
-
const registry = new DisposableRegistry();
|
|
50
|
-
// Bounded history ring buffer backing `subscribe(sink, {replay:true})` —
|
|
51
|
-
// see the interface doc comment above. Every entry is recorded regardless
|
|
52
|
-
// of whether anyone is subscribed, so a replaying subscriber that arrives
|
|
53
|
-
// long after boot (the standalone global debug window) still catches up.
|
|
54
|
-
const CONSOLE_BUFFER_CAP = 200;
|
|
55
|
-
const buffer = [];
|
|
56
|
-
// Diagnostics queued because no live service-host wc could be resolved yet,
|
|
57
|
-
// bucketed by the owning appSessionId; diagnostics with no appSessionId land
|
|
58
|
-
// in `pendingGlobal` instead. `notifyServiceHostReady` drains both into the
|
|
59
|
-
// session that just became ready.
|
|
60
|
-
const pendingBySession = new Map();
|
|
61
|
-
const pendingGlobal = [];
|
|
62
|
-
// Sessions whose service host has finished loading service.html (the caller
|
|
63
|
-
// signals this via `notifyServiceHostReady`). A resolvable wc alone is NOT
|
|
64
|
-
// readiness: the window exists (and is bound) before its spawn navigation
|
|
65
|
-
// lands, and anything injected into that pre-load document is wiped by the
|
|
66
|
-
// navigation — the diagnostic would silently vanish from the Console panel.
|
|
67
|
-
const readySessions = new Set();
|
|
68
|
-
function injectDiagnostic(wc, d) {
|
|
69
|
-
wc.executeJavaScript(buildDiagnosticScript(d.severity, d.message), true).catch(() => { });
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Inject a diagnostic into its owning session's service-host console, or
|
|
73
|
-
* queue it until that host is READY (not merely constructed — see
|
|
74
|
-
* `readySessions`). Ownership is strict: a session-owned diagnostic NEVER
|
|
75
|
-
* falls back to the currently-active host — while `handleSpawn` is still
|
|
76
|
-
* running, the new session's host doesn't exist yet and the "active" host
|
|
77
|
-
* is the OUTGOING session's window, so a fallback would land the message in
|
|
78
|
-
* a console about to be destroyed instead of the session it explains. Only
|
|
79
|
-
* session-less diagnostics may use the active host. Never throws — a
|
|
80
|
-
* missing/destroyed/not-yet-ready host is a normal state, not an error.
|
|
81
|
-
*/
|
|
82
|
-
function handleDiagnostic(d) {
|
|
83
|
-
// Internal-audience diagnostics (e.g. compile-standby's warm-pool
|
|
84
|
-
// lifecycle) are devtools-tooling-only state — never inject them into a
|
|
85
|
-
// project's service host (the right-panel CDP is natively attached
|
|
86
|
-
// there), and never queue them either: queuing exists so a diagnostic
|
|
87
|
-
// survives until ITS session's host becomes resolvable, which is
|
|
88
|
-
// meaningless for something that must never reach any service host.
|
|
89
|
-
// (See global-diagnostics-mirror.ts for where these actually surface —
|
|
90
|
-
// the independent, unfiltered "debug the whole app" panel.)
|
|
91
|
-
if (d.audience === 'internal')
|
|
92
|
-
return;
|
|
93
|
-
if (d.appSessionId) {
|
|
94
|
-
const wc = readySessions.has(d.appSessionId) && bridge.getServiceWcForBridge
|
|
95
|
-
? bridge.getServiceWcForBridge(d.appSessionId)
|
|
96
|
-
: null;
|
|
97
|
-
if (wc && !wc.isDestroyed()) {
|
|
98
|
-
injectDiagnostic(wc, d);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const bucket = pendingBySession.get(d.appSessionId);
|
|
102
|
-
if (bucket)
|
|
103
|
-
bucket.push(d);
|
|
104
|
-
else
|
|
105
|
-
pendingBySession.set(d.appSessionId, [d]);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const wc = bridge.getServiceWc();
|
|
109
|
-
if (wc && !wc.isDestroyed()) {
|
|
110
|
-
injectDiagnostic(wc, d);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
pendingGlobal.push(d);
|
|
114
|
-
}
|
|
115
|
-
if (diagnostics) {
|
|
116
|
-
// replay:true so diagnostics reported before this forwarder existed (early
|
|
117
|
-
// boot, buffered on the bus) are queued/injected here too.
|
|
118
|
-
registry.add(diagnostics.subscribe(handleDiagnostic, { replay: true }));
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Render→service forward. Resolves the service host for the entry's owning
|
|
122
|
-
* page (multi-app safe), falling back to the active app's service host when
|
|
123
|
-
* the bridgeId is unknown — that's the host the embedded DevTools inspects.
|
|
124
|
-
* No-op on a destroyed/missing host so we never write to a torn-down wc (pool
|
|
125
|
-
* reuse / session swap can swap the host out under us). Skips dimina
|
|
126
|
-
* framework-internal render-layer log lines (`isInternalLogMessage`) —
|
|
127
|
-
* those must never reach the project's right-panel console at all (the
|
|
128
|
-
* global console mirror still sees them via the `sinks` broadcast in
|
|
129
|
-
* `emit()`, which runs before this function). This is the source-level fix
|
|
130
|
-
* for the render half of the noise console-filter.ts's front-end text
|
|
131
|
-
* filter used to paper over; the service-layer half (`[service]` lines,
|
|
132
|
-
* native CDP-observed, no interception point available — see
|
|
133
|
-
* service-host/preload.cjs's "console.* is deliberately NOT patched"
|
|
134
|
-
* comment) still needs that filter.
|
|
135
|
-
*/
|
|
136
|
-
function forwardRenderToServiceHost(entry) {
|
|
137
|
-
if (isInternalLogMessage(entry))
|
|
138
|
-
return;
|
|
139
|
-
let wc = null;
|
|
140
|
-
if (entry.bridgeId && bridge.getServiceWcForBridge) {
|
|
141
|
-
wc = bridge.getServiceWcForBridge(entry.bridgeId);
|
|
142
|
-
}
|
|
143
|
-
if (!wc)
|
|
144
|
-
wc = bridge.getServiceWc();
|
|
145
|
-
if (!wc || wc.isDestroyed())
|
|
146
|
-
return;
|
|
147
|
-
let script;
|
|
148
|
-
try {
|
|
149
|
-
script = buildForwardScript(entry.level ?? 'log', entry.args ?? []);
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
// Args that escaped safeSerialize and aren't JSON-stringifiable — drop
|
|
153
|
-
// rather than break the forward. Console capture must never throw.
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
// executeJavaScript rejects if the host navigates/teardowns mid-call; the
|
|
157
|
-
// injected body is itself try/caught. Swallow either — best-effort mirror.
|
|
158
|
-
wc.executeJavaScript(script, true).catch(() => { });
|
|
159
|
-
}
|
|
160
|
-
return {
|
|
161
|
-
// The single sink bridge-router calls (`ctx.guestConsole.emit`). Fans out
|
|
162
|
-
// to external subscribers (both layers) then runs the render→service forward
|
|
163
|
-
// (render only — see loop-safety invariant in the module header).
|
|
164
|
-
emit(raw) {
|
|
165
|
-
const entry = (raw ?? {});
|
|
166
|
-
buffer.push(entry);
|
|
167
|
-
if (buffer.length > CONSOLE_BUFFER_CAP)
|
|
168
|
-
buffer.shift();
|
|
169
|
-
for (const sink of sinks) {
|
|
170
|
-
try {
|
|
171
|
-
sink(entry);
|
|
172
|
-
}
|
|
173
|
-
catch { /* a sink must never break the others */ }
|
|
174
|
-
}
|
|
175
|
-
// Forward ONLY the render layer. Service entries are already shown
|
|
176
|
-
// natively in the attached DevTools, and forwarding them would loop
|
|
177
|
-
// (see header).
|
|
178
|
-
if (entry.source === 'render')
|
|
179
|
-
forwardRenderToServiceHost(entry);
|
|
180
|
-
},
|
|
181
|
-
subscribe(sink, opts) {
|
|
182
|
-
if (opts?.replay) {
|
|
183
|
-
for (const entry of buffer) {
|
|
184
|
-
try {
|
|
185
|
-
sink(entry);
|
|
186
|
-
}
|
|
187
|
-
catch { /* isolate a replay throw same as a live one */ }
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
sinks.add(sink);
|
|
191
|
-
return registry.add(toDisposable(() => { sinks.delete(sink); }));
|
|
192
|
-
},
|
|
193
|
-
notifyServiceHostReady(appSessionId) {
|
|
194
|
-
// Readiness is sticky per session: from here on, session-owned
|
|
195
|
-
// diagnostics inject directly instead of queueing.
|
|
196
|
-
readySessions.add(appSessionId);
|
|
197
|
-
// Re-resolve fresh rather than trusting whatever `handleDiagnostic` saw at
|
|
198
|
-
// report time — the caller invokes this exactly when it knows the wc just
|
|
199
|
-
// became live, so that resolution wins even if an earlier snapshot was
|
|
200
|
-
// destroyed/missing.
|
|
201
|
-
const wc = bridge.getServiceWcForBridge ? bridge.getServiceWcForBridge(appSessionId) : null;
|
|
202
|
-
if (!wc)
|
|
203
|
-
return;
|
|
204
|
-
const sessionEntries = pendingBySession.get(appSessionId);
|
|
205
|
-
if (sessionEntries) {
|
|
206
|
-
for (const d of sessionEntries)
|
|
207
|
-
injectDiagnostic(wc, d);
|
|
208
|
-
pendingBySession.delete(appSessionId);
|
|
209
|
-
}
|
|
210
|
-
if (pendingGlobal.length) {
|
|
211
|
-
for (const d of pendingGlobal)
|
|
212
|
-
injectDiagnostic(wc, d);
|
|
213
|
-
pendingGlobal.length = 0;
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
dispose() {
|
|
217
|
-
sinks.clear();
|
|
218
|
-
buffer.length = 0;
|
|
219
|
-
pendingBySession.clear();
|
|
220
|
-
pendingGlobal.length = 0;
|
|
221
|
-
readySessions.clear();
|
|
222
|
-
return registry.disposeAll();
|
|
223
|
-
},
|
|
224
|
-
};
|
|
225
|
-
}
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/console-forward';
|
|
226
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Judges whether a guest console entry is dimina framework-internal output
|
|
4
|
-
* (a bridge/lifecycle log the framework itself prints) rather than the
|
|
5
|
-
* mini-app author's own business `console.*` call. Only the FIRST arg is
|
|
6
|
-
* inspected — framework logs always lead with the literal tag; a
|
|
7
|
-
* business log that happens to mention the tag later in its args must not
|
|
8
|
-
* be swept up.
|
|
9
|
-
*/
|
|
10
|
-
export declare function isInternalLogMessage(entry: GuestConsoleEntry): boolean;
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/internal-log';
|
|
11
2
|
//# sourceMappingURL=internal-log.d.ts.map
|
|
@@ -1,23 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* source literals (dimina/fe/packages/service/src/core/message.js:26 and
|
|
3
|
-
* siblings use `'[service]'`; dimina/fe/packages/render/src/core/message.js:18
|
|
4
|
-
* and siblings use `'[system]'`). */
|
|
5
|
-
const SERVICE_PREFIX = '[service]';
|
|
6
|
-
const RENDER_PREFIX = '[system]';
|
|
7
|
-
/**
|
|
8
|
-
* Judges whether a guest console entry is dimina framework-internal output
|
|
9
|
-
* (a bridge/lifecycle log the framework itself prints) rather than the
|
|
10
|
-
* mini-app author's own business `console.*` call. Only the FIRST arg is
|
|
11
|
-
* inspected — framework logs always lead with the literal tag; a
|
|
12
|
-
* business log that happens to mention the tag later in its args must not
|
|
13
|
-
* be swept up.
|
|
14
|
-
*/
|
|
15
|
-
export function isInternalLogMessage(entry) {
|
|
16
|
-
const first = entry.args?.[0];
|
|
17
|
-
if (typeof first !== 'string')
|
|
18
|
-
return false;
|
|
19
|
-
if (first === RENDER_PREFIX)
|
|
20
|
-
return true;
|
|
21
|
-
return first === SERVICE_PREFIX || first.startsWith(`${SERVICE_PREFIX} `);
|
|
22
|
-
}
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/internal-log';
|
|
23
2
|
//# sourceMappingURL=internal-log.js.map
|
|
@@ -1,59 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
* Diagnostics bus: the single authoritative channel for developer-facing
|
|
3
|
-
* diagnostics synthesized by main (e.g. "page not found", "logic bundle
|
|
4
|
-
* unreachable") that do not originate from a real `console.*` call the
|
|
5
|
-
* embedded service-host DevTools' CDP capture could observe on its own.
|
|
6
|
-
*
|
|
7
|
-
* Main-synthesized diagnostics used to reach only `ctx.guestConsole.emit`,
|
|
8
|
-
* which fans out to automation subscribers but — for `source:'service'`
|
|
9
|
-
* entries — is never injected into the service host's own console (see
|
|
10
|
-
* `console-forward`'s render-only forward invariant), so they never appeared
|
|
11
|
-
* in the Console panel. This bus is the fix: `report()` is the one place a
|
|
12
|
-
* diagnostic is born, and `console-forward` subscribes to inject each one
|
|
13
|
-
* into the owning session's service-host console (queuing until that
|
|
14
|
-
* session's window is ready — see `notifyServiceHostReady`).
|
|
15
|
-
*/
|
|
16
|
-
export type DiagnosticSeverity = 'error' | 'warn' | 'info';
|
|
17
|
-
export interface Diagnostic {
|
|
18
|
-
severity: DiagnosticSeverity;
|
|
19
|
-
code: string;
|
|
20
|
-
message: string;
|
|
21
|
-
appSessionId?: string;
|
|
22
|
-
ts: number;
|
|
23
|
-
/**
|
|
24
|
-
* Who this diagnostic is for. `'internal'` means devtools-tooling-only
|
|
25
|
-
* state (e.g. compile-standby's warm-pool lifecycle) that must never reach
|
|
26
|
-
* the per-project service-host console the right-panel CDP is attached to
|
|
27
|
-
* — see `console-forward/index.ts`'s `handleDiagnostic` gate. `'user'` or
|
|
28
|
-
* omitted means the existing behavior: a real diagnostic about the
|
|
29
|
-
* inspected mini-program, injected into that project's Console panel.
|
|
30
|
-
*/
|
|
31
|
-
audience?: 'user' | 'internal';
|
|
32
|
-
}
|
|
33
|
-
export interface DiagnosticsBus {
|
|
34
|
-
/** Record one diagnostic: buffers it, mirrors it to the main-process console, and synchronously notifies every live subscriber. No-op after `dispose()`. */
|
|
35
|
-
report(d: {
|
|
36
|
-
severity: DiagnosticSeverity;
|
|
37
|
-
code: string;
|
|
38
|
-
message: string;
|
|
39
|
-
appSessionId?: string;
|
|
40
|
-
audience?: 'user' | 'internal';
|
|
41
|
-
}): void;
|
|
42
|
-
/**
|
|
43
|
-
* Register a sink. With `replay` (default true) the sink is first called,
|
|
44
|
-
* in order, for every buffered diagnostic still held, then for every
|
|
45
|
-
* diagnostic reported from now on; `replay: false` skips the backlog and
|
|
46
|
-
* only delivers diagnostics reported after this call.
|
|
47
|
-
*/
|
|
48
|
-
subscribe(sink: (d: Diagnostic) => void, opts?: {
|
|
49
|
-
replay?: boolean;
|
|
50
|
-
}): {
|
|
51
|
-
dispose(): void;
|
|
52
|
-
};
|
|
53
|
-
/** Clears subscribers and the buffer. `report()` becomes a no-op afterward (including the console mirror — dispose means fully off, not "log-only"). */
|
|
54
|
-
dispose(): void;
|
|
55
|
-
}
|
|
56
|
-
export declare function createDiagnosticsBus(opts?: {
|
|
57
|
-
bufferCap?: number;
|
|
58
|
-
}): DiagnosticsBus;
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/diagnostics';
|
|
59
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,61 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
const CONSOLE_METHOD = {
|
|
3
|
-
error: 'error',
|
|
4
|
-
warn: 'warn',
|
|
5
|
-
info: 'info',
|
|
6
|
-
};
|
|
7
|
-
export function createDiagnosticsBus(opts) {
|
|
8
|
-
const bufferCap = opts?.bufferCap && opts.bufferCap > 0 ? opts.bufferCap : DEFAULT_BUFFER_CAP;
|
|
9
|
-
const buffer = [];
|
|
10
|
-
const sinks = new Set();
|
|
11
|
-
let disposed = false;
|
|
12
|
-
return {
|
|
13
|
-
report(d) {
|
|
14
|
-
if (disposed)
|
|
15
|
-
return;
|
|
16
|
-
const entry = { ...d, ts: Date.now() };
|
|
17
|
-
buffer.push(entry);
|
|
18
|
-
// Ring buffer: drop the oldest once over cap. Bounded at `bufferCap` so a
|
|
19
|
-
// burst of synthesized diagnostics can never grow this without limit.
|
|
20
|
-
if (buffer.length > bufferCap)
|
|
21
|
-
buffer.shift();
|
|
22
|
-
// The one guaranteed-visible sink: unlike Console-panel injection (which
|
|
23
|
-
// needs a live, ready service-host wc), the main-process terminal is
|
|
24
|
-
// always there.
|
|
25
|
-
console[CONSOLE_METHOD[entry.severity]](`[dimina-kit:${entry.code}] ${entry.message}`);
|
|
26
|
-
for (const sink of sinks) {
|
|
27
|
-
try {
|
|
28
|
-
sink(entry);
|
|
29
|
-
}
|
|
30
|
-
catch { /* a sink must never break the others */ }
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
subscribe(sink, subOpts) {
|
|
34
|
-
const replay = subOpts?.replay ?? true;
|
|
35
|
-
if (replay) {
|
|
36
|
-
for (const entry of buffer) {
|
|
37
|
-
try {
|
|
38
|
-
sink(entry);
|
|
39
|
-
}
|
|
40
|
-
catch { /* isolate a replay throw same as a live one */ }
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
sinks.add(sink);
|
|
44
|
-
let released = false;
|
|
45
|
-
return {
|
|
46
|
-
dispose() {
|
|
47
|
-
if (released)
|
|
48
|
-
return;
|
|
49
|
-
released = true;
|
|
50
|
-
sinks.delete(sink);
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
dispose() {
|
|
55
|
-
disposed = true;
|
|
56
|
-
sinks.clear();
|
|
57
|
-
buffer.length = 0;
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/diagnostics';
|
|
61
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
baseUrl: string;
|
|
3
|
-
close(): Promise<void>;
|
|
4
|
-
}
|
|
5
|
-
export declare function startDiminaResourceServer(rootDir: string): Promise<DiminaResourceServer>;
|
|
6
|
-
export declare function toSourceUrl(filePath: string): string;
|
|
1
|
+
export * from '@dimina-kit/electron-runtime/main/dimina-resource-server';
|
|
7
2
|
//# sourceMappingURL=dimina-resource-server.d.ts.map
|