diff --git a/rewriter/Cargo.lock b/rewriter/Cargo.lock
index cdd3346..845f33b 100644
--- a/rewriter/Cargo.lock
+++ b/rewriter/Cargo.lock
@@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "ahash"
@@ -14,12 +14,33 @@ dependencies = [
"zerocopy",
]
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
[[package]]
name = "anyhow"
version = "1.0.94"
@@ -88,7 +109,7 @@ dependencies = [
"icu_normalizer",
"indexmap",
"intrusive-collections",
- "itertools",
+ "itertools 0.13.0",
"num-bigint",
"num-integer",
"num-traits",
@@ -224,6 +245,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
[[package]]
name = "castaway"
version = "0.2.3"
@@ -239,6 +266,58 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "ciborium"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "clap"
+version = "4.5.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
+dependencies = [
+ "clap_builder",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
+dependencies = [
+ "anstyle",
+ "clap_lex",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
[[package]]
name = "compact_str"
version = "0.8.0"
@@ -259,12 +338,73 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79"
+[[package]]
+name = "criterion"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f"
+dependencies = [
+ "anes",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "is-terminal",
+ "itertools 0.10.5",
+ "num-traits",
+ "once_cell",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
+dependencies = [
+ "cast",
+ "itertools 0.10.5",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
[[package]]
name = "dashmap"
version = "6.1.0"
@@ -343,6 +483,16 @@ dependencies = [
"wasi",
]
+[[package]]
+name = "half"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+]
+
[[package]]
name = "hashbrown"
version = "0.14.5"
@@ -364,6 +514,12 @@ dependencies = [
"foldhash",
]
+[[package]]
+name = "hermit-abi"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+
[[package]]
name = "icu_collections"
version = "1.5.0"
@@ -534,6 +690,26 @@ dependencies = [
"memoffset",
]
+[[package]]
+name = "is-terminal"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "itertools"
version = "0.13.0"
@@ -608,6 +784,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"boa_engine",
+ "criterion",
"oxc",
"rewriter",
"url",
@@ -691,6 +868,12 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+[[package]]
+name = "oorandom"
+version = "11.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
+
[[package]]
name = "owo-colors"
version = "4.1.0"
@@ -950,6 +1133,34 @@ dependencies = [
"siphasher",
]
+[[package]]
+name = "plotters"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
+dependencies = [
+ "plotters-backend",
+]
+
[[package]]
name = "pollster"
version = "0.4.0"
@@ -1034,6 +1245,26 @@ dependencies = [
"getrandom",
]
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
[[package]]
name = "redox_syscall"
version = "0.5.8"
@@ -1043,6 +1274,35 @@ dependencies = [
"bitflags",
]
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
[[package]]
name = "regress"
version = "0.10.1"
@@ -1087,6 +1347,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5"
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -1296,6 +1565,16 @@ dependencies = [
"zerovec",
]
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "toml_datetime"
version = "0.6.8"
@@ -1378,6 +1657,16 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@@ -1462,6 +1751,33 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
[[package]]
name = "windows-targets"
version = "0.52.6"
diff --git a/rewriter/native/Cargo.toml b/rewriter/native/Cargo.toml
index 4f3e701..e9dcb91 100644
--- a/rewriter/native/Cargo.toml
+++ b/rewriter/native/Cargo.toml
@@ -12,3 +12,8 @@ urlencoding = "2.1.3"
[dev-dependencies]
boa_engine = "0.20.0"
+criterion = "0.5.1"
+
+[[bench]]
+name = "samples"
+harness = false
diff --git a/rewriter/native/benches/samples.rs b/rewriter/native/benches/samples.rs
new file mode 100644
index 0000000..c8f673a
--- /dev/null
+++ b/rewriter/native/benches/samples.rs
@@ -0,0 +1,62 @@
+use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
+use rewriter::{cfg::Config, rewrite};
+use std::str::FromStr;
+use url::Url;
+use urlencoding::encode;
+
+fn encode_string(str: String) -> String {
+ encode(&str).to_string()
+}
+
+pub fn bench(c: &mut Criterion) {
+ let discord = include_str!("../sample/discord.js");
+ let google = include_str!("../sample/google.js");
+
+ let cfg = Config {
+ prefix: "/scrammedjet/".to_string(),
+ encoder: Box::new(encode_string),
+
+ base: Url::from_str("https://google.com/glorngle/si.js").expect("invalid base"),
+ sourcetag: "glongle1".to_string(),
+
+ wrapfn: "$wrap".to_string(),
+ wrapthisfn: "$gwrap".to_string(),
+ importfn: "$import".to_string(),
+ rewritefn: "$rewrite".to_string(),
+ metafn: "$meta".to_string(),
+ setrealmfn: "$setrealm".to_string(),
+ pushsourcemapfn: "$pushsourcemap".to_string(),
+
+ capture_errors: true,
+ do_sourcemaps: true,
+ scramitize: false,
+ strict_rewrites: true,
+ };
+
+ c.bench_with_input(
+ BenchmarkId::new("rewrite/samples", "discord"),
+ &(discord, cfg.clone()),
+ |b, input| {
+ b.iter_batched(
+ || input.clone(),
+ |x| rewrite(x.0, x.1),
+ BatchSize::SmallInput,
+ )
+ },
+ );
+
+ c.bench_with_input(
+ BenchmarkId::new("rewrite/samples", "google"),
+ &(google, cfg.clone()),
+ |b, input| {
+ b.iter_batched(
+ || input.clone(),
+ |x| rewrite(x.0, x.1),
+ BatchSize::SmallInput,
+ )
+ },
+ );
+}
+
+criterion_group!(samples, bench);
+criterion_main!(samples);
diff --git a/rewriter/native/flamegraph.svg b/rewriter/native/flamegraph.svg
new file mode 100644
index 0000000..60f326f
--- /dev/null
+++ b/rewriter/native/flamegraph.svg
@@ -0,0 +1,491 @@
+
\ No newline at end of file
diff --git a/rewriter/native/src/main.rs b/rewriter/native/src/main.rs
index 16dcff2..2c14b21 100644
--- a/rewriter/native/src/main.rs
+++ b/rewriter/native/src/main.rs
@@ -37,34 +37,42 @@ fn dorewrite(data: &str) -> Result {
.context("failed to rewrite file")
}
+fn dobench(data: String) {
+ loop {
+ let _ = dorewrite(&data);
+ }
+}
+
fn main() -> Result<()> {
let file = env::args().nth(1).unwrap_or_else(|| "test.js".to_string());
let data = fs::read_to_string(file).context("failed to read file")?;
let bench = env::args().nth(2).is_some();
if bench {
- loop {
- dorewrite(&data)?;
+ for _ in 0..15 {
+ let data = data.clone();
+ std::thread::spawn(move || dobench(data));
}
+ dobench(data);
+ } else {
+ let res = dorewrite(&data)?;
+
+ let source = Arc::new(
+ NamedSource::new(data, "https://google.com/glorngle/si.js").with_language("javascript"),
+ );
+ eprintln!("errors:");
+ for err in res.errors {
+ eprintln!("{}", err.with_source_code(source.clone()));
+ }
+
+ println!("changes: {:#?}", res.changes);
+
+ println!(
+ "rewritten:\n{}",
+ String::from_utf8(res.js).context("failed to parse rewritten js")?
+ );
}
- let res = dorewrite(&data)?;
-
- let source = Arc::new(
- NamedSource::new(data, "https://google.com/glorngle/si.js").with_language("javascript"),
- );
- eprintln!("errors:");
- for err in res.errors {
- eprintln!("{}", err.with_source_code(source.clone()));
- }
-
- println!("changes: {:#?}", res.changes);
-
- println!(
- "rewritten:\n{}",
- String::from_utf8(res.js).context("failed to parse rewritten js")?
- );
-
Ok(())
}
diff --git a/rewriter/rewriter/src/cfg.rs b/rewriter/rewriter/src/cfg.rs
index 41af644..8155d03 100644
--- a/rewriter/rewriter/src/cfg.rs
+++ b/rewriter/rewriter/src/cfg.rs
@@ -1,24 +1,27 @@
use url::Url;
-pub struct Config {
- pub prefix: String,
+#[derive(Clone)]
+pub struct Config
+where
+ E: Fn(String) -> String,
+ E: Clone,
+{
+ pub prefix: String,
pub sourcetag: String,
pub base: Url,
- pub wrapfn: String,
- pub wrapthisfn: String,
- pub importfn: String,
- pub rewritefn: String,
- pub setrealmfn: String,
- pub metafn: String,
- pub pushsourcemapfn: String,
+ pub wrapfn: String,
+ pub wrapthisfn: String,
+ pub importfn: String,
+ pub rewritefn: String,
+ pub setrealmfn: String,
+ pub metafn: String,
+ pub pushsourcemapfn: String,
- pub encoder: EncodeFn,
+ pub encoder: E,
- pub capture_errors: bool,
- pub scramitize: bool,
- pub do_sourcemaps: bool,
- pub strict_rewrites: bool,
+ pub capture_errors: bool,
+ pub scramitize: bool,
+ pub do_sourcemaps: bool,
+ pub strict_rewrites: bool,
}
-
-pub type EncodeFn = Box String>;
diff --git a/rewriter/rewriter/src/changes.rs b/rewriter/rewriter/src/changes.rs
index 08bc348..7a813c7 100644
--- a/rewriter/rewriter/src/changes.rs
+++ b/rewriter/rewriter/src/changes.rs
@@ -112,7 +112,11 @@ impl JsChange {
// returns (bunch of stuff to add before, option)
// bunch of stuff to add after should only be some if it's not a replace op
- fn to_inner<'a>(&'a self, cfg: &'a Config) -> JsChangeInner<'a> {
+ fn to_inner<'a, E>(&'a self, cfg: &'a Config) -> JsChangeInner<'a>
+ where
+ E: Fn(String) -> String,
+ E: Clone,
+ {
match self {
Self::WrapFn { ident, wrapped, .. } => JsChangeInner::Replace(if *wrapped {
smallvec!["(", cfg.wrapfn.as_str(), "(", ident.as_str(), ")", ")"]
@@ -220,7 +224,11 @@ impl JsChanges {
self.inner.push(change);
}
- pub fn perform(&mut self, js: &str, cfg: &Config) -> JsChangeResult {
+ pub fn perform(&mut self, js: &str, cfg: &Config) -> JsChangeResult
+ where
+ E: Fn(String) -> String,
+ E: Clone,
+ {
let mut offset = 0;
let mut buffer = Vec::with_capacity(((js.len() as u64 * 120) / 100) as usize);
diff --git a/rewriter/rewriter/src/lib.rs b/rewriter/rewriter/src/lib.rs
index ec2d7b8..8b93d62 100644
--- a/rewriter/rewriter/src/lib.rs
+++ b/rewriter/rewriter/src/lib.rs
@@ -1,11 +1,11 @@
use cfg::Config;
use changes::{JsChange, JsChangeResult, JsChanges};
use oxc::{
- allocator::Allocator,
- ast::Visit,
- diagnostics::OxcDiagnostic,
- parser::{ParseOptions, Parser},
- span::SourceType,
+ allocator::Allocator,
+ ast::Visit,
+ diagnostics::OxcDiagnostic,
+ parser::{ParseOptions, Parser},
+ span::SourceType,
};
use thiserror::Error;
use visitor::Visitor;
@@ -16,50 +16,54 @@ mod visitor;
#[derive(Error, Debug)]
pub enum RewriterError {
- #[error("oxc panicked in parser")]
- OxcPanicked,
+ #[error("oxc panicked in parser")]
+ OxcPanicked,
}
#[derive(Debug)]
pub struct RewriteResult {
- pub js: Vec,
- pub sourcemap: Vec,
- pub errors: Vec,
- pub changes: Vec,
+ pub js: Vec,
+ pub sourcemap: Vec,
+ pub errors: Vec,
+ pub changes: Vec,
}
-pub fn rewrite(js: &str, config: Config) -> Result {
- let allocator = Allocator::default();
- let source_type = SourceType::default();
- let ret = Parser::new(&allocator, js, source_type)
- .with_options(ParseOptions {
- parse_regular_expression: false, // default
- allow_return_outside_function: true,
- preserve_parens: true, // default
- })
- .parse();
+pub fn rewrite(js: &str, config: Config) -> Result
+where
+ E: Fn(String) -> String,
+ E: Clone,
+{
+ let allocator = Allocator::default();
+ let source_type = SourceType::default();
+ let ret = Parser::new(&allocator, js, source_type)
+ .with_options(ParseOptions {
+ parse_regular_expression: false, // default
+ allow_return_outside_function: true,
+ preserve_parens: true, // default
+ })
+ .parse();
- if ret.panicked {
- return Err(RewriterError::OxcPanicked);
- }
+ if ret.panicked {
+ return Err(RewriterError::OxcPanicked);
+ }
- let mut visitor = Visitor {
- jschanges: JsChanges::new(),
- config,
- };
- visitor.visit_program(&ret.program);
- let Visitor {
- mut jschanges,
- config,
- } = visitor;
+ let mut visitor = Visitor {
+ jschanges: JsChanges::new(),
+ config,
+ };
+ visitor.visit_program(&ret.program);
+ let Visitor {
+ mut jschanges,
+ config,
+ } = visitor;
- let JsChangeResult { js, sourcemap } = jschanges.perform(js, &config);
- let JsChanges { inner: changes } = jschanges;
+ let JsChangeResult { js, sourcemap } = jschanges.perform(js, &config);
+ let JsChanges { inner: changes } = jschanges;
- Ok(RewriteResult {
- js,
- sourcemap,
- errors: ret.errors,
- changes,
- })
+ Ok(RewriteResult {
+ js,
+ sourcemap,
+ errors: ret.errors,
+ changes,
+ })
}
diff --git a/rewriter/rewriter/src/visitor.rs b/rewriter/rewriter/src/visitor.rs
index 8df5008..fc26315 100644
--- a/rewriter/rewriter/src/visitor.rs
+++ b/rewriter/rewriter/src/visitor.rs
@@ -34,12 +34,20 @@ const UNSAFE_GLOBALS: &[&str] = &[
"frames",
];
-pub struct Visitor {
+pub struct Visitor
+where
+ E: Fn(String) -> String,
+ E: Clone,
+{
pub jschanges: JsChanges,
- pub config: Config,
+ pub config: Config,
}
-impl Visitor {
+impl Visitor
+where
+ E: Fn(String) -> String,
+ E: Clone,
+{
fn rewrite_url(&mut self, url: String) -> String {
let url = self.config.base.join(&url).unwrap();
@@ -80,7 +88,11 @@ impl Visitor {
}
}
-impl<'a> Visit<'a> for Visitor {
+impl<'a, E> Visit<'a> for Visitor
+where
+ E: Fn(String) -> String,
+ E: Clone,
+{
fn visit_identifier_reference(&mut self, it: &IdentifierReference) {
// if self.config.capture_errors {
// self.jschanges.insert(JsChange::GenericChange {
diff --git a/rewriter/wasm/src/error.rs b/rewriter/wasm/src/error.rs
index 33fafc7..2595fdf 100644
--- a/rewriter/wasm/src/error.rs
+++ b/rewriter/wasm/src/error.rs
@@ -5,45 +5,45 @@ use wasm_bindgen::{JsError, JsValue};
#[derive(Debug, Error)]
pub enum RewriterError {
- #[error("JS: {0}")]
- Js(String),
- #[error("URL parse error: {0}")]
- Url(#[from] url::ParseError),
- #[error("str fromutf8 error: {0}")]
- Str(#[from] std::str::Utf8Error),
- #[error("Rewriter: {0}")]
- Rewriter(#[from] InnerRewriterError),
- #[error("reflect set failed: {0}")]
- ReflectSetFail(String),
+ #[error("JS: {0}")]
+ Js(String),
+ #[error("URL parse error: {0}")]
+ Url(#[from] url::ParseError),
+ #[error("str fromutf8 error: {0}")]
+ Str(#[from] std::str::Utf8Error),
+ #[error("Rewriter: {0}")]
+ Rewriter(#[from] InnerRewriterError),
+ #[error("reflect set failed: {0}")]
+ ReflectSetFail(String),
- #[error("{0} was not {1}")]
- Not(String, &'static str),
+ #[error("{0} was not {1}")]
+ Not(String, &'static str),
}
impl From for RewriterError {
- fn from(value: JsValue) -> Self {
- Self::Js(Error::from(value).to_string().into())
- }
+ fn from(value: JsValue) -> Self {
+ Self::Js(Error::from(value).to_string().into())
+ }
}
impl From for JsValue {
- fn from(value: RewriterError) -> Self {
- JsError::from(value).into()
- }
+ fn from(value: RewriterError) -> Self {
+ JsError::from(value).into()
+ }
}
impl RewriterError {
- pub fn not_str(x: &str) -> Self {
- Self::Not(x.to_string(), "string")
- }
+ pub fn not_str(x: &str) -> Self {
+ Self::Not(x.to_string(), "string")
+ }
- pub fn not_fn(x: &str) -> Self {
- Self::Not(x.to_string(), "function")
- }
+ pub fn not_fn(x: &str) -> Self {
+ Self::Not(x.to_string(), "function")
+ }
- pub fn not_bool(x: &str) -> Self {
- Self::Not(x.to_string(), "bool")
- }
+ pub fn not_bool(x: &str) -> Self {
+ Self::Not(x.to_string(), "bool")
+ }
}
pub type Result = std::result::Result;
diff --git a/rewriter/wasm/src/lib.rs b/rewriter/wasm/src/lib.rs
index f85571d..0f5f39a 100644
--- a/rewriter/wasm/src/lib.rs
+++ b/rewriter/wasm/src/lib.rs
@@ -7,8 +7,8 @@ use instant::Instant;
use js_sys::{Function, Object, Reflect};
use oxc::diagnostics::NamedSource;
use rewriter::{
- cfg::{Config, EncodeFn},
- rewrite, RewriteResult,
+ cfg::{Config, EncodeFn},
+ rewrite, RewriteResult,
};
use url::Url;
use wasm_bindgen::prelude::*;
@@ -27,148 +27,148 @@ export function scramtag() {
}
"#)]
extern "C" {
- pub fn scramtag() -> String;
+ pub fn scramtag() -> String;
}
#[wasm_bindgen]
extern "C" {
- #[wasm_bindgen(typescript_type = "RewriterOutput")]
- pub type JsRewriterOutput;
+ #[wasm_bindgen(typescript_type = "RewriterOutput")]
+ pub type JsRewriterOutput;
}
#[wasm_bindgen]
extern "C" {
- #[wasm_bindgen(js_namespace = console)]
- fn error(s: &str);
+ #[wasm_bindgen(js_namespace = console)]
+ fn error(s: &str);
}
fn create_encode_function(encode: JsValue) -> Result {
- let encode = encode.dyn_into::()?;
+ let encode = encode.dyn_into::()?;
- Ok(Box::new(move |str| {
- encode
- .call1(&JsValue::NULL, &str.into())
- .unwrap()
- .as_string()
- .unwrap()
- .to_string()
- }))
+ Ok(Box::new(move |str| {
+ encode
+ .call1(&JsValue::NULL, &str.into())
+ .unwrap()
+ .as_string()
+ .unwrap()
+ .to_string()
+ }))
}
fn get_obj(obj: &JsValue, k: &str) -> Result {
- Ok(Reflect::get(obj, &k.into())?)
+ Ok(Reflect::get(obj, &k.into())?)
}
fn get_str(obj: &JsValue, k: &str) -> Result {
- Reflect::get(obj, &k.into())?
- .as_string()
- .ok_or_else(|| RewriterError::not_str(k))
+ Reflect::get(obj, &k.into())?
+ .as_string()
+ .ok_or_else(|| RewriterError::not_str(k))
}
fn set_obj(obj: &Object, k: &str, v: &JsValue) -> Result<()> {
- if !Reflect::set(&obj.into(), &k.into(), v)? {
- Err(RewriterError::ReflectSetFail(k.to_string()))
- } else {
- Ok(())
- }
+ if !Reflect::set(&obj.into(), &k.into(), v)? {
+ Err(RewriterError::ReflectSetFail(k.to_string()))
+ } else {
+ Ok(())
+ }
}
fn get_flag(scramjet: &Object, url: &str, flag: &str) -> Result {
- let fenabled = get_obj(scramjet, "flagEnabled")?
- .dyn_into::()
- .map_err(|_| RewriterError::not_fn("scramjet.flagEnabled"))?;
- let ret = fenabled.call2(
- &JsValue::NULL,
- &flag.into(),
- &web_sys::Url::new(url)?.into(),
- )?;
+ let fenabled = get_obj(scramjet, "flagEnabled")?
+ .dyn_into::()
+ .map_err(|_| RewriterError::not_fn("scramjet.flagEnabled"))?;
+ let ret = fenabled.call2(
+ &JsValue::NULL,
+ &flag.into(),
+ &web_sys::Url::new(url)?.into(),
+ )?;
- ret.as_bool()
- .ok_or_else(|| RewriterError::not_bool("scramjet.flagEnabled return value"))
+ ret.as_bool()
+ .ok_or_else(|| RewriterError::not_bool("scramjet.flagEnabled return value"))
}
fn get_config(scramjet: &Object, url: &str) -> Result {
- let codec = &get_obj(scramjet, "codec")?;
- let config = &get_obj(scramjet, "config")?;
- let globals = &get_obj(config, "globals")?;
+ let codec = &get_obj(scramjet, "codec")?;
+ let config = &get_obj(scramjet, "config")?;
+ let globals = &get_obj(config, "globals")?;
- Ok(Config {
- prefix: get_str(config, "prefix")?,
- encoder: create_encode_function(get_obj(codec, "encode")?)?,
- base: Url::from_str(url)?,
- sourcetag: scramtag(),
+ Ok(Config {
+ prefix: get_str(config, "prefix")?,
+ encoder: create_encode_function(get_obj(codec, "encode")?)?,
+ base: Url::from_str(url)?,
+ sourcetag: scramtag(),
- wrapfn: get_str(globals, "wrapfn")?,
- wrapthisfn: get_str(globals, "wrapthisfn")?,
- importfn: get_str(globals, "importfn")?,
- rewritefn: get_str(globals, "rewritefn")?,
- metafn: get_str(globals, "metafn")?,
- setrealmfn: get_str(globals, "setrealmfn")?,
- pushsourcemapfn: get_str(globals, "pushsourcemapfn")?,
+ wrapfn: get_str(globals, "wrapfn")?,
+ wrapthisfn: get_str(globals, "wrapthisfn")?,
+ importfn: get_str(globals, "importfn")?,
+ rewritefn: get_str(globals, "rewritefn")?,
+ metafn: get_str(globals, "metafn")?,
+ setrealmfn: get_str(globals, "setrealmfn")?,
+ pushsourcemapfn: get_str(globals, "pushsourcemapfn")?,
- do_sourcemaps: get_flag(scramjet, url, "sourcemaps")?,
- capture_errors: get_flag(scramjet, url, "captureErrors")?,
- scramitize: get_flag(scramjet, url, "scramitize")?,
- strict_rewrites: get_flag(scramjet, url, "strictRewrites")?,
- })
+ do_sourcemaps: get_flag(scramjet, url, "sourcemaps")?,
+ capture_errors: get_flag(scramjet, url, "captureErrors")?,
+ scramitize: get_flag(scramjet, url, "scramitize")?,
+ strict_rewrites: get_flag(scramjet, url, "strictRewrites")?,
+ })
}
fn duration_to_millis_f64(duration: Duration) -> f64 {
- (duration.as_secs() as f64) * 1_000f64 + (duration.subsec_nanos() as f64) / 1_000_000f64
+ (duration.as_secs() as f64) * 1_000f64 + (duration.subsec_nanos() as f64) / 1_000_000f64
}
fn create_rewriter_output(
- out: RewriteResult,
- url: String,
- src: String,
- duration: Duration,
+ out: RewriteResult,
+ url: String,
+ src: String,
+ duration: Duration,
) -> Result {
- let src = Arc::new(NamedSource::new(url, src).with_language("javascript"));
- #[cfg(feature = "debug")]
- let errs: Vec<_> = out
- .errors
- .into_iter()
- .map(|x| format!("{}", x.with_source_code(src.clone())))
- .collect();
+ let src = Arc::new(NamedSource::new(url, src).with_language("javascript"));
+ #[cfg(feature = "debug")]
+ let errs: Vec<_> = out
+ .errors
+ .into_iter()
+ .map(|x| format!("{}", x.with_source_code(src.clone())))
+ .collect();
- let obj = Object::new();
- set_obj(&obj, "js", &out.js.into())?;
- #[cfg(feature = "debug")]
- set_obj(&obj, "errors", &errs.into())?;
- #[cfg(not(feature = "debug"))]
- set_obj(&obj, "errors", &js_sys::Array::new())?;
- set_obj(&obj, "duration", &duration_to_millis_f64(duration).into())?;
+ let obj = Object::new();
+ set_obj(&obj, "js", &out.js.into())?;
+ #[cfg(feature = "debug")]
+ set_obj(&obj, "errors", &errs.into())?;
+ #[cfg(not(feature = "debug"))]
+ set_obj(&obj, "errors", &js_sys::Array::new())?;
+ set_obj(&obj, "duration", &duration_to_millis_f64(duration).into())?;
- Ok(JsRewriterOutput::from(JsValue::from(obj)))
+ Ok(JsRewriterOutput::from(JsValue::from(obj)))
}
#[wasm_bindgen]
pub fn rewrite_js(
- js: String,
- url: &str,
- script_url: String,
- scramjet: &Object,
+ js: String,
+ url: &str,
+ script_url: String,
+ scramjet: &Object,
) -> Result {
- let before = Instant::now();
- let out = rewrite(&js, get_config(scramjet, url)?)?;
- let after = Instant::now();
+ let before = Instant::now();
+ let out = rewrite(&js, get_config(scramjet, url)?)?;
+ let after = Instant::now();
- create_rewriter_output(out, script_url, js, after - before)
+ create_rewriter_output(out, script_url, js, after - before)
}
#[wasm_bindgen]
pub fn rewrite_js_from_arraybuffer(
- js: Vec,
- url: &str,
- script_url: String,
- scramjet: &Object,
+ js: Vec,
+ url: &str,
+ script_url: String,
+ scramjet: &Object,
) -> Result {
- // we know that this is a valid utf-8 string
- let js = unsafe { String::from_utf8_unchecked(js) };
+ // we know that this is a valid utf-8 string
+ let js = unsafe { String::from_utf8_unchecked(js) };
- let before = Instant::now();
- let out = rewrite(&js, get_config(scramjet, url)?)?;
- let after = Instant::now();
+ let before = Instant::now();
+ let out = rewrite(&js, get_config(scramjet, url)?)?;
+ let after = Instant::now();
- create_rewriter_output(out, script_url, js, after - before)
+ create_rewriter_output(out, script_url, js, after - before)
}