turbopack_cli_utils/
runtime_entry.rs1use anyhow::Result;
2use turbo_tasks::{ResolvedVc, Vc, turbobail};
3use turbo_tasks_fs::FileSystemPath;
4use turbopack_core::{
5 chunk::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets},
6 context::AssetContext,
7 module::Module,
8 reference_type::CommonJsReferenceSubType,
9 resolve::{ResolveErrorMode, origin::PlainResolveOrigin, parse::Request},
10 source::Source,
11};
12use turbopack_resolve::ecmascript::cjs_resolve;
13
14#[turbo_tasks::value(shared)]
15pub enum RuntimeEntry {
16 Request(ResolvedVc<Request>, FileSystemPath),
17 Evaluatable(ResolvedVc<Box<dyn EvaluatableAsset>>),
18 Source(ResolvedVc<Box<dyn Source>>),
19}
20
21#[turbo_tasks::value_impl]
22impl RuntimeEntry {
23 #[turbo_tasks::function]
24 pub async fn resolve_entry(
25 &self,
26 asset_context: Vc<Box<dyn AssetContext>>,
27 ) -> Result<Vc<EvaluatableAssets>> {
28 let (request, path) = match self {
29 RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(**e)),
30 RuntimeEntry::Source(source) => {
31 return Ok(EvaluatableAssets::one(source.to_evaluatable(asset_context)));
32 }
33 RuntimeEntry::Request(r, path) => (r, path),
34 };
35
36 let modules = cjs_resolve(
37 Vc::upcast(PlainResolveOrigin::new(asset_context, path.clone())),
38 **request,
39 CommonJsReferenceSubType::Undefined,
40 None,
41 ResolveErrorMode::Error,
42 )
43 .await?
44 .primary_modules()
45 .await?;
46
47 let mut runtime_entries = Vec::with_capacity(modules.len());
48 for &module in &modules {
49 if let Some(entry) = ResolvedVc::try_sidecast::<Box<dyn EvaluatableAsset>>(module) {
50 runtime_entries.push(entry);
51 } else {
52 turbobail!(
53 "runtime reference resolved to an asset ({}) that cannot be evaluated",
54 module.ident()
55 );
56 }
57 }
58
59 Ok(Vc::cell(runtime_entries))
60 }
61}
62
63#[turbo_tasks::value(transparent)]
64pub struct RuntimeEntries(Vec<ResolvedVc<RuntimeEntry>>);
65
66#[turbo_tasks::value_impl]
67impl RuntimeEntries {
68 #[turbo_tasks::function]
69 pub async fn resolve_entries(
70 &self,
71 asset_context: Vc<Box<dyn AssetContext>>,
72 ) -> Result<Vc<EvaluatableAssets>> {
73 let mut runtime_entries = Vec::new();
74
75 for reference in &self.0 {
76 let resolved_entries = reference.resolve_entry(asset_context).await?;
77 runtime_entries.extend(&resolved_entries);
78 }
79
80 Ok(Vc::cell(runtime_entries))
81 }
82}