@skillbuilder/miniapp-simulator 0.2.7 → 0.2.9

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.
Files changed (46) hide show
  1. package/README.md +18 -1
  2. package/dist/sw/miniapp-simulator-service-worker.js +725 -375
  3. package/dist/sw/miniapp-simulator-service-worker.min.js +2 -1
  4. package/docs/assets/road-king-controls.png +0 -0
  5. package/docs/desktop-gesture-design.redoc.xml +96 -0
  6. package/lib/client-CX13jDtT.mjs +1371 -0
  7. package/lib/{index-CqClPZVv.mjs → index-DwepISqo.mjs} +1 -1
  8. package/lib/index.js +4228 -2791
  9. package/lib/remote-client.js +2 -2
  10. package/lib/types/core/simulator.d.ts +242 -2
  11. package/lib/types/gesture/host-bus.d.ts +27 -2
  12. package/lib/types/gesture/input-scheduler.d.ts +29 -0
  13. package/lib/types/gesture/keyboard-panel-view.d.ts +16 -0
  14. package/lib/types/gesture/keyboard-panel.d.ts +54 -0
  15. package/lib/types/gesture/plugins/index.d.ts +11 -14
  16. package/lib/types/gesture/plugins/keyboard-touch.d.ts +4 -0
  17. package/lib/types/gesture/plugins/multi-touch-hint.d.ts +1 -9
  18. package/lib/types/gesture/plugins/multi-touch-switch.d.ts +1 -1
  19. package/lib/types/gesture/plugins/touch-emitter.d.ts +1 -9
  20. package/lib/types/gesture/plugins/wheel-pinch.d.ts +3 -0
  21. package/lib/types/gesture/plugins/wheel-scroll.d.ts +1 -1
  22. package/lib/types/gesture/touch-cursor.d.ts +4 -0
  23. package/lib/types/gesture/touch-sequence.d.ts +12 -0
  24. package/lib/types/gesture/types.d.ts +33 -9
  25. package/lib/types/host/shadow-host.d.ts +19 -4
  26. package/lib/types/inspector/host-inspector.d.ts +1 -1
  27. package/lib/types/offload/manifest.d.ts +12 -0
  28. package/lib/types/offload/resource-session.d.ts +33 -0
  29. package/lib/types/remote/audit-controller.d.ts +2 -0
  30. package/lib/types/remote/audit-leave-monitor.d.ts +2 -0
  31. package/lib/types/remote/client.d.ts +4 -0
  32. package/lib/types/remote/keyboard-panel-host.d.ts +19 -0
  33. package/lib/types/remote/protocol.d.ts +30 -2
  34. package/lib/types/remote/runtime-entry.d.ts +2 -1
  35. package/lib/types/remote/runtime.d.ts +1 -1
  36. package/lib/types/sw/protocol.d.ts +2 -1
  37. package/lib/types/sw/service-worker-host.d.ts +1 -0
  38. package/lib/types/sw/worker/mount-store.d.ts +7 -4
  39. package/lib/types/sw/worker/offloaded.d.ts +3 -0
  40. package/lib/types/types/options.d.ts +4 -0
  41. package/lib/types/types/renderer.d.ts +8 -0
  42. package/lib/types/utils/screen-coordinates.d.ts +31 -0
  43. package/lib/types/utils/stage-fit.d.ts +7 -1
  44. package/lib/workbench.js +1 -1
  45. package/package.json +2 -1
  46. package/lib/client-BjYHK9LR.mjs +0 -1220
@@ -7,11 +7,13 @@
7
7
  * #shadow-root(shadow=true 时)
8
8
  * <style> base reset </style>
9
9
  * bounds(.dms-bounds,stageFit 的可用区域 / 默认 bounds)
10
- * stage(.dms-stage,渲染器实际挂载点,等价于旧的 container)
10
+ * stage(.dms-stage,缩放与旋转后的占位)
11
+ * device(实际设备,包含手机壳与完整内容)
11
12
  *
12
13
  * shadow=false 时不创建 shadow root,bounds/stage 直接挂在 host 的 light DOM 下,
13
14
  * 仅依赖内联样式(手机壳 / 内容层 / 手柄本身就是内联样式,自定义元素自带 :host 样式)。
14
15
  */
16
+ import type { ScreenRotationDirection } from "../utils/screen-coordinates";
15
17
  /** 挂载目标:CSS 选择器字符串或 HTMLElement */
16
18
  export type MiniAppMountTarget = string | HTMLElement;
17
19
  export interface CreateShadowHostOptions {
@@ -27,20 +29,33 @@ export interface MiniAppShadowHost {
27
29
  shadowRoot: ShadowRoot | null;
28
30
  /** stageFit 的默认可用区域(bounds) */
29
31
  bounds: HTMLElement;
30
- /** 渲染器实际挂载点(等价于旧 container) */
32
+ /** stageFit 缩放的设备占位,旋转时交换宽高 */
31
33
  stage: HTMLElement;
34
+ /** 渲染器实际挂载点,逻辑宽高不随屏幕旋转改变 */
35
+ device: HTMLElement;
32
36
  /** 宿主侧 overlay(如 toast)应挂载到的根:shadowRoot 或 host */
33
37
  overlayRoot: ShadowRoot | HTMLElement;
34
38
  /**
35
- * 与设备画布并排的侧栏槽位(评测面板等)。
39
+ * 评测面板等内容的独立槽位:竖直摆放时在设备右侧,横向摆放时在设备下方。
36
40
  *
37
41
  * 默认宽度为 0 且不渲染,只有调用 setSidePanelWidth 打开后才占位。
38
42
  * 走分栏而非浮层:浮层会直接盖住设备,而审核页把挂载点限制成手机尺寸,
39
43
  * 盖住后审核员既看不到小工具也点不到它。
40
44
  */
41
45
  sidePanel: HTMLElement;
42
- /** 设置侧栏最小/最大宽度;传 0 收起。bounds 自动让出对应宽度。 */
46
+ /** 设置竖直摆放时侧栏最小/最大宽度;传 0 收起。bounds 自动让出面板空间。 */
43
47
  setSidePanelWidth(width: number, maxWidth?: number): void;
48
+ /** 同一宿主内,整台手机转过 90° 后可用于显示的区域。 */
49
+ getQuarterTurnBounds(bounds: HTMLElement): {
50
+ width: number;
51
+ height: number;
52
+ };
53
+ /** 桌面工具栏的空间只影响宿主布局。 */
54
+ setDesktopControls(enabled: boolean): void;
55
+ /** 整台设备每次按指定方向旋转 90°,四次回到原位,不改变 guest 逻辑尺寸。 */
56
+ rotateScreen(direction: ScreenRotationDirection): void;
57
+ /** 渲染器挂载或逻辑尺寸改变后同步设备占位。 */
58
+ syncDeviceLayout(): void;
44
59
  /** 销毁:移除创建的宿主元素 */
45
60
  destroy(): void;
46
61
  }
@@ -86,7 +86,7 @@ export declare class HostInspector {
86
86
  private selectionRect;
87
87
  /**
88
88
  * 宿主视口坐标 → iframe 内容元素。
89
- * 与手势模块 `readCursorAt` 同一套换算:用 offsetWidth/rect.width 修正设备缩放。
89
+ * 与手势模块共用坐标转换,修正设备缩放和旋转。
90
90
  * 同源不可访问(跨源 / webview)时返回 null 并降级告警一次。
91
91
  */
92
92
  private resolveElement;
@@ -0,0 +1,12 @@
1
+ export declare const RESOURCE_MANIFEST_PATH = "__xhs_offload__/resources.json";
2
+ export interface OffloadedResource {
3
+ fileId: string;
4
+ size: number;
5
+ sha256: string;
6
+ mimeType: string;
7
+ }
8
+ export interface ResourceManifest {
9
+ artifactId: string;
10
+ resources: Map<string, OffloadedResource>;
11
+ }
12
+ export declare function parseResourceManifest(bytes: ArrayBuffer | undefined): ResourceManifest;
@@ -0,0 +1,33 @@
1
+ import { BusinessLine } from "../business-line";
2
+ import type { MiniAppHostRequest } from "../types";
3
+ import type { ResourceManifest } from "./manifest";
4
+ export interface OffloadedResourceContext {
5
+ url: string;
6
+ params: Record<string, string>;
7
+ creatorId: string;
8
+ request: MiniAppHostRequest;
9
+ }
10
+ export declare function getOffloadedResourceRoute(businessLine: BusinessLine, { edith, appId, contentId }: {
11
+ edith: string;
12
+ appId: string;
13
+ contentId: string;
14
+ }): Pick<OffloadedResourceContext, "url" | "params"> | undefined;
15
+ /** 一个精简包的签名表。SW 只能按已登记的包内路径查询。 */
16
+ export declare class OffloadedResourceSession {
17
+ readonly manifest: ResourceManifest;
18
+ private readonly context;
19
+ private readonly onUnavailable;
20
+ private readonly lifetime;
21
+ private readonly addresses;
22
+ private readonly ids;
23
+ private pending?;
24
+ private retryAfter;
25
+ private refreshAfter;
26
+ private refreshCount;
27
+ constructor(manifest: ResourceManifest, context: OffloadedResourceContext, onUnavailable: (count: number) => void);
28
+ dispose(): void;
29
+ resolve(path: string, rejectedUrl?: string): Promise<string>;
30
+ prepare(): Promise<void>;
31
+ private unresolvedIds;
32
+ private exchange;
33
+ }
@@ -19,6 +19,8 @@ export interface AuditControllerDeps {
19
19
  /** Apollo 下发的评测策略原始值;未下发时为 undefined */
20
20
  getPolicy(): unknown;
21
21
  getInteractionRegions(): readonly HTMLElement[];
22
+ /** 外层键位面板属于审核操作区域,保护离开倒计时而不增加真实输入次数。 */
23
+ isExternalInteractionActive?: () => boolean;
22
24
  /** 与当前 Runtime release 绑定的独立插件地址。 */
23
25
  auditPluginUrl?: string;
24
26
  /** 把评测进度 / 报告以事件推给宿主 */
@@ -3,6 +3,8 @@ export declare function resolveAutoStopOnLeaveMs(value: unknown): number;
3
3
  /** 监听稳定的模拟器区域,不进入 guest DOM,也不把 iframe 内部切换当作离开。 */
4
4
  export declare function createAuditLeaveMonitor(options: {
5
5
  regions: readonly HTMLElement[];
6
+ /** 已验证宿主通道报告的外层面板悬停/焦点;不作为游戏输入证据。 */
7
+ isExternalInside?: () => boolean;
6
8
  delayMs: number;
7
9
  onCountdown(seconds: number | null): void;
8
10
  onTimeout(): void;
@@ -44,6 +44,8 @@ export interface RemoteMiniAppSimulator {
44
44
  load(): Promise<void>;
45
45
  loadZip(source: Blob | ArrayBuffer | Uint8Array, options?: {
46
46
  entry?: string;
47
+ offloaded?: boolean;
48
+ creatorId?: string;
47
49
  }): Promise<MiniAppLoadZipResult>;
48
50
  loadFiles(files: RemoteMethodArgumentMap["loadFiles"][0]["files"], options?: RemoteMethodArgumentMap["loadFiles"][0]["options"]): Promise<MiniAppLoadFilesResult>;
49
51
  loadApp(url: string, options?: RemoteMethodArgumentMap["loadApp"][1]): Promise<void>;
@@ -109,5 +111,7 @@ export interface RemoteMiniAppSimulator {
109
111
  destroy(reason?: string): void;
110
112
  }
111
113
  export declare function createRemoteMiniAppSimulator(input: RemoteMiniAppSimulatorOptions): RemoteMiniAppSimulator;
114
+ /** @internal 地址由当前 Runtime entry 经握手端口提供,仅在同一会话内使用。 */
115
+ export declare function resolveRuntimeModuleUrl(ready: RemoteSimulatorReadyMessage, runtimeDocumentUrl: URL): URL;
112
116
  /** @internal Exported for deterministic retry tests; not part of the package public entry. */
113
117
  export declare function resolveRuntimeUrl(serviceUrls: URL[], loadTiming: RemoteLoadTiming): Promise<URL>;
@@ -0,0 +1,19 @@
1
+ import type { KeyboardPanelHost, keyboardPanelCommandNeedsGameFocus } from "../gesture/keyboard-panel";
2
+ import type { createKeyboardPanelView } from "../gesture/keyboard-panel-view";
3
+ import type { RemoteKeyboardPanelCommandMessage, RemoteKeyboardPanelPresenceMessage, RemoteKeyboardPanelStateMessage } from "./protocol";
4
+ export type RemoteRuntimeModule = {
5
+ createKeyboardPanelView: typeof createKeyboardPanelView;
6
+ keyboardPanelCommandNeedsGameFocus: typeof keyboardPanelCommandNeedsGameFocus;
7
+ };
8
+ /** Runtime 每个 gesture controller 独立注册;触点和编辑状态始终留在 Runtime。 */
9
+ export declare function createRuntimeKeyboardPanelHost(port: MessagePort, sessionId: string): {
10
+ host: KeyboardPanelHost;
11
+ receive(message: RemoteKeyboardPanelCommandMessage | RemoteKeyboardPanelPresenceMessage): void;
12
+ isActive: () => boolean;
13
+ destroy(): void;
14
+ };
15
+ /** 浮窗挂在 Remote Client 页面,位置、拖动和焦点边界使用外层 viewport。 */
16
+ export declare function createClientKeyboardPanelHost(iframe: HTMLIFrameElement, send: (message: RemoteKeyboardPanelCommandMessage | RemoteKeyboardPanelPresenceMessage) => void, loadRuntimeModule: () => Promise<RemoteRuntimeModule>, onError: (error: unknown) => void): {
17
+ receive(message: RemoteKeyboardPanelStateMessage): void;
18
+ destroy(): void;
19
+ };
@@ -1,4 +1,5 @@
1
1
  import type { BusinessLine } from "../business-line";
2
+ import type { KeyboardPanelCommand, KeyboardPanelState } from "../gesture/keyboard-panel";
2
3
  import type { ManagedRequestChunk, ManagedRequestHeaders, ManagedRequestOptions, ManagedRequestResult } from "../runtime/request/request-types";
3
4
  import type { MiniAppContentMode, MiniAppFileMap, MiniAppHostApiRequest, MiniAppInspectorSelectionMode, MiniAppLoadFilesOptions, MiniAppLoadZipOptions, MiniAppRedirectOptions, MiniAppSecurityOptions, MiniAppSimulatorOptions, MiniAppSimulatorRoute, MiniAppViewport } from "../types";
4
5
  /**
@@ -14,6 +15,10 @@ export declare const REMOTE_INSPECTOR_PAUSE_RUNTIME_CAPABILITY = "inspectorPause
14
15
  * 版本不一致会让老 runtime 直接握手失败,而评测是可选能力,缺失只应降级。
15
16
  */
16
17
  export declare const REMOTE_AUDIT_CAPABILITY = "audit";
18
+ /** 当前会话支持加载带外移资源清单的精简包。 */
19
+ export declare const REMOTE_OFFLOADED_PACKAGE_CAPABILITY = "offloadedPackage";
20
+ /** Client 可在外层页面承载 Runtime 的键位编辑浮窗。 */
21
+ export declare const REMOTE_KEYBOARD_PANEL_CAPABILITY = "keyboardPanelPortal";
17
22
  export declare const REMOTE_SIMULATOR_CAPABILITIES: string[];
18
23
  export type RemoteSimulatorSerializableOptions = Omit<MiniAppSimulatorOptions, "mount" | "appId" | "renderer" | "serviceWorker" | "security" | "jsapi" | "hostApi" | "tracker" | "runtimeLimits" | "onEvent" | "onReady" | "onBeforeLoad" | "onLoad" | "onRenderDone" | "onError" | "onNavigation" | "onConsole" | "onNetwork" | "onDestroy" | "onRouterChange" | "onScreenShot"> & {
19
24
  appUrl?: string;
@@ -39,6 +44,7 @@ export interface RemoteSimulatorConnectMessage {
39
44
  hostApiStubs: Record<string, {
40
45
  toast: string;
41
46
  }>;
47
+ clientCapabilities?: string[];
42
48
  options: RemoteSimulatorSerializableOptions;
43
49
  }
44
50
  /** Mars 队列项提供的稳定业务标识;随评测点位进入 APM,不进入被测 guest。 */
@@ -60,6 +66,8 @@ export interface RemoteSimulatorReadyMessage {
60
66
  protocolVersion: number;
61
67
  runtimeVersion: string;
62
68
  capabilities: string[];
69
+ /** 当前 Runtime entry 自身的模块地址,供外层页面复用同一资源。 */
70
+ runtimeModuleUrl?: string;
63
71
  }
64
72
  export interface RemoteSimulatorRequestMessage {
65
73
  type: "request";
@@ -82,6 +90,23 @@ export interface RemoteSimulatorEventMessage {
82
90
  event: string;
83
91
  payload: unknown;
84
92
  }
93
+ export interface RemoteKeyboardPanelStateMessage {
94
+ type: "keyboard-panel-state";
95
+ controllerId: string;
96
+ revision: number;
97
+ /** null 显式销毁该控制器的浮窗;后续状态不能复活它。 */
98
+ state: KeyboardPanelState | null;
99
+ }
100
+ export interface RemoteKeyboardPanelCommandMessage {
101
+ type: "keyboard-panel-command";
102
+ controllerId: string;
103
+ command: KeyboardPanelCommand;
104
+ }
105
+ export interface RemoteKeyboardPanelPresenceMessage {
106
+ type: "keyboard-panel-presence";
107
+ controllerId: string;
108
+ active: boolean;
109
+ }
85
110
  /** Runtime 请求宿主执行不可序列化的 hostApi handler。 */
86
111
  export interface RemoteHostApiRequestMessage {
87
112
  type: "host-api-request";
@@ -132,11 +157,14 @@ export interface RemoteHostRequestEventMessage {
132
157
  export type RemoteSimulatorPortMessage = {
133
158
  type: "worker-visibility";
134
159
  visible: boolean;
135
- } | RemoteSimulatorReadyMessage | RemoteSimulatorRequestMessage | RemoteSimulatorResponseMessage | RemoteSimulatorEventMessage | RemoteHostApiRequestMessage | RemoteHostApiResponseMessage | RemoteHostRequestMessage | RemoteHostRequestResponseMessage | RemoteHostRequestAbortMessage | RemoteHostRequestEventMessage;
160
+ } | RemoteKeyboardPanelStateMessage | RemoteKeyboardPanelCommandMessage | RemoteKeyboardPanelPresenceMessage | RemoteSimulatorReadyMessage | RemoteSimulatorRequestMessage | RemoteSimulatorResponseMessage | RemoteSimulatorEventMessage | RemoteHostApiRequestMessage | RemoteHostApiResponseMessage | RemoteHostRequestMessage | RemoteHostRequestResponseMessage | RemoteHostRequestAbortMessage | RemoteHostRequestEventMessage;
136
161
  export type RemoteSimulatorMethod = "load" | "loadZip" | "loadFiles" | "loadApp" | "unload" | "reload" | "setViewport" | "switchContentMode" | "switchPhoneFrame" | "switchDevice" | "setTouchEmulation" | "permissionSheet.show" | "permissionSheet.hide" | "notePreview.update" | "notePreview.updateUser" | "notePreview.updateAppCard" | "widgetCover.update" | "router.redirectTo" | "router.getRoute" | "inspector.enable" | "inspector.disable" | "inspector.toggle" | "inspector.clear" | "inspector.setSelectionMode" | "inspector.getSelectionMode" | "inspector.getSceneTree" | "inspector.selectByRef" | "capture" | "screenShot" | "setAutoScreenShot" | "hostApi.sync" | "hostApi.emit" | "audit.start" | "audit.stop" | "audit.status" | "audit.report" | "audit.setPolicy" | "destroy";
137
162
  export interface RemoteLoadZipArgs {
138
163
  buffer: ArrayBuffer;
139
- options?: Omit<MiniAppLoadZipOptions, "jszip">;
164
+ options?: Omit<MiniAppLoadZipOptions, "jszip"> & {
165
+ offloaded?: boolean;
166
+ creatorId?: string;
167
+ };
140
168
  }
141
169
  export interface RemoteLoadFilesArgs {
142
170
  files: MiniAppFileMap;
@@ -1 +1,2 @@
1
- export {};
1
+ export { keyboardPanelCommandNeedsGameFocus } from "../gesture/keyboard-panel";
2
+ export { createKeyboardPanelView } from "../gesture/keyboard-panel-view";
@@ -13,4 +13,4 @@ export interface RemoteRuntimeConfig {
13
13
  /** 与本 Runtime release 绑定的独立评测插件;仅 Mars 审核会话动态加载。 */
14
14
  auditPluginUrl?: string;
15
15
  }
16
- export declare function startRemoteMiniAppSimulatorRuntime(): void;
16
+ export declare function startRemoteMiniAppSimulatorRuntime(runtimeModuleUrl: string): void;
@@ -1,5 +1,6 @@
1
1
  /** Runtime 与 Service Worker 随同一 release 发布,协议版本必须精确一致。 */
2
- export declare const SERVICE_WORKER_PROTOCOL_VERSION = 5;
2
+ export declare const SERVICE_WORKER_PROTOCOL_VERSION = 6;
3
+ export declare const SW_OFFLOADED_URL = "miniapp:offloaded-resource-url";
3
4
  /** 资源 SW 重启后,向持有包快照的可信宿主请求恢复 Worker 挂载。 */
4
5
  export declare const SW_WORKER_MOUNT_RECOVERY = "miniapp:restore-worker-mount";
5
6
  /** 当前 Service Worker 提供的文件系统操作。 */
@@ -8,6 +8,7 @@ import { type ServiceWorkerFileSystemArgs, type ServiceWorkerFileSystemOperation
8
8
  /** 是否具备启用 SW 模式的运行环境(API 可用 + 安全上下文)。 */
9
9
  export declare function isServiceWorkerHostSupported(): boolean;
10
10
  export interface ServiceWorkerMountInput {
11
+ offloaded?: import("../offload/resource-session").OffloadedResourceSession;
11
12
  worker?: import("../worker/adapters/package-policy").WorkerMountPolicy;
12
13
  id: string;
13
14
  /** 入口文件包内路径(如 `index.html`),用于生成虚拟 URL。 */
@@ -1,13 +1,15 @@
1
- /**
2
- * 挂载表 —— id → 已挂载小工具实例。多预览实例 / 多 iframe 共用一个 SW,按 id 前缀隔离。
3
- * 负责 MOUNT/UNMOUNT 的存储,以及请求路径 → 实例的两级归属查找(`/<id>/` 标记 + clientId 反查)。
4
- */
1
+ import type { OffloadedResource } from "../../offload/manifest";
5
2
  import type { WorkerMountPolicy } from "../../worker/adapters/package-policy";
6
3
  export interface MountedFile {
7
4
  bytes: ArrayBuffer;
8
5
  mime: string;
9
6
  }
10
7
  export interface MountedApp {
8
+ offloaded?: {
9
+ id: string;
10
+ resources: Map<string, OffloadedResource>;
11
+ lifetime: AbortController;
12
+ };
11
13
  worker?: WorkerMountPolicy;
12
14
  /** 以包内文件路径为键缓存原始字节及独立 CSP 响应。 */
13
15
  workerResponses: Map<string, Response>;
@@ -25,6 +27,7 @@ export interface MountedApp {
25
27
  }
26
28
  export declare const STORE: Map<string, MountedApp>;
27
29
  export interface MountInput {
30
+ offloaded?: Map<string, OffloadedResource>;
28
31
  worker?: WorkerMountPolicy;
29
32
  id: string;
30
33
  files: Record<string, ArrayBuffer>;
@@ -0,0 +1,3 @@
1
+ import type { OffloadedResource } from "../../offload/manifest";
2
+ import type { MountedApp } from "./mount-store";
3
+ export declare function serveOffloaded(app: MountedApp, path: string, resource: OffloadedResource, request: Request): Promise<Response>;
@@ -487,6 +487,9 @@ export interface MiniAppSimulatorOptions extends MiniAppLifecycleCallbacks {
487
487
  debug?: boolean;
488
488
  /** 开启鼠标→触摸事件模拟,使桌面端鼠标操作还原真机 touch 行为(显示小手光标与触点圆点) */
489
489
  touchEmulation?: boolean;
490
+ /** 桌面审核操作面板(区域键位映射与屏幕旋转),默认关闭;Mars Runtime 自动启用。
491
+ * 启用时默认开启 touchEmulation;显式关闭 touchEmulation 时面板一并关闭。 */
492
+ desktopControls?: boolean;
490
493
  /** Visual Inspector 运行时能力;游戏暂停代理默认关闭。 */
491
494
  visualInspector?: MiniAppVisualInspectorOptions;
492
495
  /** 在父级 bounds 内自适应缩放;默认开启,可传 `false` 关闭或 `{ resizeHandle: true }` 启用手动拖拽缩放 */
@@ -548,6 +551,7 @@ export interface NormalizedMiniAppSimulatorOptions extends Omit<MiniAppSimulator
548
551
  timeout: number;
549
552
  debug: boolean;
550
553
  touchEmulation: boolean;
554
+ desktopControls: boolean;
551
555
  visualInspector: NormalizedMiniAppVisualInspectorOptions;
552
556
  stageFit: false | NormalizedMiniAppStageFitOptions;
553
557
  jsapi: NormalizedMiniAppJsApiOptions;
@@ -1,3 +1,5 @@
1
+ import type { ScreenRotationDirection } from "../utils/screen-coordinates";
2
+ import type { KeyboardPanelHost } from "../gesture/keyboard-panel";
1
3
  import type { InjectionRegistry } from "../injection/registry";
2
4
  import type { NotePublishResult, NotePublishViewData } from "../native-ui/note-publish/view-data";
3
5
  import type { MiniAppPermissionKind, MiniAppPermissionSheetResult } from "../native-ui/permission-sheet/types";
@@ -99,6 +101,12 @@ export interface RendererAdapterContext {
99
101
  debug: boolean;
100
102
  /** 是否启用鼠标→触摸事件模拟 */
101
103
  touchEmulation?: boolean;
104
+ /** 显示桌面审核操作面板。 */
105
+ desktopControls?: boolean;
106
+ /** Remote Client 承载键位浮窗的内部通道。 */
107
+ keyboardPanelHost?: KeyboardPanelHost;
108
+ /** 整台设备 CSS 按指定方向旋转 90 度,保持 guest 逻辑视口尺寸。 */
109
+ rotateScreen?: (direction: ScreenRotationDirection) => void;
102
110
  /** jsapi 注入与 mock 配置 */
103
111
  jsapi: NormalizedMiniAppJsApiOptions;
104
112
  contentMode: MiniAppContentMode;
@@ -0,0 +1,31 @@
1
+ export type ScreenRotationDirection = "clockwise" | "counterclockwise";
2
+ export type ScreenRotation = 0 | -90 | -180 | -270;
3
+ /** 设备 CSS 旋转只改变显示方向,载体的 offset 尺寸始终属于 guest 逻辑视口。 */
4
+ export declare function getScreenRotation(element: Element): ScreenRotation;
5
+ /** host client 坐标 → guest / 元素局部 CSS 像素;保留屏幕外拖拽坐标。 */
6
+ export declare function hostToLocal(element: HTMLElement, hostX: number, hostY: number): {
7
+ x: number;
8
+ y: number;
9
+ };
10
+ /** guest / 元素局部 CSS 像素 → host client 坐标。 */
11
+ export declare function localToHost(element: HTMLElement, x: number, y: number): {
12
+ x: number;
13
+ y: number;
14
+ };
15
+ /** host 向量 → guest 向量;行/页单位传 false,只转换方向、不缩放。 */
16
+ export declare function hostVectorToLocal(element: HTMLElement, dx: number, dy: number, scaleToPixels?: boolean): {
17
+ x: number;
18
+ y: number;
19
+ };
20
+ /** 局部矩形在 host client 空间的轴对齐包围盒。 */
21
+ export declare function localRectToHost(element: HTMLElement, rect: {
22
+ x: number;
23
+ y: number;
24
+ width: number;
25
+ height: number;
26
+ }): {
27
+ x: number;
28
+ y: number;
29
+ width: number;
30
+ height: number;
31
+ };
@@ -3,4 +3,10 @@ import type { NormalizedMiniAppStageFitOptions } from "../types";
3
3
  * 在 bounds 内对 container 做自适应缩放(默认 100% 撑满;可选右上角拖拽调整 scaleMultiplier)。
4
4
  * 卸载时恢复挂载前的内联样式。
5
5
  */
6
- export declare function attachMiniAppStageFit(container: HTMLElement, config: NormalizedMiniAppStageFitOptions): () => void;
6
+ export declare function attachMiniAppStageFit(container: HTMLElement, config: NormalizedMiniAppStageFitOptions, rotation?: {
7
+ host: HTMLElement;
8
+ getQuarterTurnBounds(bounds: HTMLElement): {
9
+ width: number;
10
+ height: number;
11
+ };
12
+ }): () => void;
package/lib/workbench.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as Mn } from "./client-BjYHK9LR.mjs";
1
+ import { c as Mn } from "./client-CX13jDtT.mjs";
2
2
  function Sn(a, i) {
3
3
  const e = /* @__PURE__ */ new Map();
4
4
  let v = 0, l = !1, w, b, L, m, u;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillbuilder/miniapp-simulator",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Designable Miniapp Simulator - 技术栈无关的小应用 PC 预览与审核模拟器 SDK",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.js",
@@ -55,6 +55,7 @@
55
55
  "dependencies": {
56
56
  "@koa/router": "^15.7.0",
57
57
  "@koa/send": "^6.0.0",
58
+ "@noble/hashes": "1.8.0",
58
59
  "chokidar": "^4.0.3",
59
60
  "html-to-image": "^1.11.13",
60
61
  "jszip": "^3.10.1",