Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 0 additions & 3 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl Plugin for TestPluginCaller {
args: &HookResolveIdArgs<'_>,
) -> HookResolveIdReturn {
if args.specifier == "foo" {
let custom = CustomField::default();
let mut custom = CustomField::default();
custom.insert(MyArg { id: 0 }, "hello, world".to_string());
let custom_resolve_ret = ctx
.resolve(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub struct BindingHookJsResolveIdOptions {

impl From<BindingHookJsResolveIdOptions> for Arc<CustomField> {
fn from(value: BindingHookJsResolveIdOptions) -> Self {
let map = CustomField::default();
let mut map = CustomField::default();
map.insert(ResolveIdOptionsScan, value.scan.unwrap_or(false));
if let Some(is_sub_imports_pattern) =
value.custom.and_then(|v| v.vite_import_glob.and_then(|v| v.is_sub_imports_pattern))
Expand Down
2 changes: 1 addition & 1 deletion crates/rolldown_binding/src/options/plugin/js_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl Plugin for JsPlugin {
custom: args
.custom
.get::<JsPluginContextResolveCustomArgId>(&JsPluginContextResolveCustomArgId)
.map(|v| *v),
.copied(),
};

cb.await_call(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl TryFrom<BindingPluginContextResolveOptions> for PluginContextResolveOptions
type Error = String;

fn try_from(value: BindingPluginContextResolveOptions) -> Result<Self, Self::Error> {
let custom = CustomField::new();
let mut custom = CustomField::new();
if let Some(js_custom_id) = value.custom {
custom.insert(JsPluginContextResolveCustomArgId, js_custom_id);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/rolldown_plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ string_wizard = { workspace = true }
sugar_path = { workspace = true }
tokio = { workspace = true, features = ["sync"] }
tracing = { workspace = true, features = ["valuable"] }
typedmap = { workspace = true, features = ["dashmap"] }
typedmap = { workspace = true }

[package.metadata.cargo-shear]
# `serde_json` is used in `trace_action` macro.
Expand Down
29 changes: 21 additions & 8 deletions crates/rolldown_plugin/src/types/custom_field.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use std::ops::Deref;
use std::fmt;
use std::ops::{Deref, DerefMut};

use rustc_hash::FxBuildHasher;
use typedmap::TypedDashMap;
use typedmap::TypedMap;

#[derive(Debug)]
pub struct CustomField(
TypedDashMap<(), typedmap::SyncAnyBounds, typedmap::SyncAnyBounds, FxBuildHasher>,
);
// See meta/design/plugin-context-resolve.md.
type Inner = TypedMap<(), typedmap::SyncAnyBounds, typedmap::SyncAnyBounds, FxBuildHasher>;

pub struct CustomField(Inner);

impl fmt::Debug for CustomField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CustomField").finish_non_exhaustive()
}
}

impl CustomField {
pub fn new() -> Self {
Expand All @@ -16,14 +23,20 @@ impl CustomField {

impl Default for CustomField {
fn default() -> Self {
Self(TypedDashMap::with_hasher(FxBuildHasher))
Self(TypedMap::with_hasher(FxBuildHasher))
}
}

impl Deref for CustomField {
type Target = TypedDashMap<(), typedmap::SyncAnyBounds, typedmap::SyncAnyBounds, FxBuildHasher>;
type Target = Inner;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for CustomField {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
7 changes: 5 additions & 2 deletions crates/rolldown_plugin_vite_import_glob/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,12 @@ impl GlobImportVisit<'_> {
glob,
Some(self.id),
is_sub_imports_pattern.then(|| {
let custom = Arc::new(rolldown_plugin::CustomField::new());
let mut custom = rolldown_plugin::CustomField::new();
custom.insert(ViteImportGlob, ViteImportGlobValue(true));
rolldown_plugin::PluginContextResolveOptions { custom, ..Default::default() }
rolldown_plugin::PluginContextResolveOptions {
custom: Arc::new(custom),
..Default::default()
}
}),
);

Expand Down
14 changes: 14 additions & 0 deletions meta/design/plugin-context-resolve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Plugin Context Resolve

## Summary

`PluginContextResolveOptions::custom` uses `CustomField`, and `CustomField` is intentionally backed by `TypedMap` instead of `TypedDashMap`.

Today this data is populated before the value is shared and then passed around as `Arc<CustomField>` for read-only access during resolve flows. Concurrent write access is not needed, so the extra sharding and synchronization overhead of `TypedDashMap` would be wasted here.

If plugin-context resolve grows features that need the same custom field to be written from multiple places concurrently, we can revisit this choice and switch `CustomField` back to `TypedDashMap`.

## Related

- `crates/rolldown_plugin/src/types/custom_field.rs`
- `crates/rolldown_plugin/src/types/plugin_context_resolve_options.rs`
Loading