# ts-native（我们还在开发中）

TypeScript 到原生可执行文件的 AOT 编译器，基于 Cranelift 代码生成引擎。将 TypeScript 直接编译为 x86-64 机器码，生成独立的 `.exe` 文件。

**定位**：对标 Node.js 在**桌面场景（非服务器）** 下的 AOT 编译。不追求通用 Web 可部署性，聚焦桌面应用、CLI 工具、本地脚本、单文件分发等场景。
**策略**：先在 Windows 上把所有功能跑通，再考虑跨平台。

## 快速开始

```bash
# 编译
cargo build --release

# 编译 TypeScript 项目
ts-native build ./my-project

# 编译单个文件
ts-native build main.ts
```

## 技术原理

ts-native 将 TypeScript 编译为原生可执行文件，工作流程：

```
TypeScript 源码 → SWC 解析 → HIR → Cranelift IR → 机器码 → COFF → 可执行文件
```

1. **语法分析**：使用 [swc](https://swc.rs/) 解析 TypeScript，生成 AST
2. **HIR 生成**：将 AST 转换为内部中间表示（HIR），支持 CJS → HIR 转换
3. **代码生成**：通过 [Cranelift](https://cranelift.dev/) 生成 x86-64 机器码
4. **对象生成**：输出 COFF 目标文件
5. **链接**：链接 Runtime DLL + Loader，生成最终独立可执行文件

### 核心设计

- **NaN-boxing**：64 位统一表示所有 JavaScript 值（Number、String、Boolean、Object、Array、Buffer、Function、Null、Undefined）
- **Rust Runtime**：字符串操作、数组管理、类型转换、Promise/事件循环、GC 引用计数、文件系统、网络、加密、压缩、DNS、子进程、TLS、UDP、Stream、EventEmitter
- **内存管理**：基于引用计数的 Pool 分配器，函数退出自动释放、变量赋值释放旧值、函数传参 retain/release
- **跨模块编译**：多文件项目的依赖分析、拓扑排序、符号重命名
- **Node.js 模块兼容**：24/32 内置模块实现，Shim 机制、node_modules 解析、C++ Addon FFI、QuickJS 兜底
- **可观测性**：编译报告包含内存使用、代码覆盖率、各阶段耗时

## 项目结构

```
ts-native/
├── src/
│   ├── lib.rs                  # 库入口
│   ├── main.rs                 # CLI 入口
│   ├── codegen.rs              # 代码生成（HIR → Cranelift IR → 机器码）
│   ├── coff.rs                 # COFF 目标文件生成
│   ├── dep_graph.rs            # 依赖图构建与拓扑排序
│   ├── project.rs              # 项目发现、模块解析、shim/addon 配置
│   ├── project_compiler.rs     # 项目级编译器（编译报告、可观测性、E2E）
│   ├── standalone_gen.rs       # 独立可执行文件生成（含 addon DLL 加载）
│   ├── swc_transform.rs        # SWC AST → HIR 转换（含 CJS→HIR）
│   └── tsn_ffi.rs              # FFI 导出接口（供 loader 调用）
├── runtime/
│   ├── src/lib.rs              # Rust runtime crate（~3800行，200+ 导出函数）
│   ├── build.rs                # QuickJS C 源码编译（可选）
│   └── Cargo.toml              # runtime 依赖（aes, ureq, native-tls, uuid 等）
├── loader/                     # 独立 loader（加载 .tsnobj + runtime DLL 执行）
├── tests/                      # 单元测试 + 集成测试 + E2E 测试项目
│   ├── e2e_test_project/       # 端到端测试项目
│   └── feature_*_test/         # 功能特性测试（shim, node_modules, addon, QuickJS）
├── test_multi_entry/           # 多入口示例项目
├── docs/                       # 文档
└── Cargo.toml
```

## 功能特性

### 支持的 TypeScript 特性

| 类别 | 特性 |
|------|------|
| **基础类型** | number, string, boolean, null, undefined |
| **变量** | let, const, 类型注解 |
| **函数** | 普通函数、递归、多返回值 |
| **控制流** | if/else, for, while, break, continue, return |
| **运算符** | 算术、比较、逻辑、短路、赋值、复合赋值、位运算 |
| **数组** | 字面量、索引访问、push/pop/shift/unshift/splice/join/slice、indexOf/includes、concat/reverse、forEach/map/filter/reduce/sort、length |
| **对象** | 字面量、属性访问/设置、Object.keys/values/entries/assign/create/hasOwn、Object.isArray |
| **字符串** | 模板字符串、拼接(+)、charAt/substring/slice、toLowerCase/toUpperCase、trim/split/replace、startsWith/endsWith/indexOf/includes/concat/repeat、match、length |
| **Buffer** | alloc, from, toString, byteLength, write, concat, 索引读写 |
| **类** | class 定义、构造函数、方法、extends 继承、super()/super.method()、instanceof |
| **错误处理** | try/catch/finally、throw、异常传播 |
| **正则** | 字面量、RegExp.test/exec、String.match |
| **异步** | async/await、Promise、事件循环 |
| **Generator** | function*、yield、状态机 |
| **内置 API** | console.log, Math.\*, parseInt, parseFloat, String, Number, Boolean, toString, typeof |
| **模块** | import/export、多文件项目、入口配置 |
| **CJS 兼容** | require(), module.exports, exports.xxx |

### 不支持的特性

- `with` 语句
- `satisfies` 操作符
- DOM API（document, window 等）
- ES Module 动态 `import()`

### 内存管理（GC）

基于引用计数的自动内存管理：

| 场景 | 机制 |
|------|------|
| **函数退出** | 自动释放所有局部变量 |
| **变量赋值** | `a = newVal` 时释放旧值 |
| **变量引用** | `let a = b` 时 retain，两变量共享引用 |
| **函数传参** | 调用前 retain 参数，返回后 release |
| **数组/对象操作** | push/unshift/concat 时 retain 元素；object_set 时 retain 新值 + release 旧值 |
| **循环引用** | 暂不支持（后续考虑 weak ref）|

### 运行时函数库（200+ 导出函数）

`tsn_runtime.dll` 提供：

| 模块 | 函数 |
|------|------|
| **字符串** | from_static, charAt, substring, slice, toLowerCase, toUpperCase, trim, split, replace, startsWith, endsWith, match, fromCharCode, concat, repeat, indexOf, includes |
| **数组** | new, push, pop, shift, unshift, splice, join, slice, indexOf, includes, concat, reverse, forEach, map, filter, reduce, sort |
| **Buffer** | alloc, from, byteLength, toString, write, concat, index_get, index_set |
| **对象** | new, set, get, keys, values, entries, assign, create, hasOwn, setPrototype |
| **数学** | add, sub, mul, div, fmod, sin, cos, sqrt, pow, abs, floor, ceil, round, log, exp, tan, atan, asin, acos, max, min, random |
| **类型** | strictEquals, typeof, toString |
| **JSON** | stringify, parse |
| **异常** | try_begin, try_end, throw, get_exception, clear_exception |
| **异步** | promise_new, promise_resolve, await, schedule, tick, run_event_loop |
| **定时器** | set_timeout, clear_timeout, set_interval, clear_interval, set_immediate, clear_immediate |
| **GC** | retain, release |
| **I/O** | print, print_multi |

## Node.js 内置模块兼容

ts-native 实现了 **24/32 个 Node.js 核心模块**的运行时支持。

### 已实现模块

| 类别 | 模块 | 状态 | 说明 |
|------|------|------|------|
| **核心** | buffer | ✅ 完整 | alloc/allocUnsafe/from/toString/byteLength/write/concat/slice/fill/copy/equals/indexOf/includes/索引读写 |
| | events | ✅ 完整 | EventEmitter：on/emit/once/removeListener/listenerCount/eventNames |
| | stream | ✅ AOT简化 | Readable/Writable 全量缓冲模式 |
| **文件** | fs | ✅ 35/60+ 函数 | 读写/目录/权限/链接/状态/时间戳/常量/临时目录 |
| | path | ✅ 完整 | join/resolve/dirname/basename/extname/isAbsolute/normalize/relative/format/parse/sep/delimiter |
| **系统** | os | ✅ 完整 | platform/arch/cpus/hostname/homedir/totalmem/freemem/uptime/networkInterfaces/deng 20 函数 |
| | process | ✅ 核心 | argv/env/cwd/exit/kill/umask/pid/stdout/stderr/stdin/uptime/hrtime/memoryUsage |
| **网络** | http | ✅ 核心 | get/request/createServer（基于 ureq，同步 HTTP 客户端+服务端） |
| | https | ✅ 核心 | 委托 http |
| | net | ✅ 基础 | createConnection/TcpStream/TcpListener |
| | dns | ✅ 基础 | lookup/resolve（ToSocketAddrs） |
| | dgram | ✅ 基础 | UDP createSocket/send/close |
| | tls | ✅ 基础 | TLS connect（native-tls，Windows SChannel） |
| **加密** | crypto | ✅ 增强 | hash/randomBytes/randomUUID/createHash/createCipheriv/createDecipheriv/pbkdf2/时序安全比较/getHashes/getCiphers |
| **压缩** | zlib | ✅ 核心 | deflateSync/inflateSync/gzipSync/gunzipSync |
| **工具** | assert | ✅ 核心 | ok/equal/strictEqual/notEqual |
| | util | ✅ 完整 | format（%s/%d/%f/%j 占位符）/inspect（递归对象展示） |
| | url | ✅ 核心 | parse/format（protocol/host/pathname/query 完整解析/格式化） |
| | querystring | ✅ 核心 | parse/stringify |
| **并发** | worker_threads | ✅ 简化 | isMainThread/parentPort/Worker（AOT 单线程模型） |
| | child_process | ✅ 核心 | execSync/spawnSync/execFileSync |
| **输入** | readline | ✅ 简化 | createInterface/question/close |
| **监测** | perf_hooks | ✅ 核心 | performance.now() |
| **异步** | timers | ✅ 完整 | setTimeout/clearTimeout/setInterval/clearInterval/setImmediate/clearImmediate |

### 未实现的模块

以下模块 **明确放弃支持**，与 AOT 编译定位不兼容：

| 模块 | 放弃原因 |
|------|---------|
| **cluster** | ❌ 多进程集群模式与 AOT 单进程定位冲突。Node.js cluster 的进程间通信和负载均衡在原生编译场景下无实际应用。 |
| **vm** | ❌ 运行时动态执行代码的能力与 AOT 编译理念相悖。所有代码应在编译期确定，运行时无需沙箱执行引擎。 |
| **repl** | ❌ REPL 交互式解释器与 AOT 生成独立可执行文件的目标不兼容。编译产物是原生 exe，不是运行时解释器。 |
| **module** | ❌ 模块解析在编译期完成，运行时无需模块加载器。 |

### 模块解析优先级

```
1. 相对路径（./, ../）
2. 用户模块（src/ 目录）
3. Shim（ts-native.toml 配置）
4. node_modules（源码级编译）
5. Native Addon DLL（FFI 桥接）
6. QuickJS fallback（JS 引擎兜底）
7. 内置模块（runtime js_xxx）
```

### ts-native.toml 配置

在项目根目录创建 `ts-native.toml` 配置文件：

```toml
# 项目入口配置
[project]
entries = ["main.ts", "cli.ts"]
src_dir = "src"

# Shim 配置 — 为 npm 包提供原生替代实现
[shims]
lodash = "ts_native_shim_lodash"
dayjs = "ts_native_shim_dayjs"
uuid = "ts_native_shim_uuid"
clsx = "ts_native_shim_clsx"
chalk = "ts_native_shim_chalk"

# Native Addon 配置 — 调用 C++ Addon DLL
[native_addons.myaddon]
dll = "myaddon.dll"

[native_addons.myaddon.functions]
process = "native_process"
transform = "native_transform"

# QuickJS 配置 — 兜底执行纯 JS 包
[js-engine]
enabled = true
fallback = ["express", "axios"]
```

### 内置 Shim

| 包 | 函数数量 | 实现方式 |
|----|---------|---------|
| lodash | 52 | 纯 Rust（clone, isEqual, range, flatten, uniq, compact, forEach, map, filter, reduce, find 等） |
| dayjs | 2 | chrono crate（dayjs, format） |
| uuid | 2 | uuid crate（v4, v1） |
| clsx | 1 | 纯 Rust |
| chalk | 10 | 纯 Rust（ANSI 颜色：red/green/blue/yellow/cyan/magenta/gray/bold/rgb） |

### 使用示例

```typescript
// 内置模块 — 直接 import，编译为原生调用
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
import { createHash, randomBytes } from "crypto";
import { execSync } from "child_process";

const data = readFileSync("file.txt", "utf8");
const hash = createHash("sha256").update(data).digest("hex");
writeFileSync("output.txt", hash);

// HTTP 请求
import { get } from "http";
const body = get("https://api.example.com/data");
console.log(body);

// 子进程
const output = execSync("ls -la");
console.log(output);

// Shim — 直接 import，编译为原生调用
import { debounce, clone } from "lodash";
const debounced = debounce(() => console.log("hello"), 100);

// node_modules — 纯 JS 包源码级编译
import { something } from "some-pure-js-package";

// CJS 兼容 — 自动转换 require/module.exports
const _ = require("lodash");
module.exports = _.debounce;

// Native Addon
import { process } from "myaddon";
const result = process(data);
```

## 编译报告

编译时自动输出可观测性指标：

```
╔══════════════════════════════════════════════════════════════╗
║              Compile Report                                  ║
╠══════════════════════════════════════════════════════════════╣
║ Total Duration:        398 ms                                 ║
║ Memory Usage:      14.1 MB                                     ║
║ Modules:            1                                         ║
║ Entries:            1                                         ║
║ Functions:      1/1     compiled (100.0%)                      ║
║ Code Size:         832 B                                       ║
║ Total Size:        842 B                                       ║
║ Symbols:            7                                         ║
║ Relocations:       13                                         ║
║ Phase Timings:                                                 ║
║   Module Compilation                              4 ms         ║
║   Executable Generation                         385 ms         ║
║   Report Generation                               0 ms         ║
╚══════════════════════════════════════════════════════════════╝
```

## Feature Flags

| Feature | 默认 | 说明 |
|---------|------|------|
| `native-linker` | 关闭 | 启用原生 PE 链接器（实验性） |
| `coff` | 关闭 | 启用 COFF 相关功能 |
| `quickjs` | 关闭 | 启用 QuickJS 嵌入引擎（runtime crate） |

```bash
# 启用 QuickJS
cd runtime && cargo build --features quickjs

# 启用 native-linker
cargo build --features native-linker
```

## 测试

```bash
# 运行所有测试（含 E2E）
cargo test --release

# 运行单元测试
cargo test --release -- lib::tests

# 运行集成测试
cargo test --test integration_feature_tests

# 运行 E2E 测试（编译并执行 TypeScript → .exe → 验证输出）
cargo test --test e2e_execution_tests
```

### 测试覆盖

| 层级 | 测试数量 | 覆盖范围 |
|------|---------|---------|
| 单元测试 | 129 | 配置解析、模块解析、HIR 解析、COFF 读写 |
| E2E 特性测试 | 4 | ESM Export、Rest/Spread、Proxy/Reflect、JSX（基于 Node.js 标准用例的 AOT 适配）✅ 全部通过 |
| E2E 模块测试 | 11 | Buffer、Events、Crypto、FS、Path、OS、Process、Assert、Console、URL、Querystring、Util |
| E2E 全链路测试 | 2 | 完整编译管道 + 执行验证 + obj 有效性 |
| 功能测试 | 18 | Shim、node_modules、Addon、QuickJS 配置解析 |
| 总计 | 164 | 全部通过 |

## 项目状态

- **核心编译器**: 稳定。支持基础 TS 语法、类、异常、异步、Generator
- **Runtime**: 稳定。250+ 导出函数，26/32 个 Node.js 模块，引用计数 GC。Workspace 集成，`cargo build --workspace` 自动构建 tsn_runtime.dll
- **编译验证**: 129 单元测试 + 35 集成/E2E 测试全部通过（18 个 E2E 执行测试全部 ✅）
- **Math**: 完整支持（14 函数）、JSON.stringify/parse、util.format/inspect 完整实现
- **Buffer**: allocUnsafe/slice/fill/copy/equals 实例方法
- **Path**: relative/format/parse、process.kill/umask
- **Lodash**: forEach/map/filter/reduce/find 迭代器
- **Chalk**: 真实 ANSI 颜色（red/green/blue/cyan/magenta/gray/yellow/bold/rgb）
- **Crypto**: PBKDF2 真实 HMAC-SHA256 实现、timingSafeEqual 常量时间比较
- **E2E**: 18 个 E2E 测试全部通过，覆盖完整编译-执行链路，涵盖 ESM Export（命名/默认/重导出/星号/命名空间）、Rest/Spread（数组/对象展开/剩余参数）、Proxy/Reflect（get/set/has/deleteProperty + Reflect 方法）、JSX（零胶水 VNode 结构）
- **Shim**: 5 个常用 npm 包的原生替代（62 函数）
- **Proxy / Reflect**: 原生底座实现（Rust 层陷阱调度，性能优于 JS 层 Proxy）。已实现 `get/set/has/deleteProperty` 高频陷阱 + `Reflect.get/set/has/deleteProperty/construct/apply` 静态方法。通过 `__tsn_proxy__` 标记 + 函数指针调度，零开销 for 非代理对象（仅一次 hash 查找）。低频陷阱 `preventExtensions/isExtensible/defineProperty/getPrototypeOf/setPrototypeOf/ownKeys/getOwnPropertyDescriptor` 未实现
- **Proxy 限制**: `new Proxy(obj, handler)` 中 handler 必须是字面量对象或同一作用域内的稳定引用。注意：直接属性访问（如 `proxy.x`）可能绕过陷阱，陷阱主要通过 `Reflect.*` 方法生效。以下用法**不保证工作**：
  - 跨函数返回的动态 handler（`function makeProxy() { return new Proxy(obj, makeHandler()); }`）
  - handler 在运行时被替换（`proxy.handler = newHandler`）
  - 代理非对象目标（`new Proxy(42, handler)`）
- **测试策略**: 采用 Node.js 官方 ECMAScript 标准用例改造为 AOT 测试，覆盖完整的 ESM 导出（命名/默认/重导出/星号/命名空间）、Rest/Spread（数组/对象展开、剩余参数）、Proxy/Reflect（get/set/has/deleteProperty 陷阱+Reflect 方法）、JSX（零胶水 VNode 结构）
- **v0.6.0 修复**: Cranelift verifier 错误（`ireduce` → `bitcast`）、Rest 参数调用方数组打包（避免 padding 污染）、命名空间导入（`import * as X` 的 Property 调用/值解析）、跨模块 const export 值编译时内联、运行时字符串去重（`Pool::find` + `store_string` dedup）、`js_object_assign` 重复定义移除
- **远期**: 跨平台 ELF/Mach-O 链接器（先聚焦 Windows）
- **明确不支持**: 非阻塞 I/O（同步 AOT 模型）、cluster/worker_threads（单进程桌面场景）

## 文档

- [ARCHITECTURE.md](ARCHITECTURE.md) — 完整架构设计（编译管线、HIR、NaN-boxing、模块解析、Shim、FFI、QuickJS、事件循环、GC）
- [CONTRIBUTING.md](CONTRIBUTING.md) — 贡献指南
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) — 行为准则
- [docs/NODEJS_COMPAT_STATUS.md](docs/NODEJS_COMPAT_STATUS.md) — Node.js 模块兼容状态与差距分析
- [docs/](docs/) — 技术文档索引

## 许可证

MIT

## Core Authors & AI Collaborators
1. **豆包 (Doubao)** — 全程架构思路梳理、底层原理拆解、Rust 基础语法、工程结构规划
2. **Trae Solo** — 核心编译器实现主力：Cranelift、Windows x64 ABI、DLL 系统
3. **CodeArts** — 早期原型探索、初始 Rust 工程搭建、SWC 解析适配
4. **Qoder** — 第二版 tnsp、DLL 加载测试、单文件执行模式试错、目前权限等兼容问题解决。
5. **CodeBuddy** — 超级新兵
## Human Lead Architect
本人：整体顶层设计、需求定义、项目目标演化、本地实测调试、工程思想指引、实施路径引导、混合运行时落地、全工程整合验收、最终测试发布。
