diff --git a/Cargo.lock b/Cargo.lock index d21116d0f..a05886f40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4795,6 +4795,7 @@ name = "sb_module_loader" version = "0.1.0" dependencies = [ "anyhow", + "base64 0.21.7", "deno_ast", "deno_core", "deno_fs", diff --git a/crates/base/src/deno_runtime.rs b/crates/base/src/deno_runtime.rs index 8652169b9..adb9fb604 100644 --- a/crates/base/src/deno_runtime.rs +++ b/crates/base/src/deno_runtime.rs @@ -362,6 +362,7 @@ impl DenoRuntime { eszip, maybe_arc_import_map, import_map_path, + maybe_inspector.is_some(), ) .await?; diff --git a/crates/sb_module_loader/Cargo.toml b/crates/sb_module_loader/Cargo.toml index 95427ee5c..59657b29e 100644 --- a/crates/sb_module_loader/Cargo.toml +++ b/crates/sb_module_loader/Cargo.toml @@ -24,6 +24,7 @@ deno_npm.workspace = true once_cell.workspace = true deno_tls.workspace = true monch.workspace = true +base64.workspace = true sb_core = { version = "0.1.0", path = "../sb_core" } sb_node = { version = "0.1.0", path = "../node" } sb_npm = { version = "0.1.0", path = "../npm" } diff --git a/crates/sb_module_loader/standalone/mod.rs b/crates/sb_module_loader/standalone/mod.rs index 921bb1e90..0ef4dfc15 100644 --- a/crates/sb_module_loader/standalone/mod.rs +++ b/crates/sb_module_loader/standalone/mod.rs @@ -57,6 +57,7 @@ pub async fn create_module_loader_for_eszip( mut eszip: eszip::EszipV2, metadata: Metadata, maybe_import_map: Option, + include_source_map: bool, ) -> Result { // let main_module = &metadata.entrypoint; let current_exe_path = std::env::current_exe().unwrap(); @@ -191,6 +192,7 @@ pub async fn create_module_loader_for_eszip( Ok(RuntimeProviders { module_loader: Rc::new(EmbeddedModuleLoader { shared: module_loader_factory.shared.clone(), + include_source_map, }), npm_resolver: npm_resolver.into_npm_resolver(), vfs, @@ -205,6 +207,7 @@ pub async fn create_module_loader_for_standalone_from_eszip_kind( eszip_payload_kind: EszipPayloadKind, maybe_import_map_arc: Option>, maybe_import_map_path: Option, + include_source_map: bool, ) -> Result { let eszip = payload_to_eszip(eszip_payload_kind).await; @@ -233,6 +236,7 @@ pub async fn create_module_loader_for_standalone_from_eszip_kind( package_json_deps: None, }, maybe_import_map, + include_source_map, ) .await } diff --git a/crates/sb_module_loader/standalone/standalone_module_loader.rs b/crates/sb_module_loader/standalone/standalone_module_loader.rs index 9082116d8..8dec3a638 100644 --- a/crates/sb_module_loader/standalone/standalone_module_loader.rs +++ b/crates/sb_module_loader/standalone/standalone_module_loader.rs @@ -1,6 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use crate::node::node_module_loader::NpmModuleLoader; +use base64::Engine; use deno_ast::MediaType; use deno_core::error::generic_error; use deno_core::error::type_error; @@ -28,6 +29,7 @@ pub struct SharedModuleLoaderState { #[derive(Clone)] pub struct EmbeddedModuleLoader { pub(crate) shared: Arc, + pub(crate) include_source_map: bool, } impl ModuleLoader for EmbeddedModuleLoader { @@ -101,6 +103,7 @@ impl ModuleLoader for EmbeddedModuleLoader { _is_dynamic: bool, _requested_module_type: RequestedModuleType, ) -> deno_core::ModuleLoadResponse { + let include_source_map = self.include_source_map; let permissions = sb_node::allow_all(); if original_specifier.scheme() == "data" { @@ -155,11 +158,36 @@ impl ModuleLoader for EmbeddedModuleLoader { deno_core::ModuleLoadResponse::Async( async move { - let code = module.source().await.ok_or_else(|| { - type_error(format!("Module not found: {}", original_specifier)) - })?; - let code = arc_u8_to_arc_str(code) - .map_err(|_| type_error("Module source is not utf-8"))?; + let code = module + .source() + .await + .ok_or_else(|| type_error(format!("Module not found: {}", original_specifier))) + .and_then(|it| { + arc_u8_to_arc_str(it).map_err(|_| type_error("Module source is not utf-8")) + })?; + + let source_map = module.source_map().await; + let maybe_code_with_source_map = 'scope: { + if !include_source_map { + break 'scope code; + } + + let Some(source_map) = source_map else { + break 'scope code; + }; + + let mut src = code.to_string(); + + if src.ends_with('\n') { + src.push('\n'); + } + + src.push_str("//# sourceMappingURL=data:application/json;base64,"); + base64::prelude::BASE64_STANDARD.encode_string(source_map, &mut src); + + Arc::from(src) + }; + Ok(deno_core::ModuleSource::new_with_redirect( match module.kind { eszip::ModuleKind::JavaScript => ModuleType::JavaScript, @@ -171,7 +199,7 @@ impl ModuleLoader for EmbeddedModuleLoader { unreachable!(); } }, - ModuleSourceCode::String(code.into()), + ModuleSourceCode::String(maybe_code_with_source_map.into()), &original_specifier, &found_specifier, ))