never-jscore 2.2.0__cp38-abi3-win_amd64.whl

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.
@@ -0,0 +1,1357 @@
1
+ Metadata-Version: 2.4
2
+ Name: never-jscore
3
+ Version: 2.2.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.8
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: Implementation :: CPython
14
+ Classifier: Programming Language :: Rust
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Software Development :: Interpreters
17
+ Classifier: Typing :: Typed
18
+ Summary: High-performance Python JavaScript execution engine based on Deno Core (V8) with full Promise/async support - py_mini_racer style API
19
+ Keywords: javascript,execjs,deno,v8,js,python,rust,promise,async,py_mini_racer
20
+ License: MIT
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
+ Project-URL: Homepage, https://github.com/neverl805/never-jscore
24
+ Project-URL: Repository, https://github.com/neverl805/never-jscore
25
+ Project-URL: Documentation, https://github.com/neverl805/never-jscore#readme
26
+ Project-URL: Bug Tracker, https://github.com/neverl805/never-jscore/issues
27
+
28
+ # never_jscore 中文文档
29
+
30
+ 基于 Deno Core (V8) 的高性能 Python JavaScript 执行引擎,**专为 JS 逆向工程和补环境优化**。
31
+ 努力成为PyExecJS上位替代品
32
+
33
+ ## 项目特点
34
+
35
+ - ⚡ **极致性能**:
36
+ - 使用 Rust + Deno Core (V8 引擎)
37
+ - 实例化 Context 复用优化
38
+ - **比 PyExecJS 快 100-300倍**
39
+ - **与 PyMiniRacer 性能相当,部分场景更快**
40
+ - 🔄 **Promise/async 支持**:
41
+ - 完整支持 Promise 和 async/await
42
+ - 自动等待异步结果
43
+ - **唯一高性能 Promise 方案**(PyMiniRacer 不支持)
44
+ - 🌐 **完整 Web API 扩展** (v2.2.0):
45
+ - ✅ **Node.js APIs**: require()、fs、path、fetch()
46
+ - ✅ **浏览器存储**: localStorage、sessionStorage
47
+ - ✅ **浏览器环境(简易实现)**: navigator、location、document、window、screen
48
+ - ✅ **URL 处理**: URL、URLSearchParams
49
+ - ✅ **表单数据**: FormData
50
+ - ✅ **事件系统**: Event、EventTarget
51
+ - ✅ **网络请求**: fetch()、XMLHttpRequest
52
+ - ✅ **Crypto APIs**: Base64、MD5、SHA1/256/512、HMAC、Hex
53
+ - ✅ **URL 编码**: encodeURIComponent、encodeURI 等
54
+ - ✅ **定时器**: setTimeout、setInterval(立即执行版本)
55
+ - ✅ **随机数**: crypto.randomUUID()、crypto.getRandomValues()
56
+ - 🎯 专为 JS 逆向和补环境设计,无需额外 polyfill
57
+ - 📦 **上下文隔离**: 每个 Context 独立的 V8 执行环境,互不干扰
58
+ - 🎯 **py_mini_racer 兼容**: API 设计类似 py_mini_racer,实例化使用
59
+ - 🧹 **自动内存管理**: 基于 Rust 的自动垃圾回收,无内存泄漏
60
+ - 🛡️ **类型安全**: 提供完整的类型提示(.pyi 文件)
61
+
62
+
63
+ ## 特性对比表
64
+
65
+ | 特性 | never_jscore | PyExecJS | PyMiniRacer | js2py | dukpy |
66
+ |------|--------------|----------|-------------|-------|-------|
67
+ | 引擎 | V8 | Node/V8等 | V8 | 纯Python | Duktape |
68
+ | Promise | ✅ 完整 | ❌ | ⚠️ 有限 | ❌ | ❌ |
69
+ | async/await | ✅ | ❌ | ⚠️ | ❌ | ❌ |
70
+ | require() | ✅ 完整 | ✅ | ❌ | ❌ | ❌ |
71
+ | fetch() | ✅ | ❌ | ❌ | ❌ | ❌ |
72
+ | localStorage | ✅ | ❌ | ❌ | ❌ | ❌ |
73
+ | 浏览器环境 | ️ ⚠️大部分 | ❌ | ❌ | ⚠️ 部分 | ❌ |
74
+ | 性能 | ⚡⚡⚡⚡⚡ | ⚡⚡ | ⚡⚡⚡⚡⚡ | ⚡ | ⚡⚡⚡ |
75
+ | 安装难度 | 简单 | 需Node.js | 简单 | 简单 | 简单 |
76
+ | 上下文复用 | ✅ | ✅ | ✅ | ✅ | ✅ |
77
+ | 类型转换 | 自动 | 自动 | 自动 | 自动 | 自动 |
78
+ | ES6+ | ✅ 完整 | ✅ | ✅ | ⚠️ 部分 | ⚠️ 部分 |
79
+
80
+ ---
81
+
82
+ ## 常见问题
83
+
84
+ ### Q: 为什么 PyMiniRacer 在某些测试中更快?
85
+ A: PyMiniRacer 是 V8 的直接绑定,开销最小。never_jscore 使用 rust开发以及Deno Core,有轻量级包装层,但提供了更多功能(如 Promise 支持)。
86
+
87
+ ### Q: 什么时候选择 never_jscore?
88
+ A: 当你需要:
89
+ - Promise/async 支持(现代 JS 库)
90
+ - 高性能 + Rust 稳定性
91
+ - 完整的 Node.js 环境(require、fs、path)
92
+ - 浏览器环境模拟(补环境)
93
+ - fetch() 网络请求
94
+ - localStorage/sessionStorage
95
+ - JS 逆向工程
96
+
97
+ ### Q: PyExecJS 为什么这么慢?
98
+ A: PyExecJS 通过进程调用外部 JS 运行时,每次都有进程通信开销。
99
+
100
+
101
+
102
+ ## 可用测试文件
103
+ - [benchmark.py](examples/benchmark.py) - 性能基准测试
104
+ - [test_async_simple.py](tests/test_async_simple.py) - 异步功能测试
105
+ - [test_extensions.py](tests/test_extensions.py) - 扩展 API 测试
106
+ - [test_new_apis.py](tests/test_new_apis.py) - 新 API 测试
107
+ - [test_all_features.py](tests/test_all_features.py) - 完整功能测试套件
108
+ - [test_browser_apis.py](tests/test_browser_apis.py) - 浏览器 API 测试
109
+ - [test_high_priority_apis.py](tests/test_high_priority_apis.py) - 高优先级 API 测试
110
+ - [test_wasm.py](tests/test_wasm.py) - WebAssembly 测试
111
+ - [use_polyfill.py](examples/use_polyfill.py) - Polyfill 使用示例
112
+
113
+
114
+
115
+
116
+ ## 性能对比
117
+ ![img.png](img.png)
118
+
119
+ | 测试项目 | never_jscore | PyMiniRacer | PyExecJS |
120
+ |------------------------------|----------------|------------|----------|
121
+ | 简单计算 | 0.007ms | 0.005ms | 2.3ms |
122
+ | 字符串操作 | **0.004ms** 🏆 | 0.008ms | 2.3ms |
123
+ | 数组操作 | **0.004ms** 🏆 | 0.006ms | 2.3ms |
124
+ | 复杂算法参数生成<br/>(1000次循环 )<br/>[benchmark.py](examples/benchmark.py) | **0.0111s** 🏆 | 0.0383s | 69.4735s |
125
+ | Promise | **✅ 0.003ms** | ❌ 不支持 | ❌ 不支持 |
126
+
127
+
128
+ ## 安装
129
+ ```bash
130
+ pip install never-jscore
131
+ ```
132
+
133
+ ### 从源码安装
134
+
135
+ ```bash
136
+ pip install maturin
137
+ maturin develop --release
138
+ ```
139
+
140
+ ## 快速开始
141
+
142
+ ### 0. 创建 Context(启用扩展)
143
+
144
+ ```python
145
+ import never_jscore
146
+
147
+ # 启用 Web API 扩展(默认,推荐用于 JS 逆向)
148
+ ctx = never_jscore.Context(enable_extensions=True)
149
+
150
+ # 或禁用扩展(纯净 V8 环境)
151
+ ctx = never_jscore.Context(enable_extensions=False)
152
+ ```
153
+
154
+ ### 1. 基本用法(实例化 Context)
155
+
156
+ ```python
157
+ import never_jscore
158
+
159
+ # 创建 JavaScript 执行上下文
160
+ ctx = never_jscore.Context()
161
+
162
+ # 一次性求值
163
+ result = ctx.evaluate("1 + 2 + 3")
164
+ print(result) # 6
165
+
166
+ # 字符串操作
167
+ result = ctx.evaluate("'Hello'.toUpperCase()")
168
+ print(result) # HELLO
169
+
170
+ # 数组操作
171
+ result = ctx.evaluate("[1, 2, 3].map(x => x * 2)")
172
+ print(result) # [2, 4, 6]
173
+ ```
174
+
175
+ ### 2. 编译和调用
176
+
177
+ ```python
178
+ import never_jscore
179
+
180
+ # 创建上下文
181
+ ctx = never_jscore.Context()
182
+
183
+ # 编译 JavaScript 代码
184
+ ctx.compile("""
185
+ function add(a, b) {
186
+ return a + b;
187
+ }
188
+
189
+ function greet(name) {
190
+ return "Hello, " + name + "!";
191
+ }
192
+ """)
193
+
194
+ # 调用函数
195
+ print(ctx.call("add", [5, 3])) # 8
196
+ print(ctx.call("greet", ["World"])) # Hello, World!
197
+ ```
198
+
199
+ ### 3. 异步支持(Promise/async/await)
200
+
201
+ ```python
202
+ import never_jscore
203
+
204
+ ctx = never_jscore.Context()
205
+
206
+ # async 函数
207
+ ctx.compile("""
208
+ async function fetchData(id) {
209
+ // 模拟异步操作
210
+ return await Promise.resolve({id: id, name: "User" + id});
211
+ }
212
+ """)
213
+
214
+ # Promise 自动等待
215
+ result = ctx.evaluate("Promise.resolve(42)")
216
+ print(result) # 42
217
+
218
+ result = ctx.call("fetchData", [123])
219
+ print(result) # {'id': 123, 'name': 'User123'}
220
+
221
+ # Promise 链
222
+ result = ctx.evaluate("""
223
+ Promise.resolve(10)
224
+ .then(x => x * 2)
225
+ .then(x => x + 5)
226
+ """)
227
+ print(result) # 25
228
+
229
+ # Promise.all 并发
230
+ result = ctx.evaluate("""
231
+ Promise.all([
232
+ Promise.resolve(1),
233
+ Promise.resolve(2),
234
+ Promise.resolve(3)
235
+ ])
236
+ """)
237
+ print(result) # [1, 2, 3]
238
+ ```
239
+
240
+ ### 4. 上下文状态管理
241
+
242
+ ```python
243
+ import never_jscore
244
+
245
+ ctx = never_jscore.Context()
246
+ ctx.compile("""
247
+ var counter = 0;
248
+
249
+ function increment() {
250
+ return ++counter;
251
+ }
252
+
253
+ function getCounter() {
254
+ return counter;
255
+ }
256
+ """)
257
+
258
+ print(ctx.call("increment", [])) # 1
259
+ print(ctx.call("increment", [])) # 2
260
+ print(ctx.call("getCounter", [])) # 2
261
+ ```
262
+
263
+ ### 5. 复杂对象处理
264
+
265
+ ```python
266
+ import never_jscore
267
+
268
+ ctx = never_jscore.Context()
269
+ ctx.compile("""
270
+ function processUser(name, age, tags) {
271
+ return {
272
+ name: name,
273
+ age: age,
274
+ isAdult: age >= 18,
275
+ tags: tags,
276
+ summary: name + ' (' + age + '岁)'
277
+ };
278
+ }
279
+ """)
280
+
281
+ result = ctx.call("processUser", ["张三", 25, ["Python", "JavaScript"]])
282
+ print(result)
283
+ # {
284
+ # 'name': '张三',
285
+ # 'age': 25,
286
+ # 'isAdult': True,
287
+ # 'tags': ['Python', 'JavaScript'],
288
+ # 'summary': '张三 (25岁)'
289
+ # }
290
+ ```
291
+
292
+ ### 6. 性能监控
293
+
294
+ ```python
295
+ import never_jscore
296
+
297
+ ctx = never_jscore.Context()
298
+ ctx.compile("function compute(n) { return n * n; }")
299
+
300
+ # 执行多次
301
+ for i in range(100):
302
+ ctx.call("compute", [i])
303
+
304
+ # 查看统计
305
+ stats = ctx.get_stats()
306
+ print(f"执行次数: {stats[0]}") # 100
307
+
308
+ # 请求垃圾回收(可选)
309
+ ctx.gc()
310
+
311
+ # 重置统计
312
+ ctx.reset_stats()
313
+ ```
314
+
315
+ ## API 参考
316
+
317
+ ### Context 类
318
+
319
+ #### `never_jscore.Context(enable_extensions: bool = True)`
320
+
321
+ 创建一个新的 JavaScript 执行上下文。
322
+
323
+ **参数**:
324
+ - `enable_extensions` (可选): 是否启用内置 Web API 扩展(默认 True)
325
+ - `True`: 启用 Crypto、URL 编码、setTimeout、Worker 等扩展
326
+ - `False`: 纯净 V8 环境,只有 ECMAScript 标准 API
327
+
328
+ **返回**: Context 对象
329
+
330
+ **示例**:
331
+ ```python
332
+ # 启用扩展(默认,推荐用于 JS 逆向)
333
+ ctx = never_jscore.Context()
334
+ ctx = never_jscore.Context(enable_extensions=True)
335
+
336
+ # 禁用扩展(纯净 V8)
337
+ ctx = never_jscore.Context(enable_extensions=False)
338
+ ```
339
+
340
+ #### `compile(code: str) -> None`
341
+
342
+ 编译 JavaScript 代码并加入全局作用域。
343
+
344
+ **参数**:
345
+ - `code`: JavaScript 代码字符串
346
+
347
+ **示例**:
348
+ ```python
349
+ ctx.compile('''
350
+ function add(a, b) { return a + b; }
351
+ ''')
352
+ ```
353
+
354
+ #### `eval(code: str, return_value: bool = False, auto_await: bool = True) -> Any`
355
+
356
+ 执行代码并将其加入全局作用域。
357
+
358
+ **参数**:
359
+ - `code`: JavaScript 代码字符串
360
+ - `return_value`: 是否返回最后表达式的值(默认 False)
361
+ - `auto_await`: 是否自动等待 Promise(默认 True)
362
+
363
+ **返回**: 如果 return_value=True,返回执行结果;否则返回 None
364
+
365
+ **示例**:
366
+ ```python
367
+ ctx.eval("var x = 10;") # 添加到全局作用域
368
+ result = ctx.eval("x * 2", return_value=True) # 返回 20
369
+ ```
370
+
371
+ #### `evaluate(code: str, auto_await: bool = True) -> Any`
372
+
373
+ 执行代码并返回结果(不影响全局作用域)。
374
+
375
+ **参数**:
376
+ - `code`: JavaScript 代码字符串
377
+ - `auto_await`: 是否自动等待 Promise(默认 True)
378
+
379
+ **返回**: 表达式的值
380
+
381
+ **示例**:
382
+ ```python
383
+ result = ctx.evaluate("1 + 2 + 3") # 6
384
+ result = ctx.evaluate("Promise.resolve(42)") # 42
385
+ ```
386
+
387
+ #### `call(name: str, args: list, auto_await: bool = True) -> Any`
388
+
389
+ 调用 JavaScript 函数。
390
+
391
+ **参数**:
392
+ - `name`: 函数名称
393
+ - `args`: 参数列表
394
+ - `auto_await`: 是否自动等待 Promise(默认 True)
395
+
396
+ **返回**: 函数返回值
397
+
398
+ **示例**:
399
+ ```python
400
+ result = ctx.call("add", [1, 2])
401
+ result = ctx.call("asyncFunc", [arg], auto_await=True)
402
+ ```
403
+
404
+ #### `gc() -> None`
405
+
406
+ 请求 V8 垃圾回收。
407
+
408
+ **注意**: 这只是提示,V8 会根据自己的策略决定是否执行。在大多数情况下无需手动调用。
409
+
410
+ #### `get_stats() -> tuple[int]`
411
+
412
+ 获取执行统计信息。
413
+
414
+ **返回**: `(exec_count,)` 执行次数元组
415
+
416
+ #### `reset_stats() -> None`
417
+
418
+ 重置统计信息。
419
+
420
+ ## 类型转换
421
+
422
+ Python 和 JavaScript 之间的类型自动转换:
423
+
424
+ | Python 类型 | JavaScript 类型 | 说明 |
425
+ |------------|----------------|------|
426
+ | None | null | 空值 |
427
+ | bool | boolean | 布尔值 |
428
+ | int | number | 整数 |
429
+ | float | number | 浮点数 |
430
+ | str | string | 字符串 |
431
+ | list | Array | 数组 |
432
+ | dict | Object | 对象 |
433
+
434
+ **示例**:
435
+ ```python
436
+ # Python -> JavaScript
437
+ ctx.call("func", [None, True, 42, 3.14, "hello", [1, 2], {"key": "value"}])
438
+
439
+ # JavaScript -> Python
440
+ result = ctx.evaluate("{name: 'John', age: 30}") # dict
441
+ result = ctx.evaluate("[1, 2, 3]") # list
442
+ result = ctx.evaluate("null") # None
443
+ ```
444
+
445
+ ## 使用限制
446
+
447
+ ### ⚠️ 多 Context 限制(重要!)
448
+
449
+ 由于 V8 引擎的 thread-local storage 限制和内存管理机制,**多个 Context 必须遵循特定的使用模式**。
450
+
451
+ #### 限制 1: 不能交叉使用
452
+
453
+ **一旦创建了第二个 Context,就不能再使用第一个 Context!**
454
+
455
+ ```python
456
+ # ❌ 错误用法:交叉使用会崩溃
457
+ ctx1 = never_jscore.Context()
458
+ ctx1.compile("function f1() { return 1; }")
459
+ result1 = ctx1.call("f1", []) # OK
460
+
461
+ ctx2 = never_jscore.Context()
462
+ ctx2.compile("function f2() { return 2; }")
463
+ result2 = ctx2.call("f2", []) # OK
464
+
465
+ result1 = ctx1.call("f1", []) # ❌ 崩溃!不能回到 ctx1
466
+ ```
467
+
468
+ #### 限制 2: LIFO 删除顺序
469
+
470
+ **多个 Context 必须按 LIFO 顺序删除(后创建先删除)**
471
+
472
+ ```python
473
+ # ❌ 错误:按创建顺序删除会崩溃
474
+ ctx1 = never_jscore.Context()
475
+ ctx2 = never_jscore.Context()
476
+ ctx3 = never_jscore.Context()
477
+
478
+ del ctx1 # ❌ 崩溃!
479
+ del ctx2
480
+ del ctx3
481
+
482
+ # ✅ 正确:LIFO 顺序(后进先出)
483
+ ctx1 = never_jscore.Context()
484
+ ctx2 = never_jscore.Context()
485
+ ctx3 = never_jscore.Context()
486
+
487
+ # 使用最后创建的 Context
488
+ result = ctx3.call("func", [])
489
+
490
+ # 按逆序删除
491
+ del ctx3 # ✅ 最后创建,最先删除
492
+ del ctx2 # ✅
493
+ del ctx1 # ✅
494
+
495
+ # ❌ 错误:让 Python 自动清理(顺序不确定)
496
+ # 程序结束时会崩溃
497
+ ```
498
+
499
+ #### 推荐的使用模式
500
+
501
+ **模式 1: 单 Context 模式(最推荐)**
502
+
503
+ 将所有函数定义在一个 Context 中:
504
+
505
+ ```python
506
+ import never_jscore
507
+
508
+ ctx = never_jscore.Context()
509
+ ctx.compile("""
510
+ function f1() { return 1; }
511
+ function f2() { return 2; }
512
+ function f3() { return 3; }
513
+ """)
514
+
515
+ # 可以任意调用
516
+ ctx.call("f1", []) # OK
517
+ ctx.call("f2", []) # OK
518
+ ctx.call("f1", []) # OK - 可以重复调用
519
+ ```
520
+
521
+ **模式 2: 顺序使用(用完即删)**
522
+
523
+ ```python
524
+ import never_jscore
525
+
526
+ # 使用第一个 Context
527
+ ctx1 = never_jscore.Context()
528
+ ctx1.compile("function f1() { return 1; }")
529
+ result = ctx1.call("f1", [])
530
+ del ctx1 # 用完立即删除
531
+
532
+ # 使用第二个 Context
533
+ ctx2 = never_jscore.Context()
534
+ ctx2.compile("function f2() { return 2; }")
535
+ result = ctx2.call("f2", [])
536
+ del ctx2 # 用完立即删除
537
+ ```
538
+
539
+ **模式 3: LIFO 批量清理(高级用法)**
540
+
541
+ ```python
542
+ import never_jscore
543
+
544
+ # 创建多个 Context(注意:创建第二个后不能再用第一个)
545
+ ctx1 = never_jscore.Context()
546
+ ctx1.compile("function f1() { return 1; }")
547
+ r1 = ctx1.call("f1", []) # 在创建 ctx2 之前完成所有操作
548
+
549
+ ctx2 = never_jscore.Context()
550
+ ctx2.compile("function f2() { return 2; }")
551
+ r2 = ctx2.call("f2", []) # ctx1 已不可用
552
+
553
+ ctx3 = never_jscore.Context()
554
+ ctx3.compile("function f3() { return 3; }")
555
+ r3 = ctx3.call("f3", []) # ctx1, ctx2 已不可用
556
+
557
+ # LIFO 顺序删除(后进先出)
558
+ del ctx3
559
+ del ctx2
560
+ del ctx1
561
+ ```
562
+
563
+ ## v2.2.0 新功能:Node.js 和浏览器 API
564
+
565
+ ### 1. require() - CommonJS 模块系统
566
+
567
+ 完整的 Node.js 模块解析实现,支持相对路径、node_modules、package.json:
568
+
569
+ ```python
570
+ import never_jscore
571
+
572
+ ctx = never_jscore.Context()
573
+
574
+ # 创建测试模块
575
+ with open('my_module.js', 'w') as f:
576
+ f.write('''
577
+ module.exports = {
578
+ add: function(a, b) { return a + b; },
579
+ version: '1.0.0'
580
+ };
581
+ ''')
582
+
583
+ # 使用 require() 加载模块
584
+ result = ctx.evaluate("""
585
+ const myModule = require('./my_module.js');
586
+ myModule.add(10, 20)
587
+ """)
588
+ print(result) # 30
589
+
590
+ # 使用内置模块 fs 和 path
591
+ ctx.compile("""
592
+ const fs = require('fs');
593
+ const path = require('path');
594
+
595
+ function readConfig() {
596
+ const filePath = path.join('.', 'config.json');
597
+ if (fs.existsSync(filePath)) {
598
+ return fs.readFileSync(filePath);
599
+ }
600
+ return '{}';
601
+ }
602
+ """)
603
+ ```
604
+
605
+ **支持的功能**:
606
+ - ✅ 相对路径:`./module.js`, `../lib/utils.js`
607
+ - ✅ 绝对路径:`/path/to/module.js`
608
+ - ✅ node_modules 查找(递归向上)
609
+ - ✅ package.json 主入口解析
610
+ - ✅ 自动扩展名(`.js`, `.json`)
611
+ - ✅ 目录入口(`index.js`)
612
+ - ✅ 模块缓存(`require.cache`)
613
+
614
+ **内置模块**:
615
+ - `fs` - 文件系统操作
616
+ - `path` - 路径处理
617
+
618
+ ### 2. fetch() - HTTP 网络请求
619
+
620
+ 现代 HTTP API,兼容浏览器标准:
621
+
622
+ ```python
623
+ import never_jscore
624
+
625
+ ctx = never_jscore.Context()
626
+
627
+ # GET 请求
628
+ result = ctx.evaluate("""
629
+ (async () => {
630
+ const response = await fetch('https://api.github.com/users/github');
631
+ const data = await response.json();
632
+ return {
633
+ status: response.status,
634
+ username: data.login,
635
+ followers: data.followers
636
+ };
637
+ })()
638
+ """)
639
+ print(result)
640
+
641
+ # POST 请求
642
+ result = ctx.evaluate("""
643
+ (async () => {
644
+ const response = await fetch('https://httpbin.org/post', {
645
+ method: 'POST',
646
+ headers: {
647
+ 'Content-Type': 'application/json',
648
+ 'Authorization': 'Bearer token123'
649
+ },
650
+ body: JSON.stringify({
651
+ username: 'test',
652
+ password: 'pass'
653
+ }),
654
+ timeout: 30000
655
+ });
656
+
657
+ const data = await response.json();
658
+ return data;
659
+ })()
660
+ """)
661
+ ```
662
+
663
+ **支持的功能**:
664
+ - ✅ GET/POST/PUT/DELETE/PATCH 等所有 HTTP 方法
665
+ - ✅ 自定义请求头
666
+ - ✅ JSON 自动序列化/反序列化
667
+ - ✅ Response 对象(`text()`, `json()`, `blob()`, `arrayBuffer()`)
668
+ - ✅ 状态码和状态文本
669
+ - ✅ 超时控制
670
+
671
+ ### 3. localStorage / sessionStorage
672
+
673
+ 浏览器存储 API,用于补环境:
674
+
675
+ ```python
676
+ import never_jscore
677
+
678
+ ctx = never_jscore.Context()
679
+
680
+ # localStorage - 持久化存储
681
+ ctx.eval("""
682
+ localStorage.setItem('token', 'abc123');
683
+ localStorage.setItem('user', JSON.stringify({name: 'John', id: 123}));
684
+ """)
685
+
686
+ # 获取值
687
+ token = ctx.evaluate("localStorage.getItem('token')")
688
+ print(token) # 'abc123'
689
+
690
+ # sessionStorage - 会话存储
691
+ ctx.eval("""
692
+ sessionStorage.setItem('sessionId', '999');
693
+ """)
694
+
695
+ # 完整示例
696
+ result = ctx.evaluate("""
697
+ // 存储用户偏好
698
+ localStorage.setItem('theme', 'dark');
699
+ localStorage.setItem('language', 'zh-CN');
700
+
701
+ // 读取偏好
702
+ const preferences = {
703
+ theme: localStorage.getItem('theme'),
704
+ language: localStorage.getItem('language'),
705
+ itemCount: localStorage.length
706
+ };
707
+
708
+ JSON.stringify(preferences);
709
+ """)
710
+ print(result) # {"theme":"dark","language":"zh-CN","itemCount":2}
711
+ ```
712
+
713
+ **API 方法**:
714
+ - `setItem(key, value)` - 设置值
715
+ - `getItem(key)` - 获取值(不存在返回 null)
716
+ - `removeItem(key)` - 删除键
717
+ - `clear()` - 清空所有
718
+ - `key(index)` - 按索引获取键名
719
+ - `length` - 获取键数量
720
+
721
+ ### 4. 浏览器环境对象
722
+
723
+ 模拟完整的浏览器环境(补环境必备):
724
+
725
+ ```python
726
+ import never_jscore
727
+
728
+ ctx = never_jscore.Context()
729
+
730
+ # navigator - 浏览器信息
731
+ result = ctx.evaluate("""
732
+ JSON.stringify({
733
+ userAgent: navigator.userAgent,
734
+ platform: navigator.platform,
735
+ language: navigator.language,
736
+ onLine: navigator.onLine,
737
+ cookieEnabled: navigator.cookieEnabled,
738
+ hardwareConcurrency: navigator.hardwareConcurrency
739
+ })
740
+ """)
741
+ print(result)
742
+ # {"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","platform":"Win32",...}
743
+
744
+ # location - URL 信息
745
+ result = ctx.evaluate("""
746
+ JSON.stringify({
747
+ href: location.href,
748
+ protocol: location.protocol,
749
+ hostname: location.hostname,
750
+ pathname: location.pathname
751
+ })
752
+ """)
753
+
754
+ # document - DOM 文档对象
755
+ result = ctx.evaluate("""
756
+ JSON.stringify({
757
+ readyState: document.readyState,
758
+ title: document.title,
759
+ URL: document.URL,
760
+ domain: document.domain,
761
+ characterSet: document.characterSet
762
+ })
763
+ """)
764
+
765
+ # window - 窗口对象
766
+ result = ctx.evaluate("""
767
+ JSON.stringify({
768
+ innerWidth: window.innerWidth,
769
+ innerHeight: window.innerHeight,
770
+ devicePixelRatio: window.devicePixelRatio
771
+ })
772
+ """)
773
+
774
+ # screen - 屏幕信息
775
+ result = ctx.evaluate("""
776
+ JSON.stringify({
777
+ width: screen.width,
778
+ height: screen.height,
779
+ colorDepth: screen.colorDepth
780
+ })
781
+ """)
782
+ ```
783
+
784
+ **可用对象**:
785
+ - `navigator` - 浏览器用户代理信息
786
+ - `location` - 页面 URL 信息
787
+ - `document` - DOM 文档对象(方法返回 null/空数组)
788
+ - `window` - 窗口对象
789
+ - `screen` - 屏幕信息
790
+
791
+ ### 5. URL / URLSearchParams
792
+
793
+ 完整的 URL 处理 API:
794
+
795
+ ```python
796
+ import never_jscore
797
+
798
+ ctx = never_jscore.Context()
799
+
800
+ # URL 解析
801
+ result = ctx.evaluate("""
802
+ const url = new URL('https://api.example.com:8080/search?q=test&page=1#results');
803
+
804
+ JSON.stringify({
805
+ href: url.href,
806
+ protocol: url.protocol,
807
+ hostname: url.hostname,
808
+ port: url.port,
809
+ pathname: url.pathname,
810
+ search: url.search,
811
+ hash: url.hash,
812
+ origin: url.origin
813
+ })
814
+ """)
815
+
816
+ # URLSearchParams - 查询字符串操作
817
+ result = ctx.evaluate("""
818
+ const params = new URLSearchParams('name=John&age=30');
819
+
820
+ // 获取参数
821
+ const name = params.get('name'); // "John"
822
+
823
+ // 设置参数
824
+ params.set('age', '31');
825
+
826
+ // 追加参数
827
+ params.append('tag', 'developer');
828
+ params.append('tag', 'python');
829
+
830
+ // 获取所有同名参数
831
+ const tags = params.getAll('tag'); // ["developer", "python"]
832
+
833
+ // 转回查询字符串
834
+ const queryString = params.toString(); // "name=John&age=31&tag=developer&tag=python"
835
+
836
+ JSON.stringify({name, tags, queryString});
837
+ """)
838
+
839
+ # URL + URLSearchParams 组合
840
+ result = ctx.evaluate("""
841
+ const url = new URL('https://api.example.com/search');
842
+ url.searchParams.append('q', 'javascript');
843
+ url.searchParams.append('limit', '10');
844
+
845
+ url.href // "https://api.example.com/search?q=javascript&limit=10"
846
+ """)
847
+ ```
848
+
849
+ ### 6. FormData
850
+
851
+ 表单数据处理 API:
852
+
853
+ ```python
854
+ import never_jscore
855
+
856
+ ctx = never_jscore.Context()
857
+
858
+ result = ctx.evaluate("""
859
+ const formData = new FormData();
860
+
861
+ // 添加字段
862
+ formData.append('username', 'john_doe');
863
+ formData.append('email', 'john@example.com');
864
+ formData.append('tags', 'js');
865
+ formData.append('tags', 'python');
866
+
867
+ // 获取单个值
868
+ const username = formData.get('username'); // "john_doe"
869
+
870
+ // 获取所有同名值
871
+ const tags = formData.getAll('tags'); // ["js", "python"]
872
+
873
+ // 设置(覆盖)
874
+ formData.set('email', 'new@example.com');
875
+
876
+ // 检查是否存在
877
+ const hasUser = formData.has('username'); // true
878
+
879
+ // 删除
880
+ formData.delete('tags');
881
+
882
+ JSON.stringify({username, tags, hasUser});
883
+ """)
884
+ ```
885
+
886
+ ### 7. Event / EventTarget
887
+
888
+ 完整的事件系统:
889
+
890
+ ```python
891
+ import never_jscore
892
+
893
+ ctx = never_jscore.Context()
894
+
895
+ result = ctx.evaluate("""
896
+ // 创建事件目标
897
+ const target = new EventTarget();
898
+
899
+ let eventData = [];
900
+
901
+ // 添加事件监听器
902
+ target.addEventListener('custom', (event) => {
903
+ eventData.push({
904
+ type: event.type,
905
+ bubbles: event.bubbles,
906
+ cancelable: event.cancelable
907
+ });
908
+ });
909
+
910
+ // 创建并分发事件
911
+ const event = new Event('custom', {
912
+ bubbles: true,
913
+ cancelable: true
914
+ });
915
+
916
+ target.dispatchEvent(event);
917
+
918
+ // 支持 once 选项
919
+ target.addEventListener('once-event', () => {
920
+ eventData.push('fired once');
921
+ }, { once: true });
922
+
923
+ const onceEvent = new Event('once-event');
924
+ target.dispatchEvent(onceEvent);
925
+ target.dispatchEvent(onceEvent); // 第二次不会触发
926
+
927
+ JSON.stringify(eventData);
928
+ """)
929
+ ```
930
+
931
+ ### 8. XMLHttpRequest
932
+
933
+ 传统 AJAX API(基于 fetch 实现):
934
+
935
+ ```python
936
+ import never_jscore
937
+
938
+ ctx = never_jscore.Context()
939
+
940
+ result = ctx.evaluate("""
941
+ (async () => {
942
+ return new Promise((resolve, reject) => {
943
+ const xhr = new XMLHttpRequest();
944
+
945
+ xhr.onload = function() {
946
+ if (xhr.status === 200) {
947
+ resolve({
948
+ status: xhr.status,
949
+ statusText: xhr.statusText,
950
+ responseText: xhr.responseText.substring(0, 100),
951
+ readyState: xhr.readyState
952
+ });
953
+ } else {
954
+ reject('Error: ' + xhr.status);
955
+ }
956
+ };
957
+
958
+ xhr.onerror = function() {
959
+ reject('Network error');
960
+ };
961
+
962
+ // 发送请求
963
+ xhr.open('GET', 'https://httpbin.org/get');
964
+ xhr.setRequestHeader('X-Custom-Header', 'value');
965
+ xhr.send();
966
+ });
967
+ })()
968
+ """)
969
+
970
+ print(result)
971
+ ```
972
+
973
+ **支持的功能**:
974
+ - ✅ open() / send() / abort()
975
+ - ✅ setRequestHeader() / getResponseHeader()
976
+ - ✅ onload / onerror / onreadystatechange 事件
977
+ - ✅ readyState / status / statusText
978
+ - ✅ responseText / response
979
+ - ✅ addEventListener / removeEventListener
980
+
981
+ ## 内置 Web API 扩展(v2.0+)
982
+
983
+ never_jscore 内置了常用的 Web API,**无需额外 polyfill**,开箱即用!
984
+
985
+ ### Crypto APIs(加密相关)
986
+
987
+ ```python
988
+ import never_jscore
989
+
990
+ ctx = never_jscore.Context(enable_extensions=True)
991
+
992
+ # Base64 编解码
993
+ result = ctx.evaluate("btoa('Hello World')") # "SGVsbG8gV29ybGQ="
994
+ result = ctx.evaluate("atob('SGVsbG8gV29ybGQ=')") # "Hello World"
995
+
996
+ # 哈希函数
997
+ result = ctx.evaluate("md5('test')") # "098f6bcd4621d373cade4e832627b4f6"
998
+ result = ctx.evaluate("sha256('test')") # "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
999
+
1000
+ # HMAC
1001
+ result = ctx.evaluate("CryptoUtils.hmacSha256('key', 'message')")
1002
+
1003
+ # Hex 编解码
1004
+ result = ctx.evaluate("CryptoUtils.hexEncode('test')") # "74657374"
1005
+ result = ctx.evaluate("CryptoUtils.hexDecode('74657374')") # "test"
1006
+
1007
+ # 链式 API(类 Node.js crypto)
1008
+ result = ctx.evaluate("""
1009
+ CryptoUtils.createHash('sha256')
1010
+ .update('hello')
1011
+ .update(' world')
1012
+ .digest('hex')
1013
+ """)
1014
+ ```
1015
+
1016
+ ### URL 编码
1017
+
1018
+ ```python
1019
+ # URL 编码(兼容浏览器 API)
1020
+ result = ctx.evaluate("encodeURIComponent('hello world')") # "hello%20world"
1021
+ result = ctx.evaluate("decodeURIComponent('hello%20world')") # "hello world"
1022
+ ```
1023
+
1024
+ ### 随机数生成
1025
+
1026
+ ```python
1027
+ # UUID 生成
1028
+ uuid = ctx.evaluate("crypto.randomUUID()") # "a3111236-1431-4d0d-807e-6c7b388d4433"
1029
+
1030
+ # 随机数组
1031
+ result = ctx.evaluate("""
1032
+ const arr = new Uint8Array(16);
1033
+ crypto.getRandomValues(arr);
1034
+ Array.from(arr)
1035
+ """) # [123, 45, 67, ...]
1036
+
1037
+ # 随机浮点数
1038
+ result = ctx.evaluate("Deno.core.ops.op_crypto_random()") # 0.123456789
1039
+ ```
1040
+
1041
+ ### 定时器(立即执行版本)
1042
+
1043
+ ```python
1044
+ # setTimeout/setInterval(用于 API 检测,立即执行)
1045
+ result = ctx.evaluate("""
1046
+ let value = 0;
1047
+ setTimeout(() => { value = 42; }, 100); // 立即执行
1048
+ value // 需要等待 Promise
1049
+ """)
1050
+ ```
1051
+
1052
+ ⚠️ **注意**:setTimeout/setInterval 是**假的异步**(立即执行),仅用于通过 JS 代码中的 API 存在性检测。
1053
+
1054
+ ### Worker API(单线程模拟)
1055
+
1056
+ ```python
1057
+ # Worker API(用于兼容检测,单线程模拟)
1058
+ result = ctx.evaluate("""
1059
+ typeof Worker === 'function' &&
1060
+ typeof Worker.prototype.postMessage === 'function'
1061
+ """) # True
1062
+ ```
1063
+
1064
+ ⚠️ **注意**:Worker 是**单线程模拟**,不会真正创建多线程,仅用于通过代码检测。
1065
+
1066
+ ### 禁用扩展(纯净 V8)
1067
+
1068
+ 如果不需要这些 API,可以禁用扩展:
1069
+
1070
+ ```python
1071
+ ctx = never_jscore.Context(enable_extensions=False)
1072
+
1073
+ # 此时只有 ECMAScript 标准 API
1074
+ result = ctx.evaluate("typeof btoa") # "undefined"
1075
+ result = ctx.evaluate("JSON.stringify({a: 1})") # '{"a":1}' - 标准 API 可用
1076
+ ```
1077
+
1078
+ ## 适用场景
1079
+
1080
+ ### JavaScript 逆向分析(推荐)
1081
+
1082
+ ```python
1083
+ import never_jscore
1084
+
1085
+ # 加载目标网站的加密 JS
1086
+ with open("target_crypto.js") as f:
1087
+ js_code = f.read()
1088
+
1089
+ ctx = never_jscore.Context(enable_extensions=True) # 启用内置 Web API
1090
+ ctx.compile(js_code)
1091
+
1092
+ # 直接调用加密函数(无需额外 polyfill)
1093
+ encrypted = ctx.call("encrypt", [plain_text, key])
1094
+
1095
+ # 如果 JS 代码使用了 btoa、md5、sha256 等,都可以直接使用
1096
+ result = ctx.evaluate("btoa(md5('test'))")
1097
+ ```
1098
+
1099
+ ### 真实场景:API 签名生成
1100
+
1101
+ ```python
1102
+ import never_jscore
1103
+
1104
+ ctx = never_jscore.Context(enable_extensions=True)
1105
+
1106
+ # 典型的签名算法(无需 polyfill,直接运行)
1107
+ ctx.compile("""
1108
+ function generateSignature(params, secret) {
1109
+ // 1. 参数排序
1110
+ const keys = Object.keys(params).sort();
1111
+
1112
+ // 2. 拼接查询字符串
1113
+ const query = keys.map(k =>
1114
+ encodeURIComponent(k) + '=' + encodeURIComponent(params[k])
1115
+ ).join('&');
1116
+
1117
+ // 3. 添加密钥并计算 HMAC
1118
+ const message = query + '&key=' + secret;
1119
+ const signature = CryptoUtils.hmacSha256(secret, message);
1120
+
1121
+ // 4. Base64 编码
1122
+ return btoa(signature);
1123
+ }
1124
+ """)
1125
+
1126
+ # 调用签名函数
1127
+ signature = ctx.call("generateSignature", [
1128
+ {"user": "test", "timestamp": "1234567890"},
1129
+ "my-secret-key"
1130
+ ])
1131
+ print(f"Signature: {signature}")
1132
+ ```
1133
+
1134
+ ### 异步数据处理
1135
+
1136
+ ```python
1137
+ import never_jscore
1138
+
1139
+ ctx = never_jscore.Context()
1140
+ ctx.compile("""
1141
+ async function processBatch(items) {
1142
+ const results = await Promise.all(
1143
+ items.map(async item => {
1144
+ // 模拟异步处理
1145
+ return await Promise.resolve(item * 2);
1146
+ })
1147
+ );
1148
+ return results;
1149
+ }
1150
+ """)
1151
+
1152
+ result = ctx.call("processBatch", [[1, 2, 3, 4, 5]])
1153
+ print(result) # [2, 4, 6, 8, 10]
1154
+ ```
1155
+
1156
+ ## 性能优化建议
1157
+
1158
+ 1. **重用 Context**: 对于需要多次调用的代码,创建一个 Context 并复用
1159
+ 2. **批量处理**: 在 JavaScript 端批量处理数据,减少 Python-JS 调用次数
1160
+ 3. **单 Context 模式**: 尽可能将所有函数定义在一个 Context 中
1161
+ 4. **合理使用 auto_await**: 对于不需要等待的同步代码,设置 `auto_await=False` 可略微提升性能
1162
+ 5. **避免频繁创建 Context**: 创建 Context 有开销,应尽量复用
1163
+
1164
+ ## 模块化架构
1165
+
1166
+ 项目采用清晰的模块化设计:
1167
+
1168
+ ```
1169
+ src/
1170
+ ├── lib.rs # 模块入口,仅导出 Context 类
1171
+ ├── context.rs # Context 实现(V8 isolate 封装)
1172
+ ├── runtime.rs # V8/Tokio runtime 管理
1173
+ ├── convert.rs # Python ↔ JavaScript 类型转换
1174
+ ├── storage.rs # 结果存储
1175
+ ├── fs_ops.rs # 文件系统操作(11 个操作)
1176
+ ├── fetch_ops.rs # HTTP 请求(基于 reqwest)
1177
+ ├── crypto_ops.rs # 加密操作扩展(Base64、Hash、HMAC、Random)
1178
+ ├── encoding_ops.rs # URL 编码扩展
1179
+ ├── timer_ops.rs # 定时器扩展(setTimeout/setInterval)
1180
+ ├── worker_ops.rs # Worker API 扩展
1181
+ ├── ops/ # 新增 ops 模块
1182
+ │ ├── mod.rs # 模块导出
1183
+ │ ├── web_storage.rs # localStorage/sessionStorage(12 个操作)
1184
+ │ └── browser_env.rs # 浏览器环境对象(9 个操作)
1185
+ └── dddd_js/
1186
+ └── js_polyfill.js # JavaScript polyfill 层(自动注入,1660+ 行)
1187
+
1188
+ tests/
1189
+ ├── test_all_features.py # 完整功能测试套件
1190
+ ├── test_browser_apis.py # 浏览器 API 测试
1191
+ ├── test_high_priority_apis.py # 高优先级 API 测试
1192
+ ├── test_wasm.py # WebAssembly 测试
1193
+ ├── test_async_simple.py # 异步功能测试
1194
+ ├── test_extensions.py # 扩展 API 测试
1195
+ └── test_new_apis.py # 新 API 测试
1196
+ ```
1197
+
1198
+ ### 扩展系统架构
1199
+
1200
+ - **Rust 层**: 使用 Deno Core 的 `#[op2]` 宏定义底层操作
1201
+ - **JavaScript 层**: 在 `js_polyfill.js` 中封装为标准 Web API
1202
+ - **自动注入**: `enable_extensions=True` 时自动加载所有扩展
1203
+
1204
+ ## 测试
1205
+
1206
+ ```bash
1207
+ # 基础功能测试
1208
+ python test_async_simple.py
1209
+
1210
+ # Web API 扩展测试
1211
+ python test_extensions.py
1212
+ python test_new_apis.py
1213
+ ```
1214
+
1215
+ ## 技术细节
1216
+
1217
+ - **V8 引擎**: 使用 Deno Core 提供的 V8 bindings
1218
+ - **Tokio Runtime**: 全局单线程 runtime,支持异步操作
1219
+ - **类型转换**: Python ↔ JSON ↔ JavaScript 三层转换
1220
+ - **内存管理**: 使用 `std::mem::forget()` 避免 HandleScope 错误,每 100 次执行提示 GC
1221
+ - **扩展系统**: 基于 Deno Core extension 机制,模块化设计
1222
+ - **依赖库**:
1223
+ - `deno_core 0.367.0`: V8 运行时
1224
+ - `pyo3 0.27.1`: Python 绑定(abi3-py38)
1225
+ - `tokio 1.48`: 异步运行时
1226
+ - `reqwest 0.12`: HTTP 客户端(支持 JSON 和 blocking)
1227
+ - `lazy_static 1.4`: 全局状态管理(localStorage/sessionStorage)
1228
+ - `rand 0.8`: 随机数生成
1229
+ - `base64`, `md-5`, `sha1`, `sha2`, `hmac`: 加密库
1230
+ - `urlencoding`, `percent-encoding`: URL 编解码
1231
+
1232
+ ## 许可证
1233
+
1234
+ MIT License
1235
+
1236
+ ## 贡献
1237
+
1238
+ 欢迎提交 Issue 和 Pull Request!
1239
+
1240
+ ## 相关项目
1241
+
1242
+ - [py_mini_racer](https://github.com/sqreen/PyMiniRacer) - Python MiniRacer 实现
1243
+ - [PyExecJS](https://github.com/doloopwhile/PyExecJS) - 原 Python ExecJS 实现
1244
+ - [Deno](https://github.com/denoland/deno) - 现代 JavaScript/TypeScript 运行时
1245
+ - [PyO3](https://github.com/PyO3/pyo3) - Rust Python bindings
1246
+
1247
+ ## 更新日志
1248
+
1249
+ ### v2.2.0 (2025-11-11) - 重大功能扩展
1250
+
1251
+ #### Node.js 环境 API
1252
+ - ✨ **require()**: 完整的 CommonJS 模块系统
1253
+ - 相对/绝对路径模块加载
1254
+ - node_modules 递归查找
1255
+ - package.json 主入口解析
1256
+ - 模块缓存机制
1257
+ - ✨ **fs 模块**: 文件系统操作(readFileSync, writeFileSync, existsSync 等)
1258
+ - ✨ **path 模块**: 路径处理(resolve, join, dirname, basename 等)
1259
+ - ✨ **fetch()**: 现代 HTTP API
1260
+ - 支持所有 HTTP 方法(GET/POST/PUT/DELETE 等)
1261
+ - 自定义请求头
1262
+ - JSON 自动序列化/反序列化
1263
+ - Response/Headers 对象
1264
+ - 超时控制
1265
+
1266
+ #### 浏览器环境 API(补环境)
1267
+ - ✨ **localStorage/sessionStorage**: 浏览器存储 API
1268
+ - setItem/getItem/removeItem/clear
1269
+ - key() 和 length 属性
1270
+ - 线程安全全局存储
1271
+ - ✨ **浏览器环境对象**:
1272
+ - `navigator`: 用户代理、平台、语言等信息
1273
+ - `location`: URL 解析(href, protocol, hostname 等)
1274
+ - `document`: DOM 文档对象(readyState, title, URL 等)
1275
+ - `window`: 窗口属性(innerWidth, innerHeight 等)
1276
+ - `screen`: 屏幕信息(width, height, colorDepth 等)
1277
+ - ✨ **URL/URLSearchParams**: 完整的 URL 处理
1278
+ - URL 解析和构造
1279
+ - 查询参数操作(get/set/append/delete)
1280
+ - 迭代器支持
1281
+ - ✨ **FormData**: 表单数据处理
1282
+ - append/get/set/delete 方法
1283
+ - getAll() 获取所有同名字段
1284
+ - 迭代器支持
1285
+ - ✨ **Event/EventTarget**: 完整的事件系统
1286
+ - Event 类(preventDefault, stopPropagation)
1287
+ - EventTarget 类(addEventListener, removeEventListener, dispatchEvent)
1288
+ - 事件阶段常量和选项(once, capture)
1289
+ - ✨ **XMLHttpRequest**: 传统 AJAX API
1290
+ - 基于 fetch() 实现
1291
+ - 完整的状态管理(UNSENT/OPENED/HEADERS_RECEIVED/LOADING/DONE)
1292
+ - 事件处理器(onload, onerror, onreadystatechange)
1293
+ - 请求头操作
1294
+
1295
+ #### 新增依赖
1296
+ - `reqwest 0.12`: HTTP 客户端库(blocking 模式)
1297
+ - `lazy_static 1.4`: 全局状态管理
1298
+
1299
+ #### 代码增量
1300
+ - **Rust 代码**: ~800 行新增代码
1301
+ - fs_ops.rs (11 个操作)
1302
+ - fetch_ops.rs (3 个操作)
1303
+ - web_storage.rs (12 个操作)
1304
+ - browser_env.rs (9 个操作)
1305
+ - **JavaScript 代码**: ~890 行新增代码
1306
+ - require() 实现(~200 行)
1307
+ - fetch/Response/Headers(~60 行)
1308
+ - localStorage/sessionStorage(~50 行)
1309
+ - URL/URLSearchParams(~160 行)
1310
+ - FormData(~80 行)
1311
+ - Event/EventTarget(~130 行)
1312
+ - XMLHttpRequest(~180 行)
1313
+ - 浏览器环境对象(~40 行)
1314
+
1315
+ #### 测试覆盖
1316
+ - ✅ test_all_features.py: 7 个综合测试(100% 通过)
1317
+ - ✅ test_browser_apis.py: 浏览器 API 完整测试
1318
+ - ✅ test_high_priority_apis.py: 高优先级 API 测试
1319
+ - ✅ test_wasm.py: WebAssembly 验证测试
1320
+
1321
+ ### v2.0.0 (2025-11-05)
1322
+
1323
+ #### 架构重构
1324
+ - 🔄 **架构重构**: 改为 py_mini_racer 风格的实例化 API
1325
+ - ✅ 修复 HandleScope 错误:使用 `std::mem::forget()` 管理 v8::Global
1326
+ - ✅ 明确 LIFO 清理顺序要求
1327
+ - ✅ 完善多 Context 使用限制说明
1328
+ - ✅ 新增 `compile()` 便捷方法
1329
+ - ✅ 新增 `evaluate()` 独立求值方法
1330
+
1331
+ #### Web API 扩展(全新)
1332
+ - ✨ **Crypto APIs**:
1333
+ - Base64: `btoa()`, `atob()`
1334
+ - 哈希: `md5()`, `sha1()`, `sha256()`, `sha512()`
1335
+ - HMAC: `hmacMd5()`, `hmacSha1()`, `hmacSha256()`
1336
+ - Hex: `hexEncode()`, `hexDecode()`
1337
+ - 链式 API: `CryptoUtils.createHash()`, `CryptoUtils.createHmac()`
1338
+ - ✨ **URL 编码**: `encodeURIComponent()`, `decodeURIComponent()`, `encodeURI()`, `decodeURI()`
1339
+ - ✨ **定时器**: `setTimeout()`, `setInterval()`, `clearTimeout()`, `clearInterval()` (立即执行版本)
1340
+ - ✨ **Worker API**: `Worker` 类(单线程模拟版本)
1341
+ - ✨ **随机数**: `crypto.randomUUID()`, `crypto.getRandomValues()`, 随机数 ops
1342
+ - 🎯 **扩展控制**: `Context(enable_extensions=True/False)` 可选启用/禁用
1343
+ - 📦 **自动注入**: 无需手动加载 polyfill,开箱即用
1344
+
1345
+ #### 性能优化
1346
+ - ⚡ 扩展模块采用 Rust 实现,性能接近原生
1347
+ - ⚡ JavaScript polyfill 层仅在必要时使用
1348
+
1349
+ ### v0.1.0 (2025-11-01)
1350
+
1351
+ - ✅ 基于 Deno Core 的 JavaScript 执行
1352
+ - ✅ Promise/async/await 完整支持
1353
+ - ✅ Python ↔ JavaScript 类型自动转换
1354
+ - ✅ 模块化代码架构
1355
+ - ✅ 完整的类型提示支持
1356
+ - ✅ 性能监控和统计
1357
+