@dimina-kit/devtools 0.3.2-dev.20260611063505 → 0.3.2-dev.20260611135124
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/README.md +53 -40
- package/dist/main/api.d.ts +4 -2
- package/dist/main/api.js +5 -1
- package/dist/main/app/app.d.ts +1 -5
- package/dist/main/app/app.js +4 -19
- package/dist/main/index.bundle.js +238 -392
- package/dist/main/ipc/app.d.ts +1 -1
- package/dist/main/ipc/app.js +0 -7
- package/dist/main/ipc/index.d.ts +0 -2
- package/dist/main/ipc/index.js +0 -2
- package/dist/main/ipc/settings.d.ts +1 -1
- package/dist/main/ipc/settings.js +1 -13
- package/dist/main/ipc/simulator-module.d.ts +3 -3
- package/dist/main/ipc/simulator-module.js +3 -7
- package/dist/main/ipc/simulator.js +1 -12
- package/dist/main/runtime/miniapp-runtime.d.ts +138 -28
- package/dist/main/runtime/miniapp-runtime.js +6 -11
- package/dist/main/services/layout/index.d.ts +0 -11
- package/dist/main/services/layout/index.js +0 -23
- package/dist/main/services/notifications/renderer-notifier.d.ts +0 -6
- package/dist/main/services/notifications/renderer-notifier.js +1 -10
- package/dist/main/services/service-host-pool/pool.d.ts +5 -4
- package/dist/main/services/views/host-toolbar-port-channel.d.ts +93 -0
- package/dist/main/services/views/host-toolbar-port-channel.js +169 -0
- package/dist/main/services/views/host-toolbar-session-runtime.d.ts +35 -0
- package/dist/main/services/views/host-toolbar-session-runtime.js +55 -0
- package/dist/main/services/views/view-manager.d.ts +68 -39
- package/dist/main/services/views/view-manager.js +143 -182
- package/dist/main/services/workbench-context.d.ts +6 -26
- package/dist/main/services/workbench-context.js +0 -14
- package/dist/main/services/workspace/workspace-service.js +7 -13
- package/dist/main/utils/paths.d.ts +11 -2
- package/dist/main/utils/paths.js +11 -2
- package/dist/preload/index.d.ts +15 -0
- package/dist/preload/index.js +15 -0
- package/dist/preload/runtime/host-toolbar-port.d.ts +44 -0
- package/dist/preload/runtime/host-toolbar-port.js +127 -0
- package/dist/preload/runtime/host-toolbar-runtime.d.ts +41 -0
- package/dist/preload/runtime/host-toolbar-runtime.js +49 -0
- package/dist/preload/windows/{host-toolbar.cjs → host-toolbar-runtime.cjs} +94 -3
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +7 -0
- package/dist/preload/windows/host-toolbar-runtime.d.ts +2 -0
- package/dist/preload/windows/host-toolbar-runtime.js +13 -0
- package/dist/preload/windows/simulator.cjs +0 -2
- package/dist/preload/windows/simulator.cjs.map +2 -2
- package/dist/preload/windows/simulator.js +0 -2
- package/dist/renderer/assets/constants-DI382mTP.js +2 -0
- package/dist/renderer/assets/index-DLzjz1wv.js +50 -0
- package/dist/renderer/assets/{input-CFHmbOgz.js → input-6fpCXV-n.js} +2 -2
- package/dist/renderer/assets/ipc-transport-Bs8Sf1B2.css +1 -0
- package/dist/renderer/assets/{ipc-transport-BkKKww3u.js → ipc-transport-D22e4dv7.js} +6 -6
- package/dist/renderer/assets/popover-CdGdKkkc.js +2 -0
- package/dist/renderer/assets/select-X0sbjwdP.js +2 -0
- package/dist/renderer/assets/{settings-Cl4IcWnG.js → settings-CS4jYaCw.js} +2 -2
- package/dist/renderer/assets/settings-api-CCWTAao_.js +2 -0
- package/dist/renderer/assets/workbenchSettings-Bpzaj3bm.js +8 -0
- package/dist/renderer/entries/main/index.html +7 -6
- package/dist/renderer/entries/popover/index.html +6 -6
- package/dist/renderer/entries/settings/index.html +5 -5
- package/dist/renderer/entries/workbench-settings/index.html +5 -5
- package/dist/shared/constants.d.ts +18 -0
- package/dist/shared/constants.js +18 -0
- package/dist/shared/ipc-channels.d.ts +10 -23
- package/dist/shared/ipc-channels.js +13 -34
- package/dist/shared/ipc-schemas.d.ts +0 -12
- package/dist/shared/ipc-schemas.js +0 -12
- package/dist/shared/types.d.ts +14 -67
- package/package.json +6 -6
- package/dist/main/ipc/panels.d.ts +0 -4
- package/dist/main/ipc/panels.js +0 -46
- package/dist/main/ipc/toolbar.d.ts +0 -4
- package/dist/main/ipc/toolbar.js +0 -21
- package/dist/main/services/toolbar/toolbar-store.d.ts +0 -23
- package/dist/main/services/toolbar/toolbar-store.js +0 -40
- package/dist/preload/windows/host-toolbar.cjs.map +0 -7
- package/dist/preload/windows/host-toolbar.d.ts +0 -2
- package/dist/preload/windows/host-toolbar.js +0 -12
- package/dist/renderer/assets/constants-CLAQX6VZ.js +0 -2
- package/dist/renderer/assets/index-CZQOpCvg.js +0 -50
- package/dist/renderer/assets/ipc-transport-Bv_BVu4T.css +0 -1
- package/dist/renderer/assets/popover-h1M7n3tt.js +0 -2
- package/dist/renderer/assets/select-kj0n1oYf.js +0 -2
- package/dist/renderer/assets/settings-api-CCwo2eOi.js +0 -2
- package/dist/renderer/assets/workbenchSettings-BzlpQnve.js +0 -8
package/dist/main/ipc/app.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
2
2
|
import type { Disposable } from '@dimina-kit/electron-deck/main';
|
|
3
|
-
export declare function registerAppIpc(ctx: Pick<WorkbenchContext, '
|
|
3
|
+
export declare function registerAppIpc(ctx: Pick<WorkbenchContext, 'brandingProvider' | 'appName' | 'senderPolicy'>): Disposable;
|
|
4
4
|
//# sourceMappingURL=app.d.ts.map
|
package/dist/main/ipc/app.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
1
|
import { AppChannel } from '../../shared/ipc-channels.js';
|
|
3
2
|
import { IpcRegistry } from '../utils/ipc-registry.js';
|
|
4
3
|
export function registerAppIpc(ctx) {
|
|
5
4
|
return new IpcRegistry(ctx.senderPolicy)
|
|
6
|
-
.handle(AppChannel.GetPreloadPath, () => {
|
|
7
|
-
return `file://${fs.realpathSync(ctx.preloadPath)}`;
|
|
8
|
-
})
|
|
9
5
|
.handle(AppChannel.GetBranding, async () => {
|
|
10
6
|
if (ctx.brandingProvider)
|
|
11
7
|
return ctx.brandingProvider();
|
|
12
8
|
return { appName: ctx.appName };
|
|
13
|
-
})
|
|
14
|
-
.handle(AppChannel.GetHeaderHeight, () => {
|
|
15
|
-
return ctx.headerHeight;
|
|
16
9
|
});
|
|
17
10
|
}
|
|
18
11
|
//# sourceMappingURL=app.js.map
|
package/dist/main/ipc/index.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export { registerAppIpc } from './app.js';
|
|
2
2
|
export { registerSimulatorIpc } from './simulator.js';
|
|
3
|
-
export { registerPanelsIpc } from './panels.js';
|
|
4
3
|
export { registerPopoverIpc, popoverModule } from './popover.js';
|
|
5
4
|
export { registerProjectsIpc, projectsModule } from './projects.js';
|
|
6
5
|
export { registerSessionIpc, sessionModule } from './session.js';
|
|
7
6
|
export { registerSettingsIpc, settingsModule } from './settings.js';
|
|
8
|
-
export { registerToolbarIpc } from './toolbar.js';
|
|
9
7
|
export { simulatorModule } from './simulator-module.js';
|
|
10
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/main/ipc/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export { registerAppIpc } from './app.js';
|
|
2
2
|
export { registerSimulatorIpc } from './simulator.js';
|
|
3
|
-
export { registerPanelsIpc } from './panels.js';
|
|
4
3
|
export { registerPopoverIpc, popoverModule } from './popover.js';
|
|
5
4
|
export { registerProjectsIpc, projectsModule } from './projects.js';
|
|
6
5
|
export { registerSessionIpc, sessionModule } from './session.js';
|
|
7
6
|
export { registerSettingsIpc, settingsModule } from './settings.js';
|
|
8
|
-
export { registerToolbarIpc } from './toolbar.js';
|
|
9
7
|
export { simulatorModule } from './simulator-module.js';
|
|
10
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
2
2
|
import type { Disposable } from '@dimina-kit/electron-deck/main';
|
|
3
3
|
import type { WorkbenchModule } from '../services/module.js';
|
|
4
|
-
export declare function registerSettingsIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy'
|
|
4
|
+
export declare function registerSettingsIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy'>): Disposable;
|
|
5
5
|
export declare const settingsModule: WorkbenchModule;
|
|
6
6
|
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { app } from 'electron';
|
|
2
|
-
import { openSettingsWindow } from '../app/launch.js';
|
|
3
2
|
import { loadWorkbenchSettings, saveWorkbenchSettings, applyTheme, } from '../services/settings/index.js';
|
|
4
3
|
import { WorkbenchSettingsChannel, SettingsChannel } from '../../shared/ipc-channels.js';
|
|
5
4
|
import { DEFAULT_CDP_PORT } from '../../shared/constants.js';
|
|
6
5
|
import { getMcpStatus } from '../services/mcp/status.js';
|
|
7
|
-
import { SettingsConfigChangedSchema, SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema,
|
|
6
|
+
import { SettingsConfigChangedSchema, SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema, } from '../../shared/ipc-schemas.js';
|
|
8
7
|
import { validate } from '../utils/ipc-schema.js';
|
|
9
8
|
import { IpcRegistry } from '../utils/ipc-registry.js';
|
|
10
9
|
export function registerSettingsIpc(ctx) {
|
|
@@ -44,15 +43,6 @@ export function registerSettingsIpc(ctx) {
|
|
|
44
43
|
activePort: runtime.port,
|
|
45
44
|
error: runtime.error,
|
|
46
45
|
};
|
|
47
|
-
})
|
|
48
|
-
.handle(WorkbenchSettingsChannel.SetVisible, async (_, ...args) => {
|
|
49
|
-
const [visible] = validate(WorkbenchSettingsChannel.SetVisible, WorkbenchSettingsSetVisibleSchema, args);
|
|
50
|
-
if (visible) {
|
|
51
|
-
await openSettingsWindow(ctx);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
ctx.windows.closeSettingsWindow();
|
|
55
|
-
}
|
|
56
46
|
})
|
|
57
47
|
.handle(SettingsChannel.SetVisible, async (_, ...args) => {
|
|
58
48
|
const [visible] = validate(SettingsChannel.SetVisible, SettingsSetVisibleSchema, args);
|
|
@@ -67,7 +57,6 @@ export function registerSettingsIpc(ctx) {
|
|
|
67
57
|
}
|
|
68
58
|
else {
|
|
69
59
|
ctx.views.hideSettings();
|
|
70
|
-
ctx.notify.settingsClosed();
|
|
71
60
|
}
|
|
72
61
|
})
|
|
73
62
|
.on(SettingsChannel.ConfigChanged, async (_, ...args) => {
|
|
@@ -76,7 +65,6 @@ export function registerSettingsIpc(ctx) {
|
|
|
76
65
|
if (projectPath) {
|
|
77
66
|
await ctx.workspace.saveCompileConfig(projectPath, config);
|
|
78
67
|
}
|
|
79
|
-
ctx.notify.settingsChanged(config);
|
|
80
68
|
})
|
|
81
69
|
.on(SettingsChannel.ProjectSettingsChanged, (_, ...args) => {
|
|
82
70
|
const [patch] = validate(SettingsChannel.ProjectSettingsChanged, SettingsProjectSettingsChangedSchema, args);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { WorkbenchModule } from '../services/module.js';
|
|
2
2
|
/**
|
|
3
|
-
* The 'simulator' built-in module fans out into
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* The 'simulator' built-in module fans out into the simulator + views IPC
|
|
4
|
+
* registrars. Bundle them under a single module so app.ts only sees one
|
|
5
|
+
* entry per BuiltinModuleId.
|
|
6
6
|
*
|
|
7
7
|
* Bridge router (native-host PAGE_OPEN / NAV_ACTION / TAB_ACTION etc.) hooks
|
|
8
8
|
* up unconditionally — the `__diminaNativeHost.enabled` flag in the simulator
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
|
|
2
2
|
import { registerSimulatorIpc } from './simulator.js';
|
|
3
|
-
import { registerPanelsIpc } from './panels.js';
|
|
4
|
-
import { registerToolbarIpc } from './toolbar.js';
|
|
5
3
|
import { installBridgeRouter } from './bridge-router.js';
|
|
6
4
|
import { registerViewsIpc } from './views.js';
|
|
7
5
|
/**
|
|
8
|
-
* The 'simulator' built-in module fans out into
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* The 'simulator' built-in module fans out into the simulator + views IPC
|
|
7
|
+
* registrars. Bundle them under a single module so app.ts only sees one
|
|
8
|
+
* entry per BuiltinModuleId.
|
|
11
9
|
*
|
|
12
10
|
* Bridge router (native-host PAGE_OPEN / NAV_ACTION / TAB_ACTION etc.) hooks
|
|
13
11
|
* up unconditionally — the `__diminaNativeHost.enabled` flag in the simulator
|
|
@@ -19,8 +17,6 @@ export const simulatorModule = {
|
|
|
19
17
|
setup: (ctx) => {
|
|
20
18
|
const reg = new DisposableRegistry();
|
|
21
19
|
reg.add(registerSimulatorIpc(ctx));
|
|
22
|
-
reg.add(registerPanelsIpc(ctx));
|
|
23
|
-
reg.add(registerToolbarIpc(ctx));
|
|
24
20
|
reg.add(registerViewsIpc(ctx));
|
|
25
21
|
installBridgeRouter(ctx);
|
|
26
22
|
return reg;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServiceHostChannel, SimulatorChannel, SimulatorCustomApiChannel } from '../../shared/ipc-channels.js';
|
|
2
|
-
import { SimulatorAttachNativeSchema, SimulatorCustomApiInvokeSchema,
|
|
2
|
+
import { SimulatorAttachNativeSchema, SimulatorCustomApiInvokeSchema, SimulatorSetDeviceInfoSchema, SimulatorSetNativeBoundsSchema, } from '../../shared/ipc-schemas.js';
|
|
3
3
|
import { deviceInfoToHostEnv } from '../../shared/bridge-channels.js';
|
|
4
4
|
import { validate } from '../utils/ipc-schema.js';
|
|
5
5
|
import { IpcRegistry } from '../utils/ipc-registry.js';
|
|
@@ -11,10 +11,6 @@ export function registerSimulatorIpc(ctx) {
|
|
|
11
11
|
})
|
|
12
12
|
.handle(SimulatorChannel.Detach, () => {
|
|
13
13
|
ctx.views.detachSimulator();
|
|
14
|
-
})
|
|
15
|
-
.handle(SimulatorChannel.Resize, (_, ...args) => {
|
|
16
|
-
const [simWidth] = validate(SimulatorChannel.Resize, SimulatorResizeSchema, args);
|
|
17
|
-
ctx.views.resize(simWidth);
|
|
18
14
|
})
|
|
19
15
|
.handle(SimulatorChannel.SetNativeBounds, (_, ...args) => {
|
|
20
16
|
const [p] = validate(SimulatorChannel.SetNativeBounds, SimulatorSetNativeBoundsSchema, args);
|
|
@@ -38,13 +34,6 @@ export function registerSimulatorIpc(ctx) {
|
|
|
38
34
|
if (serviceWc && !serviceWc.isDestroyed()) {
|
|
39
35
|
serviceWc.send(ServiceHostChannel.HostEnvUpdate, deviceInfoToHostEnv(device));
|
|
40
36
|
}
|
|
41
|
-
})
|
|
42
|
-
.handle(SimulatorChannel.SetVisible, (_, ...args) => {
|
|
43
|
-
const [visible, simWidth] = validate(SimulatorChannel.SetVisible, SimulatorSetVisibleSchema, args);
|
|
44
|
-
ctx.views.setVisible(visible, simWidth);
|
|
45
|
-
})
|
|
46
|
-
.handle(SimulatorCustomApiChannel.List, () => {
|
|
47
|
-
return ctx.simulatorApis.list();
|
|
48
37
|
})
|
|
49
38
|
.handle(SimulatorCustomApiChannel.Invoke, (_, ...args) => {
|
|
50
39
|
const [name, params] = validate(SimulatorCustomApiChannel.Invoke, SimulatorCustomApiInvokeSchema, args);
|
|
@@ -1,39 +1,149 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MiniappRuntime — the stable, host-facing contract surface (foundation.md §3
|
|
3
|
-
* "MiniappRuntime 契约" layer
|
|
3
|
+
* "MiniappRuntime 契约" layer).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* HAND-WRITTEN, not derived from `WorkbenchContext`. A `Pick`-style projection
|
|
6
|
+
* would drag every nested internal service type (ViewManager,
|
|
7
|
+
* BridgeRouterHandle, SimulatorApiRegistry, Electron WebContents…) onto the
|
|
8
|
+
* public semver face, so any internal refactor of those services becomes an
|
|
9
|
+
* unreviewed breaking change for downstream hosts (qdmp). Instead this module
|
|
10
|
+
* names ONLY the audited downstream consumption surface, with structural DTOs
|
|
11
|
+
* and zero Electron types — non-Electron consumers can compile against it.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* the real implementation — `MiniappRuntime` is a view onto `WorkbenchContext`,
|
|
23
|
-
* and the conformance assertion below fails to compile the moment the context
|
|
24
|
-
* stops satisfying the contract.
|
|
13
|
+
* Contract rules:
|
|
14
|
+
* - Members are FUNCTION-VALUED PROPERTIES (`m: (x) => r`), never method
|
|
15
|
+
* syntax: under strictFunctionTypes method signatures compare bivariantly,
|
|
16
|
+
* which would let a wrongly-narrowed implementation or host override slip
|
|
17
|
+
* past the drift sentinel.
|
|
18
|
+
* - `workspace.openProject` stays writable (no `readonly`): qdmp gates
|
|
19
|
+
* project permissions by reassigning it (documented monkey-patch contract).
|
|
20
|
+
* - `windows` is an OPAQUE handle (`object`): hosts pass it through to
|
|
21
|
+
* framework helpers but never reach into it (no BrowserWindow leak).
|
|
25
22
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
23
|
+
* `asMiniappRuntime(ctx)` is an identity return — the contract is a typed
|
|
24
|
+
* VIEW onto the live context, not a snapshot/projection. That is what makes
|
|
25
|
+
* the monkey-patch contract work (a copied projection would receive the patch
|
|
26
|
+
* on a dead object), and its `return ctx` doubles as the assignment-compat
|
|
27
|
+
* sentinel: if an internal service drifts away from the contract, compilation
|
|
28
|
+
* breaks HERE, in this package's CI — not in a downstream host's upgrade.
|
|
29
29
|
*/
|
|
30
30
|
import type { WorkbenchContext } from '../services/workbench-context.js';
|
|
31
|
-
/**
|
|
32
|
-
export
|
|
31
|
+
/** Compile-status payload broadcast to hosts via `notify.projectStatus`. */
|
|
32
|
+
export interface MiniappProjectStatusPayload {
|
|
33
|
+
status: string;
|
|
34
|
+
message: string;
|
|
35
|
+
/** True when the status update is emitted by the file-watcher rebuild loop. */
|
|
36
|
+
hotReload?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Host-facing control surface for the toolbar WebContentsView — the exact
|
|
40
|
+
* post-R2 message-channel surface (`send`/`onMessage`), with no `webContents`
|
|
41
|
+
* escape hatch (that would put Electron types on the contract).
|
|
42
|
+
*/
|
|
43
|
+
export interface MiniappHostToolbar {
|
|
44
|
+
/**
|
|
45
|
+
* The host's own `webPreferences.preload` for the toolbar view (purely
|
|
46
|
+
* additive — never replaces the framework's session-resident height
|
|
47
|
+
* advertiser). Must be set before the view is (re)created; `null` (default)
|
|
48
|
+
* means "no host preload".
|
|
49
|
+
*/
|
|
50
|
+
setPreloadPath: (path: string | null) => void;
|
|
51
|
+
/** Load a local file into the toolbar view (lazy-creates the view). */
|
|
52
|
+
loadFile: (path: string) => Promise<void>;
|
|
53
|
+
/** Load a URL into the toolbar view (lazy-creates the view). */
|
|
54
|
+
loadURL: (url: string) => Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Post `{ channel, payload }` to the toolbar page. Gated and non-queueing:
|
|
57
|
+
* returns false (delivering nothing, creating no view) while there is no
|
|
58
|
+
* live toolbar webContents or the current load's MessagePort handshake
|
|
59
|
+
* hasn't completed; true once the envelope went out.
|
|
60
|
+
*/
|
|
61
|
+
send: (channel: string, payload: unknown) => boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Register a host-side handler for messages the toolbar page sends via
|
|
64
|
+
* `window.diminaHostToolbar.send(channel, payload)`. May be called before
|
|
65
|
+
* the view exists; survives page reloads. `dispose()` detaches (idempotent).
|
|
66
|
+
*/
|
|
67
|
+
onMessage: (channel: string, handler: (payload: unknown) => void) => {
|
|
68
|
+
dispose: () => void;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Pin (`{ fixed }`) or unpin (`'auto'`) the toolbar strip height. `'auto'`
|
|
72
|
+
* (default) lets the in-page height advertiser drive the placeholder.
|
|
73
|
+
*/
|
|
74
|
+
setHeightMode: (mode: 'auto' | {
|
|
75
|
+
fixed: number;
|
|
76
|
+
}) => void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The audited workspace surface: project list membership, session lifecycle,
|
|
80
|
+
* and minimal session state. Thumbnails / per-project settings / providers
|
|
81
|
+
* stay internal.
|
|
82
|
+
*/
|
|
83
|
+
export interface MiniappWorkspace {
|
|
84
|
+
/** True while a project session is open. */
|
|
85
|
+
hasActiveSession: () => boolean;
|
|
86
|
+
/** Absolute path of the open project, or '' when none. */
|
|
87
|
+
getProjectPath: () => string;
|
|
88
|
+
/**
|
|
89
|
+
* Open (compile + start) a project session. WRITABLE BY CONTRACT: hosts may
|
|
90
|
+
* reassign this member to wrap it (e.g. a permission gate) — every internal
|
|
91
|
+
* caller routes through the live property, so the wrapper always intercepts.
|
|
92
|
+
*/
|
|
93
|
+
openProject: (projectPath: string) => Promise<{
|
|
94
|
+
success: boolean;
|
|
95
|
+
error?: string;
|
|
96
|
+
}>;
|
|
97
|
+
/** Tear down the active session (no-op when none). */
|
|
98
|
+
closeProject: () => Promise<void>;
|
|
99
|
+
/** True when the directory is already in the project list. */
|
|
100
|
+
hasProject: (dirPath: string) => Promise<boolean>;
|
|
101
|
+
/** Add a directory to the project list. */
|
|
102
|
+
addProject: (dirPath: string) => Promise<unknown>;
|
|
103
|
+
/**
|
|
104
|
+
* Minimal live-session DTO, or null when no session. Deliberately excludes
|
|
105
|
+
* the session's own `close` — hosts end sessions via `closeProject`, never
|
|
106
|
+
* behind the workspace's back.
|
|
107
|
+
*/
|
|
108
|
+
getSession: () => {
|
|
109
|
+
appInfo: unknown;
|
|
110
|
+
} | null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The stable miniapp-kernel surface a downstream host (qdmp) consumes.
|
|
114
|
+
* Compiler-enforced and versionable: widening it back toward internal
|
|
115
|
+
* plumbing is a deliberate semver decision, not an accident of projection.
|
|
116
|
+
*/
|
|
117
|
+
export interface MiniappRuntime {
|
|
118
|
+
/** Absolute path to the devtools renderer dist directory. */
|
|
119
|
+
rendererDir: string;
|
|
120
|
+
/** View layer — only the host-owned toolbar control is public. */
|
|
121
|
+
views: {
|
|
122
|
+
readonly hostToolbar: MiniappHostToolbar;
|
|
123
|
+
};
|
|
124
|
+
/** Project + session workspace (see {@link MiniappWorkspace}). */
|
|
125
|
+
workspace: MiniappWorkspace;
|
|
126
|
+
/** Main → renderer notifier — only the compile-status broadcast is public. */
|
|
127
|
+
notify: {
|
|
128
|
+
projectStatus: (payload: MiniappProjectStatusPayload) => void;
|
|
129
|
+
};
|
|
130
|
+
/** Lifecycle sink: hosts register their own teardown via `registry.add`. */
|
|
131
|
+
registry: {
|
|
132
|
+
add: (dispose: () => void) => unknown;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Opaque window-service handle. Pass it through to framework helpers
|
|
136
|
+
* (e.g. `openSettingsWindow`); it exposes nothing to reach into.
|
|
137
|
+
*/
|
|
138
|
+
windows: object;
|
|
139
|
+
}
|
|
33
140
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
141
|
+
* View a full `WorkbenchContext` as its `MiniappRuntime` contract. Identity
|
|
142
|
+
* return: the result IS the live context, typed down to the contract, so host
|
|
143
|
+
* monkey-patches (e.g. `runtime.workspace.openProject = gated`) land on the
|
|
144
|
+
* real object. The `return ctx` is also the compile-time drift sentinel — if
|
|
145
|
+
* `WorkbenchContext` ever stops structurally satisfying the contract, THIS
|
|
146
|
+
* stops compiling.
|
|
37
147
|
*/
|
|
38
148
|
export declare function asMiniappRuntime(ctx: WorkbenchContext): MiniappRuntime;
|
|
39
149
|
//# sourceMappingURL=miniapp-runtime.d.ts.map
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* View a full `WorkbenchContext` as its `MiniappRuntime` contract. Identity
|
|
3
|
+
* return: the result IS the live context, typed down to the contract, so host
|
|
4
|
+
* monkey-patches (e.g. `runtime.workspace.openProject = gated`) land on the
|
|
5
|
+
* real object. The `return ctx` is also the compile-time drift sentinel — if
|
|
6
|
+
* `WorkbenchContext` ever stops structurally satisfying the contract, THIS
|
|
7
|
+
* stops compiling.
|
|
5
8
|
*/
|
|
6
9
|
export function asMiniappRuntime(ctx) {
|
|
7
10
|
return ctx;
|
|
8
11
|
}
|
|
9
|
-
/**
|
|
10
|
-
* Compile-time conformance guard: if `WorkbenchContext` ever stops structurally
|
|
11
|
-
* satisfying `MiniappRuntime` (a kernel field renamed / its type narrowed),
|
|
12
|
-
* THIS line fails `tsc`, catching the contract break at build time. The runtime
|
|
13
|
-
* value is unused.
|
|
14
|
-
*/
|
|
15
|
-
const _conformance = (ctx) => ctx;
|
|
16
|
-
void _conformance;
|
|
17
12
|
//# sourceMappingURL=miniapp-runtime.js.map
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
/** Layout constants (px) */
|
|
2
|
-
export declare const SPLITTER_W = 4;
|
|
3
|
-
/**
|
|
4
|
-
* X coordinate where the legacy right-side overlay starts.
|
|
5
|
-
*/
|
|
6
|
-
export declare function getRightX(simWidth: number): number;
|
|
7
1
|
export interface Bounds {
|
|
8
2
|
x: number;
|
|
9
3
|
y: number;
|
|
10
4
|
width: number;
|
|
11
5
|
height: number;
|
|
12
6
|
}
|
|
13
|
-
export declare function computeRightPanelBounds(contentWidth: number, contentHeight: number, simWidth: number, headerHeight: number): Bounds;
|
|
14
|
-
/**
|
|
15
|
-
* Compute bounds for DevTools view (same as right panel, overlays it).
|
|
16
|
-
*/
|
|
17
|
-
export declare function computeSimulatorBounds(contentWidth: number, contentHeight: number, simWidth: number, headerHeight: number): Bounds;
|
|
18
7
|
/**
|
|
19
8
|
* NATIVE-HOST ONLY. Translate the renderer-measured simulator panel REGION rect
|
|
20
9
|
* (CSS px from the main window content top-left — the flex:1 placeholder slot)
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
/** Layout constants (px) */
|
|
2
|
-
export const SPLITTER_W = 4;
|
|
3
|
-
/**
|
|
4
|
-
* X coordinate where the legacy right-side overlay starts.
|
|
5
|
-
*/
|
|
6
|
-
export function getRightX(simWidth) {
|
|
7
|
-
return simWidth + SPLITTER_W;
|
|
8
|
-
}
|
|
9
|
-
export function computeRightPanelBounds(contentWidth, contentHeight, simWidth, headerHeight) {
|
|
10
|
-
const x = getRightX(simWidth);
|
|
11
|
-
return {
|
|
12
|
-
x,
|
|
13
|
-
y: headerHeight,
|
|
14
|
-
width: Math.max(1, contentWidth - x),
|
|
15
|
-
height: Math.max(1, contentHeight - headerHeight),
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Compute bounds for DevTools view (same as right panel, overlays it).
|
|
20
|
-
*/
|
|
21
|
-
export function computeSimulatorBounds(contentWidth, contentHeight, simWidth, headerHeight) {
|
|
22
|
-
return computeRightPanelBounds(contentWidth, contentHeight, simWidth, headerHeight);
|
|
23
|
-
}
|
|
24
1
|
/**
|
|
25
2
|
* NATIVE-HOST ONLY. Translate the renderer-measured simulator panel REGION rect
|
|
26
3
|
* (CSS px from the main window content top-left — the flex:1 placeholder slot)
|
|
@@ -45,16 +45,10 @@ export interface RendererNotifier {
|
|
|
45
45
|
projectStatus(payload: ProjectStatusPayload): void;
|
|
46
46
|
/** Ask the main renderer to navigate back to its landing screen. */
|
|
47
47
|
windowNavigateBack(): void;
|
|
48
|
-
/** Tell the main renderer the embedded settings overlay has been closed. */
|
|
49
|
-
settingsClosed(): void;
|
|
50
|
-
/** Broadcast an updated compile config to the main renderer. */
|
|
51
|
-
settingsChanged(config: CompileConfig): void;
|
|
52
48
|
/** Tell the main renderer the compile popover has been closed. */
|
|
53
49
|
popoverClosed(): void;
|
|
54
50
|
/** Ask the main renderer to relaunch the simulator with a new config. */
|
|
55
51
|
popoverRelaunch(config: CompileConfig): void;
|
|
56
|
-
/** Tell the main renderer the toolbar actions list has changed. */
|
|
57
|
-
toolbarActionsChanged(): void;
|
|
58
52
|
/**
|
|
59
53
|
* Push the reserved host-toolbar height to the main renderer so its toolbar
|
|
60
54
|
* placeholder div resizes (closes the host-toolbar dynamic-height loop).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProjectChannel, WindowChannel, SettingsChannel, PopoverChannel,
|
|
1
|
+
import { ProjectChannel, WindowChannel, SettingsChannel, PopoverChannel, WorkbenchSettingsChannel, EditorChannel, ViewChannel, } from '../../../shared/ipc-channels.js';
|
|
2
2
|
/** Safely resolve a WebContents, skipping destroyed / missing targets. */
|
|
3
3
|
function liveWebContents(wc) {
|
|
4
4
|
if (!wc)
|
|
@@ -27,21 +27,12 @@ export function createRendererNotifier(ctx) {
|
|
|
27
27
|
windowNavigateBack() {
|
|
28
28
|
sendToMain(WindowChannel.NavigateBack);
|
|
29
29
|
},
|
|
30
|
-
settingsClosed() {
|
|
31
|
-
sendToMain(SettingsChannel.Closed);
|
|
32
|
-
},
|
|
33
|
-
settingsChanged(config) {
|
|
34
|
-
sendToMain(SettingsChannel.Changed, config);
|
|
35
|
-
},
|
|
36
30
|
popoverClosed() {
|
|
37
31
|
sendToMain(PopoverChannel.Closed);
|
|
38
32
|
},
|
|
39
33
|
popoverRelaunch(config) {
|
|
40
34
|
sendToMain(PopoverChannel.Relaunch, config);
|
|
41
35
|
},
|
|
42
|
-
toolbarActionsChanged() {
|
|
43
|
-
sendToMain(ToolbarChannel.ActionsChanged);
|
|
44
|
-
},
|
|
45
36
|
hostToolbarHeightChanged(height) {
|
|
46
37
|
sendToMain(ViewChannel.HostToolbarHeightChanged, height);
|
|
47
38
|
},
|
|
@@ -5,10 +5,11 @@ import { BrowserWindow } from 'electron';
|
|
|
5
5
|
* Design source: `packages/devtools/docs/prewarm-webview.md`. WIRED into
|
|
6
6
|
* native-host via `bridge-router.handleSpawn` (acquire) + `disposeAppSession`
|
|
7
7
|
* (release / releaseDestroyed), opt-in behind `DIMINA_PREWARM_POOL_SIZE`
|
|
8
|
-
* (default OFF).
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* (default OFF). Only the SERVICE-HOST window is pooled; the simulator content
|
|
9
|
+
* WebContentsView (`view-manager.attachNativeSimulator`) is created fresh per
|
|
10
|
+
* attach. (The historical `<webview>`-tag default arch was never poolable —
|
|
11
|
+
* Electron can't reparent a pre-warmed WebContents into a `<webview>`; doc §5
|
|
12
|
+
* Phase 4 — and that route has since been deleted outright.)
|
|
12
13
|
*
|
|
13
14
|
* Lifecycle of a pool entry:
|
|
14
15
|
* warming — BrowserWindow constructed, page loading
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gated narrow channel between the main process and the host-toolbar
|
|
3
|
+
* WebContentsView's page, over a per-load transferred MessagePort.
|
|
4
|
+
*
|
|
5
|
+
* Why a MessagePort and not plain IPC: the toolbar page is HOST-ARBITRARY
|
|
6
|
+
* content. A dedicated port pair gives it exactly one pipe whose main-side end
|
|
7
|
+
* lives in this module — the page never gains a generic `ipcRenderer` reach
|
|
8
|
+
* into the ~72 internal devtools channels, and main-side inbound traffic is
|
|
9
|
+
* validated at this single waist.
|
|
10
|
+
*
|
|
11
|
+
* Lifecycle (per-load handshake):
|
|
12
|
+
* - On every toolbar-wc `did-finish-load` main builds a fresh
|
|
13
|
+
* `MessageChannelMain`, transfers port2 to the new document via
|
|
14
|
+
* `wc.postMessage(ViewChannel.HostToolbarPort, null, [port2])`, keeps
|
|
15
|
+
* port1 and `start()`s it. The previous port1 (if any) is closed first —
|
|
16
|
+
* its document is gone.
|
|
17
|
+
* - `onMessage` registrations are CONTROL-level (this module's registry), not
|
|
18
|
+
* per-port: they may be made before any view exists and survive page
|
|
19
|
+
* reloads / wc rebuilds, because each new handshake dispatches into the
|
|
20
|
+
* same registry.
|
|
21
|
+
* - `send` is gated and non-queueing: `false` means "not delivered, ever" —
|
|
22
|
+
* no toolbar view is conjured, nothing is buffered for a later handshake.
|
|
23
|
+
* - A port1 `'close'` event (the renderer end died without a re-handshake
|
|
24
|
+
* yet) drops the live-port reference so `send` reports `false` instead of
|
|
25
|
+
* posting into a dead pipe.
|
|
26
|
+
* - NAVIGATION INVALIDATES THE PORT. The port pair belongs to one DOCUMENT,
|
|
27
|
+
* so starting a navigation that replaces that document closes port1 and
|
|
28
|
+
* `send` returns `false` until the new document's `did-finish-load`
|
|
29
|
+
* handshake. Two paths:
|
|
30
|
+
* (a) host-initiated `hostToolbar.loadURL/loadFile` calls `invalidate()`
|
|
31
|
+
* synchronously AT INITIATION (view-manager does this before the
|
|
32
|
+
* `webContents.loadURL/loadFile` await), so a same-tick `send` can
|
|
33
|
+
* never report `true` for an envelope posted into the document the
|
|
34
|
+
* load is about to replace;
|
|
35
|
+
* (b) page-initiated navigation (location.href / reload) is caught by a
|
|
36
|
+
* `did-start-navigation` listener — guarded to the ACTIVE wc,
|
|
37
|
+
* main-frame, cross-document only. Same-document navigations
|
|
38
|
+
* (anchors, pushState, history) and subframe navigations do NOT
|
|
39
|
+
* invalidate: the document the port lives in survives those, and no
|
|
40
|
+
* main-frame `did-finish-load` would follow to ever restore the
|
|
41
|
+
* channel.
|
|
42
|
+
*
|
|
43
|
+
* Envelope both directions: `{ channel: string, payload: unknown }`. Inbound
|
|
44
|
+
* data that is not an object with a string `channel` is DROPPED without
|
|
45
|
+
* throwing (the counterpart is arbitrary host content).
|
|
46
|
+
*/
|
|
47
|
+
import type { WebContents } from 'electron';
|
|
48
|
+
/** Handle returned by `onMessage`; `dispose()` detaches (idempotent). */
|
|
49
|
+
export interface HostToolbarMessageSubscription {
|
|
50
|
+
dispose(): void;
|
|
51
|
+
}
|
|
52
|
+
export interface HostToolbarPortChannel {
|
|
53
|
+
/**
|
|
54
|
+
* Hook a freshly created toolbar webContents: registers the
|
|
55
|
+
* `did-finish-load` (per-load handshake) and `destroyed` (drop the live
|
|
56
|
+
* port) listeners via `wc.on(...)`. Call exactly once per wc, right after
|
|
57
|
+
* the view is created.
|
|
58
|
+
*/
|
|
59
|
+
attach(wc: WebContents): void;
|
|
60
|
+
/**
|
|
61
|
+
* Drop the live port NOW (close + clear): the document it belongs to is
|
|
62
|
+
* being replaced. Called by view-manager synchronously when the HOST
|
|
63
|
+
* initiates a `loadURL`/`loadFile` — the host-initiated half of the
|
|
64
|
+
* navigation-invalidates contract (the page-initiated half is the
|
|
65
|
+
* `did-start-navigation` listener `attach` installs). `send` returns false
|
|
66
|
+
* from this call until the next `did-finish-load` handshake. Idempotent.
|
|
67
|
+
*/
|
|
68
|
+
invalidate(): void;
|
|
69
|
+
/** Register a control-level inbound handler for `channel`. */
|
|
70
|
+
onMessage(channel: string, handler: (payload: unknown) => void): HostToolbarMessageSubscription;
|
|
71
|
+
/**
|
|
72
|
+
* Post `{ channel, payload }` to the toolbar page over the live port.
|
|
73
|
+
* Returns false (delivering NOTHING, creating NOTHING) when there is no
|
|
74
|
+
* live toolbar wc, the current load's handshake hasn't completed, or a
|
|
75
|
+
* document-replacing navigation is in flight (see `invalidate`).
|
|
76
|
+
*/
|
|
77
|
+
send(channel: string, payload: unknown): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Teardown (view-manager `disposeAll`): close the live port, sweep the
|
|
80
|
+
* handler registry, refuse further handshakes. Subsequent `send` returns
|
|
81
|
+
* false; late `dispose()` of an old subscription stays a no-op.
|
|
82
|
+
*/
|
|
83
|
+
dispose(): void;
|
|
84
|
+
}
|
|
85
|
+
export declare function createHostToolbarPortChannel(opts: {
|
|
86
|
+
/**
|
|
87
|
+
* Is `wc` still the manager's CURRENT live toolbar webContents? Guards a
|
|
88
|
+
* stale wc's late `did-finish-load` from hijacking the channel after a
|
|
89
|
+
* rebuild swapped the view out underneath it.
|
|
90
|
+
*/
|
|
91
|
+
isCurrent: (wc: WebContents) => boolean;
|
|
92
|
+
}): HostToolbarPortChannel;
|
|
93
|
+
//# sourceMappingURL=host-toolbar-port-channel.d.ts.map
|