From 46bfcbbaa84b4b715f3b829c9b4ac3b5154adfb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 30 Apr 2020 14:37:06 +0200 Subject: refactor(core): add "prepare_load" hook to ModuleLoader trait (#4866) This PR adds prepare_load hook method to ModuleLoader trait. It allows implementors to perform preparation work before starting actual module loading into isolate. It's meant to be used in CLI; where "transpilation" step will be explicitly performed during prepare_load instead of doing it adhoc for each module if needed. --- core/modules.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'core/modules.rs') diff --git a/core/modules.rs b/core/modules.rs index 7e548ec82..632df2dd0 100644 --- a/core/modules.rs +++ b/core/modules.rs @@ -47,6 +47,8 @@ pub struct ModuleSource { pub module_url_found: String, } +pub type PrepareLoadFuture = + dyn Future)>; pub type ModuleSourceFuture = dyn Future>; pub trait ModuleLoader { @@ -74,6 +76,24 @@ pub trait ModuleLoader { maybe_referrer: Option, is_dyn_import: bool, ) -> Pin>; + + /// This hook can be used by implementors to do some preparation + /// work before starting loading of modules. + /// + /// For example implementor might download multiple modules in + /// parallel and transpile them to final JS sources before + /// yielding control back to Isolate. + /// + /// It's not required to implement this method. + fn prepare_load( + &self, + _load_id: ModuleLoadId, + _module_specifier: &ModuleSpecifier, + _maybe_referrer: Option, + _is_dyn_import: bool, + ) -> Pin>>> { + async { Ok(()) }.boxed_local() + } } #[derive(Debug, Eq, PartialEq)] @@ -95,6 +115,8 @@ pub enum LoadState { /// that is consumed by the isolate. pub struct RecursiveModuleLoad { kind: Kind, + // TODO(bartlomieju): in future this value should + // be randomized pub id: ModuleLoadId, pub root_module_id: Option, pub state: LoadState, @@ -142,6 +164,41 @@ impl RecursiveModuleLoad { } } + pub async fn prepare(self) -> (ModuleLoadId, Result) { + let (module_specifier, maybe_referrer) = match self.state { + LoadState::ResolveMain(ref specifier, _) => { + let spec = match self.loader.resolve(specifier, ".", true) { + Ok(spec) => spec, + Err(e) => return (self.id, Err(e)), + }; + (spec, None) + } + LoadState::ResolveImport(ref specifier, ref referrer) => { + let spec = match self.loader.resolve(specifier, referrer, false) { + Ok(spec) => spec, + Err(e) => return (self.id, Err(e)), + }; + (spec, Some(referrer.to_string())) + } + _ => unreachable!(), + }; + + let prepare_result = self + .loader + .prepare_load( + self.id, + &module_specifier, + maybe_referrer, + self.is_dynamic_import(), + ) + .await; + + match prepare_result { + Ok(()) => (self.id, Ok(self)), + Err(e) => (self.id, Err(e)), + } + } + fn add_root(&mut self) -> Result<(), ErrBox> { let module_specifier = match self.state { LoadState::ResolveMain(ref specifier, _) => { -- cgit v1.2.3