@adep/web-container 0.2.2 → 0.2.4

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.
@@ -7,7 +7,7 @@
7
7
  * 2. 本地 `node_modules/<name>` 已有同版本 → 直接命中返回(重复安装幂等、零下载);
8
8
  * 3. 否则 `/tarball` 下载 `.tgz` 字节 → gzip 解压 + ustar 解包(`tar.ts`,零依赖手写);
9
9
  * 4. 读取包内 package.json 的 `dependencies`,按同一链路**递归**安装传递依赖
10
- * (深度上限 + 循环依赖硬错误);
10
+ * (深度上限 + `name@version` 去重;真实 npm 图允许成环,靠去重终止);
11
11
  * 5. **先暂存、后提交**:整棵依赖闭包全部抓取 + 解包成功后才一次性写入 VFS——
12
12
  * 任何一步失败(非白名单包、中继不可达、tarball 损坏)都不落一个字节的
13
13
  * `node_modules/`,杜绝「装了个半成品、import 时半可用」的状态。
@@ -31,8 +31,10 @@ export interface NpmClientOptions {
31
31
  storage: NpmInstallStorage;
32
32
  /** 网络实现(缺省 globalThis.fetch)。 */
33
33
  fetchImpl?: CloudFetch;
34
- /** 传递依赖递归深度上限(缺省 5,超限显式报错而非静默截断)。 */
34
+ /** 传递依赖递归深度上限(缺省 25,超限显式报错而非静默截断)。 */
35
35
  maxDepth?: number;
36
+ /** 退避等待实现(缺省 `setTimeout`;单测注入假实现,避免真实等待)。 */
37
+ sleep?: (ms: number) => Promise<void>;
36
38
  }
37
39
  export interface NpmInstalledPackage {
38
40
  name: string;
@@ -51,13 +53,32 @@ export interface NpmInstallResult {
51
53
  /** 根包在 VFS 中的安装目录(相对根)。 */
52
54
  nodeModulesPath: string;
53
55
  }
54
- /** 传递依赖递归深度上限:真实浅树(lodash 零依赖、dayjs 零依赖)远低于它;超它即失控。 */
55
- export declare const DEFAULT_MAX_INSTALL_DEPTH = 5;
56
+ /**
57
+ * 传递依赖递归深度上限(缺省 25)。
58
+ *
59
+ * 它不是「正确性上限」,而是「病态链兜底」:递归终止性由 `visited`(`name@version` 去重)
60
+ * 与 `onStack` 祖先链环检测保证,深度本身不会失控。原值 5 的立论(「lodash / dayjs 零依赖,
61
+ * 真实树远低于它」)与事实不符——真实前端栈轻松越过:实测 `vue@3.5.x` 闭包深度 5,
62
+ * `vue-router@5` 到最深依赖已需 6 层,于是「装不上依赖 → 预览 RESOLVE 红屏」,
63
+ * 把正常的前端开发整个挡在门外。抬到 25 覆盖真实生态(常见 ≲ 15),同时仍对真正
64
+ * 病态的深链显式报错而非静默截断。
65
+ */
66
+ export declare const DEFAULT_MAX_INSTALL_DEPTH = 25;
56
67
  /** 解析 `name` 或 `name@spec` 到 { name, spec? }(含 scoped 包)。 */
57
68
  export declare function parseSpec(spec: string): {
58
69
  name: string;
59
70
  spec?: string;
60
71
  };
72
+ /**
73
+ * 429 限速的退避重试次数上限与缺省等待(ms)。
74
+ *
75
+ * 为什么需要:`/package` + `/tarball` 是「一次真实依赖闭包 = 上百次请求」,而中继按访客
76
+ * 限速(`NPM_RELAY_MAX_REQ_PER_WINDOW`)。装一个有分量的包(vue-router@5 = 61 个包 =
77
+ * 122 次请求)必然触顶,旧行为把 429 当致命错误直接放弃整个安装(且报错文案误称
78
+ * 「不在白名单或包不存在」)。改为按服务端 `Retry-After` 退避重试——落在下一窗口即可继续;
79
+ * 只有持续被限速(重试耗尽)才判失败,并如实报「限速」而不是含糊的白名单错误。
80
+ */
81
+ export declare const RATE_LIMIT_MAX_RETRIES = 120;
61
82
  export declare function createNpmClient(options: NpmClientOptions): {
62
83
  registries(): Promise<string[]>;
63
84
  install(spec: string): Promise<NpmInstallResult>;
@@ -44,5 +44,6 @@ export interface BrowserSimRuntime {
44
44
  /** 释放资源(当前无长持句柄;与 CLI createSimRuntime.dispose 对称保留)。 */
45
45
  dispose(): Promise<void>;
46
46
  }
47
+ /** 顺序合并多份 bundle:capabilities 去重(同名后者覆盖),rpcHandlers 浅合并。 */
47
48
  /** 装配浏览器模拟运行时(async:db 引擎要先把 IndexedDB 里的快照灌回来)。 */
48
49
  export declare function createBrowserSimRuntime(options: BrowserSimRuntimeOptions): Promise<BrowserSimRuntime>;
@@ -11,20 +11,31 @@
11
11
  * (真 live binding、真模块隔离),不是 CJS 打平;
12
12
  * - **转换**:`.ts` 复用 stripTypes 擦类型;`.css` 变成「注入 `<style>` 的副作用模块」;
13
13
  * `.json` 变成默认导出对象;`.vue` 经注入的 SFC 编译器(IDE 侧装 `vue/compiler-sfc`);
14
+ * **CJS → ESM 互操作**(`.cjs` 与纯 CJS 的 `.js` 包成 ESM:静态 `require` 提为前置导入、
15
+ * 模块体内注入 `module` / `exports` / `require`,见 `wrapCommonJs`);行首 shebang 剥离;
14
16
  * JS 系产物统一过 define 替换(`process.env.NODE_ENV` / `__VUE_*__`),让 esm-bundler
15
17
  * 构建(vue 等)在无打包器的浏览器里也能跑;
18
+ * - **CSS `@import`**:编译期按导入方文件解析并内联(对齐 postcss-import 的核心语义,见
19
+ * `css-imports.ts`)——`.css` 模块与 SFC 的 `<style>` 块**两条路径都过**。缺这一层时 `@import`
20
+ * 被原样投给浏览器,浏览器改按**文档 base** 解析:预览面对未命中路径一律 SPA 回退入口文档,
21
+ * 于是 `@import` 拿到 `text/html` 被丢弃;而 SFC 的 `<style>` 块里常常只有这一条 `@import`
22
+ * (全局样式都在它指向的文件里)⇒ **整份样式表静默失效、且不产生任何 JS 异常**(IDE-038 现场);
16
23
  * - **依赖**:裸说明符经 node-resolve 命中 VFS `node_modules/`(终端 `npm install` 的产物),
17
24
  * 与 CLI / 线上同一套解析规则;相对说明符支持 Vite 风格省略扩展名(.ts/.js/.vue/…);
18
25
  * - **HMR**:订阅 VFS 变更(`vfs.onMutate`,IDE 保存 / shell 写入 / npm 解包皆触发)→
19
26
  * 防抖全量重建模块图 → 入口文档变化则经 `BroadcastChannel` 广播新 blob URL,预览 iframe
20
27
  * `location.replace` 自刷新(整页刷新式 HMR,组件级热替换留后续);构建 / 解析失败时生成
21
28
  * 「红屏错误页」而不是静默白屏。
29
+ * - **注入**:文档 `<head>` 首位内联两段**经典**脚本——控制台中继(`CONSOLE_RELAY_SCRIPT`:
30
+ * `console.*` / 未捕获错误 → postMessage 回 IDE「控制台」页签)与云函数 fetch 拦截器;
31
+ * `</body>` 前注入 HMR 脚本。module script 天然 defer,故这两段必然先于应用代码执行。
22
32
  *
23
33
  * 边界(响亮失败,不静默降级):
24
- * - **循环依赖直接报错**(与 ide-widget-bundle 同口径):blob 链的改写发生在加载期,
25
- * 环会让「先有 URL 才能写引用」无解,如实报告环路径链;
34
+ * - **环状依赖图不报错**:真实 npm 图允许成环(如 `mlly ⇄ pkg-types`),npm 口径是「已装即跳过」,
35
+ * `visited`(`name@version`)去重终止;把环当硬错误会把整个真实闭包判死(见 `npm-client.ts`);
26
36
  * - `.tsx` / `.jsx` 不支持(stripTypes 只擦类型标注,不转 JSX),明确报错;
27
- * - Node 内建模块(`node:`)与 CJS-only 包不支持(解析器只认 ESM 入口),明确报错。
37
+ * - Node 内建模块(`node:` / `fs` / `path` 等)浏览器沙箱不提供:`require()` 命中即**运行时**
38
+ * 抛可读错误(构建期不因个别 require 解析不到就整体红屏,守护式 `try { require("fs") } catch {}` 仍可用)。
28
39
  */
29
40
  import type { VirtualFileSystem } from './vfs';
30
41
  /** SFC 编译器注入契约:`vue/compiler-sfc` 的适配(IDE 侧装配,本包零依赖不引 vue)。 */
@@ -48,6 +59,12 @@ export interface ViteServerOptions {
48
59
  /** blob URL 工厂(Node 单测注入假实现)。 */
49
60
  createObjectURL?: (blob: Blob) => string;
50
61
  revokeObjectURL?: (url: string) => void;
62
+ /**
63
+ * 文档重建且**内容有变化**时回调(PV-006):blob HMR 之外的第二条出口——
64
+ * IDE 侧据此把新产物导出并发布到预览子域(真实 HTTP 源)。
65
+ * 首建不回调(宿主由 `serverready` 事件拿首屏 URL,两处都回调会长重复发布)。
66
+ */
67
+ onDocumentChange?: (url: string) => void;
51
68
  }
52
69
  /** dev server 句柄:url / root 对外只读,`touch` 驱动 HMR,`stop` 释放资源。 */
53
70
  export interface ViteServer {
@@ -93,4 +110,10 @@ export interface EsmSpecifierHit {
93
110
  * 模板串整体跳过(`${}` 里的动态 import 不在支持范围,见文件头边界注)。
94
111
  */
95
112
  export declare function scanEsmSpecifiers(source: string): EsmSpecifierHit[];
113
+ /**
114
+ * 扫描 CJS `require("x")` 的静态说明符(词法级:`require` `(` 字符串 `)` 四连)。
115
+ * `require.resolve("x")` / `require.cache` 等形态不命中(第二 token 不是 `(`)。
116
+ * 说明符位置(start/end)一并返回,供改写与去重。
117
+ */
118
+ export declare function scanRequireSpecifiers(source: string): EsmSpecifierHit[];
96
119
  export declare function createViteServer(vfs: VirtualFileSystem, options?: ViteServerOptions): ViteServer;