@deepseek-ai/dsh-experimental-webworker-runtime 0.2.2-alpha.2 → 0.2.2-rc.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.
- package/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/index.js +259 -27
- package/package.json +27 -24
package/README.i18n.yaml
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
en: 4e53164159b5ce41
|
|
16
16
|
zh: 89582dc0294d0776
|
|
17
17
|
/deepseek-ai-dsh-experimental-webworker-runtime/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: 9f4c76d6c4391037
|
|
19
|
+
zh: c55611045f4667e2
|
|
20
20
|
/deepseek-ai-dsh-experimental-webworker-runtime/model-experience:
|
|
21
21
|
en: 61fce9b4c7dc96e6
|
|
22
22
|
zh: dc2d931063a38327
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Three build artifacts and one source-owned process layer:
|
|
|
29
29
|
|
|
30
30
|
- **`lib/index.js` (assembly library)** — `createWorkerHost`/`startWorkerHost` mount the base image and any ordered data overlays (`storage/`), register the image's lazy archives, install the module loader (`module-system/`) and the `process` shim, boot the tree through the image's own `dsh-app-boot`, and hand the tunnel its serving seams. Overlays may replace files only under `home/` and `workspace/`; they cannot replace the base manifest or modules. The image layout contract (`image-layout.ts`: virtual root, manifest path, lazy archive directory, empty directories) and the manifest (`image-manifest.ts`: profile, installation, the `lowered` wrapper-contract gate, lazy archives) are shared with the packer. The Worker boots the manifest's shipped profile as the launcher does: the image's app-boot initializes `home/profiles/<profile>/` from the shipped template, resolves bundles from the installation manifest the image carries alone, and composes the bundle layers, the profile patch, and the home patch. The profile context, the launch environment snapshot, and a `PluginPackages` service without a runtime resolution are provided as the launcher provides them; the Worker loader owns module resolution. The profile context carries no command-line overlay; the image's home patch (`home/cordis.patch.yml`), which the packer writes from `PLATFORM_ENTRY_CONFIG`, keeps JSONL Session logs plaintext. ConfigEditor persists overrides in the profile patch, reconciles each write, and Loader commits live values. The Worker commits `appReady` once the tunnel serves, so HMR loads and applies profile changes live; the Worker's ES module cache stays empty and the `process` shim reports no entry script, so HMR compares and replaces no loaded modules. Plugin management lists and switches the installation's optional bundles, and its package operations fail with the `execa` refusal. Configuration edits last for the current Worker lifetime.
|
|
31
31
|
- **Lazy archives** — the manifest registers each page chunk the packer moved out of the base image by path and size, with its archive name relative to the image URL. Existence, stats, and listings answer at once; the first asynchronous read (`fs.promises.readFile`, `fs.promises.open`, `fs.createReadStream`, `fs.promises.cp`) fetches and inflates that archive once for every waiting reader, checks it against the registration, and mounts its files without publishing a mutation. A failed fetch rejects the read and leaves the files registered, so the next read fetches again. Until then, synchronous reads, writes, appends, truncation, chmod, rename, and link of a registered file fail with `ERR_DSH_VFS_DEFERRED` naming the archive; unlink and recursive removal drop the registration, and seeding the path replaces it. The archive name derives from its content digest, and the fetch checks only the registered paths and sizes, not the digest. An image that registers lazy archives must be passed as a URL.
|
|
32
|
-
- **`lib/worker.js` (worker bundle)** — the assembly plus this package's Node-compatibility layer as one self-contained ES module. The module proxy table (`module-proxies.ts`) is the only platform fork: `node:*` builtins over VFS/tunnel/browser primitives, structural stubs that fail loud on the console for what a browser cannot do, and native/binary package replacements. `node:module` supplies `createRequire().resolve` and `.resolve.paths()` over the image package root, so unchanged packages can discover manifests without evaluating their modules. `node-addon-require-builtin` answers the Node v24.18.0 internal modules that the vendored Loader, app-boot, and HMR read without `--expose-internals`: the cascaded ESM loader's `resolveSync` and `import` over the Worker loader, with Node's `ERR_MODULE_NOT_FOUND` and `ERR_PACKAGE_PATH_NOT_EXPORTED` codes, and an empty `loadCache`; and the CommonJS loader, package reader, `modules` binding, and resolve-cache members that HMR replaces, which refuse when called. `process.versions.node` reports `24.18.0`, so `ModuleLoader.fromInternal()` and the Loader's `internal` reach that cascaded loader. `node:path.win32.isAbsolute` and `node:util.inherits` follow Node; other `win32` members throw. The `node:util` JSON-data comparator compares own enumerable properties, preserving Node admission decisions for recorded fields such as `__proto__`. The global `process` shim carries Node detection fields including `title`, preventing Worker execution from entering DOM-only branches; Node’s `global` alias references the same `globalThis` object for image-loaded packages. The pack-time parser reports statically named module requests, including module-scope direct calls of the form `createRequire(import.meta.url)('pkg')` through a named `node:module` or `module` import, to the packer's reachability walk. Stored, CommonJS-obtained, and rebased `createRequire` calls require image entry seeds. VFS mutations drive `node:fs` callback, polling, and promise watchers, whose listeners run in the async context where the watcher was created rather than that of the writing code; open descriptors retain file identity and access mode across rename, replacement, and unlink, `FileHandle.stat({ bigint: true })` reports the same device and inode identity as a path stat while the name still refers to that file, and `FileHandle.chmod()` updates the opened file identity; `readable-stream` supplies `node:stream/promises` completion and pipeline helpers and the stream state machine used by file streams and unchanged image packages such as Chokidar and readdirp. The maintained `string_decoder` package supplies `node:string_decoder`, retaining incomplete multibyte characters between chunks. AsyncLocalStorage carries sync-stack causality across `await` through the snapshot/restore faces the pack-time lowering injects. The worker holds no compiler: an image the packer did not lower is refused at mount. The callback `fs.realpath.native` alias resolves within the mounted VFS and supports `util.promisify`.
|
|
32
|
+
- **`lib/worker.js` (worker bundle)** — the assembly plus this package's Node-compatibility layer as one self-contained ES module. The module proxy table (`module-proxies.ts`) is the only platform fork: `node:*` builtins over VFS/tunnel/browser primitives, structural stubs that fail loud on the console for what a browser cannot do, and native/binary package replacements. `node:module` supplies `createRequire().resolve` and `.resolve.paths()` over the image package root, so unchanged packages can discover manifests without evaluating their modules. `node-addon-require-builtin` answers the Node v24.18.0 internal modules that the vendored Loader, app-boot, and HMR read without `--expose-internals`: the cascaded ESM loader's `resolveSync` and `import` over the Worker loader, with Node's `ERR_MODULE_NOT_FOUND` and `ERR_PACKAGE_PATH_NOT_EXPORTED` codes, and an empty `loadCache`; and the CommonJS loader, package reader, `modules` binding, and resolve-cache members that HMR replaces, which refuse when called. `process.versions.node` reports `24.18.0`, so `ModuleLoader.fromInternal()` and the Loader's `internal` reach that cascaded loader. `node:path.win32.isAbsolute` and `node:util.inherits` follow Node; other `win32` members throw. The `node:util` JSON-data comparator compares own enumerable properties, preserving Node admission decisions for recorded fields such as `__proto__`. The global `process` shim carries Node detection fields including `title`, preventing Worker execution from entering DOM-only branches; Node’s `global` alias references the same `globalThis` object for image-loaded packages. The pack-time parser reports statically named module requests, including module-scope direct calls of the form `createRequire(import.meta.url)('pkg')` through a named `node:module` or `module` import, to the packer's reachability walk. Stored, CommonJS-obtained, and rebased `createRequire` calls require image entry seeds. Lowered bodies read named and default imports through the required module object at each reference, so a module in an import cycle observes a binding once the exporting module initializes it; in a module with such imports, an assignment to an imported binding, a direct `eval`, and a declaration using the reserved `__dsh$` prefix fail the pack. VFS mutations drive `node:fs` callback, polling, and promise watchers, whose listeners run in the async context where the watcher was created rather than that of the writing code; open descriptors retain file identity and access mode across rename, replacement, and unlink, `FileHandle.stat({ bigint: true })` reports the same device and inode identity as a path stat while the name still refers to that file, and `FileHandle.chmod()` updates the opened file identity; `readable-stream` supplies `node:stream/promises` completion and pipeline helpers and the stream state machine used by file streams and unchanged image packages such as Chokidar and readdirp. The maintained `string_decoder` package supplies `node:string_decoder`, retaining incomplete multibyte characters between chunks. AsyncLocalStorage carries sync-stack causality across `await` through the snapshot/restore faces the pack-time lowering injects. The worker holds no compiler: an image the packer did not lower is refused at mount. The callback `fs.realpath.native` alias resolves within the mounted VFS and supports `util.promisify`.
|
|
33
33
|
- **`src/shell/` (the worker's own process layer)** — a browser worker cannot fork, so `node:child_process` is not a stub but an implementation: `spawn` starts the command in its own Web Worker — this same bundle, told by its first frame to be a shell process — and reports it through the `ChildProcess` surface the subprocess service consumes. The command runs off the host's thread, `SIGKILL` terminates it whatever it is doing, and it reaches the VFS only by message (the host serves those frames). Worker platform executables preserve native-package protocols such as Landlock without replacing their JavaScript packages or coupling their implementations to `node:child_process`; `xdg-open` sends one VFS text file to the page's read-only viewer, so desktop-opener actions such as **Open configuration file** show the file in the page; ordinary commands use the package's evaluator and coreutils command table. The grammar is `@yarnpkg/parsers`' `parseShell`, while `execSync`/`fork` still refuse because they need a real process.
|
|
34
34
|
- **`lib/client.js` (page half)** — startup has two independent stages. `chooseWorkerHostSource({ image?, fixtureManifest? })` optionally owns the boot barrier and fixture manifest: without `preview-fixture` it waits at the source chooser, while a valid query selects directly; either path returns ordered overlays. `connectWorkerHost(worker, { image?, overlays? })` remains the public base-runtime connector; callers that skip the chooser get an empty overlay list. `apps/web` invokes both and supplies its statically bundled Worker. The opening `init` frame carries the base and ordered overlay URLs, the boot payload delivers the structured index-injection table, and `applyIndexInjections` executes it before the shell entry runs. Script preload rows are advisory and skipped because `/plugins` resources resolve only through the tunnel; `loadBundle` fetches each combo on first demand, embeds its tunnel-only source map as a Base64 data URL, and executes the script as a Blob. Before the shell entry runs, the page reads `GET /__assets__`, which the tunnel answers with an uncompressed tar of every package asset in the image, and supplies `resolveAsset`, which maps each `plugins/<package>/assets/<path>` reference a bundle passes to `require.asset` to a Blob URL of those bytes. The worker's unsolicited `view-text` frame opens the page's modal text viewer. The tunnel also exposes fetch-shaped transport, the independent file-upload carrier, and the API client. Request frames preserve Blob bodies through structured clone and transfer `ReadableStream<Uint8Array>` ownership. The Host Worker streams both forms into the route, so neither browser thread creates a complete byte array for a generic-file upload. A Remote stream's uplink crosses as `stream-uplink-item` / `stream-uplink-end` frames into an unbounded `TunnelUplink` that drops items arriving after `end`: the page and its worker are one trusted same-origin boundary, so the Host inbox cap does not apply.
|
|
35
35
|
|
package/README.zh.md
CHANGED
|
@@ -29,7 +29,7 @@ kind: "package-library"
|
|
|
29
29
|
|
|
30
30
|
- **`lib/index.js`(装配库)**——`createWorkerHost`/`startWorkerHost` 挂载基础镜像和按序排列的数据 overlays(`storage/`)、登记镜像的懒加载归档、安装模块加载器(`module-system/`)与 `process` shim、经镜像自带的 `dsh-app-boot` 启动插件树,并把服务 seam 交给隧道。Overlay 只能替换 `home/` 与 `workspace/` 下的文件,不能替换基础 manifest 或模块。镜像布局契约(`image-layout.ts`:虚拟根、manifest 路径、懒加载归档目录、空目录)与 manifest(`image-manifest.ts`:profile、安装清单、`lowered` 包装契约门、懒加载归档)与 packer 共享。Worker 按启动器的方式启动 manifest 指定的随附 profile:镜像里的 app-boot 用随附模板初始化 `home/profiles/<profile>/`,从镜像单独携带的安装 manifest 解析 bundle,并合成各 bundle 层、profile patch 与 home patch。profile 上下文、启动环境快照,以及不带运行时 resolution 的 `PluginPackages` 服务都按启动器的方式提供;模块解析由 Worker 加载器负责。profile 上下文不带命令行 overlay;packer 按 `PLATFORM_ENTRY_CONFIG` 写入镜像的 home patch(`home/cordis.patch.yml`),使 JSONL Session 日志保持明文。ConfigEditor 将覆盖值持久化到 profile patch,协调每次写入,Loader 提交实时值。Worker 在隧道开始服务后提交 `appReady`,因此 HMR 可以加载 profile 变更并实时应用;Worker 的 ES module 缓存始终为空,`process` shim 也不报告入口脚本,因此 HMR 不比较、也不替换已加载的模块。插件管理可以列出并开关安装提供的 optional bundle,其包操作会因 `execa` 拒绝而失败。配置修改在当前 Worker 生命周期内有效。
|
|
31
31
|
- **懒加载归档**——manifest 按路径和大小登记 packer 移出基础镜像的每个页面 chunk,并给出相对镜像 URL 的归档名。存在性、stat 和目录列表立即作答;第一次异步读取(`fs.promises.readFile`、`fs.promises.open`、`fs.createReadStream`、`fs.promises.cp`)为所有等待中的读取方只拉取并解压一次该归档,按登记内容校验后挂载其文件,不发布 mutation。拉取失败时本次读取被拒绝,文件保持登记状态,下次读取会重新拉取。在此之前,对已登记文件的同步读取、写入、追加、截断、chmod、rename 和 link 会以 `ERR_DSH_VFS_DEFERRED` 失败,错误中写明归档名;unlink 和递归删除会移除登记,再次 seed 该路径会替换登记。归档名由内容摘要派生,拉取时只校验登记的路径和大小,不校验摘要。登记了懒加载归档的镜像必须以 URL 传入。
|
|
32
|
-
- **`lib/worker.js`(worker 束)**——装配库加本包的 Node 兼容层,合成一个自含 ES module。模块代理表(`module-proxies.ts`)是唯一平台叉口:`node:*` 内建走 VFS、隧道和浏览器原语,浏览器做不到的走结构化 stub(调用即在 console 报错并抛出),native/binary 包则替换执行后端。`node:module` 在镜像 package 根之上提供 `createRequire().resolve` 与 `.resolve.paths()`,使未修改的包无需执行目标模块即可发现 manifest。`node-addon-require-builtin` 应答 vendor Loader、app-boot 和 HMR 在没有 `--expose-internals` 时读取的 Node v24.18.0 internal 模块:cascaded ESM loader 的 `resolveSync` 和 `import` 经 Worker 加载器完成,失败时带 Node 的 `ERR_MODULE_NOT_FOUND` 与 `ERR_PACKAGE_PATH_NOT_EXPORTED` 错误码,`loadCache` 为空;HMR 会替换的 CommonJS loader、package reader、`modules` binding 与 resolve cache 成员被调用时拒绝。`process.versions.node` 报告 `24.18.0`,因此 `ModuleLoader.fromInternal()` 和 Loader 的 `internal` 拿到的是这个 cascaded loader。`node:path.win32.isAbsolute` 与 `node:util.inherits` 与 Node 一致,其余 `win32` 成员抛出。`node:util` 的 JSON 数据比较器检查可枚举的自有属性,使 `__proto__` 等记录字段的准入判定与 Node 一致。全局 `process` shim 带有包括 `title` 在内的 Node 环境识别字段,避免 Worker 执行误入仅适用于 DOM 的分支;镜像中加载的包通过 Node 的 `global` 别名访问同一个 `globalThis` 对象。pack 期解析器会把名称静态可知的模块请求报告给 packer 的可达性遍历,其中包括通过 `node:module` 或 `module` 具名导入在模块作用域直接发起的 `createRequire(import.meta.url)('pkg')` 调用。保存、经 CommonJS 获取或另设基准的 `createRequire`
|
|
32
|
+
- **`lib/worker.js`(worker 束)**——装配库加本包的 Node 兼容层,合成一个自含 ES module。模块代理表(`module-proxies.ts`)是唯一平台叉口:`node:*` 内建走 VFS、隧道和浏览器原语,浏览器做不到的走结构化 stub(调用即在 console 报错并抛出),native/binary 包则替换执行后端。`node:module` 在镜像 package 根之上提供 `createRequire().resolve` 与 `.resolve.paths()`,使未修改的包无需执行目标模块即可发现 manifest。`node-addon-require-builtin` 应答 vendor Loader、app-boot 和 HMR 在没有 `--expose-internals` 时读取的 Node v24.18.0 internal 模块:cascaded ESM loader 的 `resolveSync` 和 `import` 经 Worker 加载器完成,失败时带 Node 的 `ERR_MODULE_NOT_FOUND` 与 `ERR_PACKAGE_PATH_NOT_EXPORTED` 错误码,`loadCache` 为空;HMR 会替换的 CommonJS loader、package reader、`modules` binding 与 resolve cache 成员被调用时拒绝。`process.versions.node` 报告 `24.18.0`,因此 `ModuleLoader.fromInternal()` 和 Loader 的 `internal` 拿到的是这个 cascaded loader。`node:path.win32.isAbsolute` 与 `node:util.inherits` 与 Node 一致,其余 `win32` 成员抛出。`node:util` 的 JSON 数据比较器检查可枚举的自有属性,使 `__proto__` 等记录字段的准入判定与 Node 一致。全局 `process` shim 带有包括 `title` 在内的 Node 环境识别字段,避免 Worker 执行误入仅适用于 DOM 的分支;镜像中加载的包通过 Node 的 `global` 别名访问同一个 `globalThis` 对象。pack 期解析器会把名称静态可知的模块请求报告给 packer 的可达性遍历,其中包括通过 `node:module` 或 `module` 具名导入在模块作用域直接发起的 `createRequire(import.meta.url)('pkg')` 调用。保存、经 CommonJS 获取或另设基准的 `createRequire` 调用需要镜像入口种子。降低后的模块体在每次引用具名导入与 default 导入时,都经所 require 的模块对象读取,因此循环导入中的模块能在导出方完成初始化后读到该绑定;在含此类导入的模块中,对导入绑定赋值、直接调用 `eval`、声明使用保留前缀 `__dsh$` 的名字,都会使 pack 失败。VFS mutation 驱动 `node:fs` 的 callback、polling 和 promise watcher,监听回调运行在创建 watcher 时的异步上下文中,而不是写入方代码的上下文中;打开的 descriptor 在 rename、replacement 和 unlink 后仍保留文件身份与访问模式,只要文件名仍指向该文件,`FileHandle.stat({ bigint: true })` 报告的 device 与 inode 身份就与路径 stat 相同,`FileHandle.chmod()` 则更新打开文件身份的权限;`readable-stream` 提供 `node:stream/promises` 的完成等待与管道方法,以及文件流以及 Chokidar、readdirp 等未修改镜像包所用的流状态机。维护中的 `string_decoder` 包提供 `node:string_decoder`,在数据块之间保留不完整的多字节字符。AsyncLocalStorage 经 pack 时降低注入的 snapshot/restore 面在 `await` 间携带同步栈因果。worker 不带编译器:packer 未降低的镜像在挂载时被拒。回调式 `fs.realpath.native` 别名在已挂载的 VFS 内解析路径,并支持 `util.promisify`。
|
|
33
33
|
- **`src/shell/`(worker 自己的进程层)**——浏览器 worker 无法 fork,所以 `node:child_process` 不是 stub 而是实现:`spawn` 把命令放进它自己的 Web Worker——就是这同一个束,由首帧告诉它「你是 shell 进程」——并以 subprocess 服务消费的 `ChildProcess` 面报告结果。命令不占宿主线程,`SIGKILL` 不管它在干什么都能终止它,而它只能靠消息触达 VFS(由宿主应答这些帧)。Worker 平台 executable 在不替换 JavaScript 包、也不把具体实现耦合进 `node:child_process` 的情况下保持 Landlock 等 native 包协议;`xdg-open` 把一个 VFS 文本文件交给页面的只读查看器,因此 **打开配置文件** 等桌面打开操作会在页面内显示该文件;普通命令使用本包的求值器与 coreutils 命令表。语法来自 `@yarnpkg/parsers` 的 `parseShell`,而 `execSync`/`fork` 依然拒绝,因为它们需要真进程。
|
|
34
34
|
- **`lib/client.js`(页面半)**——启动分为相互独立的两段。`chooseWorkerHostSource({ image?, fixtureManifest? })` 可选地拥有 boot barrier 与 fixture manifest:没有 `preview-fixture` 时停在来源选择面板,合法 query 则直接选择;两条路径都返回按序排列的 overlays。`connectWorkerHost(worker, { image?, overlays? })` 仍是公开的基础运行态连接器;调用方跳过选择器时 overlay 列表为空。`apps/web` 调用这两段并提供静态打包的 Worker。开局 `init` 帧携带基础镜像与按序排列的 overlay URL,boot 载荷送达结构化 index 注入表,`applyIndexInjections` 在壳入口运行前逐行执行。脚本 preload 行只是提示,因此会被跳过:`/plugins` 资源只能经 tunnel 解析,`loadBundle` 会在首次需要时获取 combo、把仅 tunnel 可达的 sourcemap 内嵌为 Base64 data URL,再以 Blob 执行脚本。在 shell 入口运行之前,页面读取 `GET /__assets__`(隧道以镜像中所有包资源组成的未压缩 tar 回答),并提供 `resolveAsset`,把 bundle 传给 `require.asset` 的每个 `plugins/<package>/assets/<path>` 引用映射为这些字节的 Blob URL。worker 主动发出的 `view-text` 帧会打开页面的模态文本查看器。Tunnel 还暴露 fetch 形式的传输、独立文件上传载体和 API 客户端。请求帧通过结构化克隆保留 Blob 请求体,并转移 `ReadableStream<Uint8Array>` 的所有权。Host Worker 将两种请求体都逐块送入路由,因此通用文件上传不会在任何浏览器线程创建完整字节数组。Remote 流的上行以 `stream-uplink-item` / `stream-uplink-end` 帧进入没有上限的 `TunnelUplink`,`end` 之后到达的项被丢弃:页面与其 worker 是同一个可信的同源边界,Host 的 inbox 上限在此不适用。
|
|
35
35
|
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { parse } from "acorn";
|
|
2
|
+
import { analyze } from "eslint-scope";
|
|
3
|
+
import { KEYS } from "eslint-visitor-keys";
|
|
2
4
|
//#region \0rolldown/runtime.js
|
|
3
5
|
var __defProp = Object.defineProperty;
|
|
4
6
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -1056,6 +1058,14 @@ function createSyntheticExchange(frame, sink) {
|
|
|
1056
1058
|
* so **line numbers survive**: a stack frame in a transformed module points at
|
|
1057
1059
|
* the same line as the built artifact it came from.
|
|
1058
1060
|
*
|
|
1061
|
+
* Named and default imports stay live: every reference reads the required
|
|
1062
|
+
* module object when it runs (`__dsh$m1["x"]`), never a copy taken at the
|
|
1063
|
+
* import statement, so a module in an import cycle sees a binding once the
|
|
1064
|
+
* exporting module has initialized it, as ES modules do. Scope analysis tells
|
|
1065
|
+
* those references apart from same-named locals that shadow them; it runs only
|
|
1066
|
+
* for a module that declares or assigns an import's name somewhere, because
|
|
1067
|
+
* elsewhere every read of the name is the import.
|
|
1068
|
+
*
|
|
1059
1069
|
* The image packer is this transform's only caller: it lowers every JavaScript
|
|
1060
1070
|
* entry it packs and records `LOWERING_VERSION` in the image manifest, so the
|
|
1061
1071
|
* worker wraps those bodies without carrying a compiler of its own.
|
|
@@ -1063,7 +1073,7 @@ function createSyntheticExchange(frame, sink) {
|
|
|
1063
1073
|
*/
|
|
1064
1074
|
const HELPER_SOURCE = {
|
|
1065
1075
|
def: "const __dsh$def=(t,k,get)=>Object.defineProperty(t,k,{enumerable:true,configurable:true,get});",
|
|
1066
|
-
default: "const __dsh$default=(m)=>(m&&m.__esModule?m.default:m);",
|
|
1076
|
+
default: "const __dsh$default=(m)=>(m&&m.__esModule&&Object.prototype.hasOwnProperty.call(m,\"default\")?m.default:m);",
|
|
1067
1077
|
ns: "const __dsh$ns=(m)=>(m&&m.__esModule?m:Object.assign({},m,{default:m}));",
|
|
1068
1078
|
exportAll: "const __dsh$exportAll=(t,m)=>{for(const k of Object.keys(m))if(k!==\"default\"&&!(k in t))__dsh$def(t,k,()=>m[k]);};",
|
|
1069
1079
|
dynImport: "const __dsh$dynImport=(s)=>Promise.resolve().then(()=>__dsh$ns(require(s)));"
|
|
@@ -1080,6 +1090,8 @@ function countNewlines(text) {
|
|
|
1080
1090
|
for (let index = text.indexOf("\n"); index >= 0; index = text.indexOf("\n", index + 1)) count += 1;
|
|
1081
1091
|
return count;
|
|
1082
1092
|
}
|
|
1093
|
+
/** Prefix of the identifiers this transform emits; a module declaring one would capture them. */
|
|
1094
|
+
const RESERVED_PREFIX = "__dsh$";
|
|
1083
1095
|
var Transformer = class {
|
|
1084
1096
|
path;
|
|
1085
1097
|
edits = [];
|
|
@@ -1092,6 +1104,18 @@ var Transformer = class {
|
|
|
1092
1104
|
moduleRequests = /* @__PURE__ */ new Set();
|
|
1093
1105
|
metaResolveRequests = /* @__PURE__ */ new Set();
|
|
1094
1106
|
createRequireBindings = /* @__PURE__ */ new Set();
|
|
1107
|
+
/** Module temporary per import declaration with specifiers, assigned before traversal. */
|
|
1108
|
+
importModules = /* @__PURE__ */ new Map();
|
|
1109
|
+
/** Named and default imports by local name. */
|
|
1110
|
+
importedBindings = /* @__PURE__ */ new Map();
|
|
1111
|
+
/** Read-position identifiers spelling an import's name, rewritten after traversal. */
|
|
1112
|
+
importCandidates = [];
|
|
1113
|
+
/**
|
|
1114
|
+
* Set when an import name (or the reserved prefix) is declared or assigned.
|
|
1115
|
+
* Only then can a candidate be a shadowing local, so only then does scope
|
|
1116
|
+
* analysis decide which candidates read the import.
|
|
1117
|
+
*/
|
|
1118
|
+
scopeAnalysisNeeded = false;
|
|
1095
1119
|
constructor(source, path) {
|
|
1096
1120
|
this.path = path;
|
|
1097
1121
|
this.source = source.startsWith("#!") ? `//${source.slice(2)}` : source;
|
|
@@ -1164,29 +1188,69 @@ var Transformer = class {
|
|
|
1164
1188
|
if (Array.isArray(node.attributes) && node.attributes.length > 0) this.fail("import attributes are not supported", node.start);
|
|
1165
1189
|
const source = node.source;
|
|
1166
1190
|
const request = `require(${this.literal(source)})`;
|
|
1167
|
-
const
|
|
1168
|
-
if (
|
|
1191
|
+
const held = this.importModules.get(node);
|
|
1192
|
+
if (held === void 0) {
|
|
1169
1193
|
this.replace(node.start, node.end, `${request};`);
|
|
1170
1194
|
return;
|
|
1171
1195
|
}
|
|
1172
|
-
const held = this.moduleTemp();
|
|
1173
1196
|
const lines = [`const ${held}=${request};`];
|
|
1174
|
-
for (const specifier of specifiers) {
|
|
1175
|
-
const local = specifier.local.name;
|
|
1176
|
-
if (specifier.type === "ImportDefaultSpecifier") {
|
|
1177
|
-
lines.push(`const ${local}=${this.helper("default")}(${held});`);
|
|
1178
|
-
continue;
|
|
1179
|
-
}
|
|
1180
|
-
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
1181
|
-
lines.push(`const ${local}=${this.helper("ns")}(${held});`);
|
|
1182
|
-
continue;
|
|
1183
|
-
}
|
|
1184
|
-
const imported = specifier.imported;
|
|
1185
|
-
const name = imported.type === "Identifier" ? imported.name : imported.value;
|
|
1186
|
-
lines.push(`const ${local}=${held}[${JSON.stringify(name)}];`);
|
|
1187
|
-
}
|
|
1197
|
+
for (const specifier of node.specifiers) if (specifier.type === "ImportNamespaceSpecifier") lines.push(`const ${nameOf(specifier.local)}=${this.helper("ns")}(${held});`);
|
|
1188
1198
|
this.replace(node.start, node.end, lines.join(""));
|
|
1189
1199
|
}
|
|
1200
|
+
/**
|
|
1201
|
+
* The expression that reads an import when the reference runs. The default
|
|
1202
|
+
* form is parenthesized so it stays one operand in any position, including
|
|
1203
|
+
* `new` callees and member objects.
|
|
1204
|
+
*/
|
|
1205
|
+
importAccess(binding) {
|
|
1206
|
+
return binding.kind === "default" ? `(${this.helper("default")}(${binding.held}))` : `${binding.held}[${JSON.stringify(binding.imported)}]`;
|
|
1207
|
+
}
|
|
1208
|
+
/** @returns How a local export reads its binding: imports through their module object. */
|
|
1209
|
+
bindingAccess(local) {
|
|
1210
|
+
const imported = this.importedBindings.get(local);
|
|
1211
|
+
return imported === void 0 ? local : this.importAccess(imported);
|
|
1212
|
+
}
|
|
1213
|
+
/**
|
|
1214
|
+
* Record an identifier that spells an import's name in a read position, and
|
|
1215
|
+
* flag one in a declaration or assignment position (or one using the
|
|
1216
|
+
* reserved prefix there), which makes scope analysis decide the candidates.
|
|
1217
|
+
* @param node - The identifier.
|
|
1218
|
+
* @param parent - Its parent node.
|
|
1219
|
+
* @param key - The parent property holding it.
|
|
1220
|
+
* @param statementStart - Start of the enclosing expression statement when that statement sits in a statement list.
|
|
1221
|
+
*/
|
|
1222
|
+
identifier(node, parent, key, statementStart) {
|
|
1223
|
+
if (parent === void 0 || this.importedBindings.size === 0) return;
|
|
1224
|
+
const name = node.name;
|
|
1225
|
+
const binding = this.importedBindings.get(name);
|
|
1226
|
+
if (binding === void 0 && !name.startsWith(RESERVED_PREFIX)) return;
|
|
1227
|
+
if (isBindingPosition(parent, key)) {
|
|
1228
|
+
this.scopeAnalysisNeeded = true;
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
if (binding !== void 0 && isReadPosition(parent, key)) this.importCandidates.push({
|
|
1232
|
+
node,
|
|
1233
|
+
parent,
|
|
1234
|
+
key,
|
|
1235
|
+
statementStart,
|
|
1236
|
+
binding
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
/** Flag a declared or assigned name that could shadow an import or capture an emitted temporary. */
|
|
1240
|
+
bindingOccurrence(name) {
|
|
1241
|
+
if (this.importedBindings.size === 0) return;
|
|
1242
|
+
if (this.importedBindings.has(name) || name.startsWith(RESERVED_PREFIX)) this.scopeAnalysisNeeded = true;
|
|
1243
|
+
}
|
|
1244
|
+
/** Rewrite one identifier that reads an import. */
|
|
1245
|
+
importReference({ node, parent, key, statementStart, binding }) {
|
|
1246
|
+
const access = this.importAccess(binding);
|
|
1247
|
+
if (parent.type === "Property" && parent.shorthand === true) {
|
|
1248
|
+
this.replace(node.start, node.end, `${nameOf(node)}:${access}`);
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
const text = (parent.type === "CallExpression" && key === "callee" || parent.type === "TaggedTemplateExpression" && key === "tag") && binding.kind === "named" ? `(0,${access})` : access;
|
|
1252
|
+
this.replace(node.start, node.end, text.startsWith("(") && node.start === statementStart ? `;${text}` : text);
|
|
1253
|
+
}
|
|
1190
1254
|
exportNamed(node) {
|
|
1191
1255
|
this.moduleSyntax = true;
|
|
1192
1256
|
const declaration = node.declaration;
|
|
@@ -1299,16 +1363,25 @@ var Transformer = class {
|
|
|
1299
1363
|
`finally{if(!${exhausted})${ALS}.resume(await ${ALS}.pause(${ALS}.close(${iterator})))}}`
|
|
1300
1364
|
].join(""));
|
|
1301
1365
|
}
|
|
1302
|
-
visit(node, context) {
|
|
1366
|
+
visit(node, context, parent, key) {
|
|
1303
1367
|
if (node === null || typeof node !== "object") return;
|
|
1304
1368
|
if (Array.isArray(node)) {
|
|
1305
|
-
for (const child of node) this.visit(child, context);
|
|
1369
|
+
for (const child of node) this.visit(child, context, parent, key);
|
|
1306
1370
|
return;
|
|
1307
1371
|
}
|
|
1308
1372
|
const record = node;
|
|
1309
1373
|
if (typeof record.type !== "string") return;
|
|
1310
1374
|
let next = context;
|
|
1311
1375
|
switch (record.type) {
|
|
1376
|
+
case "Identifier":
|
|
1377
|
+
this.identifier(record, parent, key, context.statementStart);
|
|
1378
|
+
break;
|
|
1379
|
+
case "ObjectPattern":
|
|
1380
|
+
for (const property of record.properties) {
|
|
1381
|
+
const value = property.value;
|
|
1382
|
+
if (value?.type === "Identifier") this.bindingOccurrence(value.name);
|
|
1383
|
+
}
|
|
1384
|
+
break;
|
|
1312
1385
|
case "ImportDeclaration":
|
|
1313
1386
|
this.importDeclaration(record);
|
|
1314
1387
|
break;
|
|
@@ -1332,6 +1405,7 @@ var Transformer = class {
|
|
|
1332
1405
|
case "CallExpression": {
|
|
1333
1406
|
const callee = record.callee;
|
|
1334
1407
|
const callArguments = record.arguments;
|
|
1408
|
+
if (callee.type === "Identifier" && callee.name === "eval" && record.optional !== true && this.importedBindings.size > 0) this.fail("direct eval cannot see imports once they are read through their module", record.start);
|
|
1335
1409
|
if (this.isRequireCall(callee, context.moduleScope) && callArguments.length === 1 && typeof callArguments[0]?.value === "string") this.moduleRequests.add(callArguments[0].value);
|
|
1336
1410
|
if (callee.type === "MemberExpression") {
|
|
1337
1411
|
const object = callee.object;
|
|
@@ -1392,11 +1466,12 @@ var Transformer = class {
|
|
|
1392
1466
|
}
|
|
1393
1467
|
if (record.type === "ExpressionStatement") next = {
|
|
1394
1468
|
...next,
|
|
1395
|
-
statement: record
|
|
1469
|
+
statement: record,
|
|
1470
|
+
statementStart: inStatementList(parent, key) ? record.start : void 0
|
|
1396
1471
|
};
|
|
1397
|
-
for (const [
|
|
1398
|
-
if (
|
|
1399
|
-
this.visit(value, next);
|
|
1472
|
+
for (const [childKey, value] of Object.entries(record)) {
|
|
1473
|
+
if (childKey === "type" || childKey === "start" || childKey === "end") continue;
|
|
1474
|
+
this.visit(value, next, record, childKey);
|
|
1400
1475
|
}
|
|
1401
1476
|
}
|
|
1402
1477
|
isCreateRequireCall(node) {
|
|
@@ -1419,11 +1494,74 @@ var Transformer = class {
|
|
|
1419
1494
|
const source = statement.source;
|
|
1420
1495
|
if (source.value !== "node:module" && source.value !== "module") continue;
|
|
1421
1496
|
for (const specifier of statement.specifiers) {
|
|
1422
|
-
if (specifier.type !== "ImportSpecifier" ||
|
|
1423
|
-
this.createRequireBindings.add(
|
|
1497
|
+
if (specifier.type !== "ImportSpecifier" || specifierName(specifier.imported) !== "createRequire") continue;
|
|
1498
|
+
this.createRequireBindings.add(specifier.local.name);
|
|
1424
1499
|
}
|
|
1425
1500
|
}
|
|
1426
1501
|
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Give every import declaration its module temporary and record its named and
|
|
1504
|
+
* default bindings before traversal, because references may precede the
|
|
1505
|
+
* declaration in source order.
|
|
1506
|
+
*/
|
|
1507
|
+
indexImports(program) {
|
|
1508
|
+
for (const statement of program.body) {
|
|
1509
|
+
if (statement.type !== "ImportDeclaration" || statement.specifiers.length === 0) continue;
|
|
1510
|
+
const held = this.moduleTemp();
|
|
1511
|
+
this.importModules.set(statement, held);
|
|
1512
|
+
for (const specifier of statement.specifiers) if (specifier.type === "ImportDefaultSpecifier") this.importedBindings.set(specifier.local.name, {
|
|
1513
|
+
held,
|
|
1514
|
+
kind: "default",
|
|
1515
|
+
imported: "default"
|
|
1516
|
+
});
|
|
1517
|
+
else if (specifier.type === "ImportSpecifier") this.importedBindings.set(specifier.local.name, {
|
|
1518
|
+
held,
|
|
1519
|
+
kind: "named",
|
|
1520
|
+
imported: specifierName(specifier.imported)
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Decide with scope analysis which candidates read an import.
|
|
1526
|
+
*
|
|
1527
|
+
* Refuses an assignment to an import, which live reads cannot express, and a
|
|
1528
|
+
* declaration using the reserved prefix, which would capture an emitted
|
|
1529
|
+
* module temporary. Direct `eval` is refused during traversal.
|
|
1530
|
+
* @param program - The parsed module, which gains node ranges here.
|
|
1531
|
+
* @returns The identifier nodes that read a named or default import.
|
|
1532
|
+
*/
|
|
1533
|
+
resolveImportReads(program) {
|
|
1534
|
+
assignRanges(program);
|
|
1535
|
+
const manager = analyze(program, {
|
|
1536
|
+
ecmaVersion: 2022,
|
|
1537
|
+
sourceType: "module",
|
|
1538
|
+
childVisitorKeys: KEYS
|
|
1539
|
+
});
|
|
1540
|
+
for (const scope of manager.scopes) for (const variable of scope.variables) {
|
|
1541
|
+
const definition = variable.defs[0];
|
|
1542
|
+
if (definition === void 0 || !variable.name.startsWith(RESERVED_PREFIX)) continue;
|
|
1543
|
+
this.fail(`${variable.name} uses the transform's reserved ${RESERVED_PREFIX} prefix`, this.rangeStart(definition.name));
|
|
1544
|
+
}
|
|
1545
|
+
const reads = /* @__PURE__ */ new Set();
|
|
1546
|
+
const moduleScope = manager.scopes.find((scope) => scope.type === "module");
|
|
1547
|
+
for (const variable of moduleScope?.variables ?? []) {
|
|
1548
|
+
if (!this.importedBindings.has(variable.name) || variable.defs[0]?.type !== "ImportBinding") continue;
|
|
1549
|
+
for (const reference of variable.references) {
|
|
1550
|
+
if (reference.isWrite()) this.fail(`the import ${variable.name} cannot be assigned`, this.rangeStart(reference.identifier));
|
|
1551
|
+
reads.add(reference.identifier);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
return reads;
|
|
1555
|
+
}
|
|
1556
|
+
/**
|
|
1557
|
+
* @param node - A node scope analysis reports.
|
|
1558
|
+
* @returns Its source offset; `assignRanges` gave every node a range.
|
|
1559
|
+
*/
|
|
1560
|
+
rangeStart(node) {
|
|
1561
|
+
const start = node.range?.[0];
|
|
1562
|
+
if (start === void 0) this.fail("scope analysis reported a node without a source range", 0);
|
|
1563
|
+
return start;
|
|
1564
|
+
}
|
|
1427
1565
|
run() {
|
|
1428
1566
|
if (this.source.includes(`${ALS}.pause(`) || this.source.includes("__als$")) this.fail("the module is already lowered; check the image manifest wiring", 0);
|
|
1429
1567
|
let program;
|
|
@@ -1437,17 +1575,21 @@ var Transformer = class {
|
|
|
1437
1575
|
this.fail(`parse failed: ${reason.message}`, 0);
|
|
1438
1576
|
}
|
|
1439
1577
|
this.indexCreateRequireImports(program);
|
|
1578
|
+
this.indexImports(program);
|
|
1440
1579
|
this.visit(program, {
|
|
1441
1580
|
asyncGenerator: false,
|
|
1442
1581
|
functionDepth: 0,
|
|
1443
1582
|
moduleScope: true
|
|
1444
1583
|
});
|
|
1584
|
+
const reads = this.scopeAnalysisNeeded ? this.resolveImportReads(program) : void 0;
|
|
1585
|
+
for (const candidate of this.importCandidates) if (reads === void 0 || reads.has(candidate.node)) this.importReference(candidate);
|
|
1445
1586
|
if (this.edits.length === 0 && !this.moduleSyntax) return this.source;
|
|
1446
1587
|
const prologue = [];
|
|
1447
1588
|
if (this.moduleSyntax) prologue.push("\"use strict\";Object.defineProperty(exports,\"__esModule\",{value:true});");
|
|
1589
|
+
const getters = this.bindings.map(({ exported, local }) => `__dsh$def(exports,${JSON.stringify(exported)},()=>${this.bindingAccess(local)});`);
|
|
1448
1590
|
if (this.bindings.length > 0) this.helper("def");
|
|
1449
1591
|
for (const [name, source] of Object.entries(HELPER_SOURCE)) if (this.helpers.has(name)) prologue.push(source);
|
|
1450
|
-
|
|
1592
|
+
prologue.push(...getters);
|
|
1451
1593
|
const sorted = [...this.edits].sort((left, right) => left.start - right.start || left.end - right.end);
|
|
1452
1594
|
const render = (from, to) => {
|
|
1453
1595
|
let cursor = from;
|
|
@@ -1476,6 +1618,96 @@ var Transformer = class {
|
|
|
1476
1618
|
function nameOf(node) {
|
|
1477
1619
|
return node.type === "Identifier" ? node.name : String(node.value);
|
|
1478
1620
|
}
|
|
1621
|
+
/** @returns The name an import or export specifier spells, as an identifier or a string literal. */
|
|
1622
|
+
function specifierName(node) {
|
|
1623
|
+
return node.type === "Identifier" ? node.name : String(node.value);
|
|
1624
|
+
}
|
|
1625
|
+
/**
|
|
1626
|
+
* Give every node the `range` that eslint-scope reads. The parse leaves ranges
|
|
1627
|
+
* out because only modules that need scope analysis use them.
|
|
1628
|
+
* @param node - A node or node array of the parsed module.
|
|
1629
|
+
*/
|
|
1630
|
+
function assignRanges(node) {
|
|
1631
|
+
if (node === null || typeof node !== "object") return;
|
|
1632
|
+
if (Array.isArray(node)) {
|
|
1633
|
+
for (const child of node) assignRanges(child);
|
|
1634
|
+
return;
|
|
1635
|
+
}
|
|
1636
|
+
const record = node;
|
|
1637
|
+
if (typeof record.type !== "string") return;
|
|
1638
|
+
record.range = [record.start, record.end];
|
|
1639
|
+
for (const value of Object.values(record)) assignRanges(value);
|
|
1640
|
+
}
|
|
1641
|
+
/**
|
|
1642
|
+
* ESTree positions where an identifier names a declared or assigned binding.
|
|
1643
|
+
* Property values inside an object pattern are checked at the pattern.
|
|
1644
|
+
*
|
|
1645
|
+
* Together with the ObjectPattern check, this must recognize every ESTree
|
|
1646
|
+
* declaration and assignment form: a missed form lets a shadowing local skip
|
|
1647
|
+
* scope analysis and be rewritten as an import read. A parser upgrade that adds
|
|
1648
|
+
* a binding form must extend this list and the shadowing cases in
|
|
1649
|
+
* `transform-imports.spec.ts`.
|
|
1650
|
+
* @param parent - Parent of the identifier.
|
|
1651
|
+
* @param key - The parent property holding it.
|
|
1652
|
+
* @returns Whether the identifier declares or assigns a binding.
|
|
1653
|
+
*/
|
|
1654
|
+
function isBindingPosition(parent, key) {
|
|
1655
|
+
switch (parent.type) {
|
|
1656
|
+
case "VariableDeclarator": return key === "id";
|
|
1657
|
+
case "FunctionDeclaration":
|
|
1658
|
+
case "FunctionExpression":
|
|
1659
|
+
case "ArrowFunctionExpression": return key === "id" || key === "params";
|
|
1660
|
+
case "ClassDeclaration":
|
|
1661
|
+
case "ClassExpression": return key === "id";
|
|
1662
|
+
case "CatchClause": return key === "param";
|
|
1663
|
+
case "ArrayPattern":
|
|
1664
|
+
case "RestElement":
|
|
1665
|
+
case "UpdateExpression": return true;
|
|
1666
|
+
case "AssignmentPattern":
|
|
1667
|
+
case "AssignmentExpression":
|
|
1668
|
+
case "ForInStatement":
|
|
1669
|
+
case "ForOfStatement": return key === "left";
|
|
1670
|
+
default: return false;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* ESTree positions where an identifier, outside a binding position, reads a
|
|
1675
|
+
* binding rather than naming a property, label, specifier, or meta property.
|
|
1676
|
+
* Positions not listed read a binding, so the binding positions must be ruled
|
|
1677
|
+
* out first (`isBindingPosition`).
|
|
1678
|
+
* @param parent - Parent of the identifier.
|
|
1679
|
+
* @param key - The parent property holding it.
|
|
1680
|
+
* @returns Whether the identifier reads a binding.
|
|
1681
|
+
*/
|
|
1682
|
+
function isReadPosition(parent, key) {
|
|
1683
|
+
switch (parent.type) {
|
|
1684
|
+
case "MemberExpression": return key !== "property" || parent.computed === true;
|
|
1685
|
+
case "Property":
|
|
1686
|
+
case "MethodDefinition":
|
|
1687
|
+
case "PropertyDefinition": return key !== "key" || parent.computed === true;
|
|
1688
|
+
case "LabeledStatement":
|
|
1689
|
+
case "BreakStatement":
|
|
1690
|
+
case "ContinueStatement":
|
|
1691
|
+
case "ImportSpecifier":
|
|
1692
|
+
case "ImportDefaultSpecifier":
|
|
1693
|
+
case "ImportNamespaceSpecifier":
|
|
1694
|
+
case "ExportSpecifier":
|
|
1695
|
+
case "ExportAllDeclaration":
|
|
1696
|
+
case "MetaProperty": return false;
|
|
1697
|
+
default: return true;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
/**
|
|
1701
|
+
* @param parent - Parent of a statement.
|
|
1702
|
+
* @param key - The parent property holding it.
|
|
1703
|
+
* @returns Whether the statement sits in a statement list, where it can follow
|
|
1704
|
+
* a statement that ends without a semicolon.
|
|
1705
|
+
*/
|
|
1706
|
+
function inStatementList(parent, key) {
|
|
1707
|
+
if (parent === void 0) return false;
|
|
1708
|
+
if (parent.type === "SwitchCase") return key === "consequent";
|
|
1709
|
+
return key === "body" && (parent.type === "Program" || parent.type === "BlockStatement" || parent.type === "StaticBlock");
|
|
1710
|
+
}
|
|
1479
1711
|
/** Every binding an exported declaration introduces, including patterns. */
|
|
1480
1712
|
function declaredBindings(declaration, fail) {
|
|
1481
1713
|
if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-experimental-webworker-runtime",
|
|
3
3
|
"description": "Browser-only harness runtime: in-memory VFS, module transform and loader, postMessage tunnel, and the dedicated Web Worker assembly, with the Node-compatibility layer that lets the host tree run unchanged",
|
|
4
|
-
"version": "0.2.2-
|
|
4
|
+
"version": "0.2.2-rc.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -28,41 +28,44 @@
|
|
|
28
28
|
},
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@deepseek-ai/dsh-util-crypto": "0.2.2-
|
|
31
|
+
"@deepseek-ai/dsh-util-crypto": "0.2.2-rc.1",
|
|
32
32
|
"@noble/hashes": "^2.4.0",
|
|
33
33
|
"@yarnpkg/parsers": "^3.1.0",
|
|
34
34
|
"acorn": "^8.18.0",
|
|
35
35
|
"buffer": "^6.0.3",
|
|
36
|
+
"eslint-scope": "^9.1.2",
|
|
37
|
+
"eslint-visitor-keys": "^5.0.1",
|
|
36
38
|
"picomatch": "^4.0.7",
|
|
37
39
|
"readable-stream": "^4.7.0",
|
|
38
|
-
"@deepseek-ai/dsh-client-web": "0.2.2-
|
|
40
|
+
"@deepseek-ai/dsh-client-web": "0.2.2-rc.1",
|
|
39
41
|
"string_decoder": "^1.3.0"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
|
-
"@deepseek-ai/cordis": "~4.0
|
|
43
|
-
"@deepseek-ai/cordis-plugin-loader": "~1.0
|
|
44
|
-
"@deepseek-ai/dsh-client-connection": "0.2.2-
|
|
45
|
-
"@deepseek-ai/dsh-client-modules": "0.2.2-
|
|
46
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.2-
|
|
44
|
+
"@deepseek-ai/cordis": "~4.1.0",
|
|
45
|
+
"@deepseek-ai/cordis-plugin-loader": "~1.1.0",
|
|
46
|
+
"@deepseek-ai/dsh-client-connection": "0.2.2-rc.1",
|
|
47
|
+
"@deepseek-ai/dsh-client-modules": "0.2.2-rc.1",
|
|
48
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.2-rc.1"
|
|
47
49
|
},
|
|
48
50
|
"devDependencies": {
|
|
49
|
-
"@deepseek-ai/cordis": "~4.0
|
|
50
|
-
"@deepseek-ai/cordis-plugin-loader": "~1.0
|
|
51
|
-
"@deepseek-ai/dsh-api-gateway": "0.2.2-
|
|
52
|
-
"@deepseek-ai/dsh-app-boot": "0.2.2-
|
|
53
|
-
"@deepseek-ai/dsh-bash-sandbox": "0.2.2-
|
|
54
|
-
"@deepseek-ai/dsh-client-connection": "0.2.2-
|
|
55
|
-
"@deepseek-ai/dsh-client-file-upload": "0.2.2-
|
|
56
|
-
"@deepseek-ai/dsh-client-modules": "0.2.2-
|
|
57
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.2-
|
|
58
|
-
"@deepseek-ai/dsh-sandbox-local": "0.2.2-
|
|
59
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.2.2-
|
|
60
|
-
"@deepseek-ai/dsh-session": "0.2.2-
|
|
61
|
-
"@deepseek-ai/dsh-session-projection": "0.2.2-
|
|
62
|
-
"@deepseek-ai/dsh-session-persistence-jsonl": "0.2.2-
|
|
63
|
-
"@deepseek-ai/dsh-subagent": "0.2.2-
|
|
64
|
-
"@deepseek-ai/dsh-subprocess-local": "0.2.2-
|
|
51
|
+
"@deepseek-ai/cordis": "~4.1.0",
|
|
52
|
+
"@deepseek-ai/cordis-plugin-loader": "~1.1.0",
|
|
53
|
+
"@deepseek-ai/dsh-api-gateway": "0.2.2-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-app-boot": "0.2.2-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-bash-sandbox": "0.2.2-rc.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-connection": "0.2.2-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-file-upload": "0.2.2-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-client-modules": "0.2.2-rc.1",
|
|
59
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.2-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-sandbox-local": "0.2.2-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.2.2-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-session": "0.2.2-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-session-projection": "0.2.2-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "0.2.2-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-subagent": "0.2.2-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-subprocess-local": "0.2.2-rc.1",
|
|
65
67
|
"@deepseek-ai/node-addon-system": "~0.1.2",
|
|
68
|
+
"@types/estree": "^1.0.9",
|
|
66
69
|
"@types/picomatch": "^4.0.3",
|
|
67
70
|
"@types/readable-stream": "^4.0.24",
|
|
68
71
|
"chokidar": "5.0.0"
|