Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ slab = "0.4.7"
sled = "0.34.7"
smallvec = { version = "1.11", features = ["union", "const_generics"] }
socket2 = "0.5"
sourcemap = "9"
sqllogictest = "0.17"
sqllogictest-engines = "0.17"
sqlparser = "0.38.0"
Expand Down
4 changes: 4 additions & 0 deletions crates/bindings-typescript/src/lib/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ export function pushReducer(
lifecycle, // <- lifecycle flag lands here
});

if (!fn.name) {
Object.defineProperty(fn, 'name', { value: name, writable: false });
}

REDUCERS.push(fn);
}

Expand Down
27 changes: 18 additions & 9 deletions crates/cli/src/tasks/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rolldown_utils::js_regex::HybridRegex;
use rolldown_utils::pattern_filter::StringOrRegex;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use std::sync::{Arc, OnceLock};
use tokio::runtime::{Builder, Handle, Runtime};

static RUNTIME: OnceLock<Runtime> = OnceLock::new();
Expand Down Expand Up @@ -62,14 +62,23 @@ pub(crate) fn build_javascript(project_path: &Path, build_debug: bool) -> anyhow
generated_code: Some(rolldown::GeneratedCodeOptions::es2015()),
es_module: Some(rolldown::EsModuleFlag::IfDefaultProp), // See https://rollupjs.org/configuration-options/#output-esmodule
drop_labels: None,
hash_characters: None, // File name hash characters, we don't care
banner: None, // String to prepend to the bundle
footer: None, // String to append to the bundle
intro: None, // Similar to the above, but inside the wrappers
outro: None, // Similar to the above, but inside the wrappers
sourcemap_base_url: None, // Absolute URLs for the source map
sourcemap_ignore_list: None, // See https://rollupjs.org/configuration-options/#output-sourcemapignorelist
sourcemap_path_transform: None, // Function to transform source map paths
hash_characters: None, // File name hash characters, we don't care
banner: None, // String to prepend to the bundle
footer: None, // String to append to the bundle
intro: None, // Similar to the above, but inside the wrappers
outro: None, // Similar to the above, but inside the wrappers
sourcemap_base_url: None, // Absolute URLs for the source map
sourcemap_ignore_list: None, // See https://rollupjs.org/configuration-options/#output-sourcemapignorelist
// Function to transform source map paths
sourcemap_path_transform: Some(rolldown::SourceMapPathTransform::new(Arc::new(
|relative_path, _sourcemap_path| {
// The output file is ./dist/bundle.js, so all the paths will be relative to it,
// e.g. from the perspective of `./dist` the entry file is `../src/index.ts`.
// So, strip the leading `../`
let path = relative_path.strip_prefix("../").unwrap_or(relative_path);
Box::pin(futures::future::ok(path.to_owned()))
},
))),
sourcemap_debug_ids: Some(true), // Seems like a good idea. See: https://rollupjs.org/configuration-options/#output-sourcemapdebugids
module_types: None, // Lets you associate file extensions with module types, e.g. `.data` -> `json`. We don't need this.
// Wrapper around https://docs.rs/oxc_resolver/latest/oxc_resolver/struct.ResolveOptions.html, see also https://rolldown.rs/guide/features#module-resolution
Expand Down
1 change: 1 addition & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ similar.workspace = true
slab.workspace = true
sled.workspace = true
smallvec.workspace = true
sourcemap.workspace = true
sqlparser.workspace = true
strum.workspace = true
tabled.workspace = true
Expand Down
44 changes: 37 additions & 7 deletions crates/core/src/host/v8/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,16 +338,46 @@ pub(super) struct JsStackTraceFrame {
impl JsStackTraceFrame {
/// Converts a V8 [`StackFrame`] into one independent of `'scope`.
fn from_frame<'scope>(scope: &PinScope<'scope, '_>, frame: Local<'scope, StackFrame>) -> Self {
let script_name = frame
.get_script_name_or_source_url(scope)
.map(|s| s.to_rust_string_lossy(scope));

let script_id = frame.get_script_id();
let mut line = frame.get_line_number();
let mut column = frame.get_column();
let mut script_name = None;
let fn_name = frame.get_function_name(scope).map(|s| s.to_rust_string_lossy(scope));

let sourcemap = scope
.get_slot()
.and_then(|super::SourceMaps(maps)| maps.get(&(script_id as i32)));

// sourcemap uses 0-based line/column numbers, while v8 uses 1-based
if let Some(token) = sourcemap.and_then(|sm| sm.lookup_token(line as u32 - 1, column as u32 - 1)) {
line = token.get_src_line() as usize + 1;
column = token.get_src_col() as usize + 1;
if let Some(file) = token.get_source() {
script_name = Some(file.to_owned())
}

// If we ever want to support de-minifying function names, uncomment this.
// The process of obtaining the original name of a function given a token
// in that function is imperfect and could return an incorrect name for an
// unminified identifier. So until we need it, turn it off.
//
// if let Some((sv, fn_name)) = Option::zip(token.get_source_view(), fn_name.as_mut()) {
// if let Some(new_name) = sv.get_original_function_name(token, fn_name) {
// new_name.clone_into(fn_name)
// }
// }
}

let script_name = script_name.or_else(|| {
frame
.get_script_name_or_source_url(scope)
.map(|s| s.to_rust_string_lossy(scope))
});

Self {
line: frame.get_line_number(),
column: frame.get_column(),
script_id: frame.get_script_id(),
line,
column,
script_id,
script_name,
fn_name,
is_eval: frame.is_eval(),
Expand Down
22 changes: 22 additions & 0 deletions crates/core/src/host/v8/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use futures::FutureExt;
use itertools::Either;
use spacetimedb_auth::identity::ConnectionAuthCtx;
use spacetimedb_client_api_messages::energy::FunctionBudget;
use spacetimedb_data_structures::map::IntMap;
use spacetimedb_datastore::locking_tx_datastore::{FuncCallType, MutTxId};
use spacetimedb_datastore::traits::Program;
use spacetimedb_lib::{ConnectionId, Identity, RawModuleDef, Timestamp};
Expand Down Expand Up @@ -489,6 +490,7 @@ fn startup_instance_worker<'scope>(
fn new_isolate() -> OwnedIsolate {
let mut isolate = Isolate::new(<_>::default());
isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 1024);
isolate.set_slot(SourceMaps::default());
isolate
}

Expand Down Expand Up @@ -705,9 +707,29 @@ fn eval_module<'scope>(
return Err(error::TypeError("module has top-level await and is pending").throw(scope));
}

let source_map_url = module.get_unbound_module_script(scope).get_source_mapping_url(scope);
let source_map_url = (!source_map_url.is_null_or_undefined()).then_some(source_map_url);

if let Some((script_id, source_map_url)) = Option::zip(module.script_id(), source_map_url) {
let mut source_map_url = source_map_url.to_rust_string_lossy(scope);
// Hacky workaround for decode_data_url expecting a specific string without `charset=utf-8`
if source_map_url.starts_with("data:application/json;charset=utf-8;base64,") {
let start = "data:application/json;".len();
let len = "charset=utf-8;".len();
source_map_url.replace_range(start..start + len, "");
}
if let Ok(sourcemap::DecodedMap::Regular(sourcemap)) = sourcemap::decode_data_url(&source_map_url) {
let SourceMaps(maps) = scope.get_slot_mut().unwrap();
maps.insert(script_id, sourcemap);
}
}

Ok((module, value))
}

#[derive(Default)]
struct SourceMaps(IntMap<i32, sourcemap::SourceMap>);

/// Compiles, instantiate, and evaluate the user module with `code`.
fn eval_user_module<'scope>(
scope: &mut PinScope<'scope, '_>,
Expand Down
Loading