xbintsc 0.5.20 → 0.5.22
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/AGENTS.md +5 -3
- package/dist/src/driver/compiler.js +1 -1
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/runtime-objects.d.ts +1 -1
- package/dist/src/driver/runtime-objects.js +1 -0
- package/dist/src/driver/runtime-objects.js.map +1 -1
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/node/fs/index.d.ts +4 -3
- package/dist/src/extensions/node/fs/index.js +12 -3
- package/dist/src/extensions/node/fs/index.js.map +1 -1
- package/dist/src/extensions/node/fs-promises/index.d.ts +5 -5
- package/dist/src/extensions/node/fs-promises/index.js +15 -6
- package/dist/src/extensions/node/fs-promises/index.js.map +1 -1
- package/dist/tests/e2e/async-await.test.js +1 -1
- package/dist/tests/e2e/async-fs.test.d.ts +9 -0
- package/dist/tests/e2e/async-fs.test.js +119 -0
- package/dist/tests/e2e/async-fs.test.js.map +1 -0
- package/dist/tests/e2e/fetch.test.js +24 -0
- package/dist/tests/e2e/fetch.test.js.map +1 -1
- package/dist/tests/e2e/gui-canvas.test.js +159 -0
- package/dist/tests/e2e/gui-canvas.test.js.map +1 -1
- package/dist/tests/e2e/gui-example-canvas.test.d.ts +11 -0
- package/dist/tests/e2e/gui-example-canvas.test.js +70 -0
- package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -0
- package/dist/tests/e2e/gui-inline-svg.test.d.ts +11 -0
- package/dist/tests/e2e/gui-inline-svg.test.js +160 -0
- package/dist/tests/e2e/gui-inline-svg.test.js.map +1 -0
- package/doc/ai/contributing.md +2 -1
- package/doc/ai/extensions.md +8 -6
- package/doc/ai/language-support.md +2 -1
- package/doc/ai/zh-CN/contributing.md +1 -1
- package/doc/ai/zh-CN/extensions.md +6 -4
- package/doc/ai/zh-CN/language-support.md +2 -1
- package/doc/gui/api.md +8 -0
- package/doc/gui/canvas.md +47 -21
- package/doc/gui/known-issues.md +10 -9
- package/doc/gui/media.md +32 -3
- package/doc/gui.md +31 -3
- package/doc/implemented/async.md +16 -3
- package/doc/implemented/fetch.md +38 -6
- package/doc/implemented/node/fs-promises.md +19 -8
- package/doc/implemented/node.md +1 -1
- package/doc/implemented.md +1 -1
- package/doc/unimplemented/deviations.md +1 -1
- package/doc/unimplemented/node/async.md +6 -3
- package/doc/unimplemented/node/fs-promises.md +10 -6
- package/doc/unimplemented/node/fs.md +7 -8
- package/doc/unimplemented/node.md +2 -2
- package/doc/unimplemented/toolchain.md +1 -1
- package/doc/zh-CN/gui/api.md +7 -0
- package/doc/zh-CN/gui/canvas.md +36 -17
- package/doc/zh-CN/gui/known-issues.md +8 -7
- package/doc/zh-CN/gui/media.md +26 -2
- package/doc/zh-CN/gui.md +24 -3
- package/doc/zh-CN/implemented/async.md +13 -2
- package/doc/zh-CN/implemented/fetch.md +23 -4
- package/doc/zh-CN/implemented/node/fs-promises.md +6 -3
- package/doc/zh-CN/implemented/node.md +1 -1
- package/doc/zh-CN/implemented.md +1 -1
- package/doc/zh-CN/unimplemented/deviations.md +1 -1
- package/doc/zh-CN/unimplemented/node/async.md +6 -3
- package/doc/zh-CN/unimplemented/node/fs-promises.md +4 -4
- package/doc/zh-CN/unimplemented/node/fs.md +2 -2
- package/doc/zh-CN/unimplemented/node.md +2 -2
- package/doc/zh-CN/unimplemented/toolchain.md +1 -1
- package/package.json +1 -1
- package/runtime/ext_gui/canvas.cpp +114 -199
- package/runtime/ext_gui/canvas.h +101 -2
- package/runtime/ext_gui/canvas_gradient.cpp +112 -0
- package/runtime/ext_gui/canvas_internal.h +6 -6
- package/runtime/ext_gui/canvas_raster.cpp +27 -5
- package/runtime/ext_gui/canvas_stroke.cpp +252 -0
- package/runtime/ext_gui/canvas_style.cpp +240 -0
- package/runtime/ext_gui/dom_api.cpp +1 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +38 -4
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +232 -0
- package/runtime/ext_gui/dom_api_internal.h +31 -0
- package/runtime/ext_gui/dom_api_proto.cpp +24 -0
- package/runtime/ext_gui/inline_svg.cpp +219 -0
- package/runtime/ext_gui/inline_svg.h +41 -0
- package/runtime/ext_gui/layout.cpp +18 -0
- package/runtime/ext_gui/layout.h +7 -0
- package/runtime/ext_gui/layout_flow.cpp +4 -3
- package/runtime/ext_gui/paint.cpp +14 -0
- package/runtime/ext_gui/paint.h +5 -1
- package/runtime/ext_gui/renderer_image.cpp +53 -25
- package/runtime/ext_gui/style_ua.cpp +3 -0
- package/runtime/ext_gui/svg.cpp +122 -39
- package/runtime/ext_gui/svg.h +14 -3
- package/runtime/ext_gui/window.cpp +28 -0
- package/runtime/ext_node/fs/async_api.c +314 -0
- package/runtime/ext_node/fs/async_complete.c +99 -0
- package/runtime/ext_node/fs/async_fh.c +206 -0
- package/runtime/ext_node/fs/async_job.c +81 -0
- package/runtime/ext_node/fs/async_job.h +132 -0
- package/runtime/ext_node/fs/async_worker.c +534 -0
- package/runtime/ext_node/fs/async_worker_dir.c +439 -0
- package/runtime/ext_node/fs/async_worker_dir.h +33 -0
- package/runtime/ext_node/fs/async_worker_fd.c +74 -0
- package/runtime/ext_node/fs/dir.c +60 -15
- package/runtime/ext_node/fs/fs_common.h +9 -0
- package/runtime/ext_node/fs/fs_ops.c +18 -29
- package/runtime/ext_node/fs/parts/builtins.inc +34 -0
- package/runtime/ext_node/fs/parts/platform.inc +66 -0
- package/runtime/ext_node/fs/promises.c +44 -234
- package/runtime/rt_internal.h +2 -0
- package/runtime/xt_async_io.c +333 -0
- package/runtime/xt_async_io.h +47 -0
- package/runtime/xt_fetch/async.inc +295 -0
- package/runtime/xt_fetch/request.inc +6 -183
- package/runtime/xt_fetch/socket.inc +5 -4
- package/runtime/xt_fetch.c +6 -4
- package/runtime/xt_loop.c +44 -3
- package/src/driver/compiler.ts +1 -1
- package/src/driver/runtime-objects.ts +1 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/node/fs/index.ts +12 -3
- package/src/extensions/node/fs-promises/index.ts +15 -6
package/doc/zh-CN/gui/canvas.md
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
CSS 盒中。
|
|
11
11
|
|
|
12
12
|
引擎侧的对象是 `xtgui::Canvas2D`(`runtime/ext_gui/canvas.{h,cpp}`)——一块 RGBA8 位图
|
|
13
|
-
加上 2D 绘制状态。光栅器位于 `canvas_raster.cpp
|
|
13
|
+
加上 2D 绘制状态。光栅器位于 `canvas_raster.cpp`,描边几何(端点、连接、虚线)位于
|
|
14
|
+
`canvas_stroke.cpp`,渐变位于 `canvas_gradient.cpp`,绘制状态解析位于
|
|
15
|
+
`canvas_style.cpp`;DOM 绑定位于 `dom_api_canvas.cpp` / `dom_api_canvas_extra.cpp`;
|
|
14
16
|
按窗口的生命周期位于 `gui_canvas.cpp`。
|
|
15
17
|
|
|
16
18
|
## 获取上下文
|
|
@@ -31,6 +33,11 @@ const ctx = canvas.getContext("2d"); // 其他上下文类型返回 null
|
|
|
31
33
|
以相反方向环绕时能形成空洞)。轴对齐矩形(变换中 `b == 0 && c == 0`)走直接的覆盖率
|
|
32
34
|
快速路径。混合为非预乘 source-over,并按 `globalAlpha` 缩放。
|
|
33
35
|
|
|
36
|
+
填充或描边可以使用纯色,也可以使用 **`CanvasGradient`**。渐变的坐标属于用户空间,
|
|
37
|
+
因此光栅器会先用当前变换的逆矩阵把每个设备像素映射回用户空间再采样——形状被平移、
|
|
38
|
+
缩放或旋转时,渐变仍然贴在形状上。描边被展平为线段四边形,再按 `lineJoin`/`lineCap`
|
|
39
|
+
补上连接/端点形状;虚线模式先把折线切成“实线”片段,然后用同样的端点规则描边。
|
|
40
|
+
|
|
34
41
|
Canvas 像素**不参与垃圾回收**:canvas 由窗口拥有、以 DOM 节点为键(与
|
|
35
42
|
`<video>`/`<audio>` 解码表结构相同)。当节点被丢弃(`loadHTML`、窗口关闭/退出,或丢弃
|
|
36
43
|
子树的变更操作)时随之释放,并释放对应的 GPU 纹理。
|
|
@@ -39,21 +46,34 @@ Canvas 像素**不参与垃圾回收**:canvas 由窗口拥有、以 DOM 节点
|
|
|
39
46
|
|
|
40
47
|
状态与变换:`save` / `restore`(会恢复变换、线宽、透明度、字体/文本设置**以及**
|
|
41
48
|
填充/描边样式)、`translate`、`rotate`、`scale`、`transform(a,b,c,d,e,f)`、
|
|
42
|
-
`setTransform`、`resetTransform
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
`
|
|
46
|
-
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
`setTransform`、`resetTransform`、`getTransform`(返回带 `a`…`f` 与 `is2D` 的对象)。
|
|
50
|
+
变换按 canvas 的顺序组合:`translate(x, y); rotate(a)` 围绕平移后的原点旋转。
|
|
51
|
+
|
|
52
|
+
样式与设置:`fillStyle` / `strokeStyle`(层叠所用的颜色解析器能识别的 CSS 颜色,或
|
|
53
|
+
`CanvasGradient`)、`lineWidth`、`globalAlpha`、`lineCap`(`butt`/`round`/`square`)、
|
|
54
|
+
`lineJoin`(`miter`/`round`/`bevel`)、`miterLimit`、`lineDashOffset`、`font`
|
|
55
|
+
(CSS 字体简写,解析出字体族、字号与粗体/斜体——默认 `10px sans-serif`)、
|
|
56
|
+
`textAlign`(`start`/`left`、`center`、`right`/`end`)与 `textBaseline`
|
|
57
|
+
(`alphabetic`、`top`、`middle`、`bottom`、`hanging`、`ideographic`)。读取属性返回
|
|
58
|
+
上次赋予的值;赋予无法解析的颜色会保留原值。
|
|
59
|
+
|
|
60
|
+
渐变:`createLinearGradient(x0, y0, x1, y1)` 与
|
|
61
|
+
`createRadialGradient(x0, y0, r0, x1, y1, r1)` 返回带
|
|
62
|
+
`addColorStop(offset, color)` 的 `CanvasGradient`。色标是**活的**:在
|
|
63
|
+
`fillStyle = gradient` 之后追加的色标会影响后续填充,且 `fillStyle`/`strokeStyle`
|
|
64
|
+
的读取返回同一个渐变句柄。径向渐变按到**外圆**圆心(`x1, y1`)的距离插值,因此目前
|
|
65
|
+
会忽略 `x0`/`y0`——请使用同心圆(`x0 == x1`、`y0 == y1`)。
|
|
66
|
+
|
|
67
|
+
路径:`beginPath`、`closePath`、`moveTo`、`lineTo`、`rect`、`roundRect`、`arc`、
|
|
68
|
+
`ellipse`、`quadraticCurveTo`、`bezierCurveTo`,然后 `fill`(多环、非零环绕)或
|
|
69
|
+
`stroke`。贝塞尔与二次曲线段会被展平为线段;弧线与椭圆同样被展平。`roundRect` 只接受
|
|
70
|
+
单个圆角半径数字(数组形式尚未实现)。
|
|
54
71
|
|
|
55
72
|
矩形:`clearRect`、`fillRect`、`strokeRect`。
|
|
56
73
|
|
|
74
|
+
虚线:`setLineDash(segments)` / `getLineDash()` / `lineDashOffset` 实现标准规则
|
|
75
|
+
(奇数长度列表会复制一遍,负数/非有限值会被忽略,全零列表表示实线)。
|
|
76
|
+
|
|
57
77
|
文本:`measureText(text)`(返回 `{ width }`)、`fillText(text, x, y)` 与
|
|
58
78
|
`strokeText(text, x, y)`。文本经 HarfBuzz 排版、FreeType 光栅化(与 HTML 文本相同的
|
|
59
79
|
技术栈),按变换的近似缩放绘制。**仅支持平移与均匀缩放**——旋转或斜切变换仍会把每个
|
|
@@ -70,11 +90,10 @@ Canvas 像素**不参与垃圾回收**:canvas 由窗口拥有、以 DOM 节点
|
|
|
70
90
|
|
|
71
91
|
## 尚未实现
|
|
72
92
|
|
|
73
|
-
|
|
74
|
-
`
|
|
75
|
-
`createImageData`、`isPointInPath`、`getTransform`、以 `DOMMatrix` 调用的
|
|
93
|
+
图案(`createPattern`)、阴影、`clip()`、`globalCompositeOperation`、
|
|
94
|
+
`putImageData`、`createImageData`、`isPointInPath`、以 `DOMMatrix` 调用的
|
|
76
95
|
`setTransform`、可切换图像平滑的 `drawImage`、`toDataURL`/`toBlob`、把 `<canvas>` 用作
|
|
77
96
|
CSS `background-image`,以及离屏画布(`OffscreenCanvas`、
|
|
78
|
-
`transferControlToOffscreen
|
|
97
|
+
`transferControlToOffscreen`)。`roundRect` 只接受单个半径,径向渐变会忽略内圆偏移。
|
|
79
98
|
|
|
80
99
|
另见[媒体](./media.md):`drawImage` 与纹理上传所共享的图像/视频/音频解码栈。
|
|
@@ -23,13 +23,14 @@
|
|
|
23
23
|
`tests/e2e/gui-example-browser.test.ts` 中。
|
|
24
24
|
- **`display: none -> flex` 的重排。** 通过类名切换让隐藏元素显示在 flex 容器上时,也曾观察
|
|
25
25
|
到同样的崩溃;`examples/gui/pelican-bike` 改用 `opacity` 显示游戏结束遮罩。
|
|
26
|
-
- **SVG
|
|
27
|
-
|
|
28
|
-
`
|
|
29
|
-
`<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
- **SVG 是 NanoSVG 的子集。** SVG *文件*(`<img src="logo.svg">`)与内联
|
|
27
|
+
`<svg>` 子树共用 vendored 的 NanoSVG 解析/光栅化器(`runtime/ext_gui/svg.cpp`、
|
|
28
|
+
`inline_svg.cpp`),它会渲染 `path`/`rect`/`circle`/`ellipse`/`line`/
|
|
29
|
+
`polyline`/`polygon`、组、`defs` 渐变以及基于 `class` 的 `<style>` 规则。
|
|
30
|
+
`<text>`、`<use>`、滤镜、遮罩与裁剪路径不会渲染,文档层叠的 CSS 也不会进入
|
|
31
|
+
图像内部(这里的 `fill`/`stroke` 是 SVG 表现属性,不是 CSS 属性)。需要这些
|
|
32
|
+
能力的矢量美术必须预先光栅化、用盒子绘制,或限制在受支持的语法内。参见
|
|
33
|
+
[媒体](./media.md#图像m6a)。
|
|
33
34
|
|
|
34
35
|
## 待决问题
|
|
35
36
|
|
package/doc/zh-CN/gui/media.md
CHANGED
|
@@ -12,7 +12,8 @@ PNG/JPEG/BMP/GIF/TGA 解码为 RGBA8,并带有解码缓存与仅头文件的
|
|
|
12
12
|
`runtime/ext_gui/svg.{h,cpp}` 在其上增加 SVG:它封装 vendored **NanoSVG**
|
|
13
13
|
库(解析 + 抗锯齿扫描线光栅化),按扩展名或内容识别 SVG,并产出与既有管线
|
|
14
14
|
相同的 RGBA8 `Image`。`stb_image` 无法解码 SVG,这正是
|
|
15
|
-
`<img src="logo.svg">`
|
|
15
|
+
`<img src="logo.svg">` 能工作的原因。内联 `<svg>` 子树会先被序列化成一个
|
|
16
|
+
独立文档(`inline_svg.{h,cpp}`),再交给同一个解析器。
|
|
16
17
|
|
|
17
18
|
- `<img>` 是一个替换元素(`display: inline-block`):设置了 CSS 尺寸时布局
|
|
18
19
|
采用该尺寸,否则采用固有像素尺寸;当只约束一个轴时保持宽高比。构建盒树时
|
|
@@ -23,11 +24,34 @@ PNG/JPEG/BMP/GIF/TGA 解码为 RGBA8,并带有解码缓存与仅头文件的
|
|
|
23
24
|
**位图**按固有分辨率解码并按路径缓存;**矢量图**(SVG)按设备像素下的绘制
|
|
24
25
|
尺寸(逻辑尺寸 × 窗口像素密度)光栅化并保持 viewBox 宽高比,再按该尺寸缓存,
|
|
25
26
|
因此缩放或 HiDPI 得到的是清晰渲染而非放大的位图。
|
|
27
|
+
- **内联** `<svg>` 元素与 `<img>` 一样是替换元素,但它的来源就是 DOM 子树
|
|
28
|
+
本身。`runtime/ext_gui/inline_svg.{h,cpp}` 把该子树序列化回独立 SVG 文档,
|
|
29
|
+
还原 HTML 解析器会小写掉的、NanoSVG 又按大小写精确匹配的拼写(`viewBox`、
|
|
30
|
+
`preserveAspectRatio`、`linearGradient`、`gradientUnits` 等)。布局先取
|
|
31
|
+
`width`/`height` 属性、其次 `viewBox`、最后 300x150 作为固有尺寸;绘制把
|
|
32
|
+
markup 挂在图像 op 上,渲染器按绘制设备像素尺寸,通过与 SVG 文件相同的
|
|
33
|
+
NanoSVG 缓存解析并光栅化。DOM 变更会在下一次布局时重新序列化(因此
|
|
34
|
+
`setAttribute` 与 `innerHTML` 都会重绘图像),markup 缓存有界
|
|
35
|
+
(最近最少使用),动画文档不会让它无限增长。
|
|
26
36
|
- 解析结果按路径缓存;解析与光栅化器状态在 `xt_svg_shutdown`
|
|
27
37
|
(`xt_image_shutdown`)中释放。
|
|
28
38
|
|
|
39
|
+
文档 CSS 只作用于 `<svg>` **盒子**——尺寸、外边距、背景、边框、`transform`、
|
|
40
|
+
opacity、`display`——与任何其他元素一样。盒子内部的艺术内容保持 SVG 语义:
|
|
41
|
+
表现属性与 SVG `<style>` 中基于 `class` 的规则由 NanoSVG 读取,而不是 HTML
|
|
42
|
+
层叠,所以这里的 `fill`/`stroke` 不是 CSS 属性。对布局、绘制、命中测试与事件
|
|
43
|
+
而言整个 `<svg>` 就是一个替换盒:其子元素没有 DOM 盒,因此点击的 `e.target`
|
|
44
|
+
是 `<svg>` 元素而不是某个 `<rect>`。渲染器按 markup 与尺寸缓存纹理,所以每帧
|
|
45
|
+
重写艺术内容的程序会为每个变体保留一张纹理;更好的做法是用 `transform`、
|
|
46
|
+
`opacity` 给盒子做动画,或在一小组文档之间切换。
|
|
47
|
+
|
|
29
48
|
图像仍需完成:CSS `background-image: url(...)`、`data:` URI、`object-fit`、
|
|
30
|
-
|
|
49
|
+
九宫格边框。
|
|
50
|
+
|
|
51
|
+
两种 SVG 都受限于 NanoSVG 的子集:`path`、`rect`、`circle`、`ellipse`、
|
|
52
|
+
`line`、`polyline`、`polygon`、组(`g`)、带线性/径向渐变的 `defs` 以及基于
|
|
53
|
+
`class` 的 `<style>` 规则会被光栅化;`<text>`、`<use>`、滤镜、遮罩与裁剪路径
|
|
54
|
+
不会渲染(见[已知问题](./known-issues.md))。
|
|
31
55
|
|
|
32
56
|
## 视频与音频(M13)
|
|
33
57
|
|
package/doc/zh-CN/gui.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 语言 / Language:[English](../gui.md) | **简体中文**
|
|
4
4
|
|
|
5
|
-
状态:**
|
|
5
|
+
状态:**M16** —— 功能(M1–M15)已全部完成:HTML 解析、CSS 选择器匹配、层叠(cascade)、计算样式与布局(块级、行内、Flexbox 与 CSS 定位)均已就位,引擎还会**绘制**:它构建一个由矩形、图像与排版后的文本 run 组成的显示列表,并通过 SDL_GPU 渲染。输入事件会经过命中测试并投递给原生 TS 处理器,`:hover`/`:focus` 会被动态匹配,`<img>` 依据其固有尺寸确定大小并从纹理绘制——位图(PNG/JPEG/…)与 SVG 文件皆可,后者按绘制尺寸光栅化,因此矢量图保持清晰——CSS transition 会为绘制属性做动画。**M16** 让内联 `<svg>` 子树获得同样的处理:子树被序列化回 SVG 文档,并按绘制设备尺寸光栅化,因此图标不再需要单独的文件。**M8** 增加了交互式 DOM:具有稳定标识的元素句柄、变更操作(`appendChild`、`textContent`、`classList`、`style` 等)以及支持捕获/冒泡的元素级事件。**M9** 会提前编译 `<script>` 主体(内联与 `<script src>`)——参见 `gui-scripts.md`。**M10** 增加 `requestAnimationFrame` 以及若干 DOM 辅助方法。**M11** 增加 `position: relative`/`absolute`/`fixed` 及其偏移,`examples/gui/pelican-bike`(一个可玩的 2D 游戏)就构建在它之上。**M12** 明确了 DOM 节点生命周期(哪些变更释放、哪些保留),并让引擎内存有界:参见[节点生命周期](./gui/dom.md)与[内存与 GC](./gui/runtime.md)。**M13** 真正播放
|
|
6
6
|
`<video>`/`<audio>`——一个 vendored 的最小 FFmpeg 在主线程解码,视频帧走图像
|
|
7
7
|
纹理路径、音频进入 SDL 流,DOM 媒体 API 暴露 `play`/`pause`/`currentTime`/…
|
|
8
8
|
与媒体事件。**M14** 增加了 `<canvas>`,配一个自研的 2D 软件光栅器(抗锯齿
|
|
@@ -212,6 +212,16 @@ FFmpeg `7.1`(可用 `SDL3_TAG` / `FREETYPE_VERSION` / `HARFBUZZ_VERSION` /
|
|
|
212
212
|
[布局](./gui/layout.md#变换m15)与[动画](./gui/animation.md#css-transformm15);
|
|
213
213
|
e2e 见 `tests/e2e/gui-transform.test.ts` 与
|
|
214
214
|
`tests/e2e/gui-example-svg.test.ts`。
|
|
215
|
+
16. **M16 — 内联 `<svg>`** ✅
|
|
216
|
+
- `<svg>` 是替换元素(`layout.*`):固有尺寸先取 `width`/`height` 属性,
|
|
217
|
+
其次 `viewBox`,最后 300x150;常规盒树遍历不再进入其子元素。
|
|
218
|
+
- `inline_svg.{h,cpp}` 把子树序列化为独立 SVG 文档,并还原 HTML 解析器
|
|
219
|
+
小写掉的、区分大小写的名称(`viewBox`、`preserveAspectRatio`、
|
|
220
|
+
`linearGradient`、`gradientUnits` 等)。
|
|
221
|
+
- 绘制把 markup 挂在图像 op 上(`PaintImage::svg`),渲染器按绘制设备尺寸、
|
|
222
|
+
通过与 SVG 文件相同的 NanoSVG 缓存(`svg.{h,cpp}`)解析并光栅化;markup
|
|
223
|
+
缓存有界,DOM 变更会在下一次布局时重新序列化。e2e 见
|
|
224
|
+
`tests/e2e/gui-inline-svg.test.ts`。
|
|
215
225
|
|
|
216
226
|
## 进度日志
|
|
217
227
|
|
|
@@ -286,8 +296,12 @@ FFmpeg `7.1`(可用 `SDL3_TAG` / `FREETYPE_VERSION` / `HARFBUZZ_VERSION` /
|
|
|
286
296
|
(4 条子扫描线 + 水平解析覆盖率、非零环绕),`getContext("2d")` 句柄及其 API
|
|
287
297
|
在 `dom_api_canvas.cpp` 绑定,`gui_canvas.cpp` 持有按窗口的生命周期。位图经
|
|
288
298
|
图像纹理路径上传(`renderer_image.cpp`),显示列表携带 `canvas_id`
|
|
289
|
-
(`paint
|
|
290
|
-
`
|
|
299
|
+
(`paint.*`)。此后绘制面又补齐了线性/径向渐变(`canvas_gradient.cpp`)、
|
|
300
|
+
`ellipse`/`roundRect`、线段端点/连接/斜接上限与虚线模式(`canvas_style.cpp`、
|
|
301
|
+
`canvas_stroke.cpp`)以及 `getTransform`;`transform` 改为后乘,因此
|
|
302
|
+
`translate(x, y); rotate(a)` 围绕平移后的原点旋转,而
|
|
303
|
+
`examples/gui/pelican-canvas` 完全用这些 API 画出会动的鹈鹕骑自行车。参见
|
|
304
|
+
[Canvas](./gui/canvas.md);e2e 见 `tests/e2e/gui-canvas.test.ts`。
|
|
291
305
|
- **M15** ✅ CSS `transform` / `transform-origin`。新的翻译单元
|
|
292
306
|
(`transform.{h,cpp}`)把 `translate`/`translateX`/`translateY`/`scale`/
|
|
293
307
|
`scaleX`/`scaleY`/`rotate`/`matrix`(以及 `translate3d`/`scale3d`,其 `z` 参数被丢弃)
|
|
@@ -299,4 +313,11 @@ FFmpeg `7.1`(可用 `SDL3_TAG` / `FREETYPE_VERSION` / `HARFBUZZ_VERSION` /
|
|
|
299
313
|
`getBoundingClientRect` 返回变换后的包围盒。`examples/gui/pelican-svg` 用它
|
|
300
314
|
为自己的画做动画;e2e 见 `tests/e2e/gui-transform.test.ts` 与
|
|
301
315
|
`tests/e2e/gui-example-svg.test.ts`。
|
|
316
|
+
- **M16** ✅ 内联 `<svg>`。`buildBoxTree` 把 `<svg>` 元素当作替换盒(固有尺寸
|
|
317
|
+
依次取 `width`/`height`、`viewBox`、300x150)并停止下探,
|
|
318
|
+
`inline_svg.{h,cpp}` 以规范 SVG 大小写序列化子树,绘制把 markup 放进
|
|
319
|
+
`PaintImage::svg`,`renderer_image.cpp` 通过 NanoSVG 缓存(`svg.{h,cpp}`,
|
|
320
|
+
markup 采用有界 LRU)按绘制设备像素尺寸光栅化。`win.inlineSvg` 诊断钩子
|
|
321
|
+
暴露序列化文档,`tests/e2e/gui-inline-svg.test.ts` 固定了尺寸、命中测试、
|
|
322
|
+
渐变、CSS 盒样式与 DOM 变更。
|
|
302
323
|
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
> 属于[已实现语法与功能](../implemented.md) · [English](../../implemented/async.md)
|
|
4
4
|
|
|
5
5
|
实现位置:`runtime/xt_async.c`、`runtime/xt_coroutine.c`、`runtime/xt_promise.c`、
|
|
6
|
-
`runtime/xt_generator.c`、`runtime/xt_loop.c`、`runtime/
|
|
6
|
+
`runtime/xt_generator.c`、`runtime/xt_loop.c`、`runtime/xt_async_io.c`、
|
|
7
|
+
`runtime/xt_performance.c`。
|
|
7
8
|
|
|
8
9
|
## async / await
|
|
9
10
|
|
|
@@ -35,4 +36,14 @@
|
|
|
35
36
|
- `setTimeout` / `clearTimeout` / `setInterval` / `clearInterval` / `setImmediate` / `clearImmediate` / `queueMicrotask` 与 `performance.now`(单调递增的小数毫秒)。
|
|
36
37
|
- 定时器使用数字 id;未实现 `Timeout` / `Immediate` 对象。
|
|
37
38
|
- 定时器 settle 的 promise 可以被 await:async 函数体在 pending promise 上挂起,定时器触发时恢复。套接字与服务端(`net`、`http`、`dgram`)的回调在同一事件循环上投递。
|
|
38
|
-
- `fetch`
|
|
39
|
+
- `fetch` 与 `fs/promises` 由 reactor 驱动而不是阻塞 —— 见下一节。
|
|
40
|
+
|
|
41
|
+
## 异步 I/O offload
|
|
42
|
+
|
|
43
|
+
- `runtime/xt_async_io.c` 维护一个小型工作线程池(默认 4 个,惰性创建)。每个 job 分成两半:worker 上的 `run` 只能访问纯 C 内存;主线程上的 `complete` 才构造值并 settle promise。这个拆分让回收器与值模型保持单线程。
|
|
44
|
+
- job 完成后通过自管道(POSIX)或回环 UDP 套接字(Windows)唤醒 `select(2)`;reactor 也会轮询线程池,因此唤醒失败只会退化为短暂等待,而不会挂起。
|
|
45
|
+
- job 排队或运行期间,每个 job 最多四个值(promise;对 `fetch` 还有 headers 对象)保存在 job 的 root 槽中,由回收器扫描。
|
|
46
|
+
- `fetch` 把每一跳请求/重定向作为 job 执行;`fs/promises` 把每个文件与描述符操作作为 job 执行。两者都不会阻塞定时器、套接字或其他 `await`。
|
|
47
|
+
- 仍有 job 未完成时事件循环保持存活(`xt_loop_has_work`),线程池空闲后退出。
|
|
48
|
+
|
|
49
|
+
异步表面的已知限制(`fetch` 无 TLS/流式、`fs.watch` 不触发、线程池固定 4 个 worker)列在[运行时偏差](../unimplemented/deviations.md)与各 Node 页面。
|
|
@@ -2,11 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
> 属于[已实现语法与功能](../implemented.md) · [English](../../implemented/fetch.md)
|
|
4
4
|
|
|
5
|
-
实现位置:`runtime/xt_fetch.c`。
|
|
5
|
+
实现位置:`runtime/xt_fetch.c`、`runtime/xt_fetch/async.inc`、`runtime/xt_async_io.c`。
|
|
6
6
|
|
|
7
|
-
- 全局 `fetch(input, init)`
|
|
7
|
+
- 全局 `fetch(input, init)` 是 HTTP/1.1 客户端。阻塞的套接字交换(`getaddrinfo`、connect、send、receive)运行在异步 I/O 工作线程池上,因此进行中的请求**不会**卡住事件循环:定时器、套接字与其他 `await` 继续运行,promise 在 reactor 派发完成结果时 settle。
|
|
8
|
+
- 重定向在主线程上处理:每一跳是一次 offload 交换,最多 20 次;301/302/303 会把 POST 改成 GET。
|
|
8
9
|
- 只接受 `http://` URL —— 由于未链接 TLS 后端,`https://` 会以 `TypeError` 拒绝。
|
|
9
|
-
- 选项:`method`、`headers`(普通对象或 `Headers`)、`body` 与 `redirect`(`follow` / `manual` / `error
|
|
10
|
-
- 解析出的 `Response` 形状对象暴露 `ok` / `status` / `statusText` / `url` / `headers` 以及 `text()` / `json()` / `arrayBuffer()` / `bytes()` / `clone()
|
|
10
|
+
- 选项:`method`、`headers`(普通对象或 `Headers`)、`body` 与 `redirect`(`follow` / `manual` / `error`)。
|
|
11
|
+
- 解析出的 `Response` 形状对象暴露 `ok` / `status` / `statusText` / `url` / `headers` 以及 `text()` / `json()` / `arrayBuffer()` / `bytes()` / `clone()`。响应体在 promise settle 前已完整缓冲;不支持流式响应体。
|
|
11
12
|
- `Headers` 大小写不敏感,提供 `get` / `has` / `set` / `append` / `delete` / `keys` / `values` / `entries` / `forEach` / `getSetCookie`。
|
|
12
13
|
- 非法 URL 与网络失败会以 `TypeError` 拒绝。
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
async function main(): Promise<void> {
|
|
17
|
+
const response = await fetch("http://127.0.0.1:8080/status");
|
|
18
|
+
console.log(response.status, await response.text());
|
|
19
|
+
}
|
|
20
|
+
main();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
在请求完成前安排的定时器会在交换仍在进行时触发:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const pending = fetch("http://127.0.0.1:8080/slow");
|
|
27
|
+
setTimeout(() => console.log("timer"), 10); // 会在 150ms 的响应之前运行
|
|
28
|
+
await pending;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
已知限制(仅 `http://`、无 TLS、响应体整体缓冲)列在[运行时偏差](../unimplemented/deviations.md)。
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> 属于[Node 扩展:已实现](../node.md) · [English](../../../implemented/node/fs-promises.md)
|
|
4
4
|
|
|
5
|
-
实现位置:`src/extensions/node/fs-promises/index.ts`、`runtime/ext_node/fs/promises.c`
|
|
5
|
+
实现位置:`src/extensions/node/fs-promises/index.ts`、`runtime/ext_node/fs/async_*.c`、`runtime/ext_node/fs/promises.c`
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
每个函数都会向运行时的异步 I/O 线程池(`runtime/xt_async_io.c`)提交一个 job:阻塞的系统调用在 worker 线程上执行,promise 在事件循环上 settle。因此 `await` 在大文件读取、慢速网络文件系统或描述符操作进行期间会让出,`then` / `catch` 保持标准 Promise 语义。失败时会以与同步形式相同的 Node `Error`(含 `code` / `errno` / `syscall` / `path`)**reject**。
|
|
8
|
+
|
|
9
|
+
`fs.promises` 也可从 `fs` 模块访问(`import { promises as fsp } from "fs"`),两个命名空间都暴露 `constants` 对象。
|
|
8
10
|
|
|
9
11
|
Promise 导出:`readFile`、`writeFile`、`appendFile`、`mkdir`、`readdir`、`rm`、`unlink`、`rmdir`、`rename`、`copyFile`、`cp`、`realpath`、`stat`、`lstat`、`statfs`、`access`、`open`、`chmod`、`lchmod`、`chown`、`lchown`、`truncate`、`utimes`、`lutimes`、`link`、`symlink`、`readlink`、`mkdtemp`、`opendir`、`glob`、`watch`。
|
|
10
12
|
|
|
11
|
-
`open(...)` 解析为 **`FileHandle`**,带有:`read`、`write`、`readFile`、`writeFile`、`appendFile`、`close`、`stat`、`truncate`、`chmod`、`chown`、`utimes`、`sync`、`datasync`。
|
|
13
|
+
`open(...)` 解析为 **`FileHandle`**,带有:`read`、`write`、`readFile`、`writeFile`、`appendFile`、`close`、`stat`、`truncate`、`chmod`、`chown`、`utimes`、`sync`、`datasync`。这些方法同样会 offload;`read(buffer, …)` 会在 worker 完成后填充调用方的 `Buffer`。
|
|
12
14
|
|
|
13
15
|
```ts
|
|
14
16
|
import { readFile, writeFile, open } from "fs/promises";
|
|
@@ -23,5 +25,6 @@ async function main(): Promise<void> {
|
|
|
23
25
|
main();
|
|
24
26
|
```
|
|
25
27
|
|
|
28
|
+
工作由固定的小型线程池(4 个 worker)执行,完成结果按每个 worker 的提交顺序派发;相互独立的操作可以重叠。任何 job 都不会阻塞其他 `await`、定时器或套接字回调。
|
|
26
29
|
|
|
27
30
|
已知偏差见[未实现:`fs/promises`](../../unimplemented/node/fs-promises.md)。
|
|
@@ -17,7 +17,7 @@ TypeScript 导出与 C 实现一一对应。新增模块不需要改动核心编
|
|
|
17
17
|
| 模块 | 页面 | 说明 |
|
|
18
18
|
| --- | --- | --- |
|
|
19
19
|
| `fs` | [fs](./node/fs.md) | 仅同步 API |
|
|
20
|
-
| `fs/promises` | [fs/promises](./node/fs-promises.md) |
|
|
20
|
+
| `fs/promises` | [fs/promises](./node/fs-promises.md) | 由 reactor 驱动、跑在异步 I/O 线程池上的文件与 `FileHandle` 操作 |
|
|
21
21
|
| `path` | [path](./node/path.md) | `path.<name>(...)` 命名空间调用 |
|
|
22
22
|
| `os` | [os](./node/os.md) | `os.<name>(...)` 命名空间调用 |
|
|
23
23
|
| `process` | [process](./node/process.md) | 对象:方法与属性 |
|
package/doc/zh-CN/implemented.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
- [集合](./implemented/collections.md) —— Map、Set、WeakMap、WeakSet、WeakRef、迭代
|
|
32
32
|
- [类型化数组与二进制数据](./implemented/typed-arrays.md) —— 类型化数组、ArrayBuffer、DataView
|
|
33
33
|
- [异步、Promise 与生成器](./implemented/async.md) —— async/await、异步生成器、Promise、定时器
|
|
34
|
-
- [fetch](./implemented/fetch.md) ——
|
|
34
|
+
- [fetch](./implemented/fetch.md) —— 由 reactor 驱动的 HTTP/1.1 客户端与 Headers
|
|
35
35
|
|
|
36
36
|
### 模块与工具
|
|
37
37
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
| 数组越界 / 稀疏 | 越界访问返回 `undefined`;对 `arr.length` 赋值会截断 / 扩展,但不区分稀疏空洞 |
|
|
15
15
|
| 内存管理 | 非移动标记-清扫回收器(在 `xt_alloc` 之后):显式根、子系统根提供者与保守 C 栈扫描。单线程、stop-the-world;无移动/压缩与分代 |
|
|
16
16
|
| 函数 `arity` / 调用参数个数 | 无参数个数校验;`fn.length` 报告声明的 arity,但调用不做校验 |
|
|
17
|
-
| `async` / `await` | 已在栈式协程上真实挂起;`await` 总会排入一次微任务(非 Promise 与已 settle 的 Promise 也一样),因此与 pending `.then` 回调的交错顺序符合规范。顶层 `await` 会阻塞事件循环等待,而不是让出模块主体。`fs/promises`
|
|
17
|
+
| `async` / `await` | 已在栈式协程上真实挂起;`await` 总会排入一次微任务(非 Promise 与已 settle 的 Promise 也一样),因此与 pending `.then` 回调的交错顺序符合规范。顶层 `await` 会阻塞事件循环等待,而不是让出模块主体。`fs/promises` 与 `fetch` 把阻塞工作 offload 到 4 线程池并在 reactor 上 settle。异步生成器可在 `await` 与 `yield` 处挂起,`for await...of` 每次迭代等待一步 |
|
|
18
18
|
| 异步生成器清理 | `for await...of` 提前退出时不会调用迭代器的 `return()`。异步生成器中的 `yield*` 只委托同步可迭代对象。在挂起的 `yield` 处调用 `.return()` 会直接完成而不执行 `finally`(与同步生成器相同的限制) |
|
|
19
19
|
| `super` | `super.x` / `super(...)` 取 `this` 原型的原型;单级继承正确,继承深度 > 1 时可能不准确 |
|
|
20
20
|
| `Error.stack` | 仅函数级帧:每帧为 `at 名称 (文件:行)`,行号取自函数声明(最内层帧会更新为错误构造处);没有列号,生成器 / `async` 函数体不产生帧(它们会切换栈) |
|
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
已实现部分:
|
|
6
6
|
|
|
7
7
|
- 核心事件循环 `runtime/xt_loop.c`(`select(2)` 反应堆),`net` / `dgram` / `http` 均构建于其上。
|
|
8
|
-
-
|
|
8
|
+
- 异步 I/O offload `runtime/xt_async_io.c`:阻塞的文件与 HTTP 客户端工作在 4 个工作线程上执行,并在 reactor 上完成,因此 `fs/promises` 与 `fetch` 不会卡住定时器或套接字。
|
|
9
|
+
- `Promise`、`async` / `await` 已可用(见核心文档),`fs/promises` 返回从 reactor settle 的 Promise。
|
|
9
10
|
- 定时器已作为全局函数提供:`setTimeout` / `clearTimeout` / `setInterval` / `clearInterval` 运行在核心反应堆上,并在仍有定时器时保持进程存活。
|
|
10
11
|
- 提供独立的 `EventEmitter`(`events` 模块,同时也是全局构造函数);流与套接字额外具备内部发射器方法(`on` / `addListener` / `once` / `off` / `removeListener` / `emit`)。
|
|
11
12
|
|
|
12
13
|
仍未实现:
|
|
13
14
|
|
|
14
15
|
- Node 的 `Timeout` 对象(`setTimeout` 返回数字 id;`setImmediate` 与 `queueMicrotask` 已作为全局函数提供)。
|
|
15
|
-
-
|
|
16
|
+
- 文件监听:`fs.watch` / `fs/promises.watch` 返回惰性对象;没有 inotify/kqueue/ReadDirectoryChangesW 后端。
|
|
17
|
+
- `Dir.read` / `Dir.close` 立即调用回调,回调式 `fs.readFile` / `fs.writeFile` / … 仍不支持(请用 `fs/promises` 或 `*Sync` 形式)。
|
|
16
18
|
- 流与套接字的内置 `once` 等同 `on`(不具「触发一次后移除」语义);`events` 模块的 `EventEmitter` 实现了真正的 `once`。
|
|
17
|
-
- `net` 的 `connect`
|
|
19
|
+
- `net` 的 `connect` 仍是在套接字加入 reactor 之前执行的阻塞 `connect(2)`;HTTP 响应要求 `Connection: close`,不做 keep-alive / 分块传输 / 流水线复用。`fetch` 没有 TLS,且在 resolve 前缓冲整个响应体。
|
|
20
|
+
- offload 线程池固定为 4 个 worker;没有线程池大小选项,也不支持对排队 job 的 `AbortSignal` 取消。
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> 属于[Node 扩展:未实现](../node.md) · [English](../../../unimplemented/node/fs-promises.md)
|
|
4
4
|
|
|
5
|
-
`fs/promises`
|
|
6
|
-
[已实现:`fs/promises`](../../implemented/node/fs-promises.md))。
|
|
5
|
+
`fs/promises` 现在把阻塞 I/O offload 到异步 I/O 线程池(已实现表面见[已实现:`fs/promises`](../../implemented/node/fs-promises.md));剩余差异主要是行为层面的:
|
|
7
6
|
|
|
8
|
-
- I/O 是同步的:Promise 在 `await` 之前就已 settle,因此 await 它不会让出事件循环。
|
|
9
7
|
- `FileHandle.appendFile` 行为等同 `writeFile`(按当前文件位置写入,而不是追加)。
|
|
10
8
|
- `FileHandle.readFile()` 从当前描述符偏移读取。
|
|
11
|
-
- `Dir.read` / `Dir.close`(同步与 Promise
|
|
9
|
+
- `Dir.read` / `Dir.close`(同步与 Promise 形式)立即调用回调;`Dir.readSync` / `closeSync` 仍是同步的。
|
|
12
10
|
- `watch` resolve 为与 `fs.watch` 相同的、永不触发的 watcher;没有真正的文件监听后端。
|
|
11
|
+
- 读写是一次性整体操作;没有流式 `FileHandle` 变体,也不支持 `AbortSignal` 取消。
|
|
12
|
+
- 线程池固定为 4 个 worker;大量并发操作会排队(但仍不会阻塞事件循环)。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 属于[Node 扩展:未实现](../node.md) · [English](../../../unimplemented/node/fs.md)
|
|
4
4
|
|
|
5
|
-
`fs`
|
|
5
|
+
`fs` 实现了**同步** API 表面(文件、目录、描述符、元数据、链接、`cp`、`glob`、`Dir`、`constants`),`fs/promises` 则把每个文件/描述符操作跑在异步 I/O 线程池上(见[已实现:`fs`](../../implemented/node/fs.md)与[已实现:`fs/promises`](../../implemented/node/fs-promises.md))。仍缺少的主要是需要不同后端或回调管线的 API:
|
|
6
6
|
|
|
7
7
|
| 未实现 API | 类别 |
|
|
8
8
|
| --- | --- |
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
- `readFileSync` 支持编码选项(默认/`utf8`/`ascii`/`latin1`/`binary`/`hex`/`base64`/`base64url`),但默认**不返回 `Buffer`**:即使提供了 `Buffer`(以普通对象模拟),`readFileSync` 仍以字符串返回。要读取原始字节请显式指定。
|
|
18
18
|
- 未实现 `utf16le` / `ucs2` 解码(按文本返回字节)。
|
|
19
19
|
- `watch` / `watchFile` / `unwatchFile` 返回 API 形态的发射器对象,`.close()` / `.on()` 方法存在但**不会触发**事件。
|
|
20
|
-
- `Dir.read(cb)` / `Dir.close(cb)`
|
|
20
|
+
- `Dir.read(cb)` / `Dir.close(cb)` 会**同步**完成(回调立即被调用);`FileHandle` 方法现在返回真正的 Promise。
|
|
21
21
|
- `mkdtempSync` 总是向前缀追加 6 个随机字符(不要求以 `XXXXXX` 结尾)。
|
|
22
22
|
- `globSync` 支持 `*`、`?`、`[...]`、`**`,但不支持 `exclude` 回调与 `follow`;`**` 不跟随符号链接(与 Node 默认一致)。
|
|
23
23
|
- `cpSync` 的符号链接处理在常见场景下与 Node 一致,但不支持 `verbatimSymlinks`。
|
|
@@ -8,10 +8,10 @@ Node 扩展实现了 21 个模块以及事件循环集成;已实现表面按
|
|
|
8
8
|
## 目录
|
|
9
9
|
|
|
10
10
|
- [`fs`](./node/fs.md) —— 回调式异步操作、真正的文件监听、选项回调
|
|
11
|
-
- [`fs/promises`](./node/fs-promises.md) ——
|
|
11
|
+
- [`fs/promises`](./node/fs-promises.md) —— `FileHandle` 追加/读取偏移、`Dir` 回调立即完成、`watch` 不触发、无取消
|
|
12
12
|
- [完全未实现的模块](./node/modules.md) —— `https`、`readline`、`tls`、`cluster`、`vm` 等
|
|
13
13
|
- [全局对象与命名空间](./node/globals.md) —— `global`、`__dirname`、`node_modules` 之外的 `require`
|
|
14
|
-
- [异步与事件循环模型](./node/async.md) ——
|
|
14
|
+
- [异步与事件循环模型](./node/async.md) —— 文件监听缺失、阻塞式 `net.connect`、无 keep-alive、固定大小线程池
|
|
15
15
|
- [Bun 扩展](./node/bun.md) —— 仅为设计示例
|
|
16
16
|
|
|
17
17
|
模块的已实现页面会链接到对应限制页;限制解除后,把条目移到
|
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
| 类型检查器 | ✗ 仅定义诊断码,无 checker |
|
|
10
10
|
| 完整标准库 | 部分:Math / JSON / Date / Map / Set / RegExp / `Error` / `BigInt` / `Symbol` / `structuredClone` 已实现;String.normalize 缺失 |
|
|
11
11
|
| 多文件模块打包 | 部分:相对路径 `.ts` 打包、ESM `node_modules` 包、命名空间导入、裸说明符扩展模块导入已实现;CommonJS 仅在 `node_modules` 内处理;循环依赖 / 实时绑定未实现 |
|
|
12
|
-
| 异步运行时 | ✓ `async`/`await` 在 `select(2)` reactor 上对 pending promise 挂起:定时器、TCP
|
|
12
|
+
| 异步运行时 | ✓ `async`/`await` 在 `select(2)` reactor 上对 pending promise 挂起:定时器、TCP 套接字、offload 的文件/HTTP 工作与 promise 回调都能恢复协程。仍缺:真正的 OS 级文件监听、非阻塞 `net.connect`、`fetch` 的 TLS,以及用户可见的 worker 线程(`worker_threads` 仍用子进程) |
|
|
13
13
|
| Windows 二进制产物验证 | 构建层已适配(`.exe` 后缀、链接参数分支),并在 CI 中验证 |
|
|
14
14
|
| 精确的 ECMAScript 数值 / 字符串 / 比较语义 | 部分,见[运行时偏差](./deviations.md) |
|