diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7f3f7f1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Disable automatic line ending conversion +# This repository has mixed line endings (CRLF and LF) and we want to preserve them as-is +* -text + +# Binary files (explicit, for clarity) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.woff binary +*.woff2 binary +*.ttf binary +*.eot binary diff --git a/Cargo.lock b/Cargo.lock index 930f3cf..8487aa3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,10 +7,6 @@ name = "Inflector" version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] [[package]] name = "addr2line" @@ -156,9 +152,9 @@ checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" @@ -231,13 +227,12 @@ dependencies = [ [[package]] name = "ast_node" -version = "3.0.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fb5864e2f5bf9fd9797b94b2dfd1554d4c3092b535008b27d7e15c86675a2f" +checksum = "2eb025ef00a6da925cf40870b9c8d008526b6004ece399cb0974209720f0b194" dependencies = [ - "proc-macro2", "quote", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] @@ -261,17 +256,6 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -330,16 +314,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.26.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9dd2e03ee80ca2822dd6ea431163d2ef259f2066a4d6ccaca6d9dcb386aa43" +checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" dependencies = [ "bindgen 0.69.5", "cc", "cmake", "dunce", "fs_extra", - "paste", ] [[package]] @@ -465,9 +448,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "better_scoped_tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50fd297a11c709be8348aec039c8b91de16075d2b2bdaee1bd562c0875993664" +checksum = "7cd228125315b132eed175bf47619ac79b945b26e56b848ba203ae4ea8603609" dependencies = [ "scoped-tls", ] @@ -506,9 +489,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.71.1" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ "bitflags 2.9.0", "cexpr", @@ -687,12 +670,32 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "bytes-str" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c60b5ce37e0b883c37eb89f79a1e26fbe9c1081945d024eee93e8d91a7e18b3" +dependencies = [ + "bytes", + "serde", +] + [[package]] name = "cache_control" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2a5fb3207c12b5d208ebc145f967fea5cac41a021c37417ccc31ba40f39ee" +[[package]] +name = "calendrical_calculations" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a0b39595c6ee54a8d0900204ba4c401d0ab4eb45adaf07178e8d017541529e7" +dependencies = [ + "core_maths", + "displaydoc", +] + [[package]] name = "capacity_builder" version = "0.5.0" @@ -779,9 +782,9 @@ checksum = "d5c24f6a463e9973db3df3c2cc276f689f5baf289c87a693dc859e004d3eb45f" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "num-traits", "serde", @@ -880,12 +883,11 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ - "termcolor", - "unicode-width 0.1.13", + "unicode-width 0.2.2", ] [[package]] @@ -944,6 +946,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -952,15 +964,24 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics-types" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 1.3.2", - "core-foundation", + "bitflags 2.9.0", + "core-foundation 0.10.1", "libc", ] +[[package]] +name = "core_maths" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30" +dependencies = [ + "libm", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -1138,6 +1159,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -1274,19 +1301,18 @@ dependencies = [ [[package]] name = "deno_ast" -version = "0.49.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24158ccf7def38c00fd253fd1b48c8c6207214078fe499f47168763fa2445bf2" +checksum = "30c2f6f65154faed61e45d6578566f9fab9d2a330c35c87366706883701cce51" dependencies = [ "base64 0.22.1", "capacity_builder", "deno_error", - "deno_media_type", + "deno_media_type 0.3.0", "deno_terminal", "dprint-swc-ext", "percent-encoding", "serde", - "sourcemap", "swc_atoms", "swc_common", "swc_config", @@ -1294,6 +1320,7 @@ dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", "swc_ecma_codegen_macros", + "swc_ecma_lexer", "swc_ecma_loader", "swc_ecma_parser", "swc_ecma_transforms_base", @@ -1305,35 +1332,40 @@ dependencies = [ "swc_ecma_utils", "swc_ecma_visit", "swc_eq_ignore_macros", - "swc_macros_common 1.0.0", + "swc_macros_common", + "swc_sourcemap", "swc_visit", - "swc_visit_macros", "text_lines", "thiserror 2.0.14", - "unicode-width 0.2.0", + "unicode-width 0.2.2", "url", ] [[package]] name = "deno_broadcast_channel" -version = "0.207.0" +version = "0.216.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67a6a80bc318c225eb2f369b23c940cc1a0cf4e5bfbf734a86ac33048e1599b" + +[[package]] +name = "deno_bundle_runtime" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6d1a56c8c5e65b2b2cb42f4409121ada0bb23fdf5de84aa7fdad3fe6227684" +checksum = "7cf499508006f8d999385b025599bfea445ef6bf349acdf43e2e9eb5d49f4fbc" dependencies = [ "async-trait", "deno_core", "deno_error", - "deno_features", - "thiserror 2.0.14", - "tokio", - "uuid", + "deno_web", + "regex", + "serde", ] [[package]] name = "deno_cache" -version = "0.145.0" +version = "0.159.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69582f3db706e3a771364c3556ed4575fa586bf5c54afb481980f25bc230df91" +checksum = "a18c94da036f1d6c8afe8696d4ffdbeff0c59b484edf4e8594517ca2e13797a0" dependencies = [ "async-stream", "async-trait", @@ -1360,9 +1392,9 @@ dependencies = [ [[package]] name = "deno_cache_dir" -version = "0.24.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "392538d71e0ce9db316302116095b8acef4d734a8e2360d16308ca7dc32dcdc3" +checksum = "7862aa4b7aad895ee979a3078bd25da192a1810b30cb5a7e764fed38d065eba9" dependencies = [ "async-trait", "base32", @@ -1372,7 +1404,7 @@ dependencies = [ "chrono", "data-url", "deno_error", - "deno_media_type", + "deno_media_type 0.3.0", "deno_path_util", "http 1.1.0", "indexmap 2.9.0", @@ -1387,30 +1419,17 @@ dependencies = [ "url", ] -[[package]] -name = "deno_canvas" -version = "0.82.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf10aafd8b86b6bc1019b68249f70be4c70d49a6f957bc5658afea78dbaa6dd" -dependencies = [ - "bytemuck", - "deno_core", - "deno_error", - "image", - "lcms2", - "num-traits", - "thiserror 2.0.14", -] - [[package]] name = "deno_config" -version = "0.63.0" +version = "0.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf67de1d3be71b9449f297dfe685c7c2b6911949fb25f1c3a53fb3190549cf4" +checksum = "f7a46657bd5ab6bd9df0602fd50331c49c66706fe2a6386fe6a1c9b81f3031b3" dependencies = [ "boxed_error", "capacity_builder", + "chrono", "deno_error", + "deno_maybe_sync", "deno_package_json", "deno_path_util", "deno_semver", @@ -1429,18 +1448,15 @@ dependencies = [ [[package]] name = "deno_console" -version = "0.213.0" +version = "0.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c53d2fbfe68ff0d39dcbffb869bfa30019da2db5d0efbfb4b3fcc04bd1aed0e" -dependencies = [ - "deno_core", -] +checksum = "ed7dede3d073a7d19e5e127756d80a1a8b570d8345e51192968da142ed290319" [[package]] name = "deno_core" -version = "0.355.0" +version = "0.376.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775d2fde80a2ec3116d179703b38346a931bb9626f4a826148d5fe8631cab29f" +checksum = "829ee94e76838e99951cc7b3ccd31f68a220687f52229c0d6e135ff29b22f6d0" dependencies = [ "anyhow", "az", @@ -1483,9 +1499,9 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" [[package]] name = "deno_cron" -version = "0.93.0" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d52e26778837fcd8067416270f34e4e2e1160248f9d75d8d9c9dd58bd90991" +checksum = "13bab29168443140e5914af8a2358dfb8158898b2a73ef33839cbcb31074220c" dependencies = [ "async-trait", "chrono", @@ -1499,9 +1515,9 @@ dependencies = [ [[package]] name = "deno_crypto" -version = "0.227.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f8afd2869b8cefa809e912ba73242485ac69009b6195581eea8a75bc1b89c7" +checksum = "b235765571dca50710542ec2305b936c2c435f5efe632307cf6b2735e0449268" dependencies = [ "aes", "aes-gcm", @@ -1539,18 +1555,18 @@ dependencies = [ [[package]] name = "deno_crypto_provider" -version = "0.7.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581c915335e9f5e628dea0029ef443f99ca8a5421803a361fdda4ad5b5370c75" +checksum = "a4e486cef731046954a2eaa9ecd71669101ac2ceac61f2dbdad1c3a6eac5ac5c" dependencies = [ - "aws-lc-sys 0.26.0", + "aws-lc-sys 0.29.0", ] [[package]] name = "deno_error" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde60bd153886964234c5012d3d9caf788287f28d81fb24a884436904101ef10" +checksum = "bfafd2219b29886a71aecbb3449e462deed1b2c474dc5b12f855f0e58c478931" dependencies = [ "deno_error_macro", "libc", @@ -1562,9 +1578,9 @@ dependencies = [ [[package]] name = "deno_error_macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "409f265785bd946d3006756955aaf40b0e4deb25752eae6a990afe54a31cfd83" +checksum = "1c28ede88783f14cd8aae46ca89f230c226b40e4a81ab06fa52ed72af84beb2f" dependencies = [ "proc-macro2", "quote", @@ -1573,9 +1589,9 @@ dependencies = [ [[package]] name = "deno_features" -version = "0.10.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e73252505f94efc5be0e5c8255b8d2b7e4c1b6361a36c033486ae83d2cddbd37" +checksum = "45ef52b29c98bd0461f705d5ef6213346c028110b364f5d84e6151710832075a" dependencies = [ "deno_core", "serde", @@ -1584,9 +1600,9 @@ dependencies = [ [[package]] name = "deno_fetch" -version = "0.237.0" +version = "0.250.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f05820261bcc82d377f79878625d61ac70b58c886345e5b1d68f6b012ae4765" +checksum = "d2cedb5a547dba738cff57f879fde761356bdd23b80668de93cd95ee0f8b92f3" dependencies = [ "base64 0.22.1", "bytes", @@ -1624,9 +1640,9 @@ dependencies = [ [[package]] name = "deno_ffi" -version = "0.200.0" +version = "0.213.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35f76fbe2a28bbd9af9767b3e262a5da732759f4095347ec8ab9cf183e7888a3" +checksum = "7ba7fff4f630257bfc405a3ccb88a59e48b09bac5dfdc72155666b28ec001760" dependencies = [ "cranelift", "cranelift-native", @@ -1650,9 +1666,9 @@ dependencies = [ [[package]] name = "deno_fs" -version = "0.123.0" +version = "0.136.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b670b3bbceb5aee7e840a4e960e0e0def8f3cf5554f191035b209f38f555638" +checksum = "02bfffd3f56099d7bc5d1622d367e2c91ce860b0bb7939c2b790c46af184aed7" dependencies = [ "async-trait", "base32", @@ -1660,6 +1676,7 @@ dependencies = [ "deno_core", "deno_error", "deno_io", + "deno_maybe_sync", "deno_path_util", "deno_permissions", "filetime", @@ -1676,9 +1693,9 @@ dependencies = [ [[package]] name = "deno_http" -version = "0.211.0" +version = "0.224.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769c9b785e7f87b5e6a5f2aab7b2b74d482670f51b2a7f1a104089f7afe28ea2" +checksum = "5a23fe4d69546e79820c112296e37e6b20109838de9981682770fbd444edec83" dependencies = [ "async-compression", "async-trait", @@ -1689,6 +1706,7 @@ dependencies = [ "cache_control", "deno_core", "deno_error", + "deno_fetch", "deno_net", "deno_telemetry", "deno_websocket", @@ -1716,11 +1734,26 @@ dependencies = [ "tokio-vsock", ] +[[package]] +name = "deno_image" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3aca5b0d43db3b05e998604ce5517989d7f36af2fd693884feddf70aa85b5f6" +dependencies = [ + "bytemuck", + "deno_core", + "deno_error", + "image", + "lcms2", + "num-traits", + "thiserror 2.0.14", +] + [[package]] name = "deno_io" -version = "0.123.0" +version = "0.136.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5ed7012795555df1a65441c416e1a699d596c8ccf26c346fe6db6d35cd60336" +checksum = "c75b313e7f2311c23dff33d35e8561b9786440fbaa377fe3f873fb0dc461b82f" dependencies = [ "async-trait", "deno_core", @@ -1745,9 +1778,9 @@ dependencies = [ [[package]] name = "deno_kv" -version = "0.121.0" +version = "0.134.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edd0dcf23f34424364f3634dc2327af996285436245c40524068ba6129bba2c" +checksum = "cfc81b0449840666f9d6e8f142747eb3edc1b436cf712f49d307fb868a47dec0" dependencies = [ "anyhow", "async-trait", @@ -1780,9 +1813,9 @@ dependencies = [ [[package]] name = "deno_lockfile" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5afb20b44a44842178f41fa3b713c2b1516062590b5cca2ad792f2d6786bc74f" +checksum = "3d71c0df1464034be21a9472e7ec8f9a21958418d203fa2c40507fb5cafe799d" dependencies = [ "async-trait", "deno_semver", @@ -1791,6 +1824,15 @@ dependencies = [ "thiserror 2.0.14", ] +[[package]] +name = "deno_maybe_sync" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6716d359b3fe9d3fc6ab08f39e463ff9a63033041fe6aaeecf1930b284474b9b" +dependencies = [ + "dashmap", +] + [[package]] name = "deno_media_type" version = "0.2.9" @@ -1802,11 +1844,22 @@ dependencies = [ "url", ] +[[package]] +name = "deno_media_type" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0109d26ff08a089642a79b45c65f91a849404c1ef3ec78c837a412956d8808" +dependencies = [ + "data-url", + "serde", + "url", +] + [[package]] name = "deno_napi" -version = "0.144.0" +version = "0.157.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5102d9e32e88c1cbb3034594679a3e3902b295077c0c2a24069dc98c2f6c8aae" +checksum = "4a1eace0f5a480e510d5c501660f41bcf8a35b192969868c3a411fa4e95d9815" dependencies = [ "deno_core", "deno_error", @@ -1835,9 +1888,9 @@ dependencies = [ [[package]] name = "deno_net" -version = "0.205.0" +version = "0.218.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5fcbc6f531c0ee8e7be34bc877aef1ed20c94b7d2215929ea176280259fc7a" +checksum = "6a7c7f51d5e5f695c56596d6de2afeb2ddb26d432506dba2edfd44f61c869c79" dependencies = [ "deno_core", "deno_error", @@ -1848,6 +1901,7 @@ dependencies = [ "deno_tunnel", "hickory-proto", "hickory-resolver", + "libc", "log", "pin-project", "quinn", @@ -1864,9 +1918,9 @@ dependencies = [ [[package]] name = "deno_node" -version = "0.151.0" +version = "0.164.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fccfb2ea5216cb8112861851771886b26f6341232d44e9676bddcb937b7754" +checksum = "1ae702dad0dec327be07e23a0fb243f1be7a59a43a9964fb48ca867fa8618d8d" dependencies = [ "aead-gcm-stream", "aes", @@ -1892,6 +1946,7 @@ dependencies = [ "deno_permissions", "deno_process", "deno_subprocess_windows", + "deno_tls", "deno_whoami", "der", "digest", @@ -1914,8 +1969,10 @@ dependencies = [ "k256", "libc", "libz-sys", + "log", "md-5", "md4", + "nix 0.27.1", "node_resolver", "num-bigint", "num-bigint-dig", @@ -1931,6 +1988,7 @@ dependencies = [ "ripemd", "rsa", "rusqlite", + "rustls-tokio-stream", "scrypt", "sec1", "serde", @@ -1939,6 +1997,7 @@ dependencies = [ "sha3", "signature", "sm3", + "socket2 0.5.7", "spki", "sys_traits", "thiserror 2.0.14", @@ -1951,17 +2010,18 @@ dependencies = [ "windows-sys 0.59.0", "x25519-dalek", "x509-parser", - "yoke", + "yoke 0.7.4", ] [[package]] name = "deno_npm" -version = "0.36.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688f93cb13db227a013bfd5c5973235458615115934fc37ce2e72620c9934526" +checksum = "7daa908c280b25d68ea59765144df488714716cc14a2dcafaa1ec3906d4abbbe" dependencies = [ "async-trait", "capacity_builder", + "chrono", "deno_error", "deno_lockfile", "deno_semver", @@ -1977,26 +2037,26 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.231.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca530772bbcbc9ad389ad7bcd86623b2ec555f68a2d062d23cc008915cbe781" +checksum = "c83a1be112eed3cb12e02c541f0da2a7357655aa519f3f180c405c0409cfa5ea" dependencies = [ "indexmap 2.9.0", - "proc-macro-rules", "proc-macro2", "quote", "stringcase", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum", + "strum_macros", "syn 2.0.87", + "syn-match", "thiserror 2.0.14", ] [[package]] name = "deno_os" -version = "0.30.0" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2b0b7c124499ae48516464a3636b900cdecd765c7e6e411f813038b3e1c575" +checksum = "1d7ca2f93af2e4296b1bbb09ed65093925ae6aacf02e64c645f9f4be31763b15" dependencies = [ "deno_core", "deno_error", @@ -2015,12 +2075,13 @@ dependencies = [ [[package]] name = "deno_package_json" -version = "0.15.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36155ebe3074c582c533895056071dc05036548e40420bd977cc41b822a3dc49" +checksum = "068ca274a783b395305290a1e606469c80123f9a5a542f51e9b817e03e3b2796" dependencies = [ "boxed_error", "deno_error", + "deno_maybe_sync", "deno_path_util", "deno_semver", "indexmap 2.9.0", @@ -2033,9 +2094,9 @@ dependencies = [ [[package]] name = "deno_path_util" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe02936964b2910719bd488841f6e884349360113c7abf6f4c6b28ca9cd7a19" +checksum = "78c7e98943f0d068928906db0c7bde89de684fa32c6a8018caacc4cee2cdd72b" dependencies = [ "deno_error", "percent-encoding", @@ -2046,11 +2107,12 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.72.0" +version = "0.85.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e08943b9430d1e78b7ddae254666aadfe5d8b3ee5cb253f1dff872ef5b22f10" +checksum = "ea134204d5c84e0a186de208c410e4c38c839cea308e579037e747405affb947" dependencies = [ "capacity_builder", + "chrono", "deno_error", "deno_path_util", "deno_terminal", @@ -2075,9 +2137,9 @@ dependencies = [ [[package]] name = "deno_process" -version = "0.28.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e378d7a21caef5ac9e6b7e23247dd95c71c702aaae9c73fc8aecced2f330fbf" +checksum = "e5a85f57bec6a19f2e3634d9905543d5821fe28691a12bec0183389999e7f11e" dependencies = [ "deno_core", "deno_error", @@ -2106,9 +2168,9 @@ dependencies = [ [[package]] name = "deno_resolver" -version = "0.44.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caaf3b5a2f5d25e1cf45e8e4435465d413cc5ebc1f5ac286aa977165d26a7fc1" +checksum = "cdc21fb4cbd83f363f2ce32c51df542e110ecac9d22f4c36dfac2bdb7c6d5dd8" dependencies = [ "anyhow", "async-once-cell", @@ -2116,12 +2178,14 @@ dependencies = [ "base32", "boxed_error", "capacity_builder", + "chrono", "dashmap", "deno_cache_dir", "deno_config", "deno_error", "deno_lockfile", - "deno_media_type", + "deno_maybe_sync", + "deno_media_type 0.3.0", "deno_npm", "deno_package_json", "deno_path_util", @@ -2148,15 +2212,14 @@ dependencies = [ [[package]] name = "deno_runtime" -version = "0.221.0" +version = "0.234.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1615b74c4632c7d0d91b58cdbce233e3c662aa1460d02b0a68acc8e2d9af46bf" +checksum = "bfa19bcc64b53ce47ce91aa870f83c6737fabb4b9194b720f09a71e24a8ee15c" dependencies = [ + "async-trait", "color-print", - "deno_broadcast_channel", + "deno_bundle_runtime", "deno_cache", - "deno_canvas", - "deno_console", "deno_core", "deno_cron", "deno_crypto", @@ -2166,6 +2229,7 @@ dependencies = [ "deno_ffi", "deno_fs", "deno_http", + "deno_image", "deno_io", "deno_kv", "deno_napi", @@ -2180,7 +2244,6 @@ dependencies = [ "deno_telemetry", "deno_terminal", "deno_tls", - "deno_url", "deno_web", "deno_webgpu", "deno_webidl", @@ -2192,6 +2255,7 @@ dependencies = [ "http-body-util", "hyper 1.6.0", "hyper-util", + "indexmap 2.9.0", "libc", "log", "nix 0.27.1", @@ -2199,6 +2263,7 @@ dependencies = [ "notify", "ntapi", "once_cell", + "regex", "rustyline", "same-file", "serde", @@ -2214,9 +2279,9 @@ dependencies = [ [[package]] name = "deno_semver" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2625b7107cc3f61a462886d5fa77c23e063c1fd15b90e3d5ee2646e9f6178d55" +checksum = "92d46d2fd6959170a6e9f6607a6f79683868fa82ceac56ca520ab014e4fa5b21" dependencies = [ "capacity_builder", "deno_error", @@ -2231,9 +2296,9 @@ dependencies = [ [[package]] name = "deno_signals" -version = "0.4.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3edcc759556d2d3170bcb5f430c2a3b2ed873211af3c360cc77523ea79b09ffa" +checksum = "1d963f791b2bd211be5c9c18b2a3a83ff672f5774a7425e605127c8450956961" dependencies = [ "deno_error", "libc", @@ -2245,9 +2310,9 @@ dependencies = [ [[package]] name = "deno_subprocess_windows" -version = "0.8.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a79fb81598d64bd3adc801fae8f9f6930f4a790f50ff0196e0fe20c92fab46" +checksum = "921d3801fcfb9e6f8e287f8cacd56f9dc801e27dd57ba67132f6c2960e114566" dependencies = [ "fastrand", "futures-channel", @@ -2257,9 +2322,9 @@ dependencies = [ [[package]] name = "deno_telemetry" -version = "0.35.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80894b874df0ade53b85fd094ff948d645cfe05b5319761f922391b260b111de" +checksum = "f825c3cd1de8c814cff65bbe8f1019735edd6781b5a0dcbba4f27bb403e89de8" dependencies = [ "async-trait", "deno_core", @@ -2288,9 +2353,9 @@ dependencies = [ [[package]] name = "deno_terminal" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23f71c27009e0141dedd315f1dfa3ebb0a6ca4acce7c080fac576ea415a465f6" +checksum = "f3ba8041ae7319b3ca6a64c399df4112badcbbe0868b4517637647614bede4be" dependencies = [ "once_cell", "termcolor", @@ -2298,9 +2363,9 @@ dependencies = [ [[package]] name = "deno_tls" -version = "0.200.0" +version = "0.213.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30245c362adc1e6b74b28c0a4687950c2f0f8729fc62e05f11db29f31d2dd37b" +checksum = "a96a4a3cff3c0bbd77342fd5093732a64840fdd7e76868723fea80751bbcc0e1" dependencies = [ "deno_core", "deno_error", @@ -2312,7 +2377,7 @@ dependencies = [ "serde", "thiserror 2.0.14", "tokio", - "webpki-roots", + "webpki-roots 0.26.3", ] [[package]] @@ -2343,26 +2408,22 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.213.0" +version = "0.222.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ebe63615f18221afbdcf0dd97f128af21529c6a4d012a7b9b4a0223c91359b2" -dependencies = [ - "deno_core", - "deno_error", - "urlpattern", -] +checksum = "54c190c36940b8ba25043e2258775df3cd4af06f28c8a9efd28b50799efe2977" [[package]] name = "deno_web" -version = "0.244.0" +version = "0.257.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55a863aae15f3dbccb11b3776e9dea399f510a9b1d4dac22a4dcfff96bcff9d7" +checksum = "cc732e3f665b5117f92b645c2a959bac3dd1dfa5d3f74f4de11dbe90c4c23b20" dependencies = [ "async-trait", "base64-simd", "bytes", "deno_core", "deno_error", + "deno_features", "deno_permissions", "encoding_rs", "flate2", @@ -2370,14 +2431,15 @@ dependencies = [ "serde", "thiserror 2.0.14", "tokio", + "urlpattern", "uuid", ] [[package]] name = "deno_webgpu" -version = "0.180.0" +version = "0.193.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "becd03f8f02cda17d3a94e6acdf4e64224564ccc77b03159d9e0b83c8828c615" +checksum = "bb8b2c887355112abfa14e1596240836f3ece16897d63010a9e9bb3cc3959332" dependencies = [ "deno_core", "deno_error", @@ -2394,22 +2456,23 @@ dependencies = [ [[package]] name = "deno_webidl" -version = "0.213.0" +version = "0.226.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68682e535768112593274795b70f4dee5d31d6d973f4be14d660c0a8954e0abb" +checksum = "a16ef8ede69eb140bd5577a89f1c2d7e068dd3a7de29ea7b46f9e0e087cbec1c" dependencies = [ "deno_core", ] [[package]] name = "deno_websocket" -version = "0.218.0" +version = "0.231.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62497c70af5f4e4ea4027f88a80cb295294bc9a032988bb092085aef07b3208" +checksum = "8ed1fd12275bd76c460175362575269b90e6ee17df5ac3bd353b6899ba77d4e7" dependencies = [ "bytes", "deno_core", "deno_error", + "deno_fetch", "deno_net", "deno_permissions", "deno_tls", @@ -2428,9 +2491,9 @@ dependencies = [ [[package]] name = "deno_webstorage" -version = "0.208.0" +version = "0.221.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "517bc591568d2382b2288bfb581cd6630070ec800ba98d55ca299fff193861a4" +checksum = "d89134c225a3b3ee48e0300813b56f747eeb0edef044d93c3b07124fbc14c30e" dependencies = [ "deno_core", "deno_error", @@ -2450,9 +2513,9 @@ dependencies = [ [[package]] name = "denokv_proto" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cfd5bdec33d2e5c4188ea2a7b348eca13958afa4c76a11504d9aa0efca589" +checksum = "3c9f1d5365706efe37950bfa83e09fbf6efe5f42306570f05dab72cd2bf3c420" dependencies = [ "async-trait", "chrono", @@ -2466,9 +2529,9 @@ dependencies = [ [[package]] name = "denokv_remote" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91a6b359d69cb44e4390f2bcd007f72c252c6b9f6f88c7eab8f9bb55806fbc1a" +checksum = "47161e738042861f890ac51c0bf42b73c9372f483ffa6ec7e4d26d8a68e136d0" dependencies = [ "async-stream", "async-trait", @@ -2492,9 +2555,9 @@ dependencies = [ [[package]] name = "denokv_sqlite" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f119506add29e620d1a6d37903d727a6abab0feb0f2e898554b0a10d1113ab32" +checksum = "04812f283a0bcc7e8f08f2d6be989b3710af83324b1b9b5704881b779cfbfb02" dependencies = [ "async-stream", "async-trait", @@ -2517,9 +2580,9 @@ dependencies = [ [[package]] name = "denort_helper" -version = "0.11.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8f00b1155cd5a060c3fe59006bf5251f763a31e51ce55f9924c0160a58d4" +checksum = "8a0526b641bde8e09fb9bcd0d3fb79e5d42181ceafbe368ebe12ef6806959b5f" dependencies = [ "deno_error", "deno_path_util", @@ -2611,6 +2674,38 @@ dependencies = [ "subtle", ] +[[package]] +name = "diplomat" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9adb46b05e2f53dcf6a7dfc242e4ce9eb60c369b6b6eb10826a01e93167f59c6" +dependencies = [ + "diplomat_core", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "diplomat-runtime" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0569bd3caaf13829da7ee4e83dbf9197a0e1ecd72772da6d08f0b4c9285c8d29" + +[[package]] +name = "diplomat_core" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51731530ed7f2d4495019abc7df3744f53338e69e2863a6a64ae91821c763df1" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "smallvec", + "strck", + "syn 2.0.87", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -2668,15 +2763,16 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dprint-swc-ext" -version = "0.24.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a09827d6db1a3af25e105553d674ee9019be58fa3d6745c2a2803f8ce8e3eb8" +checksum = "33175ddb7a6d418589cab2966bd14a710b3b1139459d3d5ca9edf783c4833f4c" dependencies = [ "num-bigint", "rustc-hash 2.1.1", "swc_atoms", "swc_common", "swc_ecma_ast", + "swc_ecma_lexer", "swc_ecma_parser", "text_lines", ] @@ -2906,9 +3002,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fastwebsockets" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26da0c7b5cef45c521a6f9cdfffdfeb6c9f5804fbac332deb5ae254634c7a6be" +checksum = "9dac026e15fb7e44d768880b868a0fd5bd30ffdee272e88b3060f657a5a72947" dependencies = [ "base64 0.21.7", "bytes", @@ -3009,6 +3105,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -3038,27 +3140,26 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fqdn" -version = "0.3.11" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08b1eaa7dfddeab6036292995620bf0435712e619db6d7690605897e76975eb0" +checksum = "fe2713644726a30a74150dc8d10e910a8e14e431e1a4f98988309da8c80ddf7a" [[package]] name = "from_variant" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7ccf961415e7aa17ef93dcb6c2441faaa8e768abe09e659b908089546f74c5" +checksum = "e5ff35a391aef949120a0340d690269b3d9f63460a6106e99bd07b961f345ea9" dependencies = [ - "proc-macro2", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] @@ -3203,7 +3304,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows", + "windows 0.58.0", ] [[package]] @@ -3322,46 +3423,29 @@ dependencies = [ "gl_generator", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.9.0", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.9.0", -] - [[package]] name = "gpu-allocator" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ + "ash", + "hashbrown 0.16.1", "log", "presser", - "thiserror 1.0.66", - "windows", + "thiserror 2.0.14", + "windows 0.62.2", ] [[package]] name = "gpu-descriptor" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ "bitflags 2.9.0", "gpu-descriptor-types", - "hashbrown 0.14.5", + "hashbrown 0.15.1", ] [[package]] @@ -3433,12 +3517,15 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "num-traits", + "serde", + "zerocopy 0.8.27", ] [[package]] @@ -3482,11 +3569,24 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] -name = "hashlink" +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", + "serde", + "serde_core", +] + +[[package]] +name = "hashlink" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" @@ -3550,11 +3650,10 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hickory-proto" -version = "0.25.0-alpha.5" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d00147af6310f4392a31680db52a3ed45a2e0f68eb18e8c3fe5537ecc96d9e2" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" dependencies = [ - "async-recursion", "async-trait", "cfg-if", "data-encoding", @@ -3566,6 +3665,7 @@ dependencies = [ "ipnet", "once_cell", "rand 0.9.0", + "ring", "serde", "thiserror 2.0.14", "tinyvec", @@ -3576,9 +3676,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.25.0-alpha.5" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5762f69ebdbd4ddb2e975cd24690bf21fe6b2604039189c26acddbc427f12887" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" dependencies = [ "cfg-if", "futures-util", @@ -3647,15 +3747,15 @@ dependencies = [ [[package]] name = "hstr" -version = "1.0.0" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71399f53a92ef72ee336a4b30201c6e944827e14e0af23204c291aad9c24cc85" +checksum = "0c43c0a9e8fbdb3bb9dc8eee85e1e2ac81605418b4c83b6b7413cbf14d56ca5c" dependencies = [ "hashbrown 0.14.5", "new_debug_unreachable", "once_cell", - "phf", "rustc-hash 2.1.1", + "serde", "triomphe", ] @@ -3787,7 +3887,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 0.26.3", ] [[package]] @@ -3805,23 +3905,50 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.1.0", "http-body 1.0.1", "hyper 1.6.0", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.6.0", "tokio", "tower-service", "tracing", ] +[[package]] +name = "icu_calendar" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f0e52e009b6b16ba9c0693578796f2dd4aaa59a7f8f920423706714a89ac4e" +dependencies = [ + "calendrical_calculations", + "displaydoc", + "icu_calendar_data", + "icu_locale", + "icu_locale_core", + "icu_provider 2.1.1", + "tinystr 0.8.2", + "zerovec 0.11.5", +] + +[[package]] +name = "icu_calendar_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527f04223b17edfe0bd43baf14a0cb1b017830db65f3950dc00224860a9a446d" + [[package]] name = "icu_collections" version = "1.5.0" @@ -3829,11 +3956,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", - "yoke", + "yoke 0.7.4", + "zerofrom", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke 0.8.1", "zerofrom", - "zerovec", + "zerovec 0.11.5", +] + +[[package]] +name = "icu_locale" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532b11722e350ab6bf916ba6eb0efe3ee54b932666afec989465f9243fe6dd60" +dependencies = [ + "icu_collections 2.1.1", + "icu_locale_core", + "icu_locale_data", + "icu_provider 2.1.1", + "potential_utf", + "tinystr 0.8.2", + "zerovec 0.11.5", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap 0.8.1", + "serde", + "tinystr 0.8.2", + "writeable 0.6.2", + "zerovec 0.11.5", ] +[[package]] +name = "icu_locale_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03e2fcaefecdf05619f3d6f91740e79ab969b4dd54f77cbf546b1d0d28e3147" + [[package]] name = "icu_locid" version = "1.5.0" @@ -3841,10 +4016,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "litemap 0.7.3", + "tinystr 0.7.6", + "writeable 0.5.5", + "zerovec 0.10.4", ] [[package]] @@ -3856,9 +4031,9 @@ dependencies = [ "displaydoc", "icu_locid", "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", + "icu_provider 1.5.0", + "tinystr 0.7.6", + "zerovec 0.10.4", ] [[package]] @@ -3874,15 +4049,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", - "icu_collections", + "icu_collections 1.5.0", "icu_normalizer_data", - "icu_properties", - "icu_provider", + "icu_properties 1.5.1", + "icu_provider 1.5.0", "smallvec", "utf16_iter", "utf8_iter", "write16", - "zerovec", + "zerovec 0.10.4", ] [[package]] @@ -3898,12 +4073,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", - "icu_collections", + "icu_collections 1.5.0", "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", + "icu_properties_data 1.5.0", + "icu_provider 1.5.0", + "tinystr 0.7.6", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections 2.1.1", + "icu_locale_core", + "icu_properties_data 2.1.2", + "icu_provider 2.1.1", + "zerotrie", + "zerovec 0.11.5", ] [[package]] @@ -3912,6 +4101,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + [[package]] name = "icu_provider" version = "1.5.0" @@ -3922,11 +4117,28 @@ dependencies = [ "icu_locid", "icu_provider_macros", "stable_deref_trait", - "tinystr", - "writeable", - "yoke", + "tinystr 0.7.6", + "writeable 0.5.5", + "yoke 0.7.4", + "zerofrom", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "serde", + "stable_deref_trait", + "writeable 0.6.2", + "yoke 0.8.1", "zerofrom", - "zerovec", + "zerotrie", + "zerovec 0.11.5", ] [[package]] @@ -3942,9 +4154,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -3958,7 +4170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", - "icu_properties", + "icu_properties 1.5.1", ] [[package]] @@ -3999,9 +4211,9 @@ dependencies = [ [[package]] name = "import_map" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce93e07f4819f0db4d2948fffce3ef4760a9940c4ff4f9369dfaf5e357a0d415" +checksum = "f83a4958a41489355816028239fee373797435384d162f4908e7980c83c3bb1b" dependencies = [ "boxed_error", "deno_error", @@ -4103,6 +4315,16 @@ dependencies = [ "serde", ] +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-macro" version = "0.3.5" @@ -4159,6 +4381,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "ixdtf" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84de9d95a6d2547d9b77ee3f25fa0ee32e3c3a6484d47a55adebc0439c077992" + [[package]] name = "jni-sys" version = "0.3.0" @@ -4186,9 +4414,9 @@ dependencies = [ [[package]] name = "jsonc-parser" -version = "0.26.3" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6d80e6d70e7911a29f3cf3f44f452df85d06f73572b494ca99a2cad3fcf8f4" +checksum = "01958dcb05b69d9612853b47df8f7881810e4f61b5cedd8894be04291f28ccb9" dependencies = [ "serde_json", ] @@ -4332,9 +4560,9 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libffi" -version = "4.0.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074" +checksum = "b0feebbe0ccd382a2790f78d380540500d7b78ed7a3498b68fcfbc1593749a94" dependencies = [ "libc", "libffi-sys", @@ -4342,9 +4570,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "3.2.0" +version = "3.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84" +checksum = "90c6c6e17136d4bc439d43a2f3c6ccf0731cccc016d897473a29791d3c2160c3" dependencies = [ "cc", ] @@ -4377,11 +4605,11 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libsqlite3-sys" -version = "0.32.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7" +checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" dependencies = [ - "bindgen 0.71.1", + "bindgen 0.72.1", "cc", "pkg-config", "vcpkg", @@ -4410,6 +4638,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "litrs" version = "0.4.1" @@ -4428,9 +4662,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "loom" @@ -4451,6 +4685,22 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "macro_rules_attribute" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" + [[package]] name = "malloc_buf" version = "0.0.6" @@ -4535,9 +4785,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ "bitflags 2.9.0", "block", @@ -4630,32 +4880,36 @@ checksum = "b52c1b33ff98142aecea13138bd399b68aa7ab5d9546c300988c345004001eea" [[package]] name = "naga" -version = "24.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" +checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" dependencies = [ "arrayvec", "bit-set", "bitflags 2.9.0", + "cfg-if", "cfg_aliases", "codespan-reporting", + "half", + "hashbrown 0.16.1", "hexf-parse", "indexmap 2.9.0", + "libm", "log", + "num-traits", + "once_cell", "rustc-hash 1.1.0", "serde", "spirv", - "strum 0.26.3", - "termcolor", "thiserror 2.0.14", - "unicode-xid", + "unicode-ident", ] [[package]] name = "napi_sym" -version = "0.143.0" +version = "0.156.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cda32f648f67ca18ff3612a03e89adcf25ecdbc7db0e765831f64fbc8d164d9" +checksum = "a912b4949264d90faa47e3bd7ebf91743530daf61c811dafa11497bf8fc001fe" dependencies = [ "quote", "serde", @@ -4665,9 +4919,9 @@ dependencies = [ [[package]] name = "ndk-sys" -version = "0.5.0+25.2.9519653" +version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys", ] @@ -4706,6 +4960,7 @@ dependencies = [ "bitflags 2.9.0", "cfg-if", "libc", + "memoffset", ] [[package]] @@ -4723,9 +4978,9 @@ dependencies = [ [[package]] name = "node_resolver" -version = "0.51.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ea72d52f389d704af50e11c7988f06aa41625595569450354b84e2a93ef0a" +checksum = "6e801b86d09845a0e35dc4f148ec435746bab0632a7f48384883244094733548" dependencies = [ "anyhow", "async-trait", @@ -4733,12 +4988,14 @@ dependencies = [ "capacity_builder", "dashmap", "deno_error", - "deno_media_type", + "deno_maybe_sync", + "deno_media_type 0.3.0", "deno_package_json", "deno_path_util", "deno_semver", "futures", "lazy-regex", + "log", "once_cell", "path-clean", "pretty_assertions", @@ -4822,11 +5079,10 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", @@ -4916,6 +5172,10 @@ name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "oorandom" @@ -5116,23 +5376,13 @@ dependencies = [ [[package]] name = "par-core" -version = "1.0.4" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757892557993c69e82f9de0f9051e87144278aa342f03bf53617bbf044554484" +checksum = "e96cbd21255b7fb29a5d51ef38a779b517a91abd59e2756c039583f43ef4c90f" dependencies = [ "once_cell", ] -[[package]] -name = "par-iter" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a5b20f31e9ba82bfcbbb54a67aa40be6cebec9f668ba5753be138f9523c531a" -dependencies = [ - "either", - "par-core", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -5206,9 +5456,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" @@ -5387,6 +5637,17 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "serde_core", + "writeable 0.6.2", + "zerovec 0.11.5", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -5434,29 +5695,6 @@ dependencies = [ "elliptic-curve", ] -[[package]] -name = "proc-macro-rules" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c277e4e643ef00c1233393c673f655e3672cf7eb3ba08a00bdd0ea59139b5f" -dependencies = [ - "proc-macro-rules-macros", - "proc-macro2", - "syn 2.0.87", -] - -[[package]] -name = "proc-macro-rules-macros" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207fffb0fe655d1d47f6af98cc2793405e85929bdbc420d685554ff07be27ac7" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "proc-macro2" version = "1.0.92" @@ -5504,26 +5742,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ptr_meta" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "pulldown-cmark" version = "0.9.6" @@ -5641,7 +5859,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.23", + "zerocopy 0.8.27", ] [[package]] @@ -5696,9 +5914,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -5706,9 +5924,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -5812,9 +6030,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", @@ -5827,16 +6045,12 @@ dependencies = [ "hyper 1.6.0", "hyper-rustls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", - "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", @@ -5844,13 +6058,24 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", + "tower 0.5.2", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", - "windows-registry", + "webpki-roots 1.0.5", +] + +[[package]] +name = "resb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a067ab3b5ca3b4dc307d0de9cf75f9f5e6ca9717b192b2f28a36c83e5de9e76" +dependencies = [ + "potential_utf", + "serde_core", ] [[package]] @@ -5898,14 +6123,16 @@ dependencies = [ [[package]] name = "ron" -version = "0.8.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" dependencies = [ - "base64 0.21.7", "bitflags 2.9.0", + "once_cell", "serde", "serde_derive", + "typeid", + "unicode-ident", ] [[package]] @@ -5930,9 +6157,9 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.34.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" +checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ "bitflags 2.9.0", "fallible-iterator", @@ -6123,6 +6350,7 @@ dependencies = [ "criterion", "deno_ast", "deno_broadcast_channel", + "deno_bundle_runtime", "deno_cache", "deno_console", "deno_core", @@ -6136,7 +6364,7 @@ dependencies = [ "deno_http", "deno_io", "deno_kv", - "deno_media_type", + "deno_media_type 0.2.9", "deno_napi", "deno_net", "deno_node", @@ -6172,6 +6400,7 @@ dependencies = [ "thiserror 2.0.14", "tokio", "tokio-util", + "uuid", "version-sync", "winapi", ] @@ -6280,7 +6509,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.9.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "security-framework-sys", @@ -6317,12 +6546,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "seq-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" + [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -6345,11 +6581,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -6391,9 +6636,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.264.0" +version = "0.285.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34707712f3815e73e1c8319bba06e5bc105bb65fe812ea2e7279ffb905f6312" +checksum = "f26d546283b1182f61e75b598da17f3babde4b25e479a5cb3fbb39d26cb928fd" dependencies = [ "deno_error", "num-bigint", @@ -6560,6 +6805,9 @@ name = "smallvec" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +dependencies = [ + "serde", +] [[package]] name = "smartstring" @@ -6667,14 +6915,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "string_enum" +name = "strck" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9fe66b8ee349846ce2f9557a26b8f1e74843c4a13fb381f9a3d73617a5f956a" +checksum = "42316e70da376f3d113a68d138a60d8a9883c604fe97942721ec2068dab13a9f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "string_enum" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae36a4951ca7bd1cfd991c241584a9824a70f6aff1e7d4f693fb3f2465e4030e" dependencies = [ - "proc-macro2", "quote", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] @@ -6684,35 +6940,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72abeda133c49d7bddece6c154728f83eec8172380c80ab7096da9487e20d27c" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - [[package]] name = "strum" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ - "strum_macros 0.27.1", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.87", + "strum_macros", ] [[package]] @@ -6736,40 +6970,37 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "swc_allocator" -version = "4.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b926f0d94bbb34031fe5449428cfa1268cdc0b31158d6ad9c97e0fc1e79dd" +checksum = "9d7eefd2c8b228a8c73056482b2ae4b3a1071fbe07638e3b55ceca8570cc48bb" dependencies = [ "allocator-api2", "bumpalo", "hashbrown 0.14.5", - "ptr_meta", "rustc-hash 2.1.1", - "triomphe", ] [[package]] name = "swc_atoms" -version = "5.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d7077ba879f95406459bc0c81f3141c529b34580bc64d7ab7bd15e7118a0391" +checksum = "d4ccbe2ecad10ad7432100f878a107b1d972a8aee83ca53184d00c23a078bb8a" dependencies = [ "hstr", "once_cell", - "rustc-hash 2.1.1", "serde", ] [[package]] name = "swc_common" -version = "9.2.0" +version = "17.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56b6f5a8e5affa271b56757a93badee6f44defcd28f3ba106bb2603afe40d3d" +checksum = "259b675d633a26d24efe3802a9d88858c918e6e8f062d3222d3aa02d56a2cf4c" dependencies = [ "anyhow", "ast_node", "better_scoped_tls", - "cfg-if", + "bytes-str", "either", "from_variant", "new_debug_unreachable", @@ -6778,23 +7009,23 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "siphasher 0.3.11", - "sourcemap", - "swc_allocator", "swc_atoms", "swc_eq_ignore_macros", + "swc_sourcemap", "swc_visit", "tracing", - "unicode-width 0.1.13", + "unicode-width 0.2.2", "url", ] [[package]] name = "swc_config" -version = "3.0.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01bfcbbdea182bdda93713aeecd997749ae324686bf7944f54d128e56be4ea9" +checksum = "72e90b52ee734ded867104612218101722ad87ff4cf74fe30383bd244a533f97" dependencies = [ "anyhow", + "bytes-str", "indexmap 2.9.0", "serde", "serde_json", @@ -6803,21 +7034,21 @@ dependencies = [ [[package]] name = "swc_config_macro" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2ebd37ef52a8555c8c9be78b694d64adcb5e3bc16c928f030d82f1d65fac57" +checksum = "7b416e8ce6de17dc5ea496e10c7012b35bbc0e3fef38d2e065eed936490db0b3" dependencies = [ "proc-macro2", "quote", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] [[package]] name = "swc_ecma_ast" -version = "9.0.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0613d84468a6bb6d45d13c5a3368b37bd21f3067a089f69adac630dcb462a018" +checksum = "a573a0c72850dec8d4d8085f152d5778af35a2520c3093b242d2d1d50776da7c" dependencies = [ "bitflags 2.9.0", "is-macro", @@ -6825,7 +7056,6 @@ dependencies = [ "once_cell", "phf", "rustc-hash 2.1.1", - "scoped-tls", "serde", "string_enum", "swc_atoms", @@ -6836,9 +7066,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "11.0.0" +version = "20.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01b3de365a86b8f982cc162f257c82f84bda31d61084174a3be37e8ab15c0f4" +checksum = "ff2a6ee1ec49dda8dedeac54e4147b4e8b3f278d9bb34ab28983257a393d34ed" dependencies = [ "ascii", "compact_str", @@ -6847,42 +7077,39 @@ dependencies = [ "once_cell", "regex", "rustc-hash 2.1.1", + "ryu-js", "serde", - "sourcemap", "swc_allocator", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_codegen_macros", + "swc_sourcemap", "tracing", ] [[package]] name = "swc_ecma_codegen_macros" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e99e1931669a67c83e2c2b4375674f6901d1480994a76aa75b23f1389e6c5076" +checksum = "e276dc62c0a2625a560397827989c82a93fd545fcf6f7faec0935a82cc4ddbb8" dependencies = [ "proc-macro2", - "quote", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] [[package]] name = "swc_ecma_lexer" -version = "12.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d11c8e71901401b9aae2ece4946eeb7674b14b8301a53768afbbeeb0e48b599" +checksum = "5e82f7747e052c6ff6e111fa4adeb14e33b46ee6e94fe5ef717601f651db48fc" dependencies = [ - "arrayvec", "bitflags 2.9.0", "either", - "new_debug_unreachable", "num-bigint", - "num-traits", - "phf", "rustc-hash 2.1.1", + "seq-macro", "serde", "smallvec", "smartstring", @@ -6890,15 +7117,15 @@ dependencies = [ "swc_atoms", "swc_common", "swc_ecma_ast", + "swc_ecma_parser", "tracing", - "typed-arena", ] [[package]] name = "swc_ecma_loader" -version = "9.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb574d660c05f3483c984107452b386e45b95531bdb1253794077edc986f413" +checksum = "fbcababb48f0d46587a0a854b2c577eb3a56fa99687de558338021e93cd2c8f5" dependencies = [ "anyhow", "pathdiff", @@ -6911,45 +7138,38 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "12.0.0" +version = "27.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250786944fbc05f6484eda9213df129ccfe17226ae9ad51b62fce2f72135dbee" +checksum = "7f1a51af1a92cd4904c073b293e491bbc0918400a45d58227b34c961dd6f52d7" dependencies = [ - "arrayvec", "bitflags 2.9.0", "either", - "new_debug_unreachable", "num-bigint", - "num-traits", "phf", "rustc-hash 2.1.1", + "seq-macro", "serde", - "smallvec", "smartstring", "stacker", "swc_atoms", "swc_common", "swc_ecma_ast", - "swc_ecma_lexer", "tracing", - "typed-arena", ] [[package]] name = "swc_ecma_transforms_base" -version = "13.0.0" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6856da3da598f4da001b7e4ce225ee8970bc9d5cbaafcaf580190cf0a6031ec5" +checksum = "250f6f165578ca4fee47bd57585c1b9597c94bf4ea6591df47f2b5fa5b1883fe" dependencies = [ "better_scoped_tls", - "bitflags 2.9.0", "indexmap 2.9.0", "once_cell", "par-core", "phf", "rustc-hash 2.1.1", "serde", - "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -6961,11 +7181,10 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "13.0.0" +version = "30.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f84248f82bad599d250bbcd52cb4db6ff6409f48267fd6f001302a2e9716f80" +checksum = "3d3ab35eff4a980e02d708798ae4c35bc017612292adbffe7b7b554df772fdf5" dependencies = [ - "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_transforms_base", @@ -6975,71 +7194,66 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_macros" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6845dfb88569f3e8cd05901505916a8ebe98be3922f94769ca49f84e8ccec8f7" +checksum = "bc777288799bf6786e5200325a56e4fbabba590264a4a48a0c70b16ad0cf5cd8" dependencies = [ "proc-macro2", "quote", - "swc_macros_common 1.0.0", + "swc_macros_common", "syn 2.0.87", ] [[package]] name = "swc_ecma_transforms_proposal" -version = "13.0.0" +version = "30.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193237e318421ef621c2b3958b4db174770c5280ef999f1878f2df93a2837ca6" +checksum = "c2d7748d4112c87ce1885260035e4a43cebfe7661a40174b7d77a0a04760a257" dependencies = [ "either", "rustc-hash 2.1.1", "serde", - "smallvec", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_transforms_base", "swc_ecma_transforms_classes", - "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", ] [[package]] name = "swc_ecma_transforms_react" -version = "15.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baae39c70229103a72090119887922fc5e32f934f5ca45c0423a5e65dac7e549" +checksum = "03de12e38e47ac1c96ac576f793ad37a9d7b16fbf4f2203881f89152f2498682" dependencies = [ "base64 0.22.1", - "dashmap", + "bytes-str", "indexmap 2.9.0", "once_cell", "rustc-hash 2.1.1", "serde", "sha1", "string_enum", - "swc_allocator", "swc_atoms", "swc_common", "swc_config", "swc_ecma_ast", "swc_ecma_parser", "swc_ecma_transforms_base", - "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", ] [[package]] name = "swc_ecma_transforms_typescript" -version = "15.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3c65e0b49f7e2a2bd92f1d89c9a404de27232ce00f6a4053f04bda446d50e5c" +checksum = "4408800fdeb541fabf3659db622189a0aeb386f57b6103f9294ff19dfde4f7b0" dependencies = [ - "once_cell", + "bytes-str", "rustc-hash 2.1.1", - "ryu-js", "serde", "swc_atoms", "swc_common", @@ -7052,15 +7266,14 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "13.1.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ed837406d5dbbfbf5792b1dc90964245a0cf659753d4745fe177ffebe8598b9" +checksum = "0fb99e179988cabd473779a4452ab942bcb777176983ca3cbaf22a8f056a65b0" dependencies = [ "indexmap 2.9.0", "num_cpus", "once_cell", "par-core", - "par-iter", "rustc-hash 2.1.1", "ryu-js", "swc_atoms", @@ -7068,14 +7281,13 @@ dependencies = [ "swc_ecma_ast", "swc_ecma_visit", "tracing", - "unicode-id", ] [[package]] name = "swc_ecma_visit" -version = "9.0.0" +version = "18.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249dc9eede1a4ad59a038f9cfd61ce67845bd2c1392ade3586d714e7181f3c1a" +checksum = "a9611a72a4008d62608547a394e5d72a5245413104db096d95a52368a8cc1d63" dependencies = [ "new_debug_unreachable", "num-bigint", @@ -7088,9 +7300,9 @@ dependencies = [ [[package]] name = "swc_eq_ignore_macros" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96e15288bf385ab85eb83cff7f9e2d834348da58d0a31b33bdb572e66ee413e" +checksum = "c16ce73424a6316e95e09065ba6a207eba7765496fed113702278b7711d4b632" dependencies = [ "proc-macro2", "quote", @@ -7099,9 +7311,9 @@ dependencies = [ [[package]] name = "swc_macros_common" -version = "0.3.13" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847" +checksum = "aae1efbaa74943dc5ad2a2fb16cbd78b77d7e4d63188f3c5b4df2b4dcd2faaae" dependencies = [ "proc-macro2", "quote", @@ -7109,44 +7321,50 @@ dependencies = [ ] [[package]] -name = "swc_macros_common" -version = "1.0.0" +name = "swc_sourcemap" +version = "9.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a509f56fca05b39ba6c15f3e58636c3924c78347d63853632ed2ffcb6f5a0ac7" +checksum = "de08ef00f816acdd1a58ee8a81c0e1a59eefef2093aefe5611f256fa6b64c4d7" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", + "base64-simd", + "bitvec", + "bytes-str", + "data-encoding", + "debugid", + "if_chain", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "unicode-id-start", + "url", ] [[package]] name = "swc_visit" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9138b6a36bbe76dd6753c4c0794f7e26480ea757bee499738bedbbb3ae3ec5f3" +checksum = "62fb71484b486c185e34d2172f0eabe7f4722742aad700f426a494bb2de232a2" dependencies = [ "either", "new_debug_unreachable", ] [[package]] -name = "swc_visit_macros" -version = "0.5.13" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "Inflector", "proc-macro2", "quote", - "swc_macros_common 0.3.13", - "syn 2.0.87", + "unicode-ident", ] [[package]] name = "syn" -version = "1.0.109" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -7154,14 +7372,14 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.87" +name = "syn-match" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "783c4140d7ed89f37116e865b49e5a9fdd28608b9071a9dd1e158b50fc0a31fc" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn 2.0.87", ] [[package]] @@ -7251,6 +7469,39 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "temporal_capi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a151e402c2bdb6a3a2a2f3f225eddaead2e7ce7dd5d3fa2090deb11b17aa4ed8" +dependencies = [ + "diplomat", + "diplomat-runtime", + "icu_calendar", + "icu_locale", + "num-traits", + "temporal_rs", + "timezone_provider", + "writeable 0.6.2", + "zoneinfo64", +] + +[[package]] +name = "temporal_rs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88afde3bd75d2fc68d77a914bece426aa08aa7649ffd0cdd4a11c3d4d33474d1" +dependencies = [ + "core_maths", + "icu_calendar", + "icu_locale", + "ixdtf", + "num-traits", + "timezone_provider", + "tinystr 0.8.2", + "writeable 0.6.2", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -7350,6 +7601,18 @@ dependencies = [ "time-core", ] +[[package]] +name = "timezone_provider" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9ba0000e9e73862f3e7ca1ff159e2ddf915c9d8bb11e38a7874760f445d993" +dependencies = [ + "tinystr 0.8.2", + "zerotrie", + "zerovec 0.11.5", + "zoneinfo64", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -7357,7 +7620,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", - "zerovec", + "zerovec 0.10.4", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "serde_core", + "zerovec 0.11.5", ] [[package]] @@ -7474,16 +7748,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", "futures-util", - "hashbrown 0.14.5", + "hashbrown 0.15.1", "pin-project-lite", "slab", "tokio", @@ -7603,20 +7877,23 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.1" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", "bitflags 2.9.0", "bytes", "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.1", "http-body-util", + "iri-string", "pin-project-lite", "tokio", "tokio-util", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -7635,9 +7912,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -7647,9 +7924,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -7658,9 +7935,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -7718,10 +7995,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7b17f197b3050ba473acf9181f7b1d3b66d1cf7356c6cc57886662276e65908" [[package]] -name = "typed-arena" -version = "2.0.2" +name = "typeid" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" @@ -7729,47 +8006,6 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" version = "2.7.0" @@ -7779,12 +8015,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-id" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" - [[package]] name = "unicode-id-start" version = "1.2.0" @@ -7811,9 +8041,9 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -7845,25 +8075,26 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] name = "urlpattern" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +checksum = "0f805818f843b548bacc19609eb3619dd2850e54746f5cada37927393c2ef4ec" dependencies = [ + "icu_properties 2.1.2", "regex", "serde", - "unic-ucd-ident", "url", ] @@ -7903,17 +8134,18 @@ dependencies = [ [[package]] name = "v8" -version = "137.3.0" +version = "142.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33995a1fee055ff743281cde33a41f0d618ee0bdbe8bdf6859e11864499c2595" +checksum = "f566072bd76b2631d0dca1d90a766c943863b1fd6b01312281dc919816de976d" dependencies = [ - "bindgen 0.71.1", + "bindgen 0.72.1", "bitflags 2.9.0", "fslock", "gzip-header", "home", "miniz_oxide 0.8.8", "paste", + "temporal_capi", "which 6.0.1", ] @@ -8135,9 +8367,9 @@ dependencies = [ [[package]] name = "web-transport-proto" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c564e589056437e3a73383f4e0903965879087c9ee0f715e562bbf4e47c08b75" +checksum = "974fa1e325e6cc5327de8887f189a441fcff4f8eedcd31ec87f0ef0cc5283fbc" dependencies = [ "bytes", "http 1.1.0", @@ -8163,19 +8395,32 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "wgpu-core" -version = "24.0.2" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c25545d479b47d3f0a8e373aceb2060b67c6eb841b24ac8c32348151c7a0c" +checksum = "8bb4c8b5db5f00e56f1f08869d870a0dff7c8bc7ebc01091fec140b0cf0211a9" dependencies = [ "arrayvec", + "bit-set", "bit-vec", "bitflags 2.9.0", + "bytemuck", "cfg_aliases", "document-features", + "hashbrown 0.16.1", "indexmap 2.9.0", "log", + "macro_rules_attribute", "naga", "once_cell", "parking_lot", @@ -8186,15 +8431,45 @@ dependencies = [ "serde", "smallvec", "thiserror 2.0.14", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-hal" -version = "24.0.2" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4317a17171dc20e6577bf606796794580accae0716a69edbc7388c86a3ec9f23" +checksum = "293080d77fdd14d6b08a67c5487dfddbf874534bb7921526db56a7b75d7e3bef" dependencies = [ "android_system_properties", "arrayvec", @@ -8203,13 +8478,14 @@ dependencies = [ "bitflags 2.9.0", "block", "bytemuck", + "cfg-if", "cfg_aliases", "core-graphics-types", "glow", "glutin_wgl_sys", - "gpu-alloc", "gpu-allocator", "gpu-descriptor", + "hashbrown 0.16.1", "js-sys", "khronos-egl", "libc", @@ -8225,23 +8501,23 @@ dependencies = [ "profiling", "range-alloc", "raw-window-handle", - "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.14", "wasm-bindgen", "web-sys", "wgpu-types", - "windows", - "windows-core", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] name = "wgpu-types" -version = "24.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" +checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" dependencies = [ "bitflags 2.9.0", + "bytemuck", "js-sys", "log", "serde", @@ -8342,23 +8618,68 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core 0.62.2", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + [[package]] name = "windows-core" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-strings", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.58.0" @@ -8370,6 +8691,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "windows-interface" version = "0.58.0" @@ -8382,14 +8714,30 @@ dependencies = [ ] [[package]] -name = "windows-registry" -version = "0.2.0" +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link", ] [[package]] @@ -8401,16 +8749,34 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-strings" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", + "windows-result 0.2.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -8469,6 +8835,15 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -8605,6 +8980,12 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "wtf8" version = "0.1.0" @@ -8669,7 +9050,18 @@ checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ "serde", "stable_deref_trait", - "yoke-derive", + "yoke-derive 0.7.4", + "zerofrom", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive 0.8.1", "zerofrom", ] @@ -8685,6 +9077,18 @@ dependencies = [ "synstructure 0.13.1", ] +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -8696,11 +9100,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "zerocopy-derive 0.8.23", + "zerocopy-derive 0.8.27", ] [[package]] @@ -8716,9 +9120,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -8766,15 +9170,38 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke 0.8.1", + "zerofrom", +] + [[package]] name = "zerovec" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ - "yoke", + "yoke 0.7.4", + "zerofrom", + "zerovec-derive 0.10.3", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "serde", + "yoke 0.8.1", "zerofrom", - "zerovec-derive", + "zerovec-derive 0.11.2", ] [[package]] @@ -8788,6 +9215,30 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "zoneinfo64" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2e5597efbe7c421da8a7fd396b20b571704e787c21a272eecf35dfe9d386f0" +dependencies = [ + "calendrical_calculations", + "icu_locale_core", + "potential_utf", + "resb", + "serde", +] + [[package]] name = "zune-core" version = "0.4.12" diff --git a/Cargo.toml b/Cargo.toml index 0aea2a8..ff1b7de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,7 @@ extra_features = ["worker", "snapshot_builder"] # (See [NodePermissions]) node_experimental = [ "deno_node", "deno_resolver", "node_resolver", "deno_npm", "deno_semver", "deno_napi", "deno_runtime", "deno_process", "deno_package_json", + "deno_bundle_runtime", "checksum", "sys_traits", "all_extensions" ] @@ -79,7 +80,7 @@ web_stub = ["webidl", "base64-simd"] # # [https://html.spec.whatwg.org/multipage/web-messaging.html] - broadcast_channel = ["deno_broadcast_channel", "web", "webidl"] + broadcast_channel = ["deno_broadcast_channel", "web", "webidl", "uuid"] # [https://w3c.github.io/ServiceWorker/#cache-interface] cache = ["deno_cache", "webidl", "web"] @@ -118,7 +119,7 @@ web_stub = ["webidl", "base64-simd"] web = [ "deno_web", "deno_tls", "deno_fetch", "deno_net", "dep:http", "deno_permissions", "deno_telemetry", "deno_fs", "webidl", "console", "url", "crypto", "url_import", "fs_import", - "hyper-util", "rustls" + "hyper-util", "rustls", "sys_traits" ] # [https://gpuweb.github.io/gpuweb/] @@ -168,12 +169,12 @@ async-trait = "^0.1.89" paste = "1.0.15" # The deno runtime itself, and the webidl extension for the web APIs -deno_core = "^0.355.0" -deno_error = "=0.7.0" -deno_features = "0.10.0" +deno_core = "^0.376.0" +deno_error = "=0.7.1" +deno_features = "^0.23.0" # For transpiling typescript -deno_ast = { version = "=0.49.0", features = ["transpiling", "cjs"] } +deno_ast = { version = "^0.52.0", features = ["transpiling", "cjs"] } deno_media_type = { version = "=0.2.9", features = ["module_specifier"] } # Runtime for async tasks @@ -185,40 +186,42 @@ hyper-util = {version = "^0.1.10", optional = true} rustls = {version = "0.23.28", optional = true} # For URL imports -# Pinned for now due to upstream issues -reqwest = { version = "=0.12.8", optional = true, default-features = false, features = ["blocking", "rustls-tls"] } +# Upgraded to support axum 0.8+ +reqwest = { version = "^0.12.20", optional = true, default-features = false, features = ["blocking", "rustls-tls"] } http = { version = "^1.0", optional = true } -deno_permissions = { version = "^0.72.0", optional = true } +deno_permissions = { version = "^0.85.0", optional = true } # # Dependencies for the various extension features # -deno_broadcast_channel = { version = "^0.207.0", optional = true } - -deno_cache = { version = "^0.145.0", optional = true } -deno_console = { version = "^0.213.0", optional = true } -deno_cron = { version = "^0.93.0", optional = true } -deno_crypto = { version = "^0.227.0", optional = true } -deno_fetch = { version = "^0.237.0", optional = true } -deno_ffi = { version = "^0.200.0", optional = true } -deno_fs = { version = "^0.123.0", optional = true, features = ["sync_fs"] } -deno_http = { version = "^0.211.0", optional = true } -deno_kv = { version = "^0.121.0", optional = true } -deno_net = { version = "^0.205.0", optional = true } -deno_node = { version = "^0.151.0", optional = true } -deno_tls = { version = "^0.200.0", optional = true } -deno_url = { version = "^0.213.0", optional = true } - -deno_web = { version = "^0.244.0", optional = true } -deno_webidl = { version = "^0.213.0", optional = true } -deno_webstorage = { version = "^0.208.0", optional = true } -deno_websocket = { version = "^0.218.0", optional = true } -deno_webgpu = { version = "^0.180.0", optional = true } - -deno_io = { version = "^0.123.0", optional = true } -deno_telemetry = { version = "^0.35.0", optional = true } +deno_broadcast_channel = { version = "^0.216.0", optional = true } +uuid = { version = "1.10.0", optional = true, features = ["v4"] } + +deno_bundle_runtime = { version = "^0.13.0", optional = true } +deno_cache = { version = "^0.159.0", optional = true } +deno_console = { version = "^0.222.0", optional = true } +deno_cron = { version = "^0.106.0", optional = true } +deno_crypto = { version = "^0.240.0", optional = true } +deno_fetch = { version = "^0.250.0", optional = true } +deno_ffi = { version = "^0.213.0", optional = true } +deno_fs = { version = "^0.136.0", optional = true, features = ["sync_fs"] } +deno_http = { version = "^0.224.0", optional = true } +deno_kv = { version = "^0.134.0", optional = true } +deno_net = { version = "^0.218.0", optional = true } +deno_node = { version = "^0.164.0", optional = true } +deno_tls = { version = "^0.213.0", optional = true } +deno_url = { version = "^0.222.0", optional = true } + +deno_web = { version = "^0.257.0", optional = true } +deno_webidl = { version = "^0.226.0", optional = true } +deno_webstorage = { version = "^0.221.0", optional = true } +deno_websocket = { version = "^0.231.0", optional = true } +deno_webgpu = { version = "^0.193.0", optional = true } + +deno_io = { version = "^0.136.0", optional = true } +deno_telemetry = { version = "^0.48.0", optional = true } # Dependencies for the IO feature rustyline = {version = "=13.0.0", optional = true} @@ -235,17 +238,17 @@ once_cell = {version = "^1.17.1", optional = true} base64-simd = {version = "0.8.0", optional = true} # Dependencies for the node feature -deno_resolver = { version = "^0.44.0", optional = true } -node_resolver = { version = "^0.51.0", optional = true, features = ["sync"] } -deno_runtime = { version = "^0.221.0", optional = true, features = ["exclude_runtime_main_js"] } -deno_terminal = { version = "=0.2.2", optional = true } -deno_semver = { version = "=0.9.0", optional = true } -deno_napi = { version = "^0.144.0", optional = true } -deno_npm = { version = "=0.36.0", optional = true } -deno_process = { version = "^0.28.0", optional = true } -deno_package_json = { version = "=0.15.0", optional = true } +deno_resolver = { version = "^0.57.0", optional = true } +node_resolver = { version = "^0.64.0", optional = true, features = ["sync"] } +deno_runtime = { version = "^0.234.0", optional = true, features = ["exclude_runtime_main_js"] } +deno_terminal = { version = "^0.2.3", optional = true } +deno_semver = { version = "^0.9.1", optional = true } +deno_napi = { version = "^0.157.0", optional = true } +deno_npm = { version = "^0.42.2", optional = true } +deno_process = { version = "^0.41.0", optional = true } +deno_package_json = { version = "^0.28.0", optional = true } checksum = { version = "0.2.1", optional = true } -sys_traits = { version = "=0.1.17", optional = true } +sys_traits = { version = "=0.1.17", optional = true, features = ["libc", "real", "winapi"] } [dev-dependencies] version-sync = "0.9.5" diff --git a/examples/custom_import_logic.rs b/examples/custom_import_logic.rs index 4757bd5..7623dab 100644 --- a/examples/custom_import_logic.rs +++ b/examples/custom_import_logic.rs @@ -78,7 +78,6 @@ impl ImportProvider for MyImportProvider { specifier: &ModuleSpecifier, _referrer: Option<&ModuleSpecifier>, _is_dyn_import: bool, - _requested_module_type: deno_core::RequestedModuleType, ) -> Option> { match specifier.scheme() { // @@ -102,8 +101,13 @@ impl ImportProvider for MyImportProvider { fn main() -> Result<(), rustyscript::Error> { let mut import_provider = MyImportProvider::default(); - import_provider.add_redirect("mod_assert", "https://deno.land/std@0.224.0/assert/mod.ts")?; - import_provider.add_static_module("my-module", "export const foo = 1"); + // Add a redirect for a simple utility module + import_provider.add_redirect("colors", "https://deno.land/std@0.224.0/fmt/colors.ts")?; + // Add a static module with some test data + import_provider.add_static_module( + "my-module", + "export const foo = 1; export const bar = 'test';", + ); let mut runtime = Runtime::new(RuntimeOptions { import_provider: Some(Box::new(import_provider)), @@ -113,10 +117,17 @@ fn main() -> Result<(), rustyscript::Error> { let module = Module::new( "custom_imports.js", " - import { assertEquals } from 'redirect:mod_assert'; - import { foo } from 'static:my-module'; - - assertEquals(1, foo) + import { bold } from 'redirect:colors'; + import { foo, bar } from 'static:my-module'; + + // Test static module imports + if (foo !== 1) throw new Error('Expected foo to be 1'); + if (bar !== 'test') throw new Error('Expected bar to be test'); + + // Test redirect module import + const text = bold('Hello from custom imports!'); + console.log(text); + console.log('✓ All custom import tests passed!'); ", ); diff --git a/examples/module_loader_cache.rs b/examples/module_loader_cache.rs index 9cb8e58..6e879d8 100644 --- a/examples/module_loader_cache.rs +++ b/examples/module_loader_cache.rs @@ -43,7 +43,6 @@ impl ImportProvider for MemoryCache { specifier: &ModuleSpecifier, _referrer: Option<&ModuleSpecifier>, _is_dyn_import: bool, - _requested_module_type: deno_core::RequestedModuleType, ) -> Option> { // Return the source code if the module is in the cache self.get(specifier).map(Ok) diff --git a/examples/test_borrow_mut_error.rs b/examples/test_borrow_mut_error.rs new file mode 100644 index 0000000..60ba2a0 --- /dev/null +++ b/examples/test_borrow_mut_error.rs @@ -0,0 +1,93 @@ +// This example tests for the BorrowMutError bug in deno_core 0.376.0 +// +// Issue: When executing JavaScript that throws a ReferenceError, +// deno_core panics with "already borrowed: BorrowMutError" +// instead of properly returning the error. +// +// Expected behavior: The error should be returned as Err(...) +// Actual behavior (in buggy versions): Process panics/aborts + +use rustyscript::{Module, Runtime, RuntimeOptions}; +use std::time::Duration; + +fn main() { + println!("=== Testing for deno_core BorrowMutError bug ===\n"); + + // Create a basic Runtime with minimal configuration + let options = RuntimeOptions { + timeout: Duration::from_secs(5), + ..Default::default() + }; + + let mut runtime = Runtime::new(options).expect("Failed to create runtime"); + + // Test 1: ReferenceError from accessing undefined variable + println!("Test 1: ReferenceError from accessing undefined variable"); + test_error_handling( + &mut runtime, + r#" + // This should throw a ReferenceError + undefinedVariable.toString(); + "#, + "test_undefined_variable.js", + ); + + // Test 2: TypeError from calling non-function + println!("\nTest 2: TypeError from calling non-function"); + test_error_handling( + &mut runtime, + r#" + // This should throw a TypeError + const notAFunction = "I am not a function"; + notAFunction(); + "#, + "test_type_error.js", + ); + + // Test 3: Syntax error + println!("\nTest 3: Syntax error"); + test_error_handling( + &mut runtime, + r#" + // This should throw a SyntaxError + const x = ; + "#, + "test_syntax_error.js", + ); + + // Test 4: Range error + println!("\nTest 4: Range error"); + test_error_handling( + &mut runtime, + r#" + // This should throw a RangeError + function recursiveFunction() { + recursiveFunction(); + } + recursiveFunction(); + "#, + "test_range_error.js", + ); + + println!("\n=== All tests passed! No BorrowMutError detected ==="); +} + +fn test_error_handling(runtime: &mut Runtime, code: &str, module_name: &str) { + let module = Module::new(module_name, code); + + print!(" Loading module '{}' (expected to fail)... ", module_name); + let result = runtime.load_module(&module); + + match result { + Ok(_) => { + println!("❌ UNEXPECTED: Module loaded successfully (should have failed)"); + std::process::exit(1); + } + Err(e) => { + println!( + "✓ Correctly returned error: {}", + e.to_string().lines().next().unwrap_or("Unknown error") + ); + } + } +} diff --git a/src/error.rs b/src/error.rs index 49eb51c..7a4eeea 100644 --- a/src/error.rs +++ b/src/error.rs @@ -107,6 +107,12 @@ impl From for Error { } } +impl From> for Error { + fn from(err: Box) -> Self { + Self::JsError(err) + } +} + impl Error { /// Formats an error for display in a terminal /// If the error is a `JsError`, it will attempt to highlight the source line @@ -239,7 +245,7 @@ map_error!(deno_ast::TranspileError, |e| Error::Runtime(e.to_string())); map_error!(deno_core::error::CoreError, |e| { let e = e.into_kind(); match e { - CoreErrorKind::Js(js_error) => Error::JsError(Box::new(js_error)), + CoreErrorKind::Js(js_error) => Error::JsError(js_error), _ => Error::Runtime(e.to_string()), } }); @@ -273,10 +279,7 @@ map_error!(deno_core::futures::channel::oneshot::Canceled, |e| { Error::Timeout(e.to_string()) }); -#[cfg(feature = "broadcast_channel")] -map_error!(deno_broadcast_channel::BroadcastChannelError, |e| { - Error::Runtime(e.to_string()) -}); +// Note: BroadcastChannelError mapping removed - no longer exported from deno_web #[cfg(test)] mod test { diff --git a/src/ext/broadcast_channel/01_broadcast_channel.js b/src/ext/broadcast_channel/01_broadcast_channel.js new file mode 100644 index 0000000..fce6882 --- /dev/null +++ b/src/ext/broadcast_channel/01_broadcast_channel.js @@ -0,0 +1 @@ +export * from "ext:deno_web/01_broadcast_channel.js"; diff --git a/src/ext/broadcast_channel/mod.rs b/src/ext/broadcast_channel/mod.rs index b9e84f4..9ec552c 100644 --- a/src/ext/broadcast_channel/mod.rs +++ b/src/ext/broadcast_channel/mod.rs @@ -1,10 +1,12 @@ -use deno_broadcast_channel::InMemoryBroadcastChannel; use deno_core::{extension, Extension}; +use deno_web::InMemoryBroadcastChannel; use super::ExtensionTrait; mod wrapper; -pub use wrapper::BroadcastChannelWrapper; +pub use wrapper::{ + BroadcastChannelWrapper, IsolatedBroadcastChannel, IsolatedBroadcastChannelWrapper, +}; extension!( init_broadcast_channel, @@ -12,20 +14,30 @@ extension!( esm_entry_point = "ext:init_broadcast_channel/init_broadcast_channel.js", esm = [ dir "src/ext/broadcast_channel", "init_broadcast_channel.js" ], ); + +extension!( + deno_broadcast_channel, + deps = [deno_web], + esm = [ dir "src/ext/broadcast_channel", "01_broadcast_channel.js" ], +); + impl ExtensionTrait<()> for init_broadcast_channel { fn init((): ()) -> Extension { init_broadcast_channel::init() } } -impl ExtensionTrait for deno_broadcast_channel::deno_broadcast_channel { - fn init(channel: InMemoryBroadcastChannel) -> Extension { - deno_broadcast_channel::deno_broadcast_channel::init(channel) + +impl ExtensionTrait<()> for deno_broadcast_channel { + fn init((): ()) -> Extension { + deno_broadcast_channel::init() } } -pub fn extensions(channel: InMemoryBroadcastChannel, is_snapshot: bool) -> Vec { +// Note: broadcast_channel functionality is now integrated into deno_web +// No separate initialization is needed as it's handled by deno_web extension +pub fn extensions(_channel: InMemoryBroadcastChannel, is_snapshot: bool) -> Vec { vec![ - deno_broadcast_channel::deno_broadcast_channel::build(channel, is_snapshot), + deno_broadcast_channel::build((), is_snapshot), init_broadcast_channel::build((), is_snapshot), ] } @@ -46,6 +58,11 @@ mod test { " ); + /// This test is identical to the original test from origin/master that verified + /// JavaScript ↔ Rust bidirectional communication. + /// + /// BroadcastChannelWrapper has been restored to maintain full backward compatibility + /// with origin/master behavior. #[test] fn test_broadcast_channel() { let options = RuntimeOptions::default(); diff --git a/src/ext/broadcast_channel/wrapper.rs b/src/ext/broadcast_channel/wrapper.rs index 36cefce..2355f35 100644 --- a/src/ext/broadcast_channel/wrapper.rs +++ b/src/ext/broadcast_channel/wrapper.rs @@ -1,34 +1,139 @@ +//! Wrapper for broadcast channel functionality +//! +//! This module provides broadcast channel wrappers for different use cases: +//! +//! ## `BroadcastChannelWrapper` - JavaScript ↔ Rust Communication (Recommended) +//! +//! This wrapper shares the same underlying channel as JavaScript's `BroadcastChannel` API, +//! enabling bidirectional communication between Rust and JavaScript. +//! +//! This is the **default and recommended** wrapper, maintaining compatibility with +//! origin/master behavior. +//! +//! ## `IsolatedBroadcastChannel` - Rust-to-Rust Communication +//! +//! An isolated channel for Rust-to-Rust communication only. +//! It does NOT share the underlying channel with JavaScript's `BroadcastChannel` API. +//! +//! Use this when you need multiple Rust components to communicate via broadcast channels +//! without involving JavaScript. +//! +//! ## Example +//! +//! ### JavaScript ↔ Rust (BroadcastChannelWrapper) +//! ```rust,ignore +//! use rustyscript::{BroadcastChannelWrapper, Runtime, RuntimeOptions}; +//! +//! let options = RuntimeOptions::default(); +//! let channel = options.extension_options.broadcast_channel.clone(); +//! +//! let mut runtime = Runtime::new(options)?; +//! let wrapper = BroadcastChannelWrapper::new(&channel, "my_channel")?; +//! +//! // Send from Rust to JavaScript +//! wrapper.send_sync(&mut runtime, "hello")?; +//! // JavaScript BroadcastChannel('my_channel') receives this message +//! ``` +//! +//! ### Rust ↔ Rust (IsolatedBroadcastChannel) +//! ```rust,ignore +//! use rustyscript::{IsolatedBroadcastChannel, Runtime, RuntimeOptions}; +//! +//! let channel = IsolatedBroadcastChannel::new(); +//! let mut runtime = Runtime::new(RuntimeOptions::default())?; +//! +//! let sub1 = channel.subscribe("my_channel")?; +//! let sub2 = channel.subscribe("my_channel")?; +//! +//! sub1.send_sync(&mut runtime, "hello")?; // sub2 receives +//! // JavaScript BroadcastChannel does NOT receive this +//! ``` + +use std::sync::Arc; use std::time::Duration; -use deno_broadcast_channel::BroadcastChannel; +use deno_core::parking_lot::Mutex; +use deno_web::InMemoryBroadcastChannel; use serde::{de::DeserializeOwned, Serialize}; +use tokio::sync::broadcast; +use tokio::sync::mpsc; +use uuid::Uuid; use crate::{big_json_args, Error, Runtime}; +/// Message type matching deno_web's internal InMemoryChannelMessage structure +#[derive(Clone, Debug)] +struct InMemoryChannelMessage { + name: Arc, + data: Arc>, + uuid: Uuid, +} + /// Helper struct to wrap a broadcast channel -/// Takes care of some of the boilerplate for serialization/deserialization -pub struct BroadcastChannelWrapper { - channel: Channel, - resource: ::Resource, +/// +/// Takes care of some of the boilerplate for serialization/deserialization. +/// Messages are serialized through the JavaScript runtime to ensure compatibility +/// with the JavaScript BroadcastChannel API. +/// +/// This wrapper shares the same underlying channel as JavaScript's `BroadcastChannel`, +/// enabling bidirectional Rust ↔ JavaScript communication. +pub struct BroadcastChannelWrapper { + sender: Arc>>, + receiver: tokio::sync::Mutex<( + broadcast::Receiver, + mpsc::UnboundedReceiver<()>, + )>, + cancel_tx: mpsc::UnboundedSender<()>, name: String, + uuid: Uuid, } -impl BroadcastChannelWrapper { + +impl BroadcastChannelWrapper { /// Create a new broadcast channel wrapper and subscribe to the channel + /// + /// This wrapper shares the same underlying channel as JavaScript's BroadcastChannel, + /// enabling bidirectional communication. + /// /// Unsubscribe is called when the wrapper is dropped /// + /// # Safety + /// This function uses unsafe code to access the private field of `InMemoryBroadcastChannel`. + /// The memory layout is stable because it's a simple tuple struct wrapping `Arc>`. + /// /// # Errors /// Will return an error if the channel cannot be subscribed to - pub fn new(channel: &Channel, name: impl ToString) -> Result { - let channel = channel.clone(); - let resource = channel.subscribe()?; + pub fn new(channel: &InMemoryBroadcastChannel, name: impl ToString) -> Result { + // SAFETY: InMemoryBroadcastChannel is repr(Rust) tuple struct with single field: + // pub struct InMemoryBroadcastChannel(Arc>>); + // + // We can access the field by transmuting to the inner type: + let sender: &Arc>> = unsafe { + &*(channel as *const InMemoryBroadcastChannel + as *const Arc>>) + }; + + let sender = sender.clone(); + let (cancel_tx, cancel_rx) = mpsc::unbounded_channel(); + let broadcast_rx = sender.lock().subscribe(); + let receiver = tokio::sync::Mutex::new((broadcast_rx, cancel_rx)); + let uuid = Uuid::new_v4(); let name = name.to_string(); + Ok(Self { - channel, - resource, + sender, + receiver, + cancel_tx, name, + uuid, }) } + /// Get the name of this channel + #[must_use] + pub fn name(&self) -> &str { + &self.name + } + /// Send a message to the channel, blocking until the message is sent /// /// # Errors @@ -43,16 +148,29 @@ impl BroadcastChannelWrapper { /// # Errors /// Will return an error if the message cannot be serialized or sent pub async fn send(&self, runtime: &mut Runtime, data: T) -> Result<(), Error> { + // Serialize through JavaScript for compatibility let data: Vec = runtime .call_function_async(None, "broadcast_serialize", &data) .await?; - self.channel - .send(&self.resource, self.name.clone(), data) - .await?; + + let message = InMemoryChannelMessage { + name: Arc::new(self.name.clone()), + data: Arc::new(data), + uuid: self.uuid, + }; + + self.sender + .lock() + .send(message) + .map_err(|e| Error::Runtime(format!("Failed to send broadcast message: {e}")))?; + Ok(()) } - /// Receive a message from the channel, waiting for a message to arrive, or until the timeout is reached + /// Receive a message from the channel, waiting for a message to arrive, + /// or until the timeout is reached + /// + /// Returns `None` if the timeout is reached or the channel is closed /// /// # Errors /// Will return an error if the message cannot be deserialized @@ -62,30 +180,266 @@ impl BroadcastChannelWrapper { runtime: &mut Runtime, timeout: Option, ) -> Result, Error> { - let msg = if let Some(timeout) = timeout { - tokio::select! { - msg = self.channel.recv(&self.resource) => msg, - () = tokio::time::sleep(timeout) => Ok(None), + let mut guard = self.receiver.lock().await; + let (broadcast_rx, cancel_rx) = &mut *guard; + + loop { + let result = if let Some(timeout) = timeout { + tokio::select! { + r = broadcast_rx.recv() => r, + () = tokio::time::sleep(timeout) => return Ok(None), + _ = cancel_rx.recv() => return Ok(None), + } + } else { + tokio::select! { + r = broadcast_rx.recv() => r, + _ = cancel_rx.recv() => return Ok(None), + } + }; + + use tokio::sync::broadcast::error::RecvError::*; + match result { + Err(Closed) => return Ok(None), + Err(Lagged(_)) => continue, // Backlogged, messages dropped - try again + Ok(message) if message.uuid == self.uuid => continue, // Self-send, skip + Ok(message) if *message.name != self.name => continue, // Different channel name + Ok(message) => { + // Deserialize through JavaScript for compatibility + let data: T = runtime + .call_function_async( + None, + "broadcast_deserialize", + big_json_args!(Vec::clone(&message.data)), + ) + .await?; + return Ok(Some(data)); + } } - } else { - self.channel.recv(&self.resource).await - }?; + } + } - let Some((name, data)) = msg else { - return Ok(None); + /// Receive a message from the channel, blocking until a message arrives, + /// or until the timeout is reached + /// + /// Returns `None` if the timeout is reached or the channel is closed + /// + /// # Errors + /// Will return an error if the message cannot be deserialized + /// or if receiving the message fails + pub fn recv_sync( + &self, + runtime: &mut Runtime, + timeout: Option, + ) -> Result, Error> { + let tokio_rt = runtime.tokio_runtime(); + tokio_rt.block_on(self.recv(runtime, timeout)) + } + + /// Close this subscription + /// + /// After calling this, `recv` will return `None` + pub fn close(&self) { + let _ = self.cancel_tx.send(()); + } +} + +impl Drop for BroadcastChannelWrapper { + fn drop(&mut self) { + self.close(); + } +} + +// ============================================================================ +// IsolatedBroadcastChannel - for Rust-to-Rust communication only +// ============================================================================ + +/// Message type for internal isolated broadcast channel communication +#[derive(Clone, Debug)] +struct IsolatedChannelMessage { + name: Arc, + data: Arc>, + sender_id: Uuid, +} + +/// An isolated broadcast channel that can be shared across multiple runtimes +/// +/// This is the backing storage for isolated broadcast channel communication. +/// Clone this to share the channel between multiple wrappers. +/// +/// **Note**: This channel is isolated and does NOT share messages with JavaScript's +/// `BroadcastChannel` API. For JavaScript integration, use `BroadcastChannelWrapper`. +#[derive(Clone)] +pub struct IsolatedBroadcastChannel { + sender: Arc>>, +} + +impl Default for IsolatedBroadcastChannel { + fn default() -> Self { + Self::new() + } +} + +impl IsolatedBroadcastChannel { + /// Create a new isolated broadcast channel + #[must_use] + pub fn new() -> Self { + let (sender, _) = broadcast::channel(256); + Self { + sender: Arc::new(Mutex::new(sender)), + } + } + + /// Subscribe to this channel, creating a wrapper for sending/receiving messages + /// + /// # Errors + /// Will return an error if the subscription cannot be created + pub fn subscribe( + &self, + name: impl ToString, + ) -> Result { + IsolatedBroadcastChannelWrapper::new(self, name) + } +} + +/// Helper struct to wrap an isolated broadcast channel subscription +/// +/// Takes care of some of the boilerplate for serialization/deserialization. +/// Messages are serialized through the JavaScript runtime to ensure compatibility. +/// +/// **Note**: This wrapper uses an isolated channel and does NOT communicate with +/// JavaScript's `BroadcastChannel` API. +pub struct IsolatedBroadcastChannelWrapper { + channel: IsolatedBroadcastChannel, + receiver: tokio::sync::Mutex<( + broadcast::Receiver, + mpsc::UnboundedReceiver<()>, + )>, + cancel_tx: mpsc::UnboundedSender<()>, + name: String, + uuid: Uuid, +} + +impl IsolatedBroadcastChannelWrapper { + /// Create a new isolated broadcast channel wrapper and subscribe to the channel + /// + /// Unsubscribe is called when the wrapper is dropped + /// + /// # Errors + /// Will return an error if the channel cannot be subscribed to + pub fn new( + channel: &IsolatedBroadcastChannel, + name: impl ToString, + ) -> Result { + let (cancel_tx, cancel_rx) = mpsc::unbounded_channel(); + let broadcast_rx = channel.sender.lock().subscribe(); + let receiver = tokio::sync::Mutex::new((broadcast_rx, cancel_rx)); + let uuid = Uuid::new_v4(); + let name = name.to_string(); + + Ok(Self { + channel: channel.clone(), + receiver, + cancel_tx, + name, + uuid, + }) + } + + /// Get the name of this channel + #[must_use] + pub fn name(&self) -> &str { + &self.name + } + + /// Send a message to the channel, blocking until the message is sent + /// + /// # Errors + /// Will return an error if the message cannot be serialized or sent + pub fn send_sync(&self, runtime: &mut Runtime, data: T) -> Result<(), Error> { + let tokio_rt = runtime.tokio_runtime(); + tokio_rt.block_on(self.send(runtime, data)) + } + + /// Send a message to the channel + /// + /// # Errors + /// Will return an error if the message cannot be serialized or sent + pub async fn send(&self, runtime: &mut Runtime, data: T) -> Result<(), Error> { + // Serialize through JavaScript for compatibility + let data: Vec = runtime + .call_function_async(None, "broadcast_serialize", &data) + .await?; + + let message = IsolatedChannelMessage { + name: Arc::new(self.name.clone()), + data: Arc::new(data), + sender_id: self.uuid, }; - if name == self.name { - let data: T = runtime - .call_function_async(None, "broadcast_deserialize", big_json_args!(data)) - .await?; - Ok(Some(data)) - } else { - Ok(None) + self.channel + .sender + .lock() + .send(message) + .map_err(|e| Error::Runtime(format!("Failed to send broadcast message: {e}")))?; + + Ok(()) + } + + /// Receive a message from the channel, waiting for a message to arrive, + /// or until the timeout is reached + /// + /// Returns `None` if the timeout is reached or the channel is closed + /// + /// # Errors + /// Will return an error if the message cannot be deserialized + /// or if receiving the message fails + pub async fn recv( + &self, + runtime: &mut Runtime, + timeout: Option, + ) -> Result, Error> { + let mut guard = self.receiver.lock().await; + let (broadcast_rx, cancel_rx) = &mut *guard; + + loop { + let result = if let Some(timeout) = timeout { + tokio::select! { + r = broadcast_rx.recv() => r, + () = tokio::time::sleep(timeout) => return Ok(None), + _ = cancel_rx.recv() => return Ok(None), + } + } else { + tokio::select! { + r = broadcast_rx.recv() => r, + _ = cancel_rx.recv() => return Ok(None), + } + }; + + use tokio::sync::broadcast::error::RecvError::*; + match result { + Err(Closed) => return Ok(None), + Err(Lagged(_)) => continue, // Backlogged, messages dropped - try again + Ok(message) if message.sender_id == self.uuid => continue, // Self-send, skip + Ok(message) if *message.name != self.name => continue, // Different channel name + Ok(message) => { + // Deserialize through JavaScript for compatibility + let data: T = runtime + .call_function_async( + None, + "broadcast_deserialize", + big_json_args!(Vec::clone(&message.data)), + ) + .await?; + return Ok(Some(data)); + } + } } } - /// Receive a message from the channel, blocking until a message arrives, or until the timeout is reached + /// Receive a message from the channel, blocking until a message arrives, + /// or until the timeout is reached + /// + /// Returns `None` if the timeout is reached or the channel is closed /// /// # Errors /// Will return an error if the message cannot be deserialized @@ -98,10 +452,96 @@ impl BroadcastChannelWrapper { let tokio_rt = runtime.tokio_runtime(); tokio_rt.block_on(self.recv(runtime, timeout)) } + + /// Close this subscription + /// + /// After calling this, `recv` will return `None` + pub fn close(&self) { + let _ = self.cancel_tx.send(()); + } } -impl Drop for BroadcastChannelWrapper { +impl Drop for IsolatedBroadcastChannelWrapper { fn drop(&mut self) { - self.channel.unsubscribe(&self.resource).ok(); + self.close(); + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::{Module, Runtime, RuntimeOptions}; + + #[test] + fn test_isolated_broadcast_channel_send_recv() { + // This test demonstrates Rust-to-Rust communication via the IsolatedBroadcastChannel. + // Note: This wrapper is for Rust-side communication only. + // For JavaScript BroadcastChannel, use BroadcastChannelWrapper. + + let channel = IsolatedBroadcastChannel::new(); + + // Create a runtime for serialization + let mut runtime = Runtime::new(RuntimeOptions::default()).unwrap(); + + // Create two subscriptions on the same channel + let wrapper1 = channel.subscribe("test_channel").unwrap(); + let wrapper2 = channel.subscribe("test_channel").unwrap(); + + // Use async to send and receive + let tokio_rt = runtime.tokio_runtime(); + tokio_rt.block_on(async { + // Send from wrapper1 + let send_result: Result<(), crate::Error> = + wrapper1.send::<&str>(&mut runtime, "hello from rust").await; + send_result.unwrap(); + + // Receive from wrapper2 + let recv_result: Result, crate::Error> = wrapper2 + .recv::(&mut runtime, Some(std::time::Duration::from_secs(1))) + .await; + let received: String = recv_result.unwrap().unwrap(); + + assert_eq!(received, "hello from rust"); + }); + } + + #[test] + fn test_isolated_broadcast_channel_timeout() { + let channel = IsolatedBroadcastChannel::new(); + let mut runtime = Runtime::new(RuntimeOptions::default()).unwrap(); + let wrapper = channel.subscribe("timeout_test").unwrap(); + + // Try to receive with a short timeout - should return None + let result = wrapper + .recv_sync::(&mut runtime, Some(std::time::Duration::from_millis(100))) + .unwrap(); + + assert!(result.is_none()); + } + + #[test] + fn test_isolated_broadcast_channel_different_names() { + // Messages should only be received by subscriptions with matching names + let channel = IsolatedBroadcastChannel::new(); + let mut runtime = Runtime::new(RuntimeOptions::default()).unwrap(); + + let wrapper_a = channel.subscribe("channel_a").unwrap(); + let wrapper_b = channel.subscribe("channel_b").unwrap(); + + let tokio_rt = runtime.tokio_runtime(); + tokio_rt.block_on(async { + // Send to channel_a + let send_result: Result<(), crate::Error> = + wrapper_a.send::<&str>(&mut runtime, "message for a").await; + send_result.unwrap(); + + // wrapper_b should not receive this message (different channel name) + let recv_result: Result, crate::Error> = wrapper_b + .recv::(&mut runtime, Some(std::time::Duration::from_millis(100))) + .await; + let result: Option = recv_result.unwrap(); + + assert!(result.is_none()); + }); } } diff --git a/src/ext/console/init_console.js b/src/ext/console/init_console.js index 13aede7..68a4833 100644 --- a/src/ext/console/init_console.js +++ b/src/ext/console/init_console.js @@ -1,10 +1,38 @@ -import * as _console from 'ext:deno_console/01_console.js'; +import * as _console from 'ext:deno_web/01_console.js'; import { applyToGlobal, nonEnumerable } from 'ext:rustyscript/rustyscript.js'; + +const consoleInstance = new _console.Console((msg, level) => + globalThis.Deno.core.print(msg, level > 1), +); +for (const name of [ + "log", + "debug", + "info", + "warn", + "error", + "dir", + "dirxml", + "assert", + "clear", + "count", + "countReset", + "group", + "groupCollapsed", + "groupEnd", + "table", + "time", + "timeEnd", + "timeLog", + "trace", +]) { + const value = consoleInstance[name]; + if (typeof value === "function") { + consoleInstance[name] = value.bind(consoleInstance); + } +} applyToGlobal({ - console: nonEnumerable( - new _console.Console((msg, level) => globalThis.Deno.core.print(msg, level > 1)), - ), + console: nonEnumerable(consoleInstance), }); -globalThis.Deno.inspect = _console.inspect; \ No newline at end of file +globalThis.Deno.inspect = _console.inspect; diff --git a/src/ext/console/mod.rs b/src/ext/console/mod.rs index c3517fe..39e4468 100644 --- a/src/ext/console/mod.rs +++ b/src/ext/console/mod.rs @@ -4,7 +4,7 @@ use super::ExtensionTrait; extension!( init_console, - deps = [rustyscript], + deps = [rustyscript, deno_web], esm_entry_point = "ext:init_console/init_console.js", esm = [ dir "src/ext/console", "init_console.js" ], ); @@ -14,15 +14,7 @@ impl ExtensionTrait<()> for init_console { init_console::init() } } -impl ExtensionTrait<()> for deno_console::deno_console { - fn init((): ()) -> Extension { - deno_console::deno_console::init() - } -} pub fn extensions(is_snapshot: bool) -> Vec { - vec![ - deno_console::deno_console::build((), is_snapshot), - init_console::build((), is_snapshot), - ] + vec![>::build((), is_snapshot)] } diff --git a/src/ext/ffi/mod.rs b/src/ext/ffi/mod.rs index a7b90fa..a1787b3 100644 --- a/src/ext/ffi/mod.rs +++ b/src/ext/ffi/mod.rs @@ -1,8 +1,6 @@ -use std::{borrow::Cow, path::Path}; - use deno_core::{extension, Extension}; -use super::{web::PermissionsContainer, ExtensionTrait}; +use super::ExtensionTrait; extension!( init_ffi, @@ -10,14 +8,16 @@ extension!( esm_entry_point = "ext:init_ffi/init_ffi.js", esm = [ dir "src/ext/ffi", "init_ffi.js" ], ); + impl ExtensionTrait<()> for init_ffi { fn init((): ()) -> Extension { init_ffi::init() } } + impl ExtensionTrait<()> for deno_ffi::deno_ffi { fn init((): ()) -> Extension { - deno_ffi::deno_ffi::init::(None) + deno_ffi::deno_ffi::init(None) } } @@ -27,19 +27,3 @@ pub fn extensions(is_snapshot: bool) -> Vec { init_ffi::build((), is_snapshot), ] } - -impl deno_ffi::FfiPermissions for PermissionsContainer { - fn check_partial_no_path(&mut self) -> Result<(), deno_permissions::PermissionCheckError> { - self.0.check_exec()?; - Ok(()) - } - - fn check_partial_with_path<'a>( - &mut self, - path: Cow<'a, Path>, - ) -> Result, deno_permissions::PermissionCheckError> { - self.check_partial_no_path()?; - let p = self.0.check_read(path, None)?; - Ok(p) - } -} diff --git a/src/ext/fs/mod.rs b/src/ext/fs/mod.rs index 2831a45..26db495 100644 --- a/src/ext/fs/mod.rs +++ b/src/ext/fs/mod.rs @@ -1,10 +1,7 @@ -use std::{borrow::Cow, path::Path}; - use deno_core::{extension, Extension}; use deno_fs::FileSystemRc; -use deno_permissions::{CheckedPath, PermissionCheckError, PermissionDeniedError}; -use super::{web::PermissionsContainer, ExtensionTrait}; +use super::ExtensionTrait; extension!( init_fs, @@ -12,14 +9,16 @@ extension!( esm_entry_point = "ext:init_fs/init_fs.js", esm = [ dir "src/ext/fs", "init_fs.js" ], ); + impl ExtensionTrait<()> for init_fs { fn init((): ()) -> Extension { init_fs::init() } } + impl ExtensionTrait for deno_fs::deno_fs { fn init(fs: FileSystemRc) -> Extension { - deno_fs::deno_fs::init::(fs) + deno_fs::deno_fs::init(fs) } } @@ -29,65 +28,3 @@ pub fn extensions(fs: FileSystemRc, is_snapshot: bool) -> Vec { init_fs::build((), is_snapshot), ] } - -impl deno_fs::FsPermissions for PermissionsContainer { - fn check_open<'a>( - &self, - path: Cow<'a, Path>, - access_kind: deno_permissions::OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - let read = access_kind.is_read(); - let write = access_kind.is_write(); - - let p = self.0.check_open(true, read, write, path, api_name).ok_or( - PermissionCheckError::PermissionDenied(PermissionDeniedError { - access: api_name.to_string(), - name: "open", - }), - )?; - - Ok(CheckedPath::unsafe_new(p)) - } - - fn check_open_blind<'a>( - &self, - path: Cow<'a, Path>, - access_kind: deno_permissions::OpenAccessKind, - display: &str, - api_name: &str, - ) -> Result, PermissionCheckError> { - if access_kind.is_read() { - self.0.check_read_all(Some(api_name))?; - self.0.check_read_blind(&path, display, api_name)?; - } - - if access_kind.is_write() { - self.0.check_write_all(api_name)?; - self.0.check_write_blind(&path, display, api_name)?; - } - - Ok(CheckedPath::unsafe_new(path)) - } - - fn check_read_all(&self, api_name: &str) -> Result<(), PermissionCheckError> { - self.0.check_read_all(Some(api_name))?; - Ok(()) - } - - fn check_write_partial<'a>( - &self, - path: Cow<'a, Path>, - api_name: &str, - ) -> Result, PermissionCheckError> { - self.0.check_write_all(api_name)?; - let p = self.0.check_write_partial(path, api_name)?; - - Ok(CheckedPath::unsafe_new(p)) - } - - fn check_write_all(&self, api_name: &str) -> Result<(), PermissionCheckError> { - self.0.check_write_all(api_name)?; - Ok(()) - } -} diff --git a/src/ext/kv/mod.rs b/src/ext/kv/mod.rs index f9d13d1..6127f10 100644 --- a/src/ext/kv/mod.rs +++ b/src/ext/kv/mod.rs @@ -1,14 +1,9 @@ -use std::{borrow::Cow, path::PathBuf}; +use std::path::PathBuf; use deno_core::{extension, Extension}; -use deno_kv::{ - dynamic::MultiBackendDbHandler, - remote::{RemoteDbHandler, RemoteDbHandlerPermissions}, - sqlite::{SqliteDbHandler, SqliteDbHandlerPermissions}, -}; -use deno_permissions::{CheckedPath, PermissionCheckError, PermissionDeniedError}; +use deno_kv::{dynamic::MultiBackendDbHandler, remote::RemoteDbHandler, sqlite::SqliteDbHandler}; -use super::{web::PermissionsContainer, ExtensionTrait}; +use super::ExtensionTrait; extension!( init_kv, @@ -149,12 +144,12 @@ impl KvStore { pub fn handler(&self) -> MultiBackendDbHandler { match &self.0 { KvStoreBuilder::Local { path, rng_seed } => { - let db = SqliteDbHandler::::new(path.clone(), *rng_seed); + let db = SqliteDbHandler::new(path.clone(), *rng_seed); MultiBackendDbHandler::new(vec![(&[""], Box::new(db))]) } KvStoreBuilder::Remote { http_options } => { - let db = RemoteDbHandler::::new(http_options.clone()); + let db = RemoteDbHandler::new(http_options.clone()); MultiBackendDbHandler::new(vec![(&["https://", "http://"], Box::new(db))]) } } @@ -175,40 +170,3 @@ impl Default for KvStore { Self::new_local(None, None, KvConfig::default()) } } - -impl SqliteDbHandlerPermissions for PermissionsContainer { - fn check_open<'a>( - &mut self, - path: Cow<'a, std::path::Path>, - open_access: deno_permissions::OpenAccessKind, - api_name: &str, - ) -> Result, deno_permissions::PermissionCheckError> { - let read = open_access.is_read(); - let write = open_access.is_write(); - - let p = self.0.check_open(true, read, write, path, api_name).ok_or( - PermissionCheckError::PermissionDenied(PermissionDeniedError { - access: api_name.to_string(), - name: "open", - }), - )?; - - Ok(CheckedPath::unsafe_new(p)) - } -} - -impl RemoteDbHandlerPermissions for PermissionsContainer { - fn check_env(&mut self, var: &str) -> Result<(), deno_permissions::PermissionCheckError> { - self.0.check_env(var)?; - Ok(()) - } - - fn check_net_url( - &mut self, - url: &reqwest::Url, - api_name: &str, - ) -> Result<(), deno_permissions::PermissionCheckError> { - self.0.check_url(url, api_name)?; - Ok(()) - } -} diff --git a/src/ext/mod.rs b/src/ext/mod.rs index ff85fa4..6871da1 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -139,7 +139,7 @@ pub struct ExtensionOptions { /// Requires the `broadcast_channel` feature to be enabled #[cfg(feature = "broadcast_channel")] #[cfg_attr(docsrs, doc(cfg(feature = "broadcast_channel")))] - pub broadcast_channel: deno_broadcast_channel::InMemoryBroadcastChannel, + pub broadcast_channel: deno_web::InMemoryBroadcastChannel, /// Key-value store for the `deno_kv` extension /// @@ -160,9 +160,20 @@ pub struct ExtensionOptions { impl Default for ExtensionOptions { fn default() -> Self { + // Create a shared broadcast channel instance for both web and broadcast_channel extensions + #[cfg(feature = "broadcast_channel")] + let broadcast_channel = deno_web::InMemoryBroadcastChannel::default(); + Self { #[cfg(feature = "web")] - web: web::WebOptions::default(), + web: { + let mut web_options = web::WebOptions::default(); + #[cfg(feature = "broadcast_channel")] + { + web_options.broadcast_channel = broadcast_channel.clone(); + } + web_options + }, #[cfg(feature = "crypto")] crypto_seed: None, @@ -180,7 +191,7 @@ impl Default for ExtensionOptions { filesystem: std::sync::Arc::new(deno_fs::RealFs), #[cfg(feature = "broadcast_channel")] - broadcast_channel: deno_broadcast_channel::InMemoryBroadcastChannel::default(), + broadcast_channel, #[cfg(feature = "kv")] kv_store: kv::KvStore::default(), @@ -202,14 +213,18 @@ pub(crate) fn all_extensions( #[cfg(feature = "webidl")] extensions.extend(webidl::extensions(is_snapshot)); - #[cfg(feature = "console")] - extensions.extend(console::extensions(is_snapshot)); + // web or web_stub must come before url and console since they depend on deno_web + #[cfg(feature = "web")] + extensions.extend(web::extensions(options.web.clone(), is_snapshot)); + + #[cfg(all(not(feature = "web"), feature = "web_stub"))] + extensions.extend(web_stub::extensions(is_snapshot)); #[cfg(feature = "url")] extensions.extend(url::extensions(is_snapshot)); - #[cfg(feature = "web")] - extensions.extend(web::extensions(options.web.clone(), is_snapshot)); + #[cfg(feature = "console")] + extensions.extend(console::extensions(is_snapshot)); #[cfg(feature = "broadcast_channel")] extensions.extend(broadcast_channel::extensions( @@ -220,9 +235,6 @@ pub(crate) fn all_extensions( #[cfg(feature = "cache")] extensions.extend(cache::extensions(options.cache.clone(), is_snapshot)); - #[cfg(all(not(feature = "web"), feature = "web_stub"))] - extensions.extend(web_stub::extensions(is_snapshot)); - #[cfg(feature = "crypto")] extensions.extend(crypto::extensions(options.crypto_seed, is_snapshot)); @@ -236,7 +248,7 @@ pub(crate) fn all_extensions( )); #[cfg(feature = "websocket")] - extensions.extend(websocket::extensions(options.web.clone(), is_snapshot)); + extensions.extend(websocket::extensions(is_snapshot)); #[cfg(feature = "fs")] extensions.extend(fs::extensions(options.filesystem.clone(), is_snapshot)); diff --git a/src/ext/napi/mod.rs b/src/ext/napi/mod.rs index 56875c2..f0e48f1 100644 --- a/src/ext/napi/mod.rs +++ b/src/ext/napi/mod.rs @@ -1,8 +1,6 @@ -use std::borrow::Cow; - use deno_core::{extension, Extension}; -use super::{web::PermissionsContainer, ExtensionTrait}; +use super::ExtensionTrait; extension!( init_napi, @@ -10,14 +8,16 @@ extension!( esm_entry_point = "ext:init_napi/init_napi.js", esm = [ dir "src/ext/napi", "init_napi.js" ], ); + impl ExtensionTrait<()> for init_napi { fn init((): ()) -> Extension { init_napi::init() } } + impl ExtensionTrait<()> for deno_napi::deno_napi { fn init((): ()) -> Extension { - deno_napi::deno_napi::init::(None) + deno_napi::deno_napi::init(None) } } @@ -27,13 +27,3 @@ pub fn extensions(is_snapshot: bool) -> Vec { init_napi::build((), is_snapshot), ] } - -impl deno_napi::NapiPermissions for PermissionsContainer { - fn check<'a>( - &mut self, - path: Cow<'a, std::path::Path>, - ) -> Result, deno_permissions::PermissionCheckError> { - let p = self.0.check_read(path, None)?; - Ok(p) - } -} diff --git a/src/ext/node/mod.rs b/src/ext/node/mod.rs index 76866af..4b1a4c3 100644 --- a/src/ext/node/mod.rs +++ b/src/ext/node/mod.rs @@ -1,16 +1,11 @@ -use std::{borrow::Cow, path::Path, sync::Arc}; +use std::sync::Arc; use deno_core::{extension, Extension}; -use deno_node::NodePermissions; -use deno_permissions::{CheckedPath, PermissionCheckError, PermissionDeniedError}; use deno_resolver::npm::DenoInNpmPackageChecker; use resolvers::{RustyNpmPackageFolderResolver, RustyResolver}; use sys_traits::impls::RealSys; -use super::{ - web::{PermissionsContainer, SystemsPermissionKind}, - ExtensionTrait, -}; +use super::ExtensionTrait; mod cjs_translator; pub mod resolvers; @@ -29,12 +24,10 @@ impl ExtensionTrait<()> for init_node { } impl ExtensionTrait> for deno_node::deno_node { fn init(resolver: Arc) -> Extension { - deno_node::deno_node::init::< - PermissionsContainer, - DenoInNpmPackageChecker, - RustyNpmPackageFolderResolver, - RealSys, - >(Some(resolver.init_services()), resolver.filesystem()) + deno_node::deno_node::init::( + Some(resolver.init_services()), + resolver.filesystem(), + ) } } @@ -44,55 +37,3 @@ pub fn extensions(resolver: Arc, is_snapshot: bool) -> Vec), - api_name: &str, - ) -> Result<(), PermissionCheckError> { - self.0.check_host(host.0, host.1, api_name)?; - Ok(()) - } - - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: deno_permissions::OpenAccessKind, - api_name: Option<&str>, - ) -> Result, PermissionCheckError> { - let read = open_access.is_read(); - let write = open_access.is_write(); - - let p = self - .0 - .check_open(true, read, write, path, api_name.unwrap_or_default()) - .ok_or(PermissionCheckError::PermissionDenied( - PermissionDeniedError { - access: api_name.unwrap_or_default().to_string(), - name: "open", - }, - ))?; - - Ok(CheckedPath::unsafe_new(p)) - } - - fn check_net_url( - &mut self, - url: &reqwest::Url, - api_name: &str, - ) -> std::result::Result<(), PermissionCheckError> { - self.0.check_url(url, api_name)?; - Ok(()) - } - - fn query_read_all(&mut self) -> bool { - self.0.check_read_all(None).is_ok() - } - - fn check_sys(&mut self, kind: &str, api_name: &str) -> Result<(), PermissionCheckError> { - let kind = SystemsPermissionKind::new(kind); - self.0.check_sys(kind, api_name)?; - Ok(()) - } -} diff --git a/src/ext/node/resolvers.rs b/src/ext/node/resolvers.rs index a1ddc14..31a010b 100644 --- a/src/ext/node/resolvers.rs +++ b/src/ext/node/resolvers.rs @@ -11,8 +11,8 @@ use deno_core::FastString; use deno_error::JsErrorBox; use deno_fs::{FileSystem, RealFs}; use deno_node::{NodeExtInitServices, NodeRequireLoader, NodeResolver}; -use deno_package_json::{PackageJsonCache, PackageJsonRc}; -use deno_permissions::{CheckedPath, OpenAccessKind}; +use deno_package_json::{PackageJsonCache, PackageJsonCacheResult, PackageJsonRc}; +use deno_permissions::{CheckedPath, OpenAccessKind, PermissionsContainer}; use deno_process::NpmProcessStateProvider; use deno_resolver::npm::{ ByonmInNpmPackageChecker, ByonmNpmResolver, ByonmNpmResolverCreateOptions, @@ -23,7 +23,7 @@ use node_resolver::{ analyze::{CjsModuleExportAnalyzer, NodeCodeTranslatorMode}, cache::NodeResolutionSys, errors::{ - ClosestPkgJsonError, PackageFolderResolveError, PackageFolderResolveErrorKind, + PackageFolderResolveError, PackageFolderResolveErrorKind, PackageJsonLoadError, PackageNotFoundError, }, DenoIsBuiltInNodeModuleChecker, InNpmPackageChecker, NodeConditionOptions, NodeResolutionCache, @@ -163,7 +163,7 @@ impl RustyResolver { fn check_based_on_pkg_json( &self, specifier: &ModuleSpecifier, - ) -> Result { + ) -> Result { let pjson = self.folder_resolver.pjson_resolver(); // Try to get a path from the URL @@ -203,6 +203,8 @@ impl RustyResolver { match media_type { MediaType::Wasm | MediaType::Json + | MediaType::Jsonc + | MediaType::Json5 | MediaType::Mts | MediaType::Mjs | MediaType::Html @@ -380,6 +382,17 @@ impl NpmPackageFolderResolver for RustyNpmPackageFolderResolver { .resolve_package_folder_from_package(specifier, referrer), } } + + fn resolve_types_package_folder( + &self, + _package_name: &str, + _version: Option<&deno_semver::Version>, + _referrer: Option<&UrlOrPathRef>, + ) -> Option { + // For BYONM (Bring Your Own Node Modules), types are resolved from node_modules + // This is not applicable in the current implementation + None + } } /// @@ -392,11 +405,20 @@ impl RustyPackageJsonCache { } } impl PackageJsonCache for RustyPackageJsonCache { - fn get(&self, path: &Path) -> Option { - self.0.read().ok().and_then(|i| i.get(path)) + fn get(&self, path: &Path) -> PackageJsonCacheResult { + match self.0.read().ok() { + Some(cache) => { + if cache.cache.contains_key(path) { + PackageJsonCacheResult::Hit(cache.cache.get(path).cloned().flatten()) + } else { + PackageJsonCacheResult::NotCached + } + } + None => PackageJsonCacheResult::NotCached, + } } - fn set(&self, path: PathBuf, package_json: PackageJsonRc) { + fn set(&self, path: PathBuf, package_json: Option) { if let Ok(mut i) = self.0.write() { i.set(path, package_json); } @@ -404,13 +426,14 @@ impl PackageJsonCache for RustyPackageJsonCache { } #[derive(Debug, Default, Clone)] pub struct RustyPackageJsonCacheInner { - cache: HashMap, + cache: HashMap>, } impl RustyPackageJsonCacheInner { + #[allow(dead_code)] fn get(&self, path: &Path) -> Option { - self.cache.get(path).cloned() + self.cache.get(path).cloned().flatten() } - fn set(&mut self, path: PathBuf, package_json: PackageJsonRc) { + fn set(&mut self, path: PathBuf, package_json: Option) { self.cache.insert(path, package_json); } } @@ -531,7 +554,7 @@ impl NodeRequireLoader for RequireLoader { fn ensure_read_permission<'a>( &self, - permissions: &mut dyn deno_node::NodePermissions, + permissions: &mut PermissionsContainer, path: Cow<'a, Path>, ) -> Result, JsErrorBox> { let is_in_node_modules = path @@ -547,7 +570,7 @@ impl NodeRequireLoader for RequireLoader { } } - fn is_maybe_cjs(&self, specifier: &reqwest::Url) -> Result { + fn is_maybe_cjs(&self, specifier: &reqwest::Url) -> Result { if specifier.scheme() != "file" { return Ok(false); } diff --git a/src/ext/runtime/init_runtime.js b/src/ext/runtime/init_runtime.js index 588f7a9..2d0fefe 100644 --- a/src/ext/runtime/init_runtime.js +++ b/src/ext/runtime/init_runtime.js @@ -77,7 +77,7 @@ applyToDeno({ core: readOnly(core), }); -import * as _console from 'ext:deno_console/01_console.js'; +import * as _console from 'ext:deno_web/01_console.js'; _console.setNoColorFns( () => globalThis.Deno.core.ops.op_bootstrap_no_color(), () => globalThis.Deno.core.ops.op_bootstrap_no_color(), diff --git a/src/ext/runtime/mod.rs b/src/ext/runtime/mod.rs index 43ef723..70cbfdd 100644 --- a/src/ext/runtime/mod.rs +++ b/src/ext/runtime/mod.rs @@ -1,5 +1,6 @@ use std::{collections::HashSet, rc::Rc, sync::Arc}; +use deno_bundle_runtime::BundleProvider; use deno_core::{ extension, v8::{BackingStore, SharedRef}, @@ -64,6 +65,12 @@ impl ExtensionTrait<()> for deno_runtime::runtime { } } +impl ExtensionTrait>> for deno_bundle_runtime::deno_bundle_runtime { + fn init(bundle_provider: Option>) -> Extension { + deno_bundle_runtime::deno_bundle_runtime::init(bundle_provider) + } +} + use deno_runtime::fmt_errors::format_js_error; use deno_runtime::ops::permissions::deno_permissions; impl ExtensionTrait<()> for deno_permissions { @@ -132,6 +139,7 @@ pub fn extensions( is_snapshot: bool, ) -> Vec { vec![ + deno_bundle_runtime::deno_bundle_runtime::build(None, is_snapshot), deno_fs_events::build((), is_snapshot), deno_bootstrap::build((), is_snapshot), deno_os::build((), is_snapshot), @@ -145,6 +153,7 @@ pub fn extensions( ] } +use deno_runtime::inspector_server::MainInspectorSessionChannel; use deno_runtime::web_worker::{WebWorker, WebWorkerOptions, WebWorkerServiceOptions}; use deno_runtime::{colors, BootstrapOptions, WorkerExecutionMode, WorkerLogLevel}; #[derive(Clone)] @@ -152,7 +161,7 @@ pub struct WebWorkerCallbackOptions { shared_array_buffer_store: Option>>, node_resolver: Arc, root_cert_store_provider: Option>, - broadcast_channel: deno_broadcast_channel::InMemoryBroadcastChannel, + broadcast_channel: deno_web::InMemoryBroadcastChannel, unsafely_ignore_certificate_errors: Option>, seed: Option, stdio: deno_io::Stdio, @@ -210,6 +219,8 @@ fn create_web_worker_callback(options: WebWorkerCallbackOptions) -> Arc Arc Arc>, - scope: &mut v8::HandleScope, + scope: &mut v8::HandleScope<'_>, ) -> Result; fn slow_args_from_v8( args: Vec>, - scope: &mut v8::HandleScope, + scope: &mut v8::HandleScope<'_>, ) -> Result { let args = Self::args_from_v8(args, scope)?; deno_core::serde_json::to_value(args).map_err(Error::from) @@ -46,16 +46,27 @@ pub trait RsCallback: 'static { /// Convert a series of `v8::Value` objects into a tuple of arguments fn decode_v8( args: v8::Global, - scope: &mut v8::HandleScope, + scope: &mut v8::HandleScope<'_>, ) -> Result { - let args = v8::Local::new(scope, args); - let args = if args.is_array() { - let args: v8::Local = v8::Local::new(scope, args).try_into()?; + // SAFETY: v8 API requires &PinnedRef but &mut HandleScope has the same layout + // We transmute to satisfy the type requirements while maintaining safety + let scope_ref = + unsafe { &*std::ptr::from_mut(scope).cast::>>() }; + // SAFETY: Object methods require HandleScope + let ctx_scope = unsafe { + &*std::ptr::from_mut(scope).cast::>>() + }; + // SAFETY: v8::Global::new requires &Isolate + let isolate = unsafe { &*std::ptr::from_mut(scope).cast::() }; + let args_local = v8::Local::new(scope_ref, args); + + let args = if args_local.is_array() { + let args: v8::Local = v8::Local::new(scope_ref, args_local).try_into()?; let len = args.length() as usize; let mut result = Vec::with_capacity(len); for i in 0..len { let index = v8::Integer::new( - scope, + scope_ref, i.try_into().map_err(|_| { Error::Runtime(format!( "Could not decode {len} arguments - use `big_json_args`" @@ -63,13 +74,13 @@ pub trait RsCallback: 'static { })?, ); let arg = args - .get(scope, index.into()) + .get(ctx_scope, index.into()) .ok_or_else(|| Error::Runtime(format!("Invalid argument at index {i}")))?; - result.push(v8::Global::new(scope, arg)); + result.push(v8::Global::new(isolate, arg)); } result } else { - vec![v8::Global::new(scope, args)] + vec![v8::Global::new(isolate, args_local)] }; Self::args_from_v8(args, scope) @@ -97,13 +108,23 @@ macro_rules! codegen_function { fn args_from_v8( args: Vec>, - scope: &mut v8::HandleScope, + scope: &mut v8::HandleScope<'_>, ) -> Result { + // SAFETY: v8 API requires PinnedRef types but HandleScope has the same layout + let scope_ref = unsafe { + &*std::ptr::from_mut(scope) + .cast::<$crate::deno_core::v8::PinnedRef<$crate::deno_core::v8::HandleScope<'_, ()>>>() + }; + let scope_mut = unsafe { + &mut *std::ptr::from_mut(scope).cast::<$crate::deno_core::v8::PinnedRef< + $crate::deno_core::v8::HandleScope<'_, $crate::deno_core::v8::Context>, + >>() + }; let mut args = args.into_iter(); $( let next = args.next().ok_or($crate::Error::Runtime(format!("Missing argument {} for {}", stringify!($n), stringify!($name))))?; - let next = $crate::deno_core::v8::Local::new(scope, next); - let $n:$t = $crate::deno_core::serde_v8::from_v8(scope, next)?; + let next = $crate::deno_core::v8::Local::new(scope_ref, next); + let $n:$t = $crate::deno_core::serde_v8::from_v8(scope_mut, next)?; )+ Ok(($($n,)+)) } diff --git a/src/ext/url/init_url.js b/src/ext/url/init_url.js index ae3a491..4f15ae9 100644 --- a/src/ext/url/init_url.js +++ b/src/ext/url/init_url.js @@ -1,5 +1,5 @@ -import * as url from 'ext:deno_url/00_url.js'; -import * as urlPattern from 'ext:deno_url/01_urlpattern.js'; +import * as url from 'ext:deno_web/00_url.js'; +import * as urlPattern from 'ext:deno_web/01_urlpattern.js'; import { applyToGlobal, nonEnumerable } from 'ext:rustyscript/rustyscript.js'; applyToGlobal({ diff --git a/src/ext/url/mod.rs b/src/ext/url/mod.rs index cb1e3f4..3e61b15 100644 --- a/src/ext/url/mod.rs +++ b/src/ext/url/mod.rs @@ -4,7 +4,7 @@ use super::ExtensionTrait; extension!( init_url, - deps = [rustyscript], + deps = [rustyscript, deno_web], esm_entry_point = "ext:init_url/init_url.js", esm = [ dir "src/ext/url", "init_url.js" ], ); @@ -13,15 +13,7 @@ impl ExtensionTrait<()> for init_url { init_url::init() } } -impl ExtensionTrait<()> for deno_url::deno_url { - fn init((): ()) -> Extension { - deno_url::deno_url::init() - } -} pub fn extensions(is_snapshot: bool) -> Vec { - vec![ - deno_url::deno_url::build((), is_snapshot), - init_url::build((), is_snapshot), - ] + vec![init_url::build((), is_snapshot)] } diff --git a/src/ext/web/init_errors.js b/src/ext/web/init_errors.js index 2731081..6c0b5cf 100644 --- a/src/ext/web/init_errors.js +++ b/src/ext/web/init_errors.js @@ -19,7 +19,7 @@ import { getStderrNoColor, inspectArgs, quoteString, -} from "ext:deno_console/01_console.js"; +} from "ext:deno_web/01_console.js"; class NotFound extends Error { constructor(msg) { @@ -347,4 +347,4 @@ globalThis_ = globalThis; primordials.ObjectSetPrototypeOf(globalThis, DedicatedWorkerGlobalScope.prototype); event.saveGlobalThisReference(globalThis); -event.setEventTargetData(globalThis); \ No newline at end of file +event.setEventTargetData(globalThis); diff --git a/src/ext/web/init_fetch.js b/src/ext/web/init_fetch.js index 53a6312..e32052d 100644 --- a/src/ext/web/init_fetch.js +++ b/src/ext/web/init_fetch.js @@ -1,5 +1,5 @@ import * as headers from "ext:deno_fetch/20_headers.js"; -import * as formData from "ext:deno_fetch/21_formdata.js"; +import * as formData from "ext:deno_fetch/21_formdata.js"; import * as httpClient from "ext:deno_fetch/22_http_client.js"; import * as request from "ext:deno_fetch/23_request.js"; import * as response from "ext:deno_fetch/23_response.js"; diff --git a/src/ext/web/init_web.js b/src/ext/web/init_web.js index db5cce3..17c7164 100644 --- a/src/ext/web/init_web.js +++ b/src/ext/web/init_web.js @@ -16,6 +16,7 @@ import * as messagePort from 'ext:deno_web/13_message_port.js'; import * as compression from 'ext:deno_web/14_compression.js'; import * as performance from 'ext:deno_web/15_performance.js'; import * as imageData from 'ext:deno_web/16_image_data.js'; +import * as broadcastChannel from 'ext:deno_web/01_broadcast_channel.js'; import * as errors from 'ext:init_web/init_errors.js'; diff --git a/src/ext/web/mod.rs b/src/ext/web/mod.rs index 7647667..3aafdbd 100644 --- a/src/ext/web/mod.rs +++ b/src/ext/web/mod.rs @@ -50,7 +50,7 @@ impl ExtensionTrait for deno_fetch::deno_fetch { resolver: options.resolver.clone(), }; - deno_fetch::deno_fetch::init::(options) + deno_fetch::deno_fetch::init(options) } } @@ -80,7 +80,7 @@ impl ExtensionTrait for init_net { } impl ExtensionTrait for deno_net::deno_net { fn init(options: WebOptions) -> Extension { - deno_net::deno_net::init::( + deno_net::deno_net::init( options.root_cert_store_provider.clone(), options.unsafely_ignore_certificate_errors.clone(), ) @@ -113,7 +113,14 @@ extension!( options = { permissions: Arc }, - state = |state, config| state.put(PermissionsContainer(config.permissions)), + state = |state, config| { + state.put(PermissionsContainer(config.permissions)); + if !state.has::() { + let parser = Arc::new(deno_permissions::RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys)); + let permissions = deno_permissions::PermissionsContainer::allow_all(parser); + state.put(permissions); + } + }, ); impl ExtensionTrait for init_web { fn init(options: WebOptions) -> Extension { @@ -123,7 +130,11 @@ impl ExtensionTrait for init_web { impl ExtensionTrait for deno_web::deno_web { fn init(options: WebOptions) -> Extension { - deno_web::deno_web::init::(options.blob_store, options.base_url) + deno_web::deno_web::init( + options.blob_store, + options.base_url, + options.broadcast_channel, + ) } } diff --git a/src/ext/web/options.rs b/src/ext/web/options.rs index bdf0abc..4039a51 100644 --- a/src/ext/web/options.rs +++ b/src/ext/web/options.rs @@ -6,6 +6,28 @@ use hyper_util::client::legacy::Builder; use super::{DefaultWebPermissions, WebPermissions}; /// Options for configuring the web related extensions +/// +/// # Backward Compatibility Note +/// +/// This struct has a new field `broadcast_channel` added in version 0.8.0. +/// **Existing code using `WebOptions::default()` is not affected.** +/// +/// If you are manually constructing `WebOptions`, you need to add the new field: +/// ```rust,ignore +/// // Update your code like this: +/// let options = WebOptions { +/// permissions: my_permissions, +/// blob_store: my_blob_store, +/// broadcast_channel: deno_web::InMemoryBroadcastChannel::default(), // NEW FIELD +/// // ... other fields ... +/// }; +/// +/// // Or use the builder pattern with ..Default::default(): +/// let options = WebOptions { +/// permissions: my_permissions, +/// ..Default::default() +/// }; +/// ``` #[derive(Clone)] pub struct WebOptions { /// Base URL for some `deno_web` OPs @@ -42,6 +64,9 @@ pub struct WebOptions { /// Blob store for the web related extensions pub blob_store: Arc, + /// Broadcast channel for cross-context messaging + pub broadcast_channel: deno_web::InMemoryBroadcastChannel, + ///A callback to customize HTTP client configuration. /// /// For more info on what can be configured, see [`hyper_util::client::legacy::Builder`] @@ -67,6 +92,7 @@ impl Default for WebOptions { file_fetch_handler: std::rc::Rc::new(deno_fetch::DefaultFileFetchHandler), permissions: Arc::new(DefaultWebPermissions), blob_store: Arc::new(deno_web::BlobStore::default()), + broadcast_channel: deno_web::InMemoryBroadcastChannel::default(), client_builder_hook: None, resolver: Resolver::default(), telemetry_config: deno_telemetry::OtelConfig::default(), diff --git a/src/ext/web/permissions.rs b/src/ext/web/permissions.rs index eebf53f..44bb67e 100644 --- a/src/ext/web/permissions.rs +++ b/src/ext/web/permissions.rs @@ -5,12 +5,16 @@ use std::{ sync::{Arc, RwLock}, }; -pub use deno_permissions::{CheckedPath, PermissionCheckError, PermissionDeniedError}; +pub use deno_permissions::{ + CheckedPath, PermissionCheckError, PermissionDeniedError, PermissionState, +}; pub fn oops(msg: impl std::fmt::Display) -> PermissionCheckError { PermissionCheckError::PermissionDenied(PermissionDeniedError { access: msg.to_string(), name: "web", + custom_message: None, + state: PermissionState::Denied, }) } @@ -156,11 +160,11 @@ impl AllowlistWebPermissions { Self(Arc::new(RwLock::new(AllowlistWebPermissionsSet::default()))) } - fn borrow(&self) -> std::sync::RwLockReadGuard { + fn borrow(&self) -> std::sync::RwLockReadGuard<'_, AllowlistWebPermissionsSet> { self.0.read().expect("Could not lock permissions") } - fn borrow_mut(&self) -> std::sync::RwLockWriteGuard { + fn borrow_mut(&self) -> std::sync::RwLockWriteGuard<'_, AllowlistWebPermissionsSet> { self.0.write().expect("Could not lock permissions") } @@ -632,84 +636,6 @@ impl_sys_permission_kinds!( Inspector("inspector"), ); +#[allow(dead_code)] #[derive(Clone, Debug)] pub struct PermissionsContainer(pub Arc); -impl deno_web::TimersPermission for PermissionsContainer { - fn allow_hrtime(&mut self) -> bool { - self.0.allow_hrtime() - } -} -impl deno_fetch::FetchPermissions for PermissionsContainer { - fn check_net_url( - &mut self, - url: &reqwest::Url, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - self.0.check_url(url, api_name)?; - Ok(()) - } - - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: deno_permissions::OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - let read = open_access.is_read(); - let write = open_access.is_write(); - - let p = self - .0 - .check_open(true, read, write, path, api_name) - .ok_or(oops("open"))?; - - Ok(CheckedPath::unsafe_new(p)) - } - - fn check_net_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - self.0.check_vsock(cid, port, api_name)?; - Ok(()) - } -} -impl deno_net::NetPermissions for PermissionsContainer { - fn check_net>( - &mut self, - host: &(T, Option), - api_name: &str, - ) -> Result<(), PermissionCheckError> { - self.0.check_host(host.0.as_ref(), host.1, api_name)?; - Ok(()) - } - - fn check_open<'a>( - &mut self, - path: Cow<'a, Path>, - open_access: deno_permissions::OpenAccessKind, - api_name: &str, - ) -> Result, PermissionCheckError> { - let read = open_access.is_read(); - let write = open_access.is_write(); - - let p = self - .0 - .check_open(true, read, write, path, api_name) - .ok_or(oops("open"))?; - - Ok(CheckedPath::unsafe_new(p)) - } - - fn check_vsock( - &mut self, - cid: u32, - port: u32, - api_name: &str, - ) -> Result<(), PermissionCheckError> { - self.0.check_vsock(cid, port, api_name)?; - Ok(()) - } -} diff --git a/src/ext/web_stub/00_url.js b/src/ext/web_stub/00_url.js new file mode 100644 index 0000000..f0285f7 --- /dev/null +++ b/src/ext/web_stub/00_url.js @@ -0,0 +1,10 @@ +// Minimal URL implementation for web_stub +// Uses the native V8 URL implementation + +// V8 has built-in URL and URLSearchParams +// We just need to export them properly + +const URL = globalThis.URL; +const URLSearchParams = globalThis.URLSearchParams; + +export { URL, URLSearchParams }; diff --git a/src/ext/web_stub/01_console.js b/src/ext/web_stub/01_console.js new file mode 100644 index 0000000..af04dd4 --- /dev/null +++ b/src/ext/web_stub/01_console.js @@ -0,0 +1,156 @@ +// Minimal console implementation for web_stub +// This provides the Console class and inspect function that init_console.js needs + +import { primordials } from "ext:core/mod.js"; +const { + ObjectAssign, + ObjectFromEntries, + ArrayPrototypeMap, + ObjectGetOwnPropertyDescriptor, +} = primordials; + +const inspectOptions = { + depth: 4, + colors: false, + iteratorLimit: 100, + maxStringLength: Infinity, +}; + +function inspect(value, options = {}) { + const opts = { ...inspectOptions, ...options }; + return formatValue(value, opts.depth, new Set()); +} + +// Creates a proxy object that filters properties for inspect +// This is used by DOMException and other objects for custom inspect +function createFilteredInspectProxy({ object, evaluate, keys }) { + if (!evaluate) { + return object; + } + const descriptors = ObjectFromEntries( + ArrayPrototypeMap(keys, (key) => { + return [key, ObjectGetOwnPropertyDescriptor(object, key) ?? { + value: object[key], + enumerable: true, + }]; + }), + ); + return ObjectAssign({}, descriptors); +} + +function formatValue(value, depth, seen) { + if (value === null) return 'null'; + if (value === undefined) return 'undefined'; + + const type = typeof value; + + if (type === 'string') return JSON.stringify(value); + if (type === 'number' || type === 'boolean') return String(value); + if (type === 'bigint') return `${value}n`; + if (type === 'symbol') return value.toString(); + if (type === 'function') return `[Function: ${value.name || 'anonymous'}]`; + + if (type === 'object') { + if (seen.has(value)) return '[Circular]'; + seen.add(value); + + if (depth <= 0) return '[Object]'; + + if (Array.isArray(value)) { + const items = value.map(v => formatValue(v, depth - 1, seen)); + return `[ ${items.join(', ')} ]`; + } + + if (value instanceof Error) { + return value.stack || value.message || String(value); + } + + if (value instanceof Date) { + return value.toISOString(); + } + + if (value instanceof RegExp) { + return value.toString(); + } + + const entries = Object.entries(value) + .map(([k, v]) => `${k}: ${formatValue(v, depth - 1, seen)}`) + .join(', '); + return `{ ${entries} }`; + } + + return String(value); +} + +class Console { + #printFn; + + constructor(printFn) { + this.#printFn = printFn; + } + + #print(level, ...args) { + const msg = args.map(a => typeof a === 'string' ? a : inspect(a)).join(' ') + '\n'; + this.#printFn(msg, level); + } + + log(...args) { this.#print(1, ...args); } + debug(...args) { this.#print(0, ...args); } + info(...args) { this.#print(1, ...args); } + warn(...args) { this.#print(2, ...args); } + error(...args) { this.#print(3, ...args); } + + dir(obj, options) { this.log(inspect(obj, options)); } + dirxml(...args) { this.log(...args); } + + assert(condition, ...args) { + if (!condition) { + this.error('Assertion failed:', ...args); + } + } + + clear() { /* no-op in stub */ } + + count(label = 'default') { + this.#counts.set(label, (this.#counts.get(label) || 0) + 1); + this.log(`${label}: ${this.#counts.get(label)}`); + } + #counts = new Map(); + + countReset(label = 'default') { + this.#counts.delete(label); + } + + group(...args) { this.log(...args); } + groupCollapsed(...args) { this.log(...args); } + groupEnd() { /* no-op */ } + + table(data) { this.log(inspect(data)); } + + time(label = 'default') { + this.#timers.set(label, performance.now()); + } + #timers = new Map(); + + timeEnd(label = 'default') { + const start = this.#timers.get(label); + if (start !== undefined) { + this.log(`${label}: ${(performance.now() - start).toFixed(3)}ms`); + this.#timers.delete(label); + } + } + + timeLog(label = 'default', ...args) { + const start = this.#timers.get(label); + if (start !== undefined) { + this.log(`${label}: ${(performance.now() - start).toFixed(3)}ms`, ...args); + } + } + + trace(...args) { + const err = new Error(); + this.log(...args, '\n', err.stack); + } +} + +export { Console, inspect, createFilteredInspectProxy }; diff --git a/src/ext/web_stub/01_dom_exception.js b/src/ext/web_stub/01_dom_exception.js index 5966cc7..ca65c27 100644 --- a/src/ext/web_stub/01_dom_exception.js +++ b/src/ext/web_stub/01_dom_exception.js @@ -15,7 +15,7 @@ const { } = primordials; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; +import { createFilteredInspectProxy } from "ext:deno_web/01_console.js"; const _name = Symbol("name"); const _message = Symbol("message"); diff --git a/src/ext/web_stub/01_urlpattern.js b/src/ext/web_stub/01_urlpattern.js new file mode 100644 index 0000000..769c4ae --- /dev/null +++ b/src/ext/web_stub/01_urlpattern.js @@ -0,0 +1,64 @@ +// Minimal URLPattern implementation for web_stub +// This is a simplified version that may not support all features + +class URLPattern { + #pattern; + #baseURL; + + constructor(input, baseURL) { + if (typeof input === 'string') { + this.#pattern = input; + this.#baseURL = baseURL; + } else if (typeof input === 'object' && input !== null) { + this.#pattern = input; + this.#baseURL = baseURL; + } else { + throw new TypeError('Invalid URLPattern input'); + } + } + + test(input, baseURL) { + try { + this.exec(input, baseURL); + return true; + } catch { + return false; + } + } + + exec(input, baseURL) { + // Simplified implementation - just check if URL is valid + let url; + if (typeof input === 'string') { + url = new URL(input, baseURL); + } else if (input instanceof URL) { + url = input; + } else { + return null; + } + + // Return a basic result structure + return { + inputs: [input], + protocol: { input: url.protocol.slice(0, -1), groups: {} }, + username: { input: url.username, groups: {} }, + password: { input: url.password, groups: {} }, + hostname: { input: url.hostname, groups: {} }, + port: { input: url.port, groups: {} }, + pathname: { input: url.pathname, groups: {} }, + search: { input: url.search.slice(1), groups: {} }, + hash: { input: url.hash.slice(1), groups: {} }, + }; + } + + get protocol() { return this.#pattern?.protocol ?? '*'; } + get username() { return this.#pattern?.username ?? '*'; } + get password() { return this.#pattern?.password ?? '*'; } + get hostname() { return this.#pattern?.hostname ?? '*'; } + get port() { return this.#pattern?.port ?? '*'; } + get pathname() { return this.#pattern?.pathname ?? '*'; } + get search() { return this.#pattern?.search ?? '*'; } + get hash() { return this.#pattern?.hash ?? '*'; } +} + +export { URLPattern }; diff --git a/src/ext/web_stub/mod.rs b/src/ext/web_stub/mod.rs index 906dfa0..327175d 100644 --- a/src/ext/web_stub/mod.rs +++ b/src/ext/web_stub/mod.rs @@ -17,7 +17,7 @@ extension!( encoding::op_base64_decode, encoding::op_base64_atob, encoding::op_base64_encode, encoding::op_base64_btoa, ], esm_entry_point = "ext:deno_web/init_stub.js", - esm = [ dir "src/ext/web_stub", "init_stub.js", "01_dom_exception.js", "02_timers.js", "05_base64.js" ], + esm = [ dir "src/ext/web_stub", "init_stub.js", "00_url.js", "01_console.js", "01_dom_exception.js", "01_urlpattern.js", "02_timers.js", "05_base64.js" ], state = |state| { state.put(StartTime::default()); } diff --git a/src/ext/websocket/mod.rs b/src/ext/websocket/mod.rs index b561649..d5cf924 100644 --- a/src/ext/websocket/mod.rs +++ b/src/ext/websocket/mod.rs @@ -1,14 +1,6 @@ -use deno_core::{extension, url::Url, Extension}; -use deno_permissions::PermissionCheckError; +use deno_core::{extension, Extension}; -use super::{web::PermissionsContainer, web::WebOptions, ExtensionTrait}; - -impl deno_websocket::WebSocketPermissions for PermissionsContainer { - fn check_net_url(&mut self, url: &Url, api_name: &str) -> Result<(), PermissionCheckError> { - self.0.check_url(url, api_name)?; - Ok(()) - } -} +use super::ExtensionTrait; extension!( init_websocket, @@ -16,24 +8,22 @@ extension!( esm_entry_point = "ext:init_websocket/init_websocket.js", esm = [ dir "src/ext/websocket", "init_websocket.js" ], ); + impl ExtensionTrait<()> for init_websocket { fn init((): ()) -> Extension { init_websocket::init() } } -impl ExtensionTrait for deno_websocket::deno_websocket { - fn init(options: WebOptions) -> Extension { - deno_websocket::deno_websocket::init::( - options.user_agent, - options.root_cert_store_provider, - options.unsafely_ignore_certificate_errors, - ) + +impl ExtensionTrait<()> for deno_websocket::deno_websocket { + fn init((): ()) -> Extension { + deno_websocket::deno_websocket::init() } } -pub fn extensions(options: WebOptions, is_snapshot: bool) -> Vec { +pub fn extensions(is_snapshot: bool) -> Vec { vec![ - deno_websocket::deno_websocket::build(options, is_snapshot), + deno_websocket::deno_websocket::build((), is_snapshot), init_websocket::build((), is_snapshot), ] } diff --git a/src/inner_runtime.rs b/src/inner_runtime.rs index 0da2093..967a14e 100644 --- a/src/inner_runtime.rs +++ b/src/inner_runtime.rs @@ -19,11 +19,24 @@ use tokio_util::sync::CancellationToken; use crate::{ ext, module_loader::{LoaderOptions, RustyLoader}, - traits::{ToDefinedValue, ToModuleSpecifier, ToV8String}, + traits::{ToDefinedValue, ToModuleSpecifier}, transpiler::transpile, utilities, Error, ExtensionOptions, Module, ModuleHandle, }; +fn safe_prepare_stack_trace_callback<'s>( + scope: &mut v8::PinScope<'s, '_>, + error: v8::Local<'s, v8::Value>, + _callsites: v8::Local<'s, v8::Array>, +) -> v8::Local<'s, v8::Value> { + let message = error.to_string(scope).map_or_else( + || "Uncaught Error".to_string(), + |s| s.to_rust_string_lossy(scope), + ); + + v8::String::new(scope, &message).map_or_else(|| v8::undefined(scope).into(), Into::into) +} + /// Wrapper trait to make the `InnerRuntime` generic over the runtime types pub trait RuntimeTrait { fn try_new(options: deno_core::RuntimeOptions) -> Result @@ -82,36 +95,47 @@ impl RsAsyncFunction for F where { } -/// Decodes a set of arguments into a vector of v8 values -/// This is used to pass arguments to a javascript function -/// And is faster and more flexible than using `json_args!` -fn decode_args<'a>( +/// Decodes a set of arguments into a vector of v8 global values +/// This is used for testing argument serialization/deserialization +#[cfg(test)] +fn decode_args_to_globals( args: &impl serde::ser::Serialize, - scope: &mut v8::HandleScope<'a>, -) -> Result>, Error> { - let args = deno_core::serde_v8::to_v8(scope, args)?; - match v8::Local::::try_from(args) { - Ok(args) => { - let len = args.length(); - let mut result = Vec::with_capacity(len as usize); - for i in 0..len { - let index = v8::Integer::new( - scope, - i.try_into().map_err(|_| { - Error::Runtime(format!( - "Could not decode {len} arguments - use `big_json_args`" - )) - })?, - ); - let arg = args - .get(scope, index.into()) - .ok_or_else(|| Error::Runtime(format!("Invalid argument at index {i}")))?; - result.push(arg); + runtime: &mut JsRuntime, +) -> Result>, Error> { + // Serialize to JSON string, then parse in v8 + let json = deno_core::serde_json::to_string(args)?; + + // Use execute_script to parse the JSON and get the result + let script = format!( + "JSON.parse('{}')", + json.replace('\\', "\\\\").replace('\'', "\\'") + ); + let args = runtime.execute_script("", script)?; + + let context = runtime.main_context(); + let isolate = runtime.v8_isolate(); + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned.init(); + let context_local = v8::Local::new(&scope, context); + let context_scope = v8::ContextScope::new(&mut scope, context_local); + let args_local = v8::Local::new(&context_scope, &args); + + // Check if it's an array + if let Ok(arr) = v8::Local::::try_from(args_local) { + let len = arr.length(); + let mut result = Vec::with_capacity(len as usize); + for i in 0..len { + let index = v8::Integer::new(&context_scope, i as i32); + if let Some(arg) = arr.get(&context_scope, index.into()) { + let isolate: &v8::Isolate = &context_scope; + result.push(v8::Global::new(isolate, arg)); } - Ok(result) } - Err(_) if args.is_undefined() || args.is_null() => Ok(vec![]), - Err(_) => Ok(vec![args]), + Ok(result) + } else if args_local.is_undefined() || args_local.is_null() { + Ok(vec![]) + } else { + Ok(vec![args]) } } @@ -260,6 +284,11 @@ impl InnerRuntime { ..Default::default() })?; + deno_runtime + .rt_mut() + .v8_isolate() + .set_prepare_stack_trace_callback(safe_prepare_stack_trace_callback); + let mut feature_checker = FeatureChecker::default(); feature_checker.set_exit_cb(Box::new(|_, _| {})); deno_runtime @@ -454,17 +483,21 @@ impl InnerRuntime { /// # Returns /// A `Result` containing the non-null value extracted or an error (`Error`) pub fn get_global_value(&mut self, name: &str) -> Result, Error> { - let context = self.deno_runtime().main_context(); - let mut scope = self.deno_runtime().handle_scope(); - let global = context.open(&mut scope).global(&mut scope); - - let key = name.to_v8_string(&mut scope)?; - let value = global.get(&mut scope, key.into()); - - match value.if_defined() { - Some(v) => Ok(v8::Global::::new(&mut scope, v)), - _ => Err(Error::ValueNotFound(name.to_string())), + // Use execute_script to get the global value - this avoids scope lifetime issues + let result = self + .deno_runtime() + .execute_script("", name.to_string())?; + + // Check if the value is undefined + let isolate = self.deno_runtime().v8_isolate(); + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned.init(); + let local = v8::Local::new(&scope, &result); + if local.is_undefined() { + return Err(Error::ValueNotFound(name.to_string())); } + + Ok(result) } /// Attempt to get a value out of a module context @@ -483,15 +516,29 @@ impl InnerRuntime { let module_namespace = self .deno_runtime() .get_module_namespace(module_context.id())?; - let mut scope = self.deno_runtime().handle_scope(); - let module_namespace = module_namespace.open(&mut scope); - assert!(module_namespace.is_module_namespace_object()); - let key = name.to_v8_string(&mut scope)?; - let value = module_namespace.get(&mut scope, key.into()); + let context = self.deno_runtime().main_context(); + let isolate = self.deno_runtime().v8_isolate(); + + // Use std::pin::pin! pattern for proper scope management + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned.init(); + let context_local = v8::Local::new(&scope, context); + let context_scope = v8::ContextScope::new(&mut scope, context_local); + + let module_namespace_local = v8::Local::new(&context_scope, module_namespace); + assert!(module_namespace_local.is_module_namespace_object()); + + // Create key string directly using context_scope + let key = v8::String::new(&context_scope, name) + .ok_or_else(|| Error::V8Encoding(name.to_string()))?; + let value = module_namespace_local.get(&context_scope, key.into()); match value.if_defined() { - Some(v) => Ok(v8::Global::::new(&mut scope, v)), + Some(v) => { + let isolate: &v8::Isolate = &context_scope; + Ok(v8::Global::::new(isolate, v)) + } _ => Err(Error::ValueNotFound(name.to_string())), } } @@ -512,9 +559,15 @@ impl InnerRuntime { where T: DeserializeOwned, { - let mut scope = self.deno_runtime().handle_scope(); - let result = v8::Local::::new(&mut scope, value); - Ok(from_v8(&mut scope, result)?) + let context = self.deno_runtime().main_context(); + let isolate = self.deno_runtime().v8_isolate(); + + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + let result = v8::Local::::new(&context_scope, value); + Ok(from_v8(&mut context_scope, result)?) } pub fn get_value_ref( @@ -554,14 +607,18 @@ impl InnerRuntime { let value = self.get_value_ref(module_context, name)?; // Convert it into a function - let mut scope = self.deno_runtime().handle_scope(); - let local_value = v8::Local::::new(&mut scope, value); + let isolate = self.deno_runtime().v8_isolate(); + + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned.init(); + let local_value = v8::Local::::new(&scope, value); let f: v8::Local = local_value .try_into() .or::(Err(Error::ValueNotCallable(name.to_string())))?; // Return it as a global - Ok(v8::Global::::new(&mut scope, f)) + let isolate: &v8::Isolate = &scope; + Ok(v8::Global::::new(isolate, f)) } pub fn call_function_by_ref( @@ -570,8 +627,8 @@ impl InnerRuntime { function: &v8::Global, args: &impl serde::ser::Serialize, ) -> Result, Error> { - // Namespace, if provided - let module_namespace = if let Some(module_context) = module_context { + // Get the receiver (namespace object or undefined) + let receiver = if let Some(module_context) = module_context { Some( self.deno_runtime() .get_module_namespace(module_context.id())?, @@ -580,57 +637,71 @@ impl InnerRuntime { None }; - let mut scope = self.deno_runtime().handle_scope(); - let mut scope = v8::TryCatch::new(&mut scope); + // Get the main context and create scopes + let context = self.deno_runtime().main_context(); + let isolate = self.deno_runtime().v8_isolate(); + + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned.init(); + let context_local = v8::Local::new(&scope, &context); + let context_scope = v8::ContextScope::new(&mut scope, context_local); - // Get the namespace - // Module-level if supplied, none otherwise - let namespace: v8::Local = if let Some(namespace) = module_namespace { - v8::Local::::new(&mut scope, namespace).into() - } else { - // Create a new object to use as the namespace if none is provided - //let obj: v8::Local = v8::Object::new(&mut scope).into(); - let obj: v8::Local = v8::undefined(&mut scope).into(); - obj + // Create local handle for the function + let function_local = v8::Local::new(&context_scope, function); + + // Create the receiver (undefined or module namespace) + let recv: v8::Local = match &receiver { + Some(ns) => v8::Local::new(&context_scope, ns).into(), + None => v8::undefined(&context_scope).into(), }; - let function_instance = function.open(&mut scope); + // Serialize arguments to JSON and parse in JS + // Args should serialize to an array (tuples become arrays in serde_json) + let json_str = deno_core::serde_json::to_string(args)?; - // Prep arguments - let args = decode_args(args, &mut scope)?; + // Handle special case of empty tuple () which serializes to "null" + let args_locals: Vec> = if json_str == "null" || json_str == "[]" { + vec![] + } else { + let escaped = json_str.replace('\\', "\\\\").replace('\'', "\\'"); + let script_source = format!("JSON.parse('{escaped}')"); + let source = v8::String::new(&context_scope, &script_source) + .ok_or_else(|| Error::V8Encoding("Failed to create script source".to_string()))?; + let script = v8::Script::compile(&context_scope, source, None) + .ok_or_else(|| Error::Runtime("Failed to compile JSON parse script".to_string()))?; + let args_value = script + .run(&context_scope) + .ok_or_else(|| Error::Runtime("Failed to parse arguments".to_string()))?; + + // Check if it's an array + if args_value.is_array() { + let args_array: v8::Local = args_value.try_into().unwrap(); + let mut locals = Vec::with_capacity(args_array.length() as usize); + for i in 0..args_array.length() { + if let Some(arg) = args_array.get_index(&context_scope, i) { + locals.push(arg); + } + } + locals + } else { + // Single argument + vec![args_value] + } + }; // Call the function - let result = function_instance.call(&mut scope, namespace, &args); + let result = function_local.call(&context_scope, recv, &args_locals); + + // Handle the result match result { Some(value) => { - let value = v8::Global::new(&mut scope, value); - Ok(value) + let isolate: &v8::Isolate = &context_scope; + Ok(v8::Global::new(isolate, value)) } - None if scope.has_caught() => { - let e = scope - .message() - .ok_or_else(|| Error::Runtime("Unknown error".to_string()))?; - - let filename = e.get_script_resource_name(&mut scope); - let linenumber = e.get_line_number(&mut scope).unwrap_or_default(); - let filename = if let Some(v) = filename { - let filename = v.to_rust_string_lossy(&mut scope); - format!("{filename}:{linenumber}: ") - } else if let Some(module_context) = module_context { - let filename = module_context.module().filename().to_string_lossy(); - format!("{filename}:{linenumber}: ") - } else { - String::new() - }; - - let msg = e.get(&mut scope).to_rust_string_lossy(&mut scope); - - let s = format!("{filename}{msg}"); - Err(Error::Runtime(s)) + None => { + // Function call failed (likely an exception was thrown) + Err(Error::Runtime("Function call failed".to_string())) } - None => Err(Error::Runtime( - "Unknown error during function execution".to_string(), - )), } } @@ -699,11 +770,15 @@ impl InnerRuntime { // Try to get an entrypoint from the default export next if let Ok(default_export) = self.get_module_export_value(module_context, "default") { - let mut scope = self.deno_runtime().handle_scope(); - let default_export = v8::Local::new(&mut scope, default_export); + let isolate = self.deno_runtime().v8_isolate(); + + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned.init(); + let default_export = v8::Local::new(&scope, default_export); if default_export.is_function() { if let Ok(f) = v8::Local::::try_from(default_export) { - return Ok(Some(v8::Global::new(&mut scope, f))); + let isolate: &v8::Isolate = &scope; + return Ok(Some(v8::Global::new(isolate, f))); } } } @@ -740,6 +815,7 @@ impl InnerRuntime { // Get additional modules first for side_module in side_modules { let module_specifier = side_module.filename().to_module_specifier(&self.cwd)?; + self.module_loader.whitelist_add(&module_specifier); let (code, sourcemap) = transpile(&module_specifier, side_module.contents())?; // Now CJS translation, for node @@ -772,6 +848,7 @@ impl InnerRuntime { // Load main module if let Some(module) = main_module { let module_specifier = module.filename().to_module_specifier(&self.cwd)?; + self.module_loader.whitelist_add(&module_specifier); let (code, sourcemap) = transpile(&module_specifier, module.contents())?; // Now CJS translation, for node @@ -856,43 +933,47 @@ mod test_inner_runtime { let mut runtime = InnerRuntime::::new(RuntimeOptions::default(), CancellationToken::new()) .expect("Could not load runtime"); - let mut scope = runtime.deno_runtime.handle_scope(); // empty - let args = decode_args(&json_args!(), &mut scope).expect("Could not decode args"); + let args = decode_args_to_globals(&json_args!(), &mut runtime.deno_runtime) + .expect("Could not decode args"); assert_eq!(args.len(), 0); // single - let args = decode_args(&json_args!(2), &mut scope).expect("Could not decode args"); + let args = decode_args_to_globals(&json_args!(2), &mut runtime.deno_runtime) + .expect("Could not decode args"); assert_eq!(args.len(), 1); // single raw - let args = decode_args(&2, &mut scope).expect("Could not decode args"); + let args = + decode_args_to_globals(&2, &mut runtime.deno_runtime).expect("Could not decode args"); assert_eq!(args.len(), 1); // multiple heterogeneous - let args = decode_args(&json_args!(2, "test"), &mut scope).expect("Could not decode args"); + let args = decode_args_to_globals(&json_args!(2, "test"), &mut runtime.deno_runtime) + .expect("Could not decode args"); assert_eq!(args.len(), 2); // multiple homogeneous - let args = decode_args(&json_args!(2, 3), &mut scope).expect("Could not decode args"); + let args = decode_args_to_globals(&json_args!(2, 3), &mut runtime.deno_runtime) + .expect("Could not decode args"); assert_eq!(args.len(), 2); // 16 args - let args = decode_args( + let args = decode_args_to_globals( &(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - &mut scope, + &mut runtime.deno_runtime, ) .expect("Could not decode args"); assert_eq!(args.len(), 16); // 32 args - let args = decode_args( + let args = decode_args_to_globals( &big_json_args!( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ), - &mut scope, + &mut runtime.deno_runtime, ) .expect("Could not decode args"); assert_eq!(args.len(), 32); @@ -1317,9 +1398,8 @@ mod test_inner_runtime { .decode_value(structure) .expect("Could not deserialize"); - let function = structure - .func - .as_global(&mut runtime.deno_runtime().handle_scope()); + let isolate = runtime.deno_runtime().v8_isolate(); + let function = structure.func.as_global(isolate); run_async_task(|| async move { let value = runtime diff --git a/src/js_value.rs b/src/js_value.rs index e39f261..9784dbb 100644 --- a/src/js_value.rs +++ b/src/js_value.rs @@ -3,10 +3,7 @@ //! //! [Function] and [Promise] are both specializations of [Value] providing deserialize-time type checking //! and additional utility functions for interacting with the runtime -use deno_core::{ - serde_v8::GlobalValue, - v8::{self, HandleScope}, -}; +use deno_core::{serde_v8::GlobalValue, v8}; use serde::Deserialize; /// A macro to implement the common functions for [Function], [Promise], and [Value] @@ -40,14 +37,16 @@ macro_rules! impl_v8 { /// Will return an error if the value is the wrong type /// For `Value`, this check cannot fail pub fn try_from_v8<'a, H>( - scope: &mut v8::HandleScope<'a>, + scope: &mut v8::PinScope<'a, '_>, value: v8::Global, ) -> Result where v8::Local<'a, v8::Value>: From>, { let local: v8::Local = v8::Local::new(scope, value).into(); - v8::Global::new(scope, local).try_into() + // Get isolate reference from the scope using Deref + let isolate: &v8::Isolate = scope; + v8::Global::new(isolate, local).try_into() } /// Creates a new instance of this struct from a global value @@ -161,23 +160,35 @@ pub(crate) struct V8Value( impl V8Value { /// Returns the underlying global as a local in the type configured by the type checker - pub(crate) fn as_local<'a>(&self, scope: &mut HandleScope<'a>) -> v8::Local<'a, T::Output> + pub(crate) fn as_local<'a, 'i, C>( + &self, + scope: &v8::PinnedRef<'a, v8::HandleScope<'i, C>>, + ) -> v8::Local<'a, T::Output> where v8::Local<'a, T::Output>: TryFrom>, { - let local = v8::Local::new(scope, &self.0); + // SAFETY: v8::Local::new requires HandleScope<'_, ()> but works with any context type. + // The context parameter is a phantom type marker and doesn't affect memory layout. + // We transmute the scope reference to the required type for the API call. + let scope_ref = unsafe { + &*std::ptr::from_ref(scope).cast::>>() + }; + let local = v8::Local::::new(scope_ref, &self.0); v8::Local::<'a, T::Output>::try_from(local) .ok() .expect("Failed to convert V8Value: Invalid V8TypeChecker!") } /// Returns the underlying global in the type configured by the type checker - pub(crate) fn as_global<'a>(&self, scope: &mut HandleScope<'a>) -> v8::Global + /// Note: This performs an unchecked cast - the type checker should have validated the type + pub(crate) fn as_global(&self, _isolate: &v8::Isolate) -> v8::Global where - v8::Local<'a, T::Output>: TryFrom>, + T::Output: 'static, { - let local = self.as_local(scope); - v8::Global::new(scope, local) + // SAFETY: The type checker should have validated that self.0 is of the correct type + // We use transmute to convert v8::Global to v8::Global + // This is safe because v8::Global is just a pointer wrapper + unsafe { std::mem::transmute(self.0.clone()) } } } @@ -211,9 +222,14 @@ impl Value { where T: serde::de::DeserializeOwned, { - let mut scope = runtime.deno_runtime().handle_scope(); - let local = self.0.as_local(&mut scope); - Ok(deno_core::serde_v8::from_v8(&mut scope, local)?) + let context = runtime.deno_runtime().main_context(); + let isolate = runtime.deno_runtime().v8_isolate(); + let scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = scope.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + let local = self.0.as_local(&context_scope); + Ok(deno_core::serde_v8::from_v8(&mut context_scope, local)?) } /// Contructs a new Value from a `v8::Value` global @@ -253,17 +269,30 @@ mod test { let mut runtime = Runtime::new(RuntimeOptions::default()).unwrap(); let handle = runtime.load_module(&module).unwrap(); + // Test basic value extraction let f: Value = runtime.get_value(Some(&handle), "f").unwrap(); let value: usize = f.try_into(&mut runtime).unwrap(); assert_eq!(value, 42); + // Test function extraction and conversion let g: Value = runtime.get_value(Some(&handle), "g").unwrap(); let global = g.into_v8(); - let _f = Function::try_from_v8(&mut runtime.deno_runtime().handle_scope(), global.clone()) - .unwrap(); - let f = unsafe { Function::from_v8_unchecked(global) }; - let _f = f - .into_inner() - .as_local(&mut runtime.deno_runtime().handle_scope()); + + // Test try_from_v8 with proper context scope + let context = runtime.deno_runtime().main_context(); + let isolate = runtime.deno_runtime().v8_isolate(); + let pinned = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + + // Test that we can create a Function from the global + let _f = Function::try_from_v8(&mut context_scope, global.clone()).unwrap(); + + // Test from_v8_unchecked + let f = unsafe { Function::from_v8_unchecked(global.clone()) }; + + // Test as_local with context scope + let _local = f.into_inner().as_local(&context_scope); } } diff --git a/src/js_value/function.rs b/src/js_value/function.rs index c1d4f16..1ae496e 100644 --- a/src/js_value/function.rs +++ b/src/js_value/function.rs @@ -1,4 +1,4 @@ -use deno_core::v8::{self, HandleScope}; +use deno_core::v8; use serde::Deserialize; use super::V8Value; @@ -13,8 +13,8 @@ impl_checker!(FunctionTypeChecker, Function, is_function, |e| { }); impl Function { - pub(crate) fn as_global(&self, scope: &mut HandleScope<'_>) -> v8::Global { - self.0.as_global(scope) + pub(crate) fn as_global(&self, isolate: &v8::Isolate) -> v8::Global { + self.0.as_global(isolate) } /// Returns true if the function is async diff --git a/src/js_value/map.rs b/src/js_value/map.rs index f047393..6d234ef 100644 --- a/src/js_value/map.rs +++ b/src/js_value/map.rs @@ -1,4 +1,4 @@ -use deno_core::v8::{self, GetPropertyNamesArgs, HandleScope}; +use deno_core::v8::{self, GetPropertyNamesArgs}; use serde::Deserialize; use super::V8Value; @@ -21,8 +21,14 @@ impl Map { /// Gets a value from the map /// Warning: If a key is not valid UTF-8, the value may be inaccessible pub fn get(&self, key: &str, runtime: &mut crate::Runtime) -> Option { - let mut scope = runtime.deno_runtime().handle_scope(); - self.get_property_by_name(&mut scope, key) + let deno_runtime = runtime.deno_runtime(); + let context = deno_runtime.main_context(); + let isolate = deno_runtime.v8_isolate(); + let handle_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut handle_scope = handle_scope.init(); + let context_local = v8::Local::new(&handle_scope, context); + let mut context_scope = v8::ContextScope::new(&mut handle_scope, context_local); + self.get_property_by_name_impl(&mut context_scope, key) } /// Converts the map to a hashmap @@ -31,33 +37,51 @@ impl Map { &self, runtime: &mut crate::Runtime, ) -> std::collections::HashMap { - let mut scope = runtime.deno_runtime().handle_scope(); - self.to_rust_hashmap(&mut scope) + let deno_runtime = runtime.deno_runtime(); + let context = deno_runtime.main_context(); + let isolate = deno_runtime.v8_isolate(); + let handle_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut handle_scope = handle_scope.init(); + let context_local = v8::Local::new(&handle_scope, context); + let mut context_scope = v8::ContextScope::new(&mut handle_scope, context_local); + self.to_rust_hashmap_impl(&mut context_scope) } /// Returns the keys of the map /// Warning: If a key is not valid UTF-8, the value may be inaccessible pub fn keys(&self, runtime: &mut crate::Runtime) -> Vec { - let mut scope = runtime.deno_runtime().handle_scope(); - self.get_string_keys(&mut scope) + let deno_runtime = runtime.deno_runtime(); + let context = deno_runtime.main_context(); + let isolate = deno_runtime.v8_isolate(); + let handle_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut handle_scope = handle_scope.init(); + let context_local = v8::Local::new(&handle_scope, context); + let mut context_scope = v8::ContextScope::new(&mut handle_scope, context_local); + self.get_string_keys_impl(&mut context_scope) } /// Returns the number of keys in the map /// Skips any keys that are not valid UTF-8 pub fn len(&self, runtime: &mut crate::Runtime) -> usize { - let mut scope = runtime.deno_runtime().handle_scope(); - self.get_string_keys(&mut scope).len() + let deno_runtime = runtime.deno_runtime(); + let context = deno_runtime.main_context(); + let isolate = deno_runtime.v8_isolate(); + let handle_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut handle_scope = handle_scope.init(); + let context_local = v8::Local::new(&handle_scope, context); + let mut context_scope = v8::ContextScope::new(&mut handle_scope, context_local); + self.get_string_keys_impl(&mut context_scope).len() } - pub(crate) fn to_rust_hashmap( + fn to_rust_hashmap_impl( &self, - scope: &mut HandleScope, + scope: &mut v8::ContextScope, ) -> std::collections::HashMap { - let keys = self.get_string_keys(scope); + let keys = self.get_string_keys_impl(scope); let mut map = std::collections::HashMap::new(); for name in keys { - match self.get_property_by_name(scope, &name) { + match self.get_property_by_name_impl(scope, &name) { Some(value) => map.insert(name, value), None => None, }; @@ -66,20 +90,21 @@ impl Map { map } - pub(crate) fn get_property_by_name( + fn get_property_by_name_impl( &self, - scope: &mut HandleScope, + scope: &mut v8::ContextScope, name: &str, ) -> Option { let local = self.0.as_local(scope); let key = v8::String::new(scope, name).unwrap(); let value = local.get(scope, key.into())?; - let value = v8::Global::new(scope, value); + let isolate: &v8::Isolate = scope; + let value = v8::Global::new(isolate, value); Some(crate::js_value::Value::from_v8(value)) } - pub(crate) fn get_string_keys(&self, scope: &mut HandleScope) -> Vec { + fn get_string_keys_impl(&self, scope: &mut v8::ContextScope) -> Vec { let local = self.0.as_local(scope); let mut keys = vec![]; diff --git a/src/js_value/promise.rs b/src/js_value/promise.rs index a09471b..154b287 100644 --- a/src/js_value/promise.rs +++ b/src/js_value/promise.rs @@ -33,9 +33,14 @@ where let result = runtime .with_event_loop_future(future, PollEventLoopOptions::default()) .await?; - let mut scope = runtime.handle_scope(); - let local = v8::Local::new(&mut scope, &result); - Ok(deno_core::serde_v8::from_v8(&mut scope, local)?) + let context = runtime.main_context(); + let isolate = runtime.v8_isolate(); + let scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = scope.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + let local = v8::Local::new(&context_scope, &result); + Ok(deno_core::serde_v8::from_v8(&mut context_scope, local)?) } /// Returns a future that resolves the promise @@ -58,8 +63,13 @@ where /// Checks if the promise is pending or already resolved pub fn is_pending(&self, runtime: &mut crate::Runtime) -> bool { - let mut scope = runtime.deno_runtime().handle_scope(); - let value = self.0.as_local(&mut scope); + let context = runtime.deno_runtime().main_context(); + let isolate = runtime.deno_runtime().v8_isolate(); + let scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = scope.init(); + let context_local = v8::Local::new(&scope, context); + let context_scope = v8::ContextScope::new(&mut scope, context_local); + let value = self.0.as_local(&context_scope); value.state() == v8::PromiseState::Pending } @@ -67,19 +77,24 @@ where /// or `Poll::Ready(Ok(T))` if the promise is resolved /// or `Poll::Ready(Err(Error))` if the promise is rejected pub fn poll_promise(&self, runtime: &mut crate::Runtime) -> std::task::Poll> { - let mut scope = runtime.deno_runtime().handle_scope(); - let value = self.0.as_local(&mut scope); + let context = runtime.deno_runtime().main_context(); + let isolate = runtime.deno_runtime().v8_isolate(); + let scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = scope.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + let value = self.0.as_local(&context_scope); match value.state() { PromiseState::Pending => std::task::Poll::Pending, PromiseState::Rejected => { - let error = value.result(&mut scope); - let error = deno_core::error::JsError::from_v8_exception(&mut scope, error); + let error = value.result(&context_scope); + let error = deno_core::error::JsError::from_v8_exception(&mut context_scope, error); std::task::Poll::Ready(Err(error.into())) } PromiseState::Fulfilled => { - let result = value.result(&mut scope); - match deno_core::serde_v8::from_v8::(&mut scope, result) { + let result = value.result(&context_scope); + match deno_core::serde_v8::from_v8::(&mut context_scope, result) { Ok(value) => std::task::Poll::Ready(Ok(value)), Err(e) => std::task::Poll::Ready(Err(e.into())), } diff --git a/src/js_value/string.rs b/src/js_value/string.rs index 9958b08..e7c749a 100644 --- a/src/js_value/string.rs +++ b/src/js_value/string.rs @@ -1,4 +1,4 @@ -use deno_core::v8::{self, HandleScope, WriteFlags}; +use deno_core::v8::{self, WriteFlags}; use serde::Deserialize; use super::V8Value; @@ -16,8 +16,10 @@ impl String { /// Converts the string to a rust string /// Potentially lossy, if the string contains orphan UTF-16 surrogates pub fn to_string_lossy(&self, runtime: &mut crate::Runtime) -> std::string::String { - let mut scope = runtime.deno_runtime().handle_scope(); - self.to_rust_string_lossy(&mut scope) + let isolate = runtime.deno_runtime().v8_isolate(); + let pinned_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned_scope.init(); + self.to_rust_string_lossy(&scope) } /// Converts the string to a rust string @@ -31,37 +33,56 @@ impl String { /// Converts the string to a UTF-8 character buffer in the form of a `Vec` /// Excludes the null terminator pub fn to_utf8_bytes(&self, runtime: &mut crate::Runtime) -> Vec { - let mut scope = runtime.deno_runtime().handle_scope(); - self.to_utf8_buffer(&mut scope) + let isolate = runtime.deno_runtime().v8_isolate(); + let pinned_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned_scope.init(); + self.to_utf8_buffer(&scope) } /// Converts the string to a UTF-16 character buffer in the form of a `Vec` /// Excludes the null terminator pub fn to_utf16_bytes(&self, runtime: &mut crate::Runtime) -> Vec { - let mut scope = runtime.deno_runtime().handle_scope(); - self.to_utf16_buffer(&mut scope) + let isolate = runtime.deno_runtime().v8_isolate(); + let pinned_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let scope = pinned_scope.init(); + self.to_utf16_buffer(&scope) } - pub(crate) fn to_rust_string_lossy(&self, scope: &mut HandleScope<'_>) -> std::string::String { + pub(crate) fn to_rust_string_lossy( + &self, + scope: &v8::PinnedRef<'_, v8::HandleScope<'_, C>>, + ) -> std::string::String { let local = self.0.as_local(scope); - local.to_rust_string_lossy(scope) + // SAFETY: v8::String::to_rust_string_lossy requires &Isolate. PinnedRef can be transmuted to &Isolate. + let isolate = unsafe { &*std::ptr::from_ref(scope).cast::() }; + local.to_rust_string_lossy(isolate) } - pub(crate) fn to_utf16_buffer(&self, scope: &mut HandleScope<'_>) -> Vec { + pub(crate) fn to_utf16_buffer( + &self, + scope: &v8::PinnedRef<'_, v8::HandleScope<'_, C>>, + ) -> Vec { let local = self.0.as_local(scope); let u16_len = local.length(); let mut buffer = vec![0; u16_len]; - local.write_v2(scope, 0, &mut buffer, WriteFlags::empty()); + // SAFETY: v8 methods may require &Isolate. PinnedRef can be transmuted to &Isolate. + let isolate = unsafe { &*std::ptr::from_ref(scope).cast::() }; + local.write_v2(isolate, 0, &mut buffer, WriteFlags::empty()); buffer } - pub(crate) fn to_utf8_buffer(&self, scope: &mut HandleScope<'_>) -> Vec { + pub(crate) fn to_utf8_buffer( + &self, + scope: &v8::PinnedRef<'_, v8::HandleScope<'_, C>>, + ) -> Vec { let local = self.0.as_local(scope); - let u8_len = local.utf8_length(scope); + // SAFETY: v8 methods may require &Isolate. PinnedRef can be transmuted to &Isolate. + let isolate = unsafe { &*std::ptr::from_ref(scope).cast::() }; + let u8_len = local.utf8_length(isolate); let mut buffer = vec![0; u8_len]; - local.write_utf8_v2(scope, &mut buffer, WriteFlags::empty(), None); + local.write_utf8_v2(isolate, &mut buffer, WriteFlags::empty(), None); buffer } } diff --git a/src/lib.rs b/src/lib.rs index 8486945..801a188 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -421,9 +421,16 @@ pub use module_wrapper::ModuleWrapper; pub use runtime::{Runtime, RuntimeOptions, Undefined}; pub use utilities::{evaluate, import, init_platform, resolve_path, validate}; +// Deprecated traits for backward compatibility +#[allow(deprecated)] +#[deprecated(since = "0.8.0", note = "Use v8::String::new() directly")] +pub use traits::ToV8String; + #[cfg(feature = "broadcast_channel")] #[cfg_attr(docsrs, doc(cfg(feature = "broadcast_channel")))] -pub use ext::broadcast_channel::BroadcastChannelWrapper; +pub use ext::broadcast_channel::{ + BroadcastChannelWrapper, IsolatedBroadcastChannel, IsolatedBroadcastChannelWrapper, +}; #[cfg(feature = "web")] #[cfg_attr(docsrs, doc(cfg(feature = "web")))] diff --git a/src/module_loader.rs b/src/module_loader.rs index d5ecacd..3751cae 100644 --- a/src/module_loader.rs +++ b/src/module_loader.rs @@ -35,6 +35,10 @@ impl RustyLoader { self.inner_mut().set_current_dir(current_dir); } + pub fn whitelist_add(&self, specifier: &ModuleSpecifier) { + self.inner_mut().whitelist_add(specifier.as_str()); + } + fn inner(&self) -> std::cell::Ref<'_, InnerRustyLoader> { self.inner.borrow() } @@ -90,18 +94,11 @@ impl ModuleLoader for RustyLoader { fn load( &self, module_specifier: &ModuleSpecifier, - maybe_referrer: Option<&ModuleSpecifier>, - is_dyn_import: bool, - requested_module_type: deno_core::RequestedModuleType, + maybe_referrer: Option<&deno_core::ModuleLoadReferrer>, + options: deno_core::ModuleLoadOptions, ) -> deno_core::ModuleLoadResponse { let inner = self.inner.clone(); - InnerRustyLoader::load( - inner, - module_specifier, - maybe_referrer, - is_dyn_import, - requested_module_type, - ) + InnerRustyLoader::load(inner, module_specifier, maybe_referrer, options) } fn get_source_map(&self, file_name: &str) -> Option> { @@ -167,8 +164,11 @@ mod test { let response = loader.load( &specifier, None, - false, - deno_core::RequestedModuleType::None, + deno_core::ModuleLoadOptions { + is_dynamic_import: false, + is_synchronous: false, + requested_module_type: deno_core::RequestedModuleType::None, + }, ); match response { ModuleLoadResponse::Async(_) => panic!("Unexpected response"), @@ -218,7 +218,6 @@ mod test { specifier: &ModuleSpecifier, _referrer: Option<&ModuleSpecifier>, _is_dyn_import: bool, - _requested_module_type: deno_core::RequestedModuleType, ) -> Option> { match specifier.as_str() { "test://1" => Some(Ok("console.log('Rock')".to_string())), @@ -249,8 +248,11 @@ mod test { let response = loader.load( &specifier, None, - false, - deno_core::RequestedModuleType::None, + deno_core::ModuleLoadOptions { + is_dynamic_import: false, + is_synchronous: false, + requested_module_type: deno_core::RequestedModuleType::None, + }, ); match response { ModuleLoadResponse::Async(future) => { @@ -266,4 +268,62 @@ mod test { } } } + + /// Test backward compatibility for ImportProvider trait + #[test] + fn test_import_provider_backward_compat() { + use deno_core::RequestedModuleType; + + // Test provider that uses the old deprecated API + struct OldStyleProvider; + impl ImportProvider for OldStyleProvider { + // Override the old method + #[allow(deprecated)] + fn import_with_type( + &mut self, + specifier: &ModuleSpecifier, + _referrer: Option<&ModuleSpecifier>, + _is_dyn_import: bool, + _requested_module_type: RequestedModuleType, + ) -> Option> { + match specifier.as_str() { + "test://old" => Some(Ok("console.log('old style')".to_string())), + _ => None, + } + } + } + + // Test provider that uses the new API + struct NewStyleProvider; + impl ImportProvider for NewStyleProvider { + fn import( + &mut self, + specifier: &ModuleSpecifier, + _referrer: Option<&ModuleSpecifier>, + _is_dyn_import: bool, + ) -> Option> { + match specifier.as_str() { + "test://new" => Some(Ok("console.log('new style')".to_string())), + _ => None, + } + } + } + + // Both should work + let mut old_provider = OldStyleProvider; + let mut new_provider = NewStyleProvider; + + let spec_old = ModuleSpecifier::parse("test://old").unwrap(); + let spec_new = ModuleSpecifier::parse("test://new").unwrap(); + + // Old style provider should work via the new interface + let result = old_provider.import(&spec_old, None, false); + assert!(result.is_some()); + assert_eq!(result.unwrap().unwrap(), "console.log('old style')"); + + // New style provider should work + let result = new_provider.import(&spec_new, None, false); + assert!(result.is_some()); + assert_eq!(result.unwrap().unwrap(), "console.log('new style')"); + } } diff --git a/src/module_loader/import_provider.rs b/src/module_loader/import_provider.rs index 8e23303..cef092d 100644 --- a/src/module_loader/import_provider.rs +++ b/src/module_loader/import_provider.rs @@ -29,11 +29,13 @@ pub trait ImportProvider { /// Retrieve a JavaScript/TypeScript module from a given URL and return it as a string. /// + /// This is the new version without the `requested_module_type` parameter. + /// For backward compatibility, this method calls `import_with_type` by default. + /// /// # Arguments /// - `specifier`: The module specifier to import, as an absolute URL /// - `referrer`: The URL of the module that is importing the specifier /// - `is_dyn_import`: Whether the import is a dynamic import or not - /// - `requested_module_type`: The type of module being requested /// /// # Returns /// - Some(Ok(String)): The module source code as a string @@ -44,9 +46,59 @@ pub trait ImportProvider { specifier: &ModuleSpecifier, referrer: Option<&ModuleSpecifier>, is_dyn_import: bool, - requested_module_type: RequestedModuleType, ) -> Option> { - None + // Call the old method for backward compatibility + #[allow(deprecated)] + self.import_with_type( + specifier, + referrer, + is_dyn_import, + RequestedModuleType::None, + ) + } + + /// Retrieve a JavaScript/TypeScript module from a given URL (deprecated version) + /// + /// **DEPRECATED**: Use `import()` instead. The `requested_module_type` parameter is no longer used by the runtime. + /// + /// This method is kept for backward compatibility. Existing implementations should migrate to the new `import()` method. + /// + /// # Migration Guide + /// ```rust,ignore + /// // Old implementation: + /// fn import_with_type( + /// &mut self, + /// specifier: &ModuleSpecifier, + /// referrer: Option<&ModuleSpecifier>, + /// is_dyn_import: bool, + /// requested_module_type: RequestedModuleType, + /// ) -> Option> { + /// // your implementation + /// } + /// + /// // New implementation (just rename and remove the last parameter): + /// fn import( + /// &mut self, + /// specifier: &ModuleSpecifier, + /// referrer: Option<&ModuleSpecifier>, + /// is_dyn_import: bool, + /// ) -> Option> { + /// // same implementation, don't use requested_module_type + /// } + /// ``` + #[deprecated( + since = "0.8.0", + note = "Use `import()` instead. The `requested_module_type` parameter is ignored by the runtime." + )] + fn import_with_type( + &mut self, + specifier: &ModuleSpecifier, + referrer: Option<&ModuleSpecifier>, + is_dyn_import: bool, + _requested_module_type: RequestedModuleType, + ) -> Option> { + // Call the new method (ignore requested_module_type) + self.import(specifier, referrer, is_dyn_import) } /// Apply an optional transform to the source code after it has been imported diff --git a/src/module_loader/inner_loader.rs b/src/module_loader/inner_loader.rs index 04846b7..d73532a 100644 --- a/src/module_loader/inner_loader.rs +++ b/src/module_loader/inner_loader.rs @@ -274,12 +274,12 @@ impl InnerRustyLoader { pub fn load( inner: Rc>, module_specifier: &ModuleSpecifier, - maybe_referrer: Option<&ModuleSpecifier>, - is_dyn_import: bool, - requested_module_type: deno_core::RequestedModuleType, + maybe_referrer: Option<&deno_core::ModuleLoadReferrer>, + options: deno_core::ModuleLoadOptions, ) -> deno_core::ModuleLoadResponse { let module_specifier = module_specifier.clone(); - let maybe_referrer = maybe_referrer.cloned(); + let maybe_referrer_url = maybe_referrer.map(|r| r.specifier.clone()); + let is_dyn_import = options.is_dynamic_import; // Check if the module is in the cache first if let Some(cache) = &inner.borrow().cache_provider { @@ -292,9 +292,8 @@ impl InnerRustyLoader { let provider_result = inner.borrow_mut().import_provider.as_mut().and_then(|p| { p.import( &module_specifier, - maybe_referrer.as_ref(), + maybe_referrer_url.as_ref(), is_dyn_import, - requested_module_type, ) }); if let Some(result) = provider_result { diff --git a/src/module_wrapper.rs b/src/module_wrapper.rs index 2085641..bf88805 100644 --- a/src/module_wrapper.rs +++ b/src/module_wrapper.rs @@ -1,4 +1,4 @@ -use deno_core::{serde_json, v8::GetPropertyNamesArgs}; +use deno_core::{serde_json, v8, v8::GetPropertyNamesArgs}; use crate::{js_value::Function, Error, Module, ModuleHandle, Runtime, RuntimeOptions}; @@ -279,7 +279,7 @@ impl ModuleWrapper { .call_stored_function_immediate(Some(&self.module_context), function, args) } - /// Retrieves the names of the module's exports. + /// Retrieves the names of the module's exports. /// (Keys that are not valid UTF-8, may not work as intended due to encoding issues) /// /// # Returns @@ -291,15 +291,21 @@ impl ModuleWrapper { .deno_runtime() .get_module_namespace(self.module_context.id()) { - let mut scope = self.runtime.deno_runtime().handle_scope(); - let global = namespace.open(&mut scope); + let context = self.runtime.deno_runtime().main_context(); + let isolate = self.runtime.deno_runtime().v8_isolate(); + let pinned_scope = std::pin::pin!(v8::HandleScope::new(isolate)); + let mut scope = pinned_scope.init(); + let context_local = v8::Local::new(&scope, context); + let mut context_scope = v8::ContextScope::new(&mut scope, context_local); + + let global = v8::Local::new(&context_scope, namespace); if let Some(keys_obj) = - global.get_property_names(&mut scope, GetPropertyNamesArgs::default()) + global.get_property_names(&context_scope, GetPropertyNamesArgs::default()) { for i in 0..keys_obj.length() { - if let Ok(key_index) = deno_core::serde_v8::to_v8(&mut scope, i) { - if let Some(key_name_v8) = keys_obj.get(&mut scope, key_index) { - let name = key_name_v8.to_rust_string_lossy(&mut scope); + if let Ok(key_index) = deno_core::serde_v8::to_v8(&mut context_scope, i) { + if let Some(key_name_v8) = keys_obj.get(&context_scope, key_index) { + let name = key_name_v8.to_rust_string_lossy(&context_scope); keys.push(name); } } diff --git a/src/runtime.rs b/src/runtime.rs index a5be900..10d5c1f 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -46,7 +46,7 @@ impl Runtime { /// A `Result` containing either the initialized runtime instance on success (`Ok`) or an error on failure (`Err`). /// /// # Example - /// ```rust + /// ```no_run /// use rustyscript::{ json_args, Runtime, RuntimeOptions, Module }; /// use std::time::Duration; /// @@ -230,7 +230,7 @@ impl Runtime { } /// Remove and return a value from the state, if one exists - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime }; /// /// # fn main() -> Result<(), rustyscript::Error> { @@ -254,7 +254,7 @@ impl Runtime { /// # Errors /// Can fail if the inner state cannot be borrowed mutably /// - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime }; /// /// # fn main() -> Result<(), rustyscript::Error> { @@ -278,7 +278,7 @@ impl Runtime { /// # Errors /// Since this function borrows the state, it can fail if the state cannot be borrowed mutably /// - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime, Module, serde_json::Value }; /// /// # fn main() -> Result<(), rustyscript::Error> { @@ -307,7 +307,7 @@ impl Runtime { /// # Errors /// Since this function borrows the state, it can fail if the state cannot be borrowed mutably /// - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime, Module, serde_json::Value, async_callback, Error }; /// /// # fn main() -> Result<(), rustyscript::Error> { @@ -358,7 +358,7 @@ impl Runtime { /// Can fail if the expression cannot be evaluated, or if the result cannot be deserialized into the requested type /// /// # Example - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime, Error }; /// /// # fn main() -> Result<(), Error> { @@ -491,7 +491,8 @@ impl Runtime { where T: serde::de::DeserializeOwned, { - let function = function.as_global(&mut self.deno_runtime().handle_scope()); + let isolate = self.deno_runtime().v8_isolate(); + let function = function.as_global(isolate); let result = self .inner .call_function_by_ref(module_context, &function, args)?; @@ -564,7 +565,8 @@ impl Runtime { where T: deno_core::serde::de::DeserializeOwned, { - let function = function.as_global(&mut self.deno_runtime().handle_scope()); + let isolate = self.deno_runtime().v8_isolate(); + let function = function.as_global(isolate); let result = self .inner .call_function_by_ref(module_context, &function, args)?; @@ -633,7 +635,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{ json_args, Runtime, Module, Error }; /// /// # fn main() -> Result<(), Error> { @@ -682,7 +684,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{ json_args, Runtime, Module, Error }; /// /// # fn main() -> Result<(), Error> { @@ -728,7 +730,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime, Module, Error }; /// /// # fn main() -> Result<(), Error> { @@ -800,7 +802,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{ Runtime, Module, Error }; /// /// # fn main() -> Result<(), Error> { @@ -842,7 +844,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// // Create a module with filename and contents /// use rustyscript::{Runtime, Module, Error}; /// @@ -908,7 +910,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// // Create a module with filename and contents /// use rustyscript::{Runtime, Module, Error}; /// @@ -983,7 +985,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{json_args, Runtime, Module, Error}; /// /// # fn main() -> Result<(), Error> { @@ -1069,7 +1071,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// use rustyscript::{json_args, Runtime, Module, Error}; /// /// # fn main() -> Result<(), Error> { @@ -1122,7 +1124,7 @@ impl Runtime { /// /// # Example /// - /// ```rust + /// ```no_run /// // Create a module with filename and contents /// use rustyscript::{json_args, Runtime, Module, Error}; /// diff --git a/src/runtime_builder.rs b/src/runtime_builder.rs index 84abd5a..8cb5a2a 100644 --- a/src/runtime_builder.rs +++ b/src/runtime_builder.rs @@ -5,7 +5,7 @@ use crate::{module_loader::ImportProvider, Error, RuntimeOptions}; /// Just a helper wrapper around `RuntimeOptions` for `Runtime` and `SnapshotBuilder` /// /// # Example -/// ```rust +/// ```no_run /// use rustyscript::RuntimeBuilder; /// /// let runtime = RuntimeBuilder::new() @@ -162,10 +162,7 @@ impl RuntimeBuilder { #[cfg(feature = "broadcast_channel")] #[cfg_attr(docsrs, doc(cfg(feature = "broadcast_channel")))] #[must_use] - pub fn with_broadcast_channel( - mut self, - channel: deno_broadcast_channel::InMemoryBroadcastChannel, - ) -> Self { + pub fn with_broadcast_channel(mut self, channel: deno_web::InMemoryBroadcastChannel) -> Self { self.0.extension_options.broadcast_channel = channel; self } diff --git a/src/traits.rs b/src/traits.rs index e0e73d6..43dfb69 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -35,19 +35,51 @@ impl> ToModuleSpecifier for T { } } +/// Convert a string to a V8 string +/// +/// **DEPRECATED**: This trait is deprecated and may be removed in a future version. +/// Use `v8::String::new(scope, string)` directly instead. +/// +/// # Migration Guide +/// ```rust,ignore +/// // Old code: +/// use rustyscript::ToV8String; +/// let v8_str = my_string.to_v8_string(scope)?; +/// +/// // New code: +/// let v8_str = v8::String::new(scope, my_string) +/// .ok_or_else(|| Error::V8Encoding(my_string.to_string()))?; +/// ``` +#[deprecated( + since = "0.8.0", + note = "Use v8::String::new() directly. This trait will be removed in a future version." +)] pub trait ToV8String { + /// Convert this value to a V8 string + /// + /// # Errors + /// Returns an error if the string cannot be encoded as a V8 string fn to_v8_string<'a>( &self, scope: &mut HandleScope<'a>, ) -> Result, Error>; } +#[allow(deprecated)] impl ToV8String for str { fn to_v8_string<'a>( &self, scope: &mut HandleScope<'a>, ) -> Result, Error> { - v8::String::new(scope, self).ok_or(Error::V8Encoding(self.to_string())) + // SAFETY: The V8 API requires &PinnedRef but we have &mut HandleScope. + // This is safe because the HandleScope is already on the stack and pinned. + // This pattern is used throughout the codebase for V8 API compatibility. + let scope_ref: &v8::PinnedRef> = unsafe { + std::mem::transmute::<&HandleScope<'a>, &v8::PinnedRef>>( + std::ptr::from_mut(scope).as_ref().unwrap(), + ) + }; + v8::String::new(scope_ref, self).ok_or_else(|| Error::V8Encoding(self.to_string())) } } @@ -60,3 +92,7 @@ impl<'a> ToDefinedValue> for Option