@skillbuilder/miniapp-simulator 0.0.0-stage → 0.2.0

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 (229) hide show
  1. package/README.md +263 -2
  2. package/assets/phones/Nexus-5X.png +0 -0
  3. package/assets/phones/iPhone-14ProMax.png +0 -0
  4. package/assets/rednote-preview/cover/homebar-1439.jpg +0 -0
  5. package/assets/rednote-preview/cover/homebar-1679.jpg +0 -0
  6. package/assets/rednote-preview/cover/homebar-1919.jpg +0 -0
  7. package/assets/rednote-preview/cover/homebar-2284.jpg +0 -0
  8. package/assets/rednote-preview/cover/homebar-2285.jpg +0 -0
  9. package/assets/rednote-preview/cover/like.png +0 -0
  10. package/assets/rednote-preview/cover/play.png +0 -0
  11. package/assets/rednote-preview/cover/topbar-1439.jpg +0 -0
  12. package/assets/rednote-preview/cover/topbar-1679.jpg +0 -0
  13. package/assets/rednote-preview/cover/topbar-1919.jpg +0 -0
  14. package/assets/rednote-preview/cover/topbar-2284.jpg +0 -0
  15. package/assets/rednote-preview/cover/topbar-2285.jpg +0 -0
  16. package/assets/workbench/index.html +77 -0
  17. package/dist/sw/miniapp-simulator-service-worker.js +971 -0
  18. package/dist/sw/miniapp-simulator-service-worker.min.js +1 -0
  19. package/docs/consumer-guide.md +143 -0
  20. package/docs/electron-review.md +21 -0
  21. package/docs/external-cli-workbench.md +195 -0
  22. package/docs/file-system-design.md +334 -0
  23. package/docs/host-external-api.md +235 -0
  24. package/docs/iframe-service-worker.md +190 -0
  25. package/docs/local-dev.md +106 -0
  26. package/docs/npm-integration-verification.md +35 -0
  27. package/docs/remote-architecture.md +404 -0
  28. package/docs/remote-load-observability.md +268 -0
  29. package/docs/remote-usage.md +371 -0
  30. package/docs/request-design.md +247 -0
  31. package/docs/sdk-usage.md +260 -0
  32. package/docs/server-playground-https-debugging.md +150 -0
  33. package/docs/storage-api-design.md +275 -0
  34. package/docs/tracker.md +339 -0
  35. package/docs/worker-runtime.md +62 -0
  36. package/lib/business-line-CMb3ehRn.mjs +15 -0
  37. package/lib/client-CO-UjIY3.mjs +775 -0
  38. package/lib/index-B5oixYXr.mjs +574 -0
  39. package/lib/index.js +10763 -0
  40. package/lib/preload/webview-preload.js +37 -0
  41. package/lib/remote-client.js +11 -0
  42. package/lib/types/business-line.d.ts +7 -0
  43. package/lib/types/capabilities/constants.d.ts +29 -0
  44. package/lib/types/capabilities/csp-snippet.d.ts +34 -0
  45. package/lib/types/capabilities/launch-options.d.ts +7 -0
  46. package/lib/types/capabilities/performance-policy.d.ts +5 -0
  47. package/lib/types/capabilities/security-head-snippet.d.ts +21 -0
  48. package/lib/types/capabilities/security.d.ts +25 -0
  49. package/lib/types/capabilities/style-snippet.d.ts +2 -0
  50. package/lib/types/core/controllers/game-playtest.d.ts +9 -0
  51. package/lib/types/core/controllers/gesture.d.ts +8 -0
  52. package/lib/types/core/controllers/host-api.d.ts +19 -0
  53. package/lib/types/core/controllers/index.d.ts +11 -0
  54. package/lib/types/core/controllers/inspector.d.ts +20 -0
  55. package/lib/types/core/controllers/note-preview.d.ts +9 -0
  56. package/lib/types/core/controllers/permission-sheet.d.ts +7 -0
  57. package/lib/types/core/controllers/widget-cover.d.ts +12 -0
  58. package/lib/types/core/lifecycle.d.ts +7 -0
  59. package/lib/types/core/options.d.ts +33 -0
  60. package/lib/types/core/simulator.d.ts +9 -0
  61. package/lib/types/errors.d.ts +11 -0
  62. package/lib/types/event-bus.d.ts +15 -0
  63. package/lib/types/gesture/host-bus.d.ts +113 -0
  64. package/lib/types/gesture/index.d.ts +27 -0
  65. package/lib/types/gesture/plugins/double-tap.d.ts +10 -0
  66. package/lib/types/gesture/plugins/index.d.ts +27 -0
  67. package/lib/types/gesture/plugins/long-press.d.ts +13 -0
  68. package/lib/types/gesture/plugins/multi-touch-hint.d.ts +11 -0
  69. package/lib/types/gesture/plugins/multi-touch-switch.d.ts +18 -0
  70. package/lib/types/gesture/plugins/selection-disabler.d.ts +11 -0
  71. package/lib/types/gesture/plugins/tap.d.ts +11 -0
  72. package/lib/types/gesture/plugins/touch-emitter.d.ts +11 -0
  73. package/lib/types/gesture/plugins/wheel-scroll.d.ts +11 -0
  74. package/lib/types/gesture/receiver-runtime.d.ts +10 -0
  75. package/lib/types/gesture/receiver-runtime.impl.d.ts +6 -0
  76. package/lib/types/gesture/touch-cursor.d.ts +78 -0
  77. package/lib/types/gesture/touch-dot.d.ts +12 -0
  78. package/lib/types/gesture/types.d.ts +206 -0
  79. package/lib/types/host/shadow-host.d.ts +40 -0
  80. package/lib/types/index.d.ts +56 -0
  81. package/lib/types/injection/guest-log-mark.d.ts +7 -0
  82. package/lib/types/injection/head-builder.d.ts +4 -0
  83. package/lib/types/injection/index.d.ts +19 -0
  84. package/lib/types/injection/modules/console-forward.d.ts +2 -0
  85. package/lib/types/injection/modules/gesture.d.ts +6 -0
  86. package/lib/types/injection/modules/inspector-guest-runtime.d.ts +5 -0
  87. package/lib/types/injection/modules/inspector-pause-runtime.d.ts +6 -0
  88. package/lib/types/injection/modules/inspector.d.ts +8 -0
  89. package/lib/types/injection/modules/jsapi-channel.d.ts +9 -0
  90. package/lib/types/injection/modules/jsapi.d.ts +22 -0
  91. package/lib/types/injection/modules/render-done.d.ts +2 -0
  92. package/lib/types/injection/modules/resource-guard.d.ts +7 -0
  93. package/lib/types/injection/modules/scroll-containment.d.ts +3 -0
  94. package/lib/types/injection/modules/security.d.ts +3 -0
  95. package/lib/types/injection/modules/widget-snapshot.d.ts +13 -0
  96. package/lib/types/injection/preload-builder.d.ts +41 -0
  97. package/lib/types/injection/registry.d.ts +20 -0
  98. package/lib/types/injection/types.d.ts +45 -0
  99. package/lib/types/inspector/host-inspector.d.ts +108 -0
  100. package/lib/types/inspector/index.d.ts +8 -0
  101. package/lib/types/inspector/selector.d.ts +18 -0
  102. package/lib/types/native-ui/devtools/CapabilitiesView.d.ts +18 -0
  103. package/lib/types/native-ui/devtools/DevtoolsPanel.d.ts +24 -0
  104. package/lib/types/native-ui/devtools/LogsView.d.ts +17 -0
  105. package/lib/types/native-ui/devtools/dom.d.ts +40 -0
  106. package/lib/types/native-ui/devtools/index.d.ts +19 -0
  107. package/lib/types/native-ui/devtools/log-entry.d.ts +8 -0
  108. package/lib/types/native-ui/devtools/shortcut.d.ts +12 -0
  109. package/lib/types/native-ui/devtools/tokens.d.ts +14 -0
  110. package/lib/types/native-ui/devtools/types.d.ts +51 -0
  111. package/lib/types/native-ui/index.d.ts +17 -0
  112. package/lib/types/native-ui/note-publish/defaults.d.ts +40 -0
  113. package/lib/types/native-ui/note-publish/index.d.ts +2 -0
  114. package/lib/types/native-ui/note-publish/miniapp-note-publish.d.ts +15 -0
  115. package/lib/types/native-ui/note-publish/note-publish-host.d.ts +15 -0
  116. package/lib/types/native-ui/note-publish/view-data.d.ts +21 -0
  117. package/lib/types/native-ui/permission-sheet/defaults.d.ts +12 -0
  118. package/lib/types/native-ui/permission-sheet/index.d.ts +4 -0
  119. package/lib/types/native-ui/permission-sheet/miniapp-permission-sheet.d.ts +19 -0
  120. package/lib/types/native-ui/permission-sheet/permission-sheet-host.d.ts +23 -0
  121. package/lib/types/native-ui/permission-sheet/types.d.ts +8 -0
  122. package/lib/types/native-ui/rednote-preview/chrome-tone.d.ts +44 -0
  123. package/lib/types/native-ui/rednote-preview/defaults.d.ts +30 -0
  124. package/lib/types/native-ui/rednote-preview/half-sheet-drag.d.ts +61 -0
  125. package/lib/types/native-ui/rednote-preview/index.d.ts +2 -0
  126. package/lib/types/native-ui/rednote-preview/register.d.ts +7 -0
  127. package/lib/types/native-ui/rednote-preview/styles.d.ts +4 -0
  128. package/lib/types/native-ui/rednote-preview/xhs-note-detail-shell.d.ts +70 -0
  129. package/lib/types/native-ui/rednote-preview/xhs-note-half-sheet.d.ts +100 -0
  130. package/lib/types/native-ui/rednote-preview/xhs-profile-shell.d.ts +31 -0
  131. package/lib/types/native-ui/toast/frame-toast-host.d.ts +18 -0
  132. package/lib/types/native-ui/toast/index.d.ts +19 -0
  133. package/lib/types/presets.d.ts +11 -0
  134. package/lib/types/remote/client.d.ts +89 -0
  135. package/lib/types/remote/jsapi-config.d.ts +9 -0
  136. package/lib/types/remote/load-timing.d.ts +46 -0
  137. package/lib/types/remote/protocol.d.ts +165 -0
  138. package/lib/types/remote/review-launch.d.ts +6 -0
  139. package/lib/types/remote/runtime-entry.d.ts +1 -0
  140. package/lib/types/remote/runtime.d.ts +14 -0
  141. package/lib/types/remote/simulator-prompt.d.ts +9 -0
  142. package/lib/types/remote/widget-snapshot-guest-runtime.d.ts +1 -0
  143. package/lib/types/remote-client.d.ts +5 -0
  144. package/lib/types/renderer/base.d.ts +8 -0
  145. package/lib/types/renderer/content-host/iframe-content-host.d.ts +84 -0
  146. package/lib/types/renderer/content-host/index.d.ts +3 -0
  147. package/lib/types/renderer/content-host/types.d.ts +89 -0
  148. package/lib/types/renderer/content-host/webview-content-host.d.ts +53 -0
  149. package/lib/types/renderer/iframe.d.ts +93 -0
  150. package/lib/types/renderer/index.d.ts +2 -0
  151. package/lib/types/renderer/rednote-shell.d.ts +73 -0
  152. package/lib/types/renderer/webview.d.ts +59 -0
  153. package/lib/types/runtime/context.d.ts +31 -0
  154. package/lib/types/runtime/jsapi-modules/context.d.ts +19 -0
  155. package/lib/types/runtime/jsapi-modules/filesystem.d.ts +19 -0
  156. package/lib/types/runtime/jsapi-modules/index.d.ts +9 -0
  157. package/lib/types/runtime/jsapi-modules/interaction.d.ts +4 -0
  158. package/lib/types/runtime/jsapi-modules/location.d.ts +3 -0
  159. package/lib/types/runtime/jsapi-modules/media.d.ts +13 -0
  160. package/lib/types/runtime/jsapi-modules/network.d.ts +3 -0
  161. package/lib/types/runtime/jsapi-modules/storage.d.ts +26 -0
  162. package/lib/types/runtime/jsapi-modules/system.d.ts +4 -0
  163. package/lib/types/runtime/jsapi-modules/types.d.ts +21 -0
  164. package/lib/types/runtime/jsapi-modules/window-info.d.ts +43 -0
  165. package/lib/types/runtime/request/host-request.d.ts +13 -0
  166. package/lib/types/runtime/request/request-manager-frame.d.ts +29 -0
  167. package/lib/types/runtime/request/request-runtime.d.ts +26 -0
  168. package/lib/types/runtime/request/request-types.d.ts +26 -0
  169. package/lib/types/runtime/request/sse-text-framer.d.ts +16 -0
  170. package/lib/types/seal-config.d.ts +134 -0
  171. package/lib/types/sw/index.d.ts +9 -0
  172. package/lib/types/sw/parse-raw.d.ts +34 -0
  173. package/lib/types/sw/protocol.d.ts +19 -0
  174. package/lib/types/sw/served-entry.d.ts +9 -0
  175. package/lib/types/sw/service-worker-content-host.d.ts +11 -0
  176. package/lib/types/sw/service-worker-host.d.ts +74 -0
  177. package/lib/types/sw/service-worker-renderer.d.ts +10 -0
  178. package/lib/types/sw/worker/fs-codec.d.ts +23 -0
  179. package/lib/types/sw/worker/fs-ops.d.ts +22 -0
  180. package/lib/types/sw/worker/fs-store.d.ts +29 -0
  181. package/lib/types/sw/worker/globals.d.ts +50 -0
  182. package/lib/types/sw/worker/main.d.ts +6 -0
  183. package/lib/types/sw/worker/mime.d.ts +2 -0
  184. package/lib/types/sw/worker/mount-store.d.ts +48 -0
  185. package/lib/types/sw/worker/paths.d.ts +4 -0
  186. package/lib/types/sw/worker/serve.d.ts +13 -0
  187. package/lib/types/tracker/constants.d.ts +14 -0
  188. package/lib/types/tracker/default-tracker.d.ts +19 -0
  189. package/lib/types/tracker/index.d.ts +70 -0
  190. package/lib/types/transport/bridge-protocol.d.ts +78 -0
  191. package/lib/types/transport/iframe-transport.d.ts +39 -0
  192. package/lib/types/transport/index.d.ts +14 -0
  193. package/lib/types/transport/jsapi-bridge-messages.d.ts +36 -0
  194. package/lib/types/transport/types.d.ts +48 -0
  195. package/lib/types/transport/webview-transport.d.ts +52 -0
  196. package/lib/types/types/events.d.ts +130 -0
  197. package/lib/types/types/index.d.ts +11 -0
  198. package/lib/types/types/inspector.d.ts +172 -0
  199. package/lib/types/types/jsapi.d.ts +18 -0
  200. package/lib/types/types/options.d.ts +851 -0
  201. package/lib/types/types/renderer.d.ts +145 -0
  202. package/lib/types/utils/ancestor-scroll.d.ts +11 -0
  203. package/lib/types/utils/error-svg.d.ts +12 -0
  204. package/lib/types/utils/frameless-shell.d.ts +114 -0
  205. package/lib/types/utils/miniapp-chrome-svg.d.ts +47 -0
  206. package/lib/types/utils/package-constants.d.ts +8 -0
  207. package/lib/types/utils/screenshot.d.ts +14 -0
  208. package/lib/types/utils/simulator-pc-guard.d.ts +10 -0
  209. package/lib/types/utils/stage-fit.d.ts +6 -0
  210. package/lib/types/utils/touch-emulate.d.ts +26 -0
  211. package/lib/types/utils/zip-entry.d.ts +13 -0
  212. package/lib/types/workbench/index.d.ts +63 -0
  213. package/lib/types/workbench/preview-transition.d.ts +8 -0
  214. package/lib/types/workbench/server/artifact.d.ts +8 -0
  215. package/lib/types/workbench/server/index.d.ts +19 -0
  216. package/lib/types/workbench/server/watch.d.ts +6 -0
  217. package/lib/types/workbench/view.d.ts +36 -0
  218. package/lib/types/worker/adapters/csp-policy.d.ts +7 -0
  219. package/lib/types/worker/adapters/host-lifecycle.d.ts +5 -0
  220. package/lib/types/worker/adapters/mount-recovery.d.ts +2 -0
  221. package/lib/types/worker/adapters/package-policy.d.ts +12 -0
  222. package/lib/types/worker/adapters/page-lifecycle.d.ts +1 -0
  223. package/lib/types/worker/adapters/protocol.d.ts +49 -0
  224. package/lib/types/worker/adapters/scripts.d.ts +2 -0
  225. package/lib/types/worker/adapters/service-worker.d.ts +2 -0
  226. package/lib/workbench-server.mjs +183 -0
  227. package/lib/workbench.js +1404 -0
  228. package/package.json +61 -4
  229. package/scripts/mock-cli-dev.mjs +52 -0
@@ -0,0 +1,190 @@
1
+ # 接入 iframe + Service Worker 渲染模式
2
+
3
+ `renderer: "iframe-service-worker"` 用 Service Worker 把解压后的小工具文件当成「同源虚拟服务器」,
4
+ 按真实路径(`/miniapp-simulator/<id>/index.html`)提供给 iframe,iframe 以真实 URL 直连。
5
+
6
+ 这是浏览器端(Web 运行时)的渲染模式:把解压后的小工具文件当同源虚拟服务器按真实路径直供。SW 直供的能力:
7
+
8
+ | 能力 | iframe + Service Worker |
9
+ | --- | --- |
10
+ | 资源提供方式 | 不改写,按真实同源路径直供 |
11
+ | 相对路径 / `<base>` | 原生可用 |
12
+ | ESM `import` / 动态 `import()` | 原生可用 |
13
+ | `fetch` 相对路径 / `import.meta.url` / `new Worker(...)` | 原生可用 |
14
+ | 运行环境 | 需安全上下文 + 自托管 SW 脚本 |
15
+
16
+ > 本模式仅用于浏览器;Electron 审核场景走 webview 渲染,不涉及。
17
+
18
+ ### Worker 与 CSP
19
+
20
+ Worker 由 CSP `worker-src` 管控(seal 运行时不再重复拦截,CSP 是唯一闸门),默认 `'self'`:
21
+ 同源的 `new Worker('./w.js')` 可用。
22
+
23
+ `worker-src` 一条指令同时管 `Worker` / `SharedWorker` / `ServiceWorker`,三者一起放开或一起收紧。
24
+ 远端 Runtime 通过 Apollo 的 `miniappSimulatorCspPolicies` 配置。需要收紧时添加策略:
25
+
26
+ ```json
27
+ [
28
+ {
29
+ "scope": {
30
+ "appIds": [],
31
+ "userIds": [],
32
+ "businessLines": ["creator"]
33
+ },
34
+ "strategy": {
35
+ "worker-src": "'none'"
36
+ }
37
+ }
38
+ ]
39
+ ```
40
+
41
+ 改动前请确认真机容器侧的 CSP 一致——否则模拟器能跑、真机报 `SecurityError`。
42
+
43
+ ---
44
+
45
+ ## 前置条件
46
+
47
+ 1. **安全上下文**:页面必须是 `https://` 或 `http://localhost`(`window.isSecureContext === true`),否则浏览器不允许注册 Service Worker。
48
+ 2. **同源自托管 SW 脚本**:SW 脚本必须由你自己托管在与宿主页 **同源的 http(s) 路径**上,不能跨域、不能用 `blob:` 注册。
49
+ 3. **入口在包根目录**:小工具包的入口 `index.html` 必须位于 zip / 文件表的**第一层目录**,放在子目录会报错。
50
+
51
+ 不满足条件(未配 `scriptUrl`、非安全上下文、注册/挂载失败)时,SDK **直接抛错**,由宿主通过 `error` 事件感知,见下文「错误暴露」。
52
+
53
+ ---
54
+
55
+ ## 接入三步
56
+
57
+ ### ① 托管 SW 脚本
58
+
59
+ npm 包已产出独立的、**自包含单文件** SW 脚本(ESM,无任何外部 import),位于 `dist/sw/`:
60
+
61
+ ```
62
+ # 未压缩
63
+ @skillbuilder/miniapp-simulator/dist/sw/miniapp-simulator-service-worker.js
64
+ # 压缩版
65
+ @skillbuilder/miniapp-simulator/dist/sw/miniapp-simulator-service-worker.min.js
66
+ ```
67
+
68
+ 把它复制 / 拷贝到你的静态资源目录,让它在一个**同源 http(s) URL** 上可访问,例如 `https://your-host.com/miniapp-sw.js`。
69
+
70
+ 注册时 SDK 使用 `{ type: "module" }`,所以脚本必须以 **JS module(`Content-Type: text/javascript`)** 提供。
71
+
72
+ ### ② 创建模拟器并开启该模式
73
+
74
+ ```ts
75
+ import { createMiniAppSimulator } from "@skillbuilder/miniapp-simulator";
76
+
77
+ const simulator = createMiniAppSimulator({
78
+ mount: "#preview",
79
+ renderer: "iframe-service-worker",
80
+ serviceWorker: {
81
+ // 必填:自托管的同源 SW 脚本 URL
82
+ scriptUrl: "/miniapp-sw.js",
83
+ // 可选:等待挂载 ACK 的超时(ms),超时抛错,默认 5000
84
+ mountTimeout: 5000,
85
+ // 可选:除自身离线包外,额外放行的请求源(CSP 白名单)
86
+ allowedOrigins: ["https://cdn.jsdelivr.net"],
87
+ },
88
+ onError: (e) => console.error(e.code, e.message),
89
+ });
90
+ ```
91
+
92
+ ### ③ 加载小工具内容
93
+
94
+ SW 模式下用 `loadZip`(压缩包)或 `loadFiles`(已解压文件表)喂入内容,
95
+ SDK 解析后把原始文件表挂载给 Service Worker,再让 iframe 直连同源虚拟 URL:
96
+
97
+ ```ts
98
+ // A. 压缩包(Blob / ArrayBuffer)。此路径需要 JSZip:
99
+ // 通过 { jszip } 传入,或在全局挂 window.JSZip
100
+ await simulator.loadZip(zipBlob, { jszip: JSZip });
101
+
102
+ // B. 已在宿主侧解压好的文件表(path -> 内容)。此路径不依赖 JSZip:
103
+ await simulator.loadFiles({
104
+ "index.html": "<!doctype html>...",
105
+ "app.js": "...",
106
+ "style.css": "...",
107
+ });
108
+ ```
109
+
110
+ > `loadZip` 因为输入还是压缩包,必须有 JSZip 才能解压;如果你在宿主侧已经解压成文件表,请走 `loadFiles`,它完全不依赖 JSZip。
111
+
112
+ ---
113
+
114
+ ## `serviceWorker` 配置项
115
+
116
+ | 字段 | 必填 | 默认 | 说明 |
117
+ | --- | --- | --- | --- |
118
+ | `scriptUrl` | 是 | — | 自托管的同源 SW 脚本 URL;不配则 `loadZip/loadFiles` 直接抛错 |
119
+ | `mountTimeout` | 否 | `5000` | 等待 SW 返回 MOUNT ACK 的超时(ms),超时抛错 |
120
+ | `allowedOrigins` | 否 | 仅 `'self'` | CSP 请求白名单,详见下文 |
121
+
122
+ > SW 作用域固定为 `/miniapp-simulator/`(不可配置)。宿主页不在该 scope 内,因此永远不会被 SW 控制。
123
+
124
+ ---
125
+
126
+ ## scope 与 `Service-Worker-Allowed`
127
+
128
+ SW 作用域固定为 `/miniapp-simulator/`。Service Worker 默认只能控制**不高于自身脚本路径**的范围,
129
+ 所以如果你的 SW 脚本路径覆盖不了 `/miniapp-simulator/`(例如脚本放在 `/assets/miniapp-sw.js`),
130
+ 需要在 **SW 脚本的响应头**里加:
131
+
132
+ ```
133
+ Service-Worker-Allowed: /miniapp-simulator/
134
+ ```
135
+
136
+ 最省事的做法是把脚本放在站点根(如 `/miniapp-sw.js`)——`/miniapp-simulator/` 天然在其作用域之下,无需该响应头。
137
+
138
+ ---
139
+
140
+ ## 网络白名单(CSP)
141
+
142
+ SW 在返回页面时会下发 `Content-Security-Policy` 响应头,约束小工具向外发起请求的目标源:
143
+
144
+ - **默认只放行 `'self'`**——即离线包自身所在的源。小工具对**同源**路径的请求,会被限制在它自己的包内:命中包内文件则正常返回,**未命中直接 404**(不会穿透读取宿主页的真实文件)。
145
+ - 需要访问外部接口 / CDN 时,把对应源加入 `allowedOrigins`,例如:
146
+
147
+ ```ts
148
+ serviceWorker: {
149
+ scriptUrl: "/miniapp-sw.js",
150
+ allowedOrigins: ["https://api.example.com", "https://cdn.jsdelivr.net"],
151
+ }
152
+ ```
153
+
154
+ 白名单同时作用于脚本、样式、图片、字体、连接(`connect-src`)、媒体等资源类别。
155
+
156
+ ### 内联脚本用 nonce 放行(对齐真机)
157
+
158
+ SW 模式下 `script-src` 每次挂载生成一个随机 `nonce`:SDK 注入到 `<head>` 的脚本、以及运行时注入的手势脚本都带该 `nonce`,因此正常执行。
159
+
160
+ 小工具**自身的内联脚本不会被打 nonce**,会被 CSP 拦截——这与真机一致,请把内联 `<script>` 与内联事件处理器(如 `onclick="..."`)改为外链脚本 + `addEventListener`。
161
+
162
+ ---
163
+
164
+ ## 错误暴露
165
+
166
+ 任意一步失败(未配 `scriptUrl` / 非安全上下文 / SW 注册失败 / 挂载超时 / 解压失败),
167
+ SDK **直接抛错**:`loadZip` / `loadFiles` 会 reject,
168
+ 渲染期错误也通过统一的 **`error` 事件**暴露给宿主:
169
+
170
+ ```ts
171
+ simulator.on("error", (e) => {
172
+ console.warn("SW 渲染失败:", e.code, e.message);
173
+ });
174
+ // 等价于 createMiniAppSimulator({ onError })
175
+
176
+ try {
177
+ await simulator.loadFiles(files);
178
+ } catch (err) {
179
+ console.error("加载失败", err);
180
+ }
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 约束小结
186
+
187
+ - 入口 `index.html` 必须在包**根目录**,放子目录会抛 `ZIP_NO_ENTRY` / `FILES_NO_ENTRY`。
188
+ - 仅浏览器安全上下文可用;非安全上下文直接抛错。
189
+ - SW 脚本必须**同源自托管**且以 JS module 提供,跨域 / `blob:` 不可用。
190
+ - 本模式仅用于浏览器预览;Electron 审核走 webview 渲染,不使用 SW。
@@ -0,0 +1,106 @@
1
+ # Designable Miniapp Simulator 本地开发
2
+
3
+ 需要联调 `miniapp-simulator-server`、HTTPS Service Worker 或 `/ai-chat` 时,请先阅读
4
+ [`Server Playground 本地 HTTPS 与 AI 联调`](./server-playground-https-debugging.md)。
5
+
6
+ ## 启动 playground
7
+
8
+ ```bash
9
+ pnpm --filter @skillbuilder/miniapp-simulator run playground
10
+ ```
11
+
12
+ `playground` 只启动本包;封印 IIFE 与 jsapi UMD 均为包内本地文件(见下)。
13
+
14
+ 默认会启动 Vite playground。打开页面后可以使用默认的 `demo-app.html`,也可以在输入框里填入其他小应用 URL。
15
+
16
+ ## 设备能力封印(本包自维护)
17
+
18
+ 封印 IIFE 以本地文件形式存放在本包内,注入时以 `?raw` 引入 —— 与 jsapi UMD 同款加载策略:
19
+
20
+ - **IIFE 文件**:`src/injection/modules/device-capabilities-seal.iife.min.js`(人工替换为最终产物)。
21
+ - **类型与枚举**:`src/seal-config.ts`(`MiniAppCapability` / `DEFAULT_ALLOW` / `SEAL_CONFIG_GLOBAL_KEY` 等,本包自维护)。
22
+ - **热更封印**:直接替换上文的 IIFE 文件内容即可,无需额外构建。
23
+
24
+ ### 浏览器兼容基线
25
+
26
+ 封印 IIFE 需规避 `Object.entries` / `Object.values` / `Array.prototype.includes` 等 Chrome 51+ 才有的 API,构建 IIFE 时用 vite `target: ['es2015','safari13']` 让 esbuild 自动降级 ES2016+ 语法。落地到三端:
27
+
28
+ - **iOS WKWebView**:iOS 13+(≈Safari 13.1+)
29
+ - **Android WebView**:Chrome 51+(覆盖 Android 5.0+ 已更新过 system WebView 的多数设备)
30
+ - **PC iframe**:现代浏览器,无下限要求
31
+
32
+ > 没把 `chrome49` 写进 target —— esbuild 会保守把 Chrome 49 视作不完整支持 ES2015,从而尝试把 `for-of` / 解构降级到 ES5(降级器不支持,构建会失败)。Chrome 49 实测已支持这些 ES2015 语法,所以选择 `'es2015'` 让 esbuild 不再触发降级。
33
+
34
+ ### 能力白名单配置(按业务灵活放开)
35
+
36
+ 封印行为由业务能力枚举 `MiniAppCapability` 配合白名单 `allow` 控制:未列出的全部封禁。
37
+
38
+ **默认行为**(不传 `sealAllow`):放行 `camera` / `microphone` / `photo-library`,与历史一致。
39
+
40
+ **SDK 入口**:
41
+
42
+ ```ts
43
+ import { createMiniAppSimulator, MiniAppCapability } from "@skillbuilder/miniapp-simulator";
44
+
45
+ createMiniAppSimulator({
46
+ mount: "#preview",
47
+ deviceCapabilities: {
48
+ sealAllow: [
49
+ MiniAppCapability.Camera,
50
+ MiniAppCapability.Microphone,
51
+ MiniAppCapability.PhotoLibrary,
52
+ // 明天放开定位时只需要加这一行:
53
+ // MiniAppCapability.Geolocation,
54
+ ],
55
+ },
56
+ });
57
+ // 入口由 loadApp / loadZip / loadFiles 加载
58
+ ```
59
+
60
+ **自定义 srcdoc 注入(仅 seal 段)**:模拟器 iframe 内部的 Permissions-Policy / CSP / UI 限制由包内私有逻辑组装,不对外导出。若业务自行拼 srcdoc,需要自己准备 config 段与 IIFE 段:
61
+
62
+ ```html
63
+ <!-- 先写 config,再写 IIFE;IIFE 全文取自 src/injection/modules/device-capabilities-seal.iife.min.js -->
64
+ <script>window.__MINI_APP_SEAL_CONFIG__={"allow":["camera","microphone","photo-library"]};</script>
65
+ <script>{seal IIFE}</script>
66
+ ```
67
+
68
+ ### 移动端集成(Android / iOS 复用同一份脚本)
69
+
70
+ 移动端集成要点:
71
+
72
+ - **配置注入必须在 seal IIFE 之前执行**——通过同名全局变量 `window.__MINI_APP_SEAL_CONFIG__ = { allow: [...] }`。
73
+ - iOS:注册两个 `WKUserScript`(顺序:config → seal),均 `atDocumentStart`、`forMainFrameOnly: true`。
74
+ - Android:用 `WebViewCompat.addDocumentStartJavaScript`(androidx.webkit 1.4+),同样先 config 后 seal。
75
+
76
+ 不传配置(即不写第 1 段脚本)等价于默认 `allow=[camera, microphone, photo-library]`。
77
+
78
+ > 注:`camera` / `microphone` / `photo-library` 不在 seal 直接封禁范畴(`getUserMedia` 与 `input[type=file]` 由宿主层 `iframe.allow` / `WKWebView` 权限控制),它们出现在 `allow` 中的语义是「告诉 seal 不要把对应 Permissions API 设为 denied」——保证 Permissions 状态与宿主真实权限一致。
79
+
80
+ ## 与 Smoke 联调:ESM 引用 `lib/`
81
+
82
+ `testsuits/miniapp-simulator-sdk-smoke` 通过 `file:` 依赖以 ESM `import` 引用模拟器包的 `lib/`。改模拟器(非封印)源码后重新构建 lib:
83
+
84
+ ```bash
85
+ pnpm --filter @skillbuilder/miniapp-simulator run build:npm
86
+ ```
87
+
88
+ 再在另一终端启动 smoke:`pnpm --filter miniapp-simulator-sdk-smoke run dev`。需要源码级热更时,直接用 `pnpm --filter @skillbuilder/miniapp-simulator run playground`(playground 别名到 `src/`)。
89
+
90
+ ## 常用命令
91
+
92
+ ```bash
93
+ pnpm --filter @skillbuilder/miniapp-simulator run typecheck
94
+ pnpm --filter @skillbuilder/miniapp-simulator run build
95
+ pnpm --filter @skillbuilder/miniapp-simulator run playground
96
+ ```
97
+
98
+ ## 本地 URL 白名单
99
+
100
+ 本地调试默认允许:
101
+
102
+ - `http://localhost`
103
+ - `http://127.0.0.1`
104
+ - `http://0.0.0.0`
105
+
106
+ 生产环境建议只允许 `https` 和明确配置的 CDN 白名单。
@@ -0,0 +1,35 @@
1
+ # npm 外部 CLI 集成验证
2
+
3
+ 验证日期:2026-10-21。对象:`@skillbuilder/miniapp-simulator@0.1.10` 本地候选 tarball,未执行 npm 发布。
4
+
5
+ ## 结论
6
+
7
+ **单包集成可行。**消费项目只直接安装本包,npm 自动安装公开运行依赖;不依赖 workspace link、仓库里的 `endpoints` 包或 Electron。
8
+ CLI 使用 `workbench/server` 的 Node 入口即可启动完整工作台,不需要自行打包 HTML、创建模拟器或托管 SW。
9
+
10
+ ## 已执行的验证
11
+
12
+ 构建与安装宿主为 macOS arm64、Node 22.23.2;消费端运行时分别验证 Node 20.20.2 和 Node 22.23.2。
13
+
14
+ | 检查 | 结果 |
15
+ | --- | --- |
16
+ | 真实 `pnpm pack`,打包前自动编译 Node / 浏览器入口、声明与 SW | 通过 |
17
+ | 仓库外空项目安装 tarball,依赖从 npm 官方源下载 | 通过;不是源码目录软链接 |
18
+ | `exports` 对应的 JS、类型和 HTML 文件完整 | 通过 |
19
+ | ESM CLI 启动服务、CommonJS CLI 动态导入 | Node 20 / 22 通过 |
20
+ | NodeNext 严格类型检查,不加载 DOM 或 Node 全局类型;浏览器 Bundler 类型检查 | 通过;`skipLibCheck: false` |
21
+ | 工作台 HTML、配置、文件清单、原始资源与 SDK chunks 的 HTTP 响应 | 通过 |
22
+ | 文件修改后 SSE 通知、最新文件读取、SIGTERM 退出清理 | 通过 |
23
+ | Mock CLI 帮助不启动服务、未开放参数拒绝 | 通过 |
24
+ | 安装后的 Mock CLI 在浏览器唤起真实 Remote Runtime,加载本地小工具并交互 | 通过;限本机当前网络 |
25
+
26
+ 以上为历史验证记录。复验时,在仓库外新建空项目安装目标 tarball 或已发布版本,检查导出、类型、本地服务及文件监听。用户参数、SDK 参数和接入示例见 [外部 CLI 接入契约](./external-cli-workbench.md)。
27
+
28
+ ## 外发前的剩余门禁
29
+
30
+ - **源与权限:**npm 官方源匿名查询该包返回 404;这不证明 scope 的归属或发布权限。确认目标源、scope 权限和版本后,再从目标源安装验收。
31
+ - **远程服务:**默认仍连接 Beta Simulator。需从实际外部网络验证 manifest、Runtime、Service Worker 的可达性、CORS 与访问策略;当前本机通过不能代替外网验收。
32
+ - **平台覆盖:**Windows、Linux、Safari 以及真实外部 CLI 尚未验收。CommonJS 同步 `require()` 不属于本期承诺入口,应使用动态导入。
33
+ - **外发审批:**本次是安装与运行兼容性验证,不替代依赖许可、敏感信息及文档外发审查。包内现有内部联调说明也需纳入审核范围。
34
+
35
+ 单包不代表无依赖或离线可用。Runtime / SW 仍由远程服务提供;本次没有发布 npm 或上传 CDN。