Releases: OdinoCano/3va
v2.0.3
Full Changelog: v2.0.2...v2.0.3
Full Changelog: v2.0.2...v2.0.3
v2.0.2
Full Changelog: v2.0.0...v2.0.2
v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v1.0.0...v2.0.0
Full Changelog: v2.0.1...v2.0.0
Full Changelog: v2.0.1...v2.0.0
Full Changelog: v2.0.1...v2.0.0
v2.0.1
Full Changelog: v1.0.0...v2.0.1
3va 1.0.0
[1.0.0] — 2026-06-04
Added
- CDP Inspector (
--inspect) — WebSocket Chrome DevTools Protocol server.debugger;statements are rewritten to__3va_debugger__()at source-load time. Pause is implemented viatokio::task::block_in_place+Condvarso the Tokio runtime remains responsive. Connect withchrome://inspector any DAP-compatible IDE. - NAPI native module loading (
--allow-ffi) — ~30 NAPI v8 functions exposed asunsafe extern "C"..nodeaddons loaded via the standardrequire('./addon.node')path. Requires--allow-ffipermission. - WebAssembly (WASM) — WASI-preview1-compatible runtime via
wasmtime. Supports.wasmand.watfiles. Full permission integration (filesystem preopens, env vars scoped to granted capabilities). - Post-quantum TLS (
__pqTlsConnect) — hybrid classical TLS + ML-KEM-768 key exchange. Returns{ connId, pqSharedSecret }. Non-blocking: runs insidespawn_blocking. Requires--allow-net. - Post-quantum crypto JS API —
require('crypto').pq.kem.{generateKeypair,encapsulate,decapsulate}(ML-KEM-768) andrequire('crypto').pq.dsa.{generateKeypair,sign,verify}(ML-DSA-65). - Fuzz targets in CI — 3 fuzz targets built on nightly; 30 s smoke run in GitHub Actions.
- Doc-tests — public API surfaces of
vvva_core,vvva_permissions,vvva_crypto, andvvva_jsnow have doc-tests. SECURITY.md— explicit acceptance rationale for RUSTSEC-2023-0071 (Marvin Attack); documents "before 1.0" review requirement.- Process manager subcommands —
start,stop,restart,status,logs,deletefor running scripts as managed background daemons.
Fixed
__pqTlsConnectwas synchronous on the JS event loop (blocked all timers and I/O during TLS handshake). Now runs insidespawn_blockingand is registered asAsync.SemverRangesilently rejected"latest","1.x",">=1.0.0 <2.0.0"forms — added dist-tag, x-range, and compound-range support.- Dependency resolver produced non-deterministic lockfiles (HashMap iteration order). Resolution stack is now sorted alphabetically.
- Version conflict in the resolver was silent — now emits a structured
tracing::warn!. Content-Lengthheader forwarded to JS did not reflect the 100 MiB internal cap.
Changed
rquickjs-core 0.6.2vendored atvendor/rquickjs-core/with a one-line fix for thenever type fallbackfuture-incompatibility lint (Rust Edition 2024).- All crate versions bumped to
1.0.0.
Added
-
Expo / React Native package support (
crates/js/src/builtins/modules.rs,crates/js/src/transpiler.rs):
Real Expo npm packages (expo-modules-core,expo-constants,expo-asset,expo-font,expo-file-system) load and execute without errors. 45/45 tests pass intest-projects/expo-test/.ESM→CJS converter fixes:
- Circular dependency guard —
module.exportspre-cached before eval; circular requires get the partial exports object instead of re-executing the module (matches Node.js behavior, eliminates stack overflows). export default Xchained assignment — was setting.defaulton the OLDmodule.exportsobject due to JS LHS-ref evaluation order. Now uses two statements:module.exports = X+ deferredmodule.exports.default = module.exports.- Destructuring exports —
export const { a, b } = Xandexport const [a, b] = Xnow correctly emit individualmodule.exports.a = aentries. - Uninitialised var export —
export var X;is now deferred so TypeScript enum IIFEs can fill the value beforemodule.exports.Xis set. - Empty export marker —
export {}(OXC emits this to tag a file as ESM) is now a no-op; previously surfaced as "unsupported keyword: export". - Dynamic
import()— inlineimport(specifier)expressions are rewritten to__importAsync(specifier)which wraps synchronousrequire()in a resolved Promise. - Deferred exports — all deferred assignments wrapped in
try{}catch{}to tolerate read-only properties defined byObject.defineProperty.
Platform-aware extension resolution:
resolve_file_pathprobes.web.js,.web.tsx,.web.ts,.web.mjsbefore the generic.js,.tsx,.tsvariants. Expo.web.*files are the correct choice in a server/CLI context (they avoid native bridge imports).- Index file probing follows the same order (
index.web.tsbeforeindex.ts).
TypeScript transpiler:
SemanticBuilder::with_enum_eval(true)added — prevents OXC panic when transforming TypeScriptconst enumdeclarations.
New React Native / Expo polyfills:
react-nativepre-cached in__requireCachewithPlatform,NativeModules,TurboModuleRegistry,PixelRatio,Dimensions,StyleSheet,Animated, and all major component stubs.@react-native/assets-registrypre-cached withregisterAsset/getAssetByID.NativeModulesproxy changed to returnundefinedfor unregistered module names (previously returned a truthy function-proxy, causingJSON.parse(function(){})errors inexpo-constants).expo-modules-corepolyfill extended withNativeModule,SharedObject,SharedRef(extendable base classes),registerWebModule,Platform,uuid.requireOptionalNativeModulereturnsnull— correct for a web/server environment where optional native modules are absent.process.env.EXPO_OS = 'web'— Expo packages branch on this to select server-safe code paths.
- Circular dependency guard —
-
CPU sampling profiler (
--prof) (crates/js/src/profiler.rs):3va run app.ts --prof— collects samples every--prof-intervalms (default 10) viasetInterval+new Error().stack; writes V8-compatible.cpuprofileJSON.--flamegraph=<path>— also emits an Inferno-style SVG flamegraph using theinfernocrate.3va prof <file>subcommand — post-hoc analysis: prints top-N hot functions by self% or re-generates a flamegraph from an existing.cpuprofile.console.profile(label)/console.profileEnd(label)— JS-side region markers, active when--profis passed.JsEngine::new_with_profiler(perms, interval_ms)/JsEngine::take_profiler()— public Rust API.- 7 unit tests: stack parser, location parser, folded-stacks aggregation,
.cpuprofileJSON validity,analyze_cpuprofile, JS bootstrap interval embedding.
-
Buffercomo subclase real deUint8Array(builtins/buffer.rs):
Reescrito usando el patrón prototype swap: el constructor devuelve unUint8Arrayreal conBuffer.prototypeen su cadena. Esto garantiza:buf instanceof Uint8Array→truebuf[0]→ valor de byte correcto (proxy nativo de TypedArray)[...buf]spread,buf.set(),Array.from(buf)— todos funcionan como nativosDataView,Float32Arrayy otras vistas sobrebuf.bufferfuncionan sin conversión- Compatibles con
ws,msgpackr,protobufjsy cualquier librería que accede a bytes directamente
Todos los métodos (readUInt32BE,writeFloatLE,BigUInt64,slice,subarray, etc.) actualizados para operar sobrethisdirectamente.
-
crypto.createSign/createVerify— RSA PKCS1v15 y ECDSA reales (builtins/crypto.rs):
Implementación nativa vía crates Rust. Soporta:- RSA PKCS#1 v1.5: algoritmos
RSA-SHA256,RSA-SHA384,RSA-SHA512,SHA256,SHA1 - ECDSA P-256:
SHA256con clave P-256 - ECDSA P-384:
SHA384con clave P-384 - Salida en formato DER (compatible con
jsonwebtoken,passport-jwt,jose) - Acepta DER y P1363 (raw r‖s) en verificación
const sig = crypto.createSign('RSA-SHA256').update(data).sign(privateKey); crypto.createVerify('RSA-SHA256').update(data).verify(publicKey, sig); // → true
- RSA PKCS#1 v1.5: algoritmos
-
crypto.createPrivateKey/createPublicKey/createSecretKey(builtins/crypto.rs):
Importa claves PEM existentes en objetosKeyObjectcompatibles con Node.js..type→'private','public', o'secret'.asymmetricKeyType→'rsa'o'ec'.export()→ PEM string o Uint8Array (conformat: 'der')
Desbloquea:jsonwebtokencon claves externas,passport-jwt,@panva/jose.
-
crypto.sign/crypto.verify(one-shot, Node.js 15+) (builtins/crypto.rs):const sig = crypto.sign('SHA256', data, privateKey); crypto.verify('SHA256', data, publicKey, sig); // → boolean
-
crypto.createHash('md5')(builtins/crypto.rs):
MD5 ahora soportado vía cratemd-5 0.10(algoritmo RustCrypto). Para fingerprinting de contenido,
ETags, compatibilidad legacy. No recomendado para seguridad. -
crypto.getCiphers()/getHashes()/getCurves()(builtins/crypto.rs):
Nuevas funciones de enumeración que devuelven los algoritmos soportados. -
crypto.generateKeyPair/generateKeyPairSync— RSA y EC nativos (builtins/crypto.rs):
Generación de pares de claves asimétricas vía Rust (rsa 0.9,p256 0.13,p384 0.13).crypto.generateKeyPairSync('rsa', { modulusLength: 2048 })→{ publicKey, privateKey }con.export()que devuelve PEM PKCS#8/SPKI.crypto.generateKeyPair('rsa', opts, callback)— versión async con spawn_blocking.- Curvas EC soportadas:
P-256(prime256v1),P-384(secp384r1). - Claves RSA-PSS: misma implementación que RSA estándar.
Desbloquea: JWT RS256/ES256/ES384 conjsonwebtoken,passport-jwt,node-jose.
-
crypto.webcrypto(builtins/crypto.rs):
Añadidocrypto.webcrypto = { subtle }como alias alcrypto.subtleexistente.
Requerido por Hono, edge runtimes, y cualquier código que accede a WebCrypto víarequire('crypto').webcrypto. -
crypto.scryptSync— implementación real con scrypt (builtins/crypto.rs):
Sustituye la aproximación anterior (PBKDF2 como fallback) por__cryptoScryptSync, que llama
directamente a la implementación nativascrypt::scrypt. N...