@skillbuilder/miniapp-simulator 0.0.0-stage → 0.2.1

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 (231) 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 +408 -0
  28. package/docs/remote-load-observability.md +268 -0
  29. package/docs/remote-usage.md +376 -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/client-BlQ9j4FW.mjs +775 -0
  37. package/lib/index-DI2oETZ_.mjs +574 -0
  38. package/lib/index.js +10831 -0
  39. package/lib/options-B34ipLmF.mjs +15 -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/phone-vibration.d.ts +10 -0
  123. package/lib/types/native-ui/rednote-preview/chrome-tone.d.ts +44 -0
  124. package/lib/types/native-ui/rednote-preview/defaults.d.ts +30 -0
  125. package/lib/types/native-ui/rednote-preview/half-sheet-drag.d.ts +61 -0
  126. package/lib/types/native-ui/rednote-preview/index.d.ts +2 -0
  127. package/lib/types/native-ui/rednote-preview/register.d.ts +7 -0
  128. package/lib/types/native-ui/rednote-preview/styles.d.ts +4 -0
  129. package/lib/types/native-ui/rednote-preview/xhs-note-detail-shell.d.ts +70 -0
  130. package/lib/types/native-ui/rednote-preview/xhs-note-half-sheet.d.ts +100 -0
  131. package/lib/types/native-ui/rednote-preview/xhs-profile-shell.d.ts +31 -0
  132. package/lib/types/native-ui/toast/frame-toast-host.d.ts +18 -0
  133. package/lib/types/native-ui/toast/index.d.ts +19 -0
  134. package/lib/types/presets.d.ts +11 -0
  135. package/lib/types/remote/client.d.ts +89 -0
  136. package/lib/types/remote/jsapi-config.d.ts +9 -0
  137. package/lib/types/remote/load-timing.d.ts +46 -0
  138. package/lib/types/remote/protocol.d.ts +165 -0
  139. package/lib/types/remote/review-launch.d.ts +6 -0
  140. package/lib/types/remote/runtime-entry.d.ts +1 -0
  141. package/lib/types/remote/runtime.d.ts +14 -0
  142. package/lib/types/remote/simulator-prompt.d.ts +9 -0
  143. package/lib/types/remote/widget-snapshot-guest-runtime.d.ts +1 -0
  144. package/lib/types/remote-client.d.ts +5 -0
  145. package/lib/types/renderer/base.d.ts +8 -0
  146. package/lib/types/renderer/content-host/iframe-content-host.d.ts +84 -0
  147. package/lib/types/renderer/content-host/index.d.ts +3 -0
  148. package/lib/types/renderer/content-host/types.d.ts +89 -0
  149. package/lib/types/renderer/content-host/webview-content-host.d.ts +53 -0
  150. package/lib/types/renderer/iframe.d.ts +93 -0
  151. package/lib/types/renderer/index.d.ts +2 -0
  152. package/lib/types/renderer/rednote-shell.d.ts +73 -0
  153. package/lib/types/renderer/webview.d.ts +59 -0
  154. package/lib/types/runtime/context.d.ts +31 -0
  155. package/lib/types/runtime/jsapi-alert.d.ts +3 -0
  156. package/lib/types/runtime/jsapi-modules/context.d.ts +21 -0
  157. package/lib/types/runtime/jsapi-modules/filesystem.d.ts +19 -0
  158. package/lib/types/runtime/jsapi-modules/index.d.ts +9 -0
  159. package/lib/types/runtime/jsapi-modules/interaction.d.ts +4 -0
  160. package/lib/types/runtime/jsapi-modules/location.d.ts +3 -0
  161. package/lib/types/runtime/jsapi-modules/media.d.ts +13 -0
  162. package/lib/types/runtime/jsapi-modules/network.d.ts +3 -0
  163. package/lib/types/runtime/jsapi-modules/storage.d.ts +26 -0
  164. package/lib/types/runtime/jsapi-modules/system.d.ts +4 -0
  165. package/lib/types/runtime/jsapi-modules/types.d.ts +21 -0
  166. package/lib/types/runtime/jsapi-modules/window-info.d.ts +43 -0
  167. package/lib/types/runtime/request/host-request.d.ts +13 -0
  168. package/lib/types/runtime/request/request-manager-frame.d.ts +29 -0
  169. package/lib/types/runtime/request/request-runtime.d.ts +26 -0
  170. package/lib/types/runtime/request/request-types.d.ts +26 -0
  171. package/lib/types/runtime/request/sse-text-framer.d.ts +16 -0
  172. package/lib/types/seal-config.d.ts +134 -0
  173. package/lib/types/sw/index.d.ts +9 -0
  174. package/lib/types/sw/parse-raw.d.ts +34 -0
  175. package/lib/types/sw/protocol.d.ts +19 -0
  176. package/lib/types/sw/served-entry.d.ts +9 -0
  177. package/lib/types/sw/service-worker-content-host.d.ts +11 -0
  178. package/lib/types/sw/service-worker-host.d.ts +74 -0
  179. package/lib/types/sw/service-worker-renderer.d.ts +10 -0
  180. package/lib/types/sw/worker/fs-codec.d.ts +23 -0
  181. package/lib/types/sw/worker/fs-ops.d.ts +22 -0
  182. package/lib/types/sw/worker/fs-store.d.ts +29 -0
  183. package/lib/types/sw/worker/globals.d.ts +50 -0
  184. package/lib/types/sw/worker/main.d.ts +6 -0
  185. package/lib/types/sw/worker/mime.d.ts +2 -0
  186. package/lib/types/sw/worker/mount-store.d.ts +48 -0
  187. package/lib/types/sw/worker/paths.d.ts +4 -0
  188. package/lib/types/sw/worker/serve.d.ts +13 -0
  189. package/lib/types/tracker/constants.d.ts +14 -0
  190. package/lib/types/tracker/default-tracker.d.ts +19 -0
  191. package/lib/types/tracker/index.d.ts +70 -0
  192. package/lib/types/transport/bridge-protocol.d.ts +78 -0
  193. package/lib/types/transport/iframe-transport.d.ts +39 -0
  194. package/lib/types/transport/index.d.ts +14 -0
  195. package/lib/types/transport/jsapi-bridge-messages.d.ts +36 -0
  196. package/lib/types/transport/types.d.ts +48 -0
  197. package/lib/types/transport/webview-transport.d.ts +52 -0
  198. package/lib/types/types/events.d.ts +130 -0
  199. package/lib/types/types/index.d.ts +11 -0
  200. package/lib/types/types/inspector.d.ts +172 -0
  201. package/lib/types/types/jsapi.d.ts +18 -0
  202. package/lib/types/types/options.d.ts +851 -0
  203. package/lib/types/types/renderer.d.ts +145 -0
  204. package/lib/types/utils/ancestor-scroll.d.ts +11 -0
  205. package/lib/types/utils/error-svg.d.ts +12 -0
  206. package/lib/types/utils/frameless-shell.d.ts +114 -0
  207. package/lib/types/utils/miniapp-chrome-svg.d.ts +47 -0
  208. package/lib/types/utils/package-constants.d.ts +8 -0
  209. package/lib/types/utils/screenshot.d.ts +14 -0
  210. package/lib/types/utils/simulator-pc-guard.d.ts +10 -0
  211. package/lib/types/utils/stage-fit.d.ts +6 -0
  212. package/lib/types/utils/touch-emulate.d.ts +26 -0
  213. package/lib/types/utils/zip-entry.d.ts +13 -0
  214. package/lib/types/workbench/index.d.ts +63 -0
  215. package/lib/types/workbench/preview-transition.d.ts +8 -0
  216. package/lib/types/workbench/server/artifact.d.ts +8 -0
  217. package/lib/types/workbench/server/index.d.ts +19 -0
  218. package/lib/types/workbench/server/watch.d.ts +6 -0
  219. package/lib/types/workbench/view.d.ts +36 -0
  220. package/lib/types/worker/adapters/csp-policy.d.ts +7 -0
  221. package/lib/types/worker/adapters/host-lifecycle.d.ts +5 -0
  222. package/lib/types/worker/adapters/mount-recovery.d.ts +2 -0
  223. package/lib/types/worker/adapters/package-policy.d.ts +12 -0
  224. package/lib/types/worker/adapters/page-lifecycle.d.ts +1 -0
  225. package/lib/types/worker/adapters/protocol.d.ts +49 -0
  226. package/lib/types/worker/adapters/scripts.d.ts +2 -0
  227. package/lib/types/worker/adapters/service-worker.d.ts +2 -0
  228. package/lib/workbench-server.mjs +183 -0
  229. package/lib/workbench.js +1404 -0
  230. package/package.json +61 -4
  231. package/scripts/mock-cli-dev.mjs +52 -0
@@ -0,0 +1,971 @@
1
+ const h = self, pe = "index.html", me = "default-src 'none'; script-src 'none'; connect-src 'none'; worker-src 'none'; child-src 'none'", ge = {
2
+ workerCsp: me
3
+ }, G = ge.workerCsp, ye = ["default-src", "script-src", "connect-src", "worker-src", "child-src"];
4
+ function Z(e) {
5
+ if (!e || typeof e != "object" || Array.isArray(e)) return;
6
+ const t = {};
7
+ for (const [n, r] of Object.entries(e)) {
8
+ if (!ye.includes(n) || typeof r != "string" || !r.trim() || /[;,]|[^\x20-\x7e]/u.test(r))
9
+ return;
10
+ t[n] = r.trim();
11
+ }
12
+ return Object.keys(t).length ? t : void 0;
13
+ }
14
+ function we(e) {
15
+ const t = Z(e);
16
+ return t ? G.split("; ").map((n) => {
17
+ const r = n.slice(0, n.indexOf(" "));
18
+ return t[r] === void 0 ? n : `${r} ${t[r]}`;
19
+ }).join("; ") : G;
20
+ }
21
+ const be = {
22
+ html: "text/html; charset=utf-8",
23
+ htm: "text/html; charset=utf-8",
24
+ js: "text/javascript; charset=utf-8",
25
+ mjs: "text/javascript; charset=utf-8",
26
+ cjs: "text/javascript; charset=utf-8",
27
+ css: "text/css; charset=utf-8",
28
+ json: "application/json; charset=utf-8",
29
+ xml: "application/xml; charset=utf-8",
30
+ txt: "text/plain; charset=utf-8",
31
+ csv: "text/csv; charset=utf-8",
32
+ svg: "image/svg+xml",
33
+ wasm: "application/wasm",
34
+ map: "application/json; charset=utf-8"
35
+ }, _e = {
36
+ png: "image/png",
37
+ jpg: "image/jpeg",
38
+ jpeg: "image/jpeg",
39
+ gif: "image/gif",
40
+ webp: "image/webp",
41
+ avif: "image/avif",
42
+ ico: "image/x-icon",
43
+ bmp: "image/bmp",
44
+ woff: "font/woff",
45
+ woff2: "font/woff2",
46
+ ttf: "font/ttf",
47
+ otf: "font/otf",
48
+ eot: "application/vnd.ms-fontobject",
49
+ mp4: "video/mp4",
50
+ webm: "video/webm",
51
+ ogg: "video/ogg",
52
+ mp3: "audio/mpeg",
53
+ wav: "audio/wav",
54
+ m4a: "audio/mp4"
55
+ };
56
+ function Re(e) {
57
+ const t = e.split(".").pop()?.toLowerCase() ?? "";
58
+ return be[t] ?? _e[t] ?? "application/octet-stream";
59
+ }
60
+ function b(e) {
61
+ try {
62
+ return decodeURIComponent(e);
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ function W(e) {
68
+ const t = [];
69
+ for (const n of e.replace(/\\/g, "/").split("/"))
70
+ if (!(n === "" || n === ".")) {
71
+ if (n === "..") return "";
72
+ t.push(n);
73
+ }
74
+ return t.join("/");
75
+ }
76
+ const g = /* @__PURE__ */ new Map(), Y = 16;
77
+ function ve(e) {
78
+ if (!g.has(e.id) && g.size >= Y) {
79
+ const r = new Error(`too many active simulator mounts (max ${Y})`);
80
+ throw r.code = "ERR_MOUNT_LIMIT", r;
81
+ }
82
+ const t = /* @__PURE__ */ new Map();
83
+ for (const [r, i] of Object.entries(e.files)) {
84
+ const s = W(r);
85
+ s && t.set(s, { bytes: i, mime: Re(s) });
86
+ }
87
+ let n;
88
+ if (e.worker) {
89
+ if (e.remoteBase || e.worker.sessionId !== e.id)
90
+ throw new TypeError("Invalid package Worker mount policy");
91
+ n = {
92
+ sessionId: e.id,
93
+ csp: Z(e.worker.csp)
94
+ };
95
+ }
96
+ return g.set(e.id, {
97
+ worker: n,
98
+ workerResponses: /* @__PURE__ */ new Map(),
99
+ files: t,
100
+ injectHead: e.injectHead,
101
+ csp: e.csp,
102
+ remoteBase: e.remoteBase ?? "",
103
+ fsScope: e.fsScope ?? "",
104
+ ownerClientId: e.ownerClientId ?? ""
105
+ }), t.size;
106
+ }
107
+ function xe(e) {
108
+ g.delete(e);
109
+ }
110
+ function Ee(e) {
111
+ let t = 0;
112
+ for (const [n, r] of g)
113
+ !r.ownerClientId || e.has(r.ownerClientId) || (g.delete(n), t += 1);
114
+ return t;
115
+ }
116
+ function P(e) {
117
+ let t;
118
+ try {
119
+ t = new URL(e).pathname;
120
+ } catch {
121
+ return null;
122
+ }
123
+ for (const [n, r] of g) {
124
+ const i = `/${n}/`, s = t.indexOf(i);
125
+ if (s === -1) continue;
126
+ let a = b(t.slice(s + i.length));
127
+ if (a === null) return null;
128
+ (a === "" || a.endsWith("/")) && (a += pe);
129
+ const o = W(a);
130
+ return o ? { app: r, filePath: o } : null;
131
+ }
132
+ return null;
133
+ }
134
+ function Q(e) {
135
+ let t;
136
+ try {
137
+ t = new URL(e).pathname;
138
+ } catch {
139
+ return null;
140
+ }
141
+ for (const [n, r] of g)
142
+ if (t.includes(`/${n}/`)) return r;
143
+ return null;
144
+ }
145
+ const Se = 5, Pe = "miniapp:restore-worker-mount", De = [
146
+ "fsWriteTempFile",
147
+ "fsSaveFile",
148
+ "fsWriteFile",
149
+ "fsAppendFile",
150
+ "fsReadFile",
151
+ "fsReadDir",
152
+ "fsStatFile",
153
+ "fsUnlink",
154
+ "fsMkdir",
155
+ "fsGetStorageInfo"
156
+ ], F = /* @__PURE__ */ new Map();
157
+ async function Ie(e, t) {
158
+ const n = new URL(h.registration.scope), r = new URL(e.url);
159
+ if (r.origin !== n.origin || !r.pathname.startsWith(n.pathname)) return;
160
+ const i = r.pathname.slice(n.pathname.length), s = i.indexOf("/");
161
+ if (s < 1) return;
162
+ const a = i.slice(0, s);
163
+ if (!/^[a-zA-Z0-9_-]{1,128}$/.test(a)) return;
164
+ const o = await h.clients.get(t);
165
+ if (!o) return;
166
+ const c = new URL(o.url);
167
+ if (c.origin !== n.origin || !c.pathname.startsWith(`${n.pathname}${a}/`))
168
+ return;
169
+ let u = F.get(a);
170
+ u || (u = Te(a, n.origin).finally(() => F.delete(a)), F.set(a, u)), await u;
171
+ }
172
+ async function Te(e, t) {
173
+ const n = (await h.clients.matchAll({ type: "window", includeUncontrolled: !0 })).filter(
174
+ (r) => new URL(r.url).origin === t
175
+ );
176
+ n.length && await new Promise((r) => {
177
+ const i = [];
178
+ let s = n.length, a = !1;
179
+ const o = () => {
180
+ if (!a) {
181
+ a = !0, clearTimeout(c);
182
+ for (const u of i) u.close();
183
+ r();
184
+ }
185
+ }, c = setTimeout(o, 5e3);
186
+ for (const u of n) {
187
+ const f = new MessageChannel();
188
+ i.push(f.port1), f.port1.onmessage = ({ data: d }) => {
189
+ (d?.ok === !0 || --s === 0) && o();
190
+ };
191
+ try {
192
+ u.postMessage({ type: Pe, id: e }, [f.port2]);
193
+ } catch {
194
+ f.port2.close(), --s === 0 && o();
195
+ }
196
+ }
197
+ });
198
+ }
199
+ async function ke(e, t) {
200
+ const n = () => new Response("Worker entry denied", {
201
+ status: 403,
202
+ headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store" }
203
+ });
204
+ if (e.method !== "GET" || e.destination !== "worker" || !t) return n();
205
+ let r = P(e.url);
206
+ if (!r)
207
+ try {
208
+ await Ie(e, t), r = P(e.url);
209
+ } catch {
210
+ return n();
211
+ }
212
+ if (!r?.app.worker) return n();
213
+ const { app: i, filePath: s } = r, a = i.worker, o = new URL(h.registration.scope), c = new URL(e.url);
214
+ if (c.origin !== o.origin || !c.pathname.startsWith(`${o.pathname}${a.sessionId}/`))
215
+ return n();
216
+ try {
217
+ const u = await h.clients.get(t);
218
+ if (!u || Q(u.url) !== i || P(e.url)?.app !== i)
219
+ return n();
220
+ const f = i.workerResponses.get(s);
221
+ if (f) return f.clone();
222
+ const d = i.files.get(s);
223
+ if (!d) return n();
224
+ const y = new Response(d.bytes, {
225
+ headers: {
226
+ "Content-Type": "text/javascript; charset=utf-8",
227
+ "Cache-Control": "no-store",
228
+ "X-Content-Type-Options": "nosniff",
229
+ "Content-Security-Policy": we(a.csp)
230
+ }
231
+ });
232
+ return i.workerResponses.set(s, y), y.clone();
233
+ } catch {
234
+ return n();
235
+ }
236
+ }
237
+ const Ce = {
238
+ "image/png": "png",
239
+ "image/jpeg": "jpg",
240
+ "image/webp": "webp",
241
+ "image/gif": "gif",
242
+ "video/mp4": "mp4",
243
+ "video/quicktime": "mov",
244
+ "video/webm": "webm"
245
+ };
246
+ function J(e) {
247
+ const t = new Uint8Array(e);
248
+ if (U(t, [137, 80, 78, 71, 13, 10, 26, 10]))
249
+ return "image/png";
250
+ if (U(t, [255, 216, 255])) return "image/jpeg";
251
+ if (x(t, 0, "GIF87a") || x(t, 0, "GIF89a")) return "image/gif";
252
+ if (x(t, 0, "RIFF") && x(t, 8, "WEBP")) return "image/webp";
253
+ if (x(t, 4, "ftyp"))
254
+ return ee(t, 8, 12) === "qt " ? "video/quicktime" : "video/mp4";
255
+ if (U(t, [26, 69, 223, 163])) return "video/webm";
256
+ }
257
+ function Me(e) {
258
+ if (typeof e != "string" || e.length === 0)
259
+ return { error: "data is required", code: "ERR_INVALID_ARGS" };
260
+ const t = /^data:([^;,]+);base64,(.*)$/s.exec(e);
261
+ if (!t)
262
+ return { error: "only base64 data: URI is accepted", code: "ERR_INVALID_ARGS" };
263
+ const n = t[1].toLowerCase(), r = Ce[n];
264
+ if (!r)
265
+ return { error: `unsupported mime "${n}"`, code: "ERR_UNSUPPORTED_MIME" };
266
+ let i;
267
+ try {
268
+ i = atob(t[2]);
269
+ } catch {
270
+ return { error: "invalid base64 data", code: "ERR_INVALID_ARGS" };
271
+ }
272
+ const s = new Uint8Array(i.length);
273
+ for (let a = 0; a < i.length; a++) s[a] = i.charCodeAt(a);
274
+ return { bytes: s.buffer, mime: n, ext: r };
275
+ }
276
+ function U(e, t) {
277
+ return t.every((n, r) => e[r] === n);
278
+ }
279
+ function x(e, t, n) {
280
+ return ee(e, t, t + n.length) === n;
281
+ }
282
+ function ee(e, t, n) {
283
+ if (e.length < n) return "";
284
+ let r = "";
285
+ for (let i = t; i < n; i++) r += String.fromCharCode(e[i]);
286
+ return r;
287
+ }
288
+ const Fe = "miniapp-simulator-fs", Ue = 1, p = "files";
289
+ let _ = null;
290
+ function R() {
291
+ return _ || (_ = new Promise((e, t) => {
292
+ const n = indexedDB.open(Fe, Ue);
293
+ n.onupgradeneeded = () => {
294
+ const r = n.result;
295
+ if (!r.objectStoreNames.contains(p)) {
296
+ const i = r.createObjectStore(p, { keyPath: ["scope", "path"] });
297
+ i.createIndex("by_scope", "scope", { unique: !1 }), i.createIndex("by_createdAt", "createdAt", { unique: !1 });
298
+ }
299
+ }, n.onsuccess = () => e(n.result), n.onerror = () => {
300
+ _ = null, t(n.error ?? new Error("indexedDB open failed"));
301
+ }, n.onblocked = () => {
302
+ _ = null, t(new Error("indexedDB open blocked"));
303
+ };
304
+ }), _);
305
+ }
306
+ function te(e) {
307
+ return new Promise((t, n) => {
308
+ e.onsuccess = () => t(e.result), e.onerror = () => n(e.error ?? new Error("indexedDB request failed"));
309
+ });
310
+ }
311
+ function T(e) {
312
+ return new Promise((t, n) => {
313
+ e.oncomplete = () => t(), e.onerror = () => n(e.error ?? new Error("indexedDB transaction failed")), e.onabort = () => n(e.error ?? new Error("indexedDB transaction aborted"));
314
+ });
315
+ }
316
+ function N(e, t, n, r, i) {
317
+ const s = Date.now();
318
+ return {
319
+ scope: e,
320
+ path: t,
321
+ mime: r,
322
+ bytes: new Blob([n], { type: r }),
323
+ isDir: i,
324
+ createdAt: s,
325
+ lastModified: s
326
+ };
327
+ }
328
+ async function ne(e, t, n, r = "application/octet-stream") {
329
+ const s = (await R()).transaction(p, "readwrite");
330
+ s.objectStore(p).put(N(e, t, n, r, !1)), await T(s);
331
+ }
332
+ async function A(e, t) {
333
+ const r = (await R()).transaction(p, "readwrite");
334
+ r.objectStore(p).put(N(e, t, new ArrayBuffer(0), "application/x-directory", !0)), await T(r);
335
+ }
336
+ async function S(e, t) {
337
+ const r = (await R()).transaction(p, "readonly").objectStore(p), i = await te(r.get([e, t]));
338
+ return i ? {
339
+ path: i.path,
340
+ bytes: await i.bytes.arrayBuffer(),
341
+ mime: i.mime,
342
+ isDir: i.isDir === !0,
343
+ lastModified: i.lastModified ?? i.createdAt ?? 0
344
+ } : null;
345
+ }
346
+ async function v(e) {
347
+ const t = await R();
348
+ return (await te(
349
+ t.transaction(p, "readonly").objectStore(p).index("by_scope").getAll(e)
350
+ )).map((r) => ({
351
+ path: r.path,
352
+ mime: r.mime,
353
+ size: r.isDir === !0 ? 0 : r.bytes.size,
354
+ isDir: r.isDir === !0,
355
+ lastModified: r.lastModified ?? r.createdAt ?? 0
356
+ }));
357
+ }
358
+ async function Ae(e, t) {
359
+ const r = (await R()).transaction(p, "readwrite");
360
+ r.objectStore(p).delete([e, t]), await T(r);
361
+ }
362
+ async function Le(e, t, n, r) {
363
+ const s = (await R()).transaction(p, "readwrite"), a = s.objectStore(p);
364
+ a.put(N(e, n, r.bytes, r.mime, !1)), a.delete([e, t]), await T(s);
365
+ }
366
+ function Oe(e, t, n) {
367
+ if (e.files.has(t)) return L(e, t);
368
+ if (e.remoteBase) {
369
+ const r = new URL(t, e.remoteBase);
370
+ return r.search = new URL(n.url).search, ie(r.href);
371
+ }
372
+ return L(e, t);
373
+ }
374
+ async function Be(e, t) {
375
+ try {
376
+ const n = await h.clients.get(e);
377
+ if (n) {
378
+ const r = Q(n.url);
379
+ if (r) {
380
+ const i = new URL(t.url), s = b(i.pathname), a = s === null ? "" : W(s);
381
+ if (a && r.files.has(a))
382
+ return L(r, a);
383
+ if (r.remoteBase) {
384
+ const o = new URL(i.pathname + i.search, new URL(r.remoteBase).origin);
385
+ return ie(o.href);
386
+ }
387
+ }
388
+ }
389
+ } catch {
390
+ }
391
+ return fetch(t);
392
+ }
393
+ function re(e, t) {
394
+ return new Response(e, {
395
+ status: 200,
396
+ headers: {
397
+ "Content-Type": t,
398
+ "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
399
+ Expires: "0",
400
+ Pragma: "no-cache",
401
+ "Content-Length": String(e.byteLength)
402
+ }
403
+ });
404
+ }
405
+ function L(e, t) {
406
+ const n = e.files.get(t);
407
+ if (!n)
408
+ return new Response(`Not Found: ${t}`, {
409
+ status: 404,
410
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
411
+ });
412
+ if (n.mime.startsWith("text/html")) {
413
+ const r = We(new TextDecoder("utf-8").decode(n.bytes), e.injectHead), i = {
414
+ "Content-Type": "text/html; charset=utf-8",
415
+ "Cache-Control": "no-store",
416
+ // 与 Runtime 文档取同一值:guest 与 Runtime 同 origin,agent cluster 归属按 origin
417
+ // 一次性确定,此处显式对齐,避免同 origin 内出现矛盾声明被浏览器忽略。
418
+ "Origin-Agent-Cluster": "?1"
419
+ };
420
+ return e.csp && (i["Content-Security-Policy"] = e.csp), new Response(r, { status: 200, headers: i });
421
+ }
422
+ return re(n.bytes, n.mime);
423
+ }
424
+ async function ie(e) {
425
+ try {
426
+ return await fetch(e, { method: "GET", credentials: "omit" });
427
+ } catch {
428
+ return new Response(`Bad Gateway: ${e}`, {
429
+ status: 502,
430
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
431
+ });
432
+ }
433
+ }
434
+ function We(e, t) {
435
+ if (!t) return e;
436
+ const n = /<head\b[^>]*>/i.exec(e);
437
+ if (n) {
438
+ const i = n.index + n[0].length;
439
+ return e.slice(0, i) + t + e.slice(i);
440
+ }
441
+ const r = /<html\b[^>]*>/i.exec(e);
442
+ if (r) {
443
+ const i = r.index + r[0].length;
444
+ return `${e.slice(0, i)}<head>${t}</head>${e.slice(i)}`;
445
+ }
446
+ return `<head>${t}</head>${e}`;
447
+ }
448
+ const se = 50 * 1024 * 1024, D = 2 * 1024 * 1024, O = 2 * 1024 * 1024, Ne = 200 * 1024 * 1024, je = 4, $e = 255, K = 1e3, j = /* @__PURE__ */ new Set(["tmp", "usr"]), k = /* @__PURE__ */ new Set(["usr"]), qe = /^[A-Za-z0-9._-]{1,64}$/, I = /* @__PURE__ */ new Map();
449
+ let H = Promise.resolve();
450
+ function C(e) {
451
+ const t = H.then(e, e);
452
+ return H = t.then(
453
+ () => {
454
+ },
455
+ () => {
456
+ }
457
+ ), t;
458
+ }
459
+ function ze(e) {
460
+ I.delete(e);
461
+ }
462
+ async function Ge(e) {
463
+ const t = (n) => ({
464
+ type: "FS_ACK",
465
+ op: e.op,
466
+ id: e.id,
467
+ reqId: e.reqId,
468
+ ...n
469
+ });
470
+ if (!g.has(e.id))
471
+ return t({ ok: !1, error: "simulator not ready", code: "ERR_NOT_MOUNTED" });
472
+ try {
473
+ const n = await Ye(e);
474
+ return t(n);
475
+ } catch {
476
+ return t({ ok: !1, code: 50101, error: "storage io error" });
477
+ }
478
+ }
479
+ async function Ye(e) {
480
+ const t = e.fsScope || e.id;
481
+ switch (e.op) {
482
+ case "fsWriteTempFile":
483
+ return Ke(t, e);
484
+ case "fsSaveFile":
485
+ return He(t, e);
486
+ case "fsWriteFile":
487
+ return V(t, e, !1);
488
+ case "fsAppendFile":
489
+ return V(t, e, !0);
490
+ case "fsReadFile":
491
+ return Ve(t, e);
492
+ case "fsReadDir":
493
+ return Xe(t, e);
494
+ case "fsStatFile":
495
+ return Ze(t, e);
496
+ case "fsUnlink":
497
+ return Qe(t, e);
498
+ case "fsMkdir":
499
+ return Je(t, e);
500
+ case "fsGetStorageInfo":
501
+ return et(t);
502
+ default:
503
+ return {
504
+ ok: !1,
505
+ error: `unsupported operation: ${e.op}`,
506
+ code: "ERR_UNSUPPORTED_OP"
507
+ };
508
+ }
509
+ }
510
+ async function Ke(e, t) {
511
+ const n = Me(t.data);
512
+ if ("error" in n) return { ok: !1, error: n.error, code: n.code };
513
+ const r = `tmp/${de()}.${n.ext}`;
514
+ return await ne(e, r, n.bytes, n.mime), { ok: !0, result: { path: r, url: he(e, r) } };
515
+ }
516
+ async function He(e, t) {
517
+ const n = m(t.tempFilePath, "tempFilePath");
518
+ if (n) return n;
519
+ if (t.filePath !== void 0 && t.filePath !== null) {
520
+ const s = m(t.filePath, "filePath");
521
+ if (s) return s;
522
+ }
523
+ const r = w(t.tempFilePath, e, /* @__PURE__ */ new Set(["tmp"]), !1);
524
+ if ("code" in r) return l(r);
525
+ const i = t.filePath === void 0 || t.filePath === null ? it(r.path) : w(t.filePath, e, k, !1);
526
+ return "code" in i ? l(i) : C(async () => {
527
+ const s = await S(e, r.path);
528
+ if (!s) return l({ code: 50202, message: "file not found; reason=not_found" });
529
+ if (s.isDir) return l({ code: 50205, message: "not a file" });
530
+ const a = await v(e), o = q(a);
531
+ if (o.has(i.path))
532
+ return l({ code: 50204, message: "file already exists" });
533
+ const c = ue(i.path, o);
534
+ if ("code" in c) return l(c);
535
+ const u = ae(t.id, a, s.bytes.byteLength, 0);
536
+ return u ? l(u) : (await le(e, c.missing), await Le(e, r.path, i.path, s), ce(t.id, s.bytes.byteLength), { ok: !0, result: { savedFilePath: he(e, i.path) } });
537
+ });
538
+ }
539
+ async function V(e, t, n) {
540
+ const r = m(t.filePath, "filePath");
541
+ if (r) return r;
542
+ const i = oe(t.data, "data", !0);
543
+ if (i) return i;
544
+ const s = m(t.encoding, "encoding");
545
+ if (s) return s;
546
+ const a = w(t.filePath, e, k, !1);
547
+ if ("code" in a) return l(a);
548
+ if (t.encoding !== "base64" && t.encoding !== "utf8")
549
+ return l({ code: 10001, message: "invalid parameter; reason=encoding_unsupported" });
550
+ const o = nt(t.data, t.encoding);
551
+ return "code" in o ? l(o) : o.bytes.byteLength > D ? l({
552
+ code: 50201,
553
+ message: "storage quota exceeded; reason=single_over_limit"
554
+ }) : C(async () => {
555
+ const c = await v(e), u = q(c), f = await S(e, a.path);
556
+ if (f?.isDir) return l({ code: 50205, message: "not a file" });
557
+ const d = ue(a.path, u);
558
+ if ("code" in d) return l(d);
559
+ const y = n ? 0 : f?.bytes.byteLength ?? 0, z = ae(
560
+ t.id,
561
+ c,
562
+ o.bytes.byteLength,
563
+ y
564
+ );
565
+ if (z) return l(z);
566
+ await le(e, d.missing);
567
+ let M = o.bytes;
568
+ return n && f && (M = st(f.bytes, o.bytes)), await ne(e, a.path, M, at(M, t.encoding)), ce(t.id, o.bytes.byteLength), { ok: !0, result: { writtenBytes: o.bytes.byteLength } };
569
+ });
570
+ }
571
+ async function Ve(e, t) {
572
+ const n = m(t.filePath, "filePath");
573
+ if (n) return n;
574
+ const r = m(t.encoding, "encoding");
575
+ if (r) return r;
576
+ const i = X(t.position, "position");
577
+ if (i) return i;
578
+ const s = X(t.length, "length");
579
+ if (s) return s;
580
+ const a = w(t.filePath, e, j, !1);
581
+ if ("code" in a) return l(a);
582
+ if (t.encoding !== "base64" && t.encoding !== "utf8")
583
+ return l({ code: 10001, message: "invalid parameter; reason=encoding_unsupported" });
584
+ const o = t.position === void 0 ? 0 : t.position, c = t.length === void 0 ? O : t.length;
585
+ if (!Number.isSafeInteger(o) || o < 0 || !Number.isSafeInteger(c) || c < 0 || c > O)
586
+ return l({ code: 10001, message: "invalid parameter; reason=range_invalid" });
587
+ const u = await S(e, a.path);
588
+ if (!u) return l({ code: 50202, message: "file not found" });
589
+ if (u.isDir) return l({ code: 50205, message: "not a file" });
590
+ const f = Math.min(u.bytes.byteLength, o + c), d = o >= u.bytes.byteLength ? new ArrayBuffer(0) : u.bytes.slice(o, f);
591
+ let y;
592
+ if (t.encoding === "base64")
593
+ y = ot(d);
594
+ else
595
+ try {
596
+ y = new TextDecoder("utf-8", { fatal: !0 }).decode(d);
597
+ } catch {
598
+ return l({ code: 10001, message: "invalid parameter; reason=decode_failed" });
599
+ }
600
+ return {
601
+ ok: !0,
602
+ result: {
603
+ data: y,
604
+ bytesRead: d.byteLength,
605
+ eof: o + d.byteLength >= u.bytes.byteLength
606
+ }
607
+ };
608
+ }
609
+ async function Xe(e, t) {
610
+ const n = m(t.dirPath, "dirPath");
611
+ if (n) return n;
612
+ const r = w(t.dirPath, e, j, !0);
613
+ if ("code" in r) return l(r);
614
+ const i = await v(e);
615
+ if (r.relativePath) {
616
+ const o = i.find((c) => c.path === r.path);
617
+ if (!o) return l({ code: 50202, message: "file not found" });
618
+ if (!o.isDir) return l({ code: 50206, message: "not a directory" });
619
+ }
620
+ const s = `${r.path}/`, a = i.filter((o) => {
621
+ if (!o.path.startsWith(s)) return !1;
622
+ const c = o.path.slice(s.length);
623
+ return c.length > 0 && !c.includes("/") && !E(o.path);
624
+ }).sort((o, c) => o.path.localeCompare(c.path));
625
+ return {
626
+ ok: !0,
627
+ result: {
628
+ files: a.slice(0, K).map((o) => ({
629
+ name: o.path.slice(s.length),
630
+ size: o.isDir ? 0 : o.size,
631
+ lastModified: o.lastModified,
632
+ isDir: o.isDir
633
+ })),
634
+ truncated: a.length > K
635
+ }
636
+ };
637
+ }
638
+ async function Ze(e, t) {
639
+ const n = m(t.filePath, "filePath");
640
+ if (n) return n;
641
+ const r = w(t.filePath, e, j, !1);
642
+ if ("code" in r) return l(r);
643
+ const i = (await v(e)).find((s) => s.path === r.path);
644
+ return i ? {
645
+ ok: !0,
646
+ result: {
647
+ size: i.isDir ? 0 : i.size,
648
+ lastModified: i.lastModified,
649
+ isDir: i.isDir
650
+ }
651
+ } : l({ code: 50202, message: "file not found" });
652
+ }
653
+ async function Qe(e, t) {
654
+ const n = m(t.filePath, "filePath");
655
+ if (n) return n;
656
+ const r = w(t.filePath, e, k, !1);
657
+ return "code" in r ? l(r) : C(async () => {
658
+ const i = await S(e, r.path);
659
+ return i ? i.isDir ? l({ code: 50205, message: "not a file" }) : (await Ae(e, r.path), { ok: !0, result: {} }) : l({ code: 50202, message: "file not found" });
660
+ });
661
+ }
662
+ async function Je(e, t) {
663
+ const n = m(t.dirPath, "dirPath");
664
+ if (n) return n;
665
+ if (t.recursive !== void 0 && typeof t.recursive != "boolean")
666
+ return $("recursive");
667
+ const r = w(t.dirPath, e, k, !1);
668
+ if ("code" in r) return l(r);
669
+ const i = t.recursive === !0;
670
+ return C(async () => {
671
+ const s = await v(e), a = q(s), o = a.get(r.path);
672
+ if (o)
673
+ return o.isDir ? i ? { ok: !0, result: {} } : l({ code: 50204, message: "file already exists" }) : l({ code: 50205, message: "not a file" });
674
+ const c = fe(r.path);
675
+ for (const u of c) {
676
+ const f = a.get(u);
677
+ if (f && !f.isDir)
678
+ return l({ code: 50205, message: "not a file" });
679
+ if (!f && !i)
680
+ return l({ code: 50202, message: "file not found" });
681
+ }
682
+ if (i)
683
+ for (const u of c)
684
+ a.has(u) || await A(e, u);
685
+ return await A(e, r.path), { ok: !0, result: {} };
686
+ });
687
+ }
688
+ async function et(e) {
689
+ const t = await v(e), n = t.filter(
690
+ (i) => !i.isDir && i.path.startsWith("usr/") && !E(i.path)
691
+ ), r = t.filter(
692
+ (i) => !i.isDir && i.path.startsWith("tmp/") && !E(i.path)
693
+ );
694
+ return {
695
+ ok: !0,
696
+ result: {
697
+ usedBytes: B(n),
698
+ limitBytes: se,
699
+ fileCount: n.length,
700
+ tmpUsedBytes: B(r),
701
+ writeChunkMaxBytes: D,
702
+ readChunkMaxBytes: O
703
+ }
704
+ };
705
+ }
706
+ function m(e, t) {
707
+ return oe(e, t, !1);
708
+ }
709
+ function oe(e, t, n) {
710
+ if (!(typeof e == "string" && (n || e.length > 0)))
711
+ return $(t);
712
+ }
713
+ function X(e, t) {
714
+ if (!(e === void 0 || typeof e == "number"))
715
+ return $(t);
716
+ }
717
+ function $(e) {
718
+ return { ok: !1, code: 10001, error: `invalid parameter; param=${e}` };
719
+ }
720
+ function l(e) {
721
+ return { ok: !1, code: e.code, error: e.message };
722
+ }
723
+ function w(e, t, n, r) {
724
+ const i = tt(e, t);
725
+ if (i === null)
726
+ return { code: 50203, message: "invalid path; reason=dir_not_allowed" };
727
+ if (i === "__DECODE_ERROR__")
728
+ return { code: 50203, message: "invalid path; reason=traversal" };
729
+ const s = i.indexOf("/"), o = (s === -1 ? i : i.slice(0, s)).toLowerCase(), c = s === -1 ? "" : i.slice(s + 1);
730
+ if (!n.has(o) || !r && c.length === 0)
731
+ return { code: 50203, message: "invalid path; reason=dir_not_allowed" };
732
+ if (i.includes("\0") || i.includes("\\") || c.split("/").includes(".."))
733
+ return { code: 50203, message: "invalid path; reason=traversal" };
734
+ if (new TextEncoder().encode(c).byteLength > $e)
735
+ return { code: 50203, message: "invalid path; reason=name_too_long" };
736
+ const u = c ? c.split("/") : [];
737
+ return u.length > je ? { code: 50203, message: "invalid path; reason=depth_exceeded" } : u.some((f) => f === "." || !qe.test(f)) ? { code: 50203, message: "invalid path; reason=name_invalid" } : u.some((f) => f.startsWith("__xhs")) ? { code: 50203, message: "invalid path; reason=reserved_name" } : {
738
+ dir: o,
739
+ relativePath: c,
740
+ path: c ? `${o}/${c}` : o
741
+ };
742
+ }
743
+ function tt(e, t) {
744
+ const n = b(e);
745
+ if (n === null) return "__DECODE_ERROR__";
746
+ const r = n.split(/[?#]/, 1)[0];
747
+ if (r.includes("\0") || r.includes("\\") || r.split("/").includes(".."))
748
+ return "__DECODE_ERROR__";
749
+ let i;
750
+ if (e.startsWith("xhsfile://"))
751
+ i = e.slice(10).split(/[?#]/, 1)[0];
752
+ else {
753
+ let a;
754
+ try {
755
+ a = new URL(e);
756
+ } catch {
757
+ return null;
758
+ }
759
+ if (a.protocol !== "http:" && a.protocol !== "https:") return null;
760
+ const o = "/_xhsfile_/", c = a.pathname.indexOf(o);
761
+ if (c === -1) return null;
762
+ const u = a.pathname.slice(c + o.length), f = u.indexOf("/");
763
+ if (f <= 0 || b(u.slice(0, f)) !== t) return null;
764
+ i = u.slice(f + 1);
765
+ }
766
+ const s = b(i);
767
+ return s === null ? "__DECODE_ERROR__" : s;
768
+ }
769
+ function nt(e, t) {
770
+ if (t === "utf8")
771
+ return e.length > D ? { code: 50201, message: "storage quota exceeded; reason=single_over_limit" } : { bytes: new TextEncoder().encode(e).buffer };
772
+ if (e.length > Math.ceil(D * 4 / 3) + 4)
773
+ return { code: 50201, message: "storage quota exceeded; reason=single_over_limit" };
774
+ if (!rt(e))
775
+ return { code: 10001, message: "invalid parameter; reason=decode_failed" };
776
+ try {
777
+ const n = atob(e), r = new Uint8Array(n.length);
778
+ for (let i = 0; i < n.length; i++) r[i] = n.charCodeAt(i);
779
+ return { bytes: r.buffer };
780
+ } catch {
781
+ return { code: 10001, message: "invalid parameter; reason=decode_failed" };
782
+ }
783
+ }
784
+ function rt(e) {
785
+ return e.length % 4 !== 0 ? !1 : /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e);
786
+ }
787
+ function ae(e, t, n, r) {
788
+ if ((I.get(e) ?? 0) + n > Ne)
789
+ return { code: 50201, message: "storage quota exceeded; reason=session_limit" };
790
+ if (B(
791
+ t.filter(
792
+ (s) => !s.isDir && s.path.startsWith("usr/") && !E(s.path)
793
+ )
794
+ ) - r + n > se)
795
+ return { code: 50201, message: "storage quota exceeded; reason=total_over_limit" };
796
+ }
797
+ function ce(e, t) {
798
+ I.set(e, (I.get(e) ?? 0) + t);
799
+ }
800
+ function q(e) {
801
+ return new Map(e.map((t) => [t.path, t]));
802
+ }
803
+ function ue(e, t) {
804
+ const n = [];
805
+ for (const r of fe(e)) {
806
+ const i = t.get(r);
807
+ if (i && !i.isDir) return { code: 50205, message: "not a file" };
808
+ i || n.push(r);
809
+ }
810
+ return { missing: n };
811
+ }
812
+ async function le(e, t) {
813
+ for (const n of t) await A(e, n);
814
+ }
815
+ function fe(e) {
816
+ const t = e.split("/"), n = [];
817
+ for (let r = 2; r < t.length; r++)
818
+ n.push(t.slice(0, r).join("/"));
819
+ return n;
820
+ }
821
+ function it(e) {
822
+ const t = e.slice(e.lastIndexOf("/") + 1), n = t.lastIndexOf("."), r = n > 0 ? t.slice(n) : "", i = `${de()}${r}`;
823
+ return { dir: "usr", relativePath: i, path: `usr/${i}` };
824
+ }
825
+ function st(e, t) {
826
+ const n = new Uint8Array(e.byteLength + t.byteLength);
827
+ return n.set(new Uint8Array(e), 0), n.set(new Uint8Array(t), e.byteLength), n.buffer;
828
+ }
829
+ function ot(e) {
830
+ const t = new Uint8Array(e), n = 32768;
831
+ let r = "";
832
+ for (let i = 0; i < t.length; i += n)
833
+ r += String.fromCharCode(...t.subarray(i, i + n));
834
+ return btoa(r);
835
+ }
836
+ function at(e, t) {
837
+ return J(e) ?? (t === "utf8" ? "text/plain; charset=utf-8" : "application/octet-stream");
838
+ }
839
+ function B(e) {
840
+ return e.reduce((t, n) => t + n.size, 0);
841
+ }
842
+ function E(e) {
843
+ return e.split("/").some((t) => t.startsWith("__xhs"));
844
+ }
845
+ function de() {
846
+ if (typeof crypto < "u" && typeof crypto.randomUUID == "function")
847
+ return crypto.randomUUID().replace(/-/g, "");
848
+ let e = "";
849
+ for (let t = 0; t < 32; t++) e += Math.floor(Math.random() * 16).toString(16);
850
+ return e;
851
+ }
852
+ function he(e, t) {
853
+ return `${h.registration.scope}_xhsfile_/${encodeURIComponent(e)}/${t}`;
854
+ }
855
+ function ct(e) {
856
+ let t;
857
+ try {
858
+ t = new URL(e).pathname;
859
+ } catch {
860
+ return null;
861
+ }
862
+ const n = "/_xhsfile_/", r = t.indexOf(n);
863
+ if (r === -1) return null;
864
+ const i = t.slice(r + n.length), s = i.indexOf("/");
865
+ if (s <= 0) return null;
866
+ const a = b(i.slice(0, s)), o = b(i.slice(s + 1));
867
+ return !a || !o || o.includes("\0") || o.includes("\\") || o.split("/").includes("..") ? null : { scope: a, path: o };
868
+ }
869
+ async function ut(e, t) {
870
+ try {
871
+ const n = await S(e, t);
872
+ if (n && !n.isDir && !E(t)) {
873
+ const r = J(n.bytes);
874
+ if (r) return re(n.bytes, r);
875
+ }
876
+ } catch {
877
+ }
878
+ return new Response("Not Found", {
879
+ status: 404,
880
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
881
+ });
882
+ }
883
+ h.addEventListener("install", () => {
884
+ h.skipWaiting();
885
+ });
886
+ h.addEventListener("activate", (e) => {
887
+ e.waitUntil(h.clients.claim());
888
+ });
889
+ h.addEventListener("message", (e) => {
890
+ const t = e.data;
891
+ if (!t || typeof t.type != "string") return;
892
+ const n = (r) => e.ports?.[0]?.postMessage(r);
893
+ if (t.type === "MOUNT") {
894
+ const r = lt(t, ft(e.source)).then(
895
+ (i) => n({
896
+ type: "MOUNT_ACK",
897
+ id: t.id,
898
+ ok: !0,
899
+ count: i,
900
+ swVersion: Se,
901
+ fsOps: De
902
+ }),
903
+ (i) => {
904
+ const s = i;
905
+ n({
906
+ type: "MOUNT_ACK",
907
+ id: t.id,
908
+ ok: !1,
909
+ error: s instanceof Error ? s.message : String(i),
910
+ code: s?.code
911
+ });
912
+ }
913
+ );
914
+ e.waitUntil?.(r);
915
+ return;
916
+ }
917
+ if (t.type === "FS") {
918
+ const r = t, i = Ge(r).then(
919
+ n,
920
+ (s) => (
921
+ // handleFsOp 内部已对已知错误 resolve 出准确 code;走到这里只可能是未预期的运行时异常,
922
+ // 用 ERR_UNKNOWN 如实反映(不要误标成 ERR_INVALID_ARGS 误导消费方分类)。
923
+ n({
924
+ type: "FS_ACK",
925
+ op: r.op,
926
+ id: r.id,
927
+ reqId: r.reqId,
928
+ ok: !1,
929
+ error: s instanceof Error ? s.message : String(s),
930
+ code: "ERR_UNKNOWN"
931
+ })
932
+ )
933
+ );
934
+ e.waitUntil?.(i);
935
+ return;
936
+ }
937
+ t.type === "UNMOUNT" && (ze(t.id), xe(t.id));
938
+ });
939
+ h.addEventListener("fetch", (e) => {
940
+ if (e.request.destination === "worker" || e.request.destination === "sharedworker") {
941
+ e.respondWith(ke(e.request, e.clientId));
942
+ return;
943
+ }
944
+ if (e.request.method !== "GET") return;
945
+ const t = ct(e.request.url);
946
+ if (t) {
947
+ e.respondWith(ut(t.scope, t.path));
948
+ return;
949
+ }
950
+ const n = P(e.request.url);
951
+ if (n) {
952
+ e.respondWith(Oe(n.app, n.filePath, e.request));
953
+ return;
954
+ }
955
+ const r = e.clientId || e.resultingClientId;
956
+ r && e.respondWith(Be(r, e.request));
957
+ });
958
+ async function lt(e, t) {
959
+ if (t)
960
+ try {
961
+ const n = await h.clients.matchAll({ type: "window", includeUncontrolled: !0 });
962
+ Ee(new Set(n.map((r) => r.id)));
963
+ } catch {
964
+ }
965
+ return ve({ ...e, ownerClientId: t });
966
+ }
967
+ function ft(e) {
968
+ if (!e || typeof e != "object" || !("id" in e)) return "";
969
+ const t = e.id;
970
+ return typeof t == "string" ? t : "";
971
+ }