mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +00:00
perf(lsp): don't clone asset text (#28165)
This commit is contained in:
parent
17a51c401a
commit
f2a8c300d4
5 changed files with 105 additions and 149 deletions
|
@ -1999,7 +1999,6 @@ mod tests {
|
||||||
StateSnapshot {
|
StateSnapshot {
|
||||||
project_version: 0,
|
project_version: 0,
|
||||||
documents: Arc::new(documents),
|
documents: Arc::new(documents),
|
||||||
assets: Default::default(),
|
|
||||||
config: Arc::new(config),
|
config: Arc::new(config),
|
||||||
resolver,
|
resolver,
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,6 +23,8 @@ use deno_core::futures::future;
|
||||||
use deno_core::futures::future::Shared;
|
use deno_core::futures::future::Shared;
|
||||||
use deno_core::futures::FutureExt;
|
use deno_core::futures::FutureExt;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
|
use deno_core::parking_lot::RwLock;
|
||||||
|
use deno_core::resolve_url;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_error::JsErrorBox;
|
use deno_error::JsErrorBox;
|
||||||
use deno_graph::Resolution;
|
use deno_graph::Resolution;
|
||||||
|
@ -36,6 +38,7 @@ use indexmap::IndexSet;
|
||||||
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
use node_resolver::cache::NodeResolutionThreadLocalCache;
|
||||||
use node_resolver::NodeResolutionKind;
|
use node_resolver::NodeResolutionKind;
|
||||||
use node_resolver::ResolutionMode;
|
use node_resolver::ResolutionMode;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use tower_lsp::lsp_types as lsp;
|
use tower_lsp::lsp_types as lsp;
|
||||||
|
|
||||||
use super::cache::calculate_fs_version;
|
use super::cache::calculate_fs_version;
|
||||||
|
@ -48,8 +51,8 @@ use super::testing::TestCollector;
|
||||||
use super::testing::TestModule;
|
use super::testing::TestModule;
|
||||||
use super::text::LineIndex;
|
use super::text::LineIndex;
|
||||||
use super::tsc;
|
use super::tsc;
|
||||||
use super::tsc::AssetDocument;
|
|
||||||
use crate::graph_util::CliJsrUrlProvider;
|
use crate::graph_util::CliJsrUrlProvider;
|
||||||
|
use crate::tsc::MaybeStaticSource;
|
||||||
|
|
||||||
pub const DOCUMENT_SCHEMES: [&str; 5] =
|
pub const DOCUMENT_SCHEMES: [&str; 5] =
|
||||||
["data", "blob", "file", "http", "https"];
|
["data", "blob", "file", "http", "https"];
|
||||||
|
@ -180,10 +183,85 @@ impl IndexValid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An lsp representation of an asset in memory, that has either been retrieved
|
||||||
|
/// from static assets built into Rust, or static assets built into tsc.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AssetDocument {
|
||||||
|
specifier: ModuleSpecifier,
|
||||||
|
text: MaybeStaticSource,
|
||||||
|
line_index: Arc<LineIndex>,
|
||||||
|
maybe_navigation_tree: Mutex<Option<Arc<tsc::NavigationTree>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AssetDocument {
|
||||||
|
pub fn new(specifier: ModuleSpecifier, text: MaybeStaticSource) -> Self {
|
||||||
|
let line_index = Arc::new(LineIndex::new(text.as_ref()));
|
||||||
|
Self {
|
||||||
|
specifier,
|
||||||
|
text,
|
||||||
|
line_index,
|
||||||
|
maybe_navigation_tree: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn specifier(&self) -> &ModuleSpecifier {
|
||||||
|
&self.specifier
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cache_navigation_tree(
|
||||||
|
&self,
|
||||||
|
navigation_tree: Arc<tsc::NavigationTree>,
|
||||||
|
) {
|
||||||
|
*self.maybe_navigation_tree.lock() = Some(navigation_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text(&self) -> MaybeStaticSource {
|
||||||
|
self.text.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_index(&self) -> Arc<LineIndex> {
|
||||||
|
self.line_index.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn maybe_navigation_tree(&self) -> Option<Arc<tsc::NavigationTree>> {
|
||||||
|
self.maybe_navigation_tree.lock().clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AssetDocuments {
|
||||||
|
inner: RwLock<HashMap<ModuleSpecifier, Arc<AssetDocument>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AssetDocuments {
|
||||||
|
pub fn contains_key(&self, k: &ModuleSpecifier) -> bool {
|
||||||
|
self.inner.read().contains_key(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, k: &ModuleSpecifier) -> Option<Arc<AssetDocument>> {
|
||||||
|
self.inner.read().get(k).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static ASSET_DOCUMENTS: Lazy<AssetDocuments> =
|
||||||
|
Lazy::new(|| AssetDocuments {
|
||||||
|
inner: RwLock::new(
|
||||||
|
crate::tsc::LAZILY_LOADED_STATIC_ASSETS
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| {
|
||||||
|
let url_str = format!("asset:///{k}");
|
||||||
|
let specifier = resolve_url(&url_str).unwrap();
|
||||||
|
let asset = Arc::new(AssetDocument::new(specifier.clone(), v.get()));
|
||||||
|
(specifier, asset)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum AssetOrDocument {
|
pub enum AssetOrDocument {
|
||||||
Document(Arc<Document>),
|
Document(Arc<Document>),
|
||||||
Asset(AssetDocument),
|
Asset(Arc<AssetDocument>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssetOrDocument {
|
impl AssetOrDocument {
|
||||||
|
@ -218,10 +296,12 @@ impl AssetOrDocument {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text(&self) -> Arc<str> {
|
pub fn text(&self) -> MaybeStaticSource {
|
||||||
match self {
|
match self {
|
||||||
AssetOrDocument::Asset(a) => a.text(),
|
AssetOrDocument::Asset(a) => a.text(),
|
||||||
AssetOrDocument::Document(d) => d.text.clone(),
|
AssetOrDocument::Document(d) => {
|
||||||
|
MaybeStaticSource::Computed(d.text.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +351,16 @@ impl AssetOrDocument {
|
||||||
AssetOrDocument::Document(d) => d.resolution_mode(),
|
AssetOrDocument::Document(d) => d.resolution_mode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cache_navigation_tree(
|
||||||
|
&self,
|
||||||
|
navigation_tree: Arc<tsc::NavigationTree>,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
AssetOrDocument::Asset(a) => a.cache_navigation_tree(navigation_tree),
|
||||||
|
AssetOrDocument::Document(d) => d.cache_navigation_tree(navigation_tree),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModuleResult = Result<deno_graph::JsModule, deno_graph::ModuleGraphError>;
|
type ModuleResult = Result<deno_graph::JsModule, deno_graph::ModuleGraphError>;
|
||||||
|
|
|
@ -75,6 +75,7 @@ use super::documents::Document;
|
||||||
use super::documents::Documents;
|
use super::documents::Documents;
|
||||||
use super::documents::DocumentsFilter;
|
use super::documents::DocumentsFilter;
|
||||||
use super::documents::LanguageId;
|
use super::documents::LanguageId;
|
||||||
|
use super::documents::ASSET_DOCUMENTS;
|
||||||
use super::jsr::CliJsrSearchApi;
|
use super::jsr::CliJsrSearchApi;
|
||||||
use super::logging::lsp_log;
|
use super::logging::lsp_log;
|
||||||
use super::logging::lsp_warn;
|
use super::logging::lsp_warn;
|
||||||
|
@ -89,8 +90,6 @@ use super::resolver::LspResolver;
|
||||||
use super::testing;
|
use super::testing;
|
||||||
use super::text;
|
use super::text;
|
||||||
use super::tsc;
|
use super::tsc;
|
||||||
use super::tsc::Assets;
|
|
||||||
use super::tsc::AssetsSnapshot;
|
|
||||||
use super::tsc::ChangeKind;
|
use super::tsc::ChangeKind;
|
||||||
use super::tsc::GetCompletionDetailsArgs;
|
use super::tsc::GetCompletionDetailsArgs;
|
||||||
use super::tsc::TsServer;
|
use super::tsc::TsServer;
|
||||||
|
@ -145,7 +144,6 @@ pub struct LanguageServer {
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct StateSnapshot {
|
pub struct StateSnapshot {
|
||||||
pub project_version: usize,
|
pub project_version: usize,
|
||||||
pub assets: AssetsSnapshot,
|
|
||||||
pub config: Arc<Config>,
|
pub config: Arc<Config>,
|
||||||
pub documents: Arc<Documents>,
|
pub documents: Arc<Documents>,
|
||||||
pub resolver: Arc<LspResolver>,
|
pub resolver: Arc<LspResolver>,
|
||||||
|
@ -191,9 +189,6 @@ impl LanguageServerTaskQueue {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
/// Cached versions of "fixed" assets that can either be inlined in Rust or
|
|
||||||
/// are part of the TypeScript snapshot and have to be fetched out.
|
|
||||||
assets: Assets,
|
|
||||||
cache: LspCache,
|
cache: LspCache,
|
||||||
/// The LSP client that this LSP server is connected to.
|
/// The LSP client that this LSP server is connected to.
|
||||||
pub client: Client,
|
pub client: Client,
|
||||||
|
@ -498,13 +493,11 @@ impl Inner {
|
||||||
ts_server.clone(),
|
ts_server.clone(),
|
||||||
diagnostics_state.clone(),
|
diagnostics_state.clone(),
|
||||||
);
|
);
|
||||||
let assets = Assets::new();
|
|
||||||
let initial_cwd = std::env::current_dir().unwrap_or_else(|_| {
|
let initial_cwd = std::env::current_dir().unwrap_or_else(|_| {
|
||||||
panic!("Could not resolve current working directory")
|
panic!("Could not resolve current working directory")
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
assets,
|
|
||||||
cache,
|
cache,
|
||||||
client,
|
client,
|
||||||
config,
|
config,
|
||||||
|
@ -553,7 +546,7 @@ impl Inner {
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Option<AssetOrDocument> {
|
) -> Option<AssetOrDocument> {
|
||||||
if specifier.scheme() == "asset" {
|
if specifier.scheme() == "asset" {
|
||||||
self.assets.get(specifier).map(AssetOrDocument::Asset)
|
ASSET_DOCUMENTS.get(specifier).map(AssetOrDocument::Asset)
|
||||||
} else {
|
} else {
|
||||||
self.documents.get(specifier).map(AssetOrDocument::Document)
|
self.documents.get(specifier).map(AssetOrDocument::Document)
|
||||||
}
|
}
|
||||||
|
@ -584,14 +577,7 @@ impl Inner {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let navigation_tree = Arc::new(navigation_tree);
|
let navigation_tree = Arc::new(navigation_tree);
|
||||||
match asset_or_doc {
|
asset_or_doc.cache_navigation_tree(navigation_tree.clone());
|
||||||
AssetOrDocument::Asset(_) => self
|
|
||||||
.assets
|
|
||||||
.cache_navigation_tree(specifier, navigation_tree.clone())?,
|
|
||||||
AssetOrDocument::Document(doc) => {
|
|
||||||
doc.cache_navigation_tree(navigation_tree.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
navigation_tree
|
navigation_tree
|
||||||
};
|
};
|
||||||
self.performance.measure(mark);
|
self.performance.measure(mark);
|
||||||
|
@ -627,7 +613,6 @@ impl Inner {
|
||||||
pub fn snapshot(&self) -> Arc<StateSnapshot> {
|
pub fn snapshot(&self) -> Arc<StateSnapshot> {
|
||||||
Arc::new(StateSnapshot {
|
Arc::new(StateSnapshot {
|
||||||
project_version: self.project_version,
|
project_version: self.project_version,
|
||||||
assets: self.assets.snapshot(),
|
|
||||||
config: Arc::new(self.config.clone()),
|
config: Arc::new(self.config.clone()),
|
||||||
documents: Arc::new(self.documents.clone()),
|
documents: Arc::new(self.documents.clone()),
|
||||||
resolver: self.resolver.snapshot(),
|
resolver: self.resolver.snapshot(),
|
||||||
|
@ -2805,7 +2790,7 @@ impl Inner {
|
||||||
}
|
}
|
||||||
Ok(span.to_folding_range(
|
Ok(span.to_folding_range(
|
||||||
asset_or_doc.line_index(),
|
asset_or_doc.line_index(),
|
||||||
asset_or_doc.text().as_bytes(),
|
asset_or_doc.text().as_ref().as_bytes(),
|
||||||
self.config.line_folding_only_capable(),
|
self.config.line_folding_only_capable(),
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
129
cli/lsp/tsc.rs
129
cli/lsp/tsc.rs
|
@ -76,6 +76,7 @@ use super::config::LspTsConfig;
|
||||||
use super::documents::AssetOrDocument;
|
use super::documents::AssetOrDocument;
|
||||||
use super::documents::Document;
|
use super::documents::Document;
|
||||||
use super::documents::DocumentsFilter;
|
use super::documents::DocumentsFilter;
|
||||||
|
use super::documents::ASSET_DOCUMENTS;
|
||||||
use super::language_server;
|
use super::language_server;
|
||||||
use super::language_server::StateSnapshot;
|
use super::language_server::StateSnapshot;
|
||||||
use super::logging::lsp_log;
|
use super::logging::lsp_log;
|
||||||
|
@ -96,7 +97,7 @@ use super::urls::INVALID_URI;
|
||||||
use crate::args::jsr_url;
|
use crate::args::jsr_url;
|
||||||
use crate::args::FmtOptionsConfig;
|
use crate::args::FmtOptionsConfig;
|
||||||
use crate::lsp::logging::lsp_warn;
|
use crate::lsp::logging::lsp_warn;
|
||||||
use crate::tsc;
|
use crate::tsc::MaybeStaticSource;
|
||||||
use crate::tsc::ResolveArgs;
|
use crate::tsc::ResolveArgs;
|
||||||
use crate::tsc::MISSING_DEPENDENCY_SPECIFIER;
|
use crate::tsc::MISSING_DEPENDENCY_SPECIFIER;
|
||||||
use crate::util::path::relative_specifier;
|
use crate::util::path::relative_specifier;
|
||||||
|
@ -1398,124 +1399,6 @@ impl TsServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An lsp representation of an asset in memory, that has either been retrieved
|
|
||||||
/// from static assets built into Rust, or static assets built into tsc.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct AssetDocument {
|
|
||||||
specifier: ModuleSpecifier,
|
|
||||||
text: Arc<str>,
|
|
||||||
line_index: Arc<LineIndex>,
|
|
||||||
maybe_navigation_tree: Option<Arc<NavigationTree>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AssetDocument {
|
|
||||||
pub fn new(specifier: ModuleSpecifier, text: impl AsRef<str>) -> Self {
|
|
||||||
let text = text.as_ref();
|
|
||||||
Self {
|
|
||||||
specifier,
|
|
||||||
text: text.into(),
|
|
||||||
line_index: Arc::new(LineIndex::new(text)),
|
|
||||||
maybe_navigation_tree: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn specifier(&self) -> &ModuleSpecifier {
|
|
||||||
&self.specifier
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_navigation_tree(&self, tree: Arc<NavigationTree>) -> Self {
|
|
||||||
Self {
|
|
||||||
maybe_navigation_tree: Some(tree),
|
|
||||||
..self.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn text(&self) -> Arc<str> {
|
|
||||||
self.text.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn line_index(&self) -> Arc<LineIndex> {
|
|
||||||
self.line_index.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn maybe_navigation_tree(&self) -> Option<Arc<NavigationTree>> {
|
|
||||||
self.maybe_navigation_tree.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type AssetsMap = HashMap<ModuleSpecifier, AssetDocument>;
|
|
||||||
|
|
||||||
fn new_assets_map() -> Arc<Mutex<AssetsMap>> {
|
|
||||||
let assets = tsc::LAZILY_LOADED_STATIC_ASSETS
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| {
|
|
||||||
let url_str = format!("asset:///{k}");
|
|
||||||
let specifier = resolve_url(&url_str).unwrap();
|
|
||||||
let asset = AssetDocument::new(specifier.clone(), v.get());
|
|
||||||
(specifier, asset)
|
|
||||||
})
|
|
||||||
.collect::<AssetsMap>();
|
|
||||||
Arc::new(Mutex::new(assets))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Snapshot of Assets.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct AssetsSnapshot(Arc<Mutex<AssetsMap>>);
|
|
||||||
|
|
||||||
impl Default for AssetsSnapshot {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self(new_assets_map())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AssetsSnapshot {
|
|
||||||
pub fn contains_key(&self, k: &ModuleSpecifier) -> bool {
|
|
||||||
self.0.lock().contains_key(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, k: &ModuleSpecifier) -> Option<AssetDocument> {
|
|
||||||
self.0.lock().get(k).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Assets are never updated and so we can safely use this struct across
|
|
||||||
/// multiple threads without needing to worry about race conditions.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Assets {
|
|
||||||
assets: Arc<Mutex<AssetsMap>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Assets {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
assets: new_assets_map(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn snapshot(&self) -> AssetsSnapshot {
|
|
||||||
// it's ok to not make a complete copy for snapshotting purposes
|
|
||||||
// because assets are static
|
|
||||||
AssetsSnapshot(self.assets.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, specifier: &ModuleSpecifier) -> Option<AssetDocument> {
|
|
||||||
self.assets.lock().get(specifier).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cache_navigation_tree(
|
|
||||||
&self,
|
|
||||||
specifier: &ModuleSpecifier,
|
|
||||||
navigation_tree: Arc<NavigationTree>,
|
|
||||||
) -> Result<(), AnyError> {
|
|
||||||
let mut assets = self.assets.lock();
|
|
||||||
let doc = assets
|
|
||||||
.get_mut(specifier)
|
|
||||||
.ok_or_else(|| anyhow!("Missing asset."))?;
|
|
||||||
*doc = doc.with_navigation_tree(navigation_tree);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_tag_body_text(
|
fn get_tag_body_text(
|
||||||
tag: &JsDocTagInfo,
|
tag: &JsDocTagInfo,
|
||||||
language_server: &language_server::Inner,
|
language_server: &language_server::Inner,
|
||||||
|
@ -4553,9 +4436,8 @@ impl State {
|
||||||
&self,
|
&self,
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Option<AssetOrDocument> {
|
) -> Option<AssetOrDocument> {
|
||||||
let snapshot = &self.state_snapshot;
|
|
||||||
if specifier.scheme() == "asset" {
|
if specifier.scheme() == "asset" {
|
||||||
snapshot.assets.get(specifier).map(AssetOrDocument::Asset)
|
ASSET_DOCUMENTS.get(specifier).map(AssetOrDocument::Asset)
|
||||||
} else {
|
} else {
|
||||||
let document = self.get_document(specifier);
|
let document = self.get_document(specifier);
|
||||||
document.map(AssetOrDocument::Document)
|
document.map(AssetOrDocument::Document)
|
||||||
|
@ -4564,7 +4446,7 @@ impl State {
|
||||||
|
|
||||||
fn script_version(&self, specifier: &ModuleSpecifier) -> Option<String> {
|
fn script_version(&self, specifier: &ModuleSpecifier) -> Option<String> {
|
||||||
if specifier.scheme() == "asset" {
|
if specifier.scheme() == "asset" {
|
||||||
if self.state_snapshot.assets.contains_key(specifier) {
|
if ASSET_DOCUMENTS.contains_key(specifier) {
|
||||||
Some("1".to_string())
|
Some("1".to_string())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -4622,7 +4504,7 @@ enum LoadError {
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct LoadResponse {
|
struct LoadResponse {
|
||||||
data: Arc<str>,
|
data: MaybeStaticSource,
|
||||||
script_kind: i32,
|
script_kind: i32,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
is_cjs: bool,
|
is_cjs: bool,
|
||||||
|
@ -5876,7 +5758,6 @@ mod tests {
|
||||||
let snapshot = Arc::new(StateSnapshot {
|
let snapshot = Arc::new(StateSnapshot {
|
||||||
project_version: 0,
|
project_version: 0,
|
||||||
documents: Arc::new(documents),
|
documents: Arc::new(documents),
|
||||||
assets: Default::default(),
|
|
||||||
config: Arc::new(config),
|
config: Arc::new(config),
|
||||||
resolver,
|
resolver,
|
||||||
});
|
});
|
||||||
|
|
|
@ -169,7 +169,8 @@ pub enum StaticAssetSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like a `Cow` but the owned form is an `Arc<str>` instead of `String`
|
/// Like a `Cow` but the owned form is an `Arc<str>` instead of `String`
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
pub enum MaybeStaticSource {
|
pub enum MaybeStaticSource {
|
||||||
Computed(Arc<str>),
|
Computed(Arc<str>),
|
||||||
Static(&'static str),
|
Static(&'static str),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue