summaryrefslogtreecommitdiff
path: root/core/modules.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-04-30 14:37:06 +0200
committerGitHub <noreply@github.com>2020-04-30 14:37:06 +0200
commit46bfcbbaa84b4b715f3b829c9b4ac3b5154adfb6 (patch)
treef856f4ccb96ac4c3eca4105985684885bf62d824 /core/modules.rs
parent5f8c4d9b686efc10abe2abb7ba453020ecfe4814 (diff)
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.
Diffstat (limited to 'core/modules.rs')
-rw-r--r--core/modules.rs57
1 files changed, 57 insertions, 0 deletions
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<Output = (ModuleLoadId, Result<RecursiveModuleLoad, ErrBox>)>;
pub type ModuleSourceFuture = dyn Future<Output = Result<ModuleSource, ErrBox>>;
pub trait ModuleLoader {
@@ -74,6 +76,24 @@ pub trait ModuleLoader {
maybe_referrer: Option<ModuleSpecifier>,
is_dyn_import: bool,
) -> Pin<Box<ModuleSourceFuture>>;
+
+ /// 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<String>,
+ _is_dyn_import: bool,
+ ) -> Pin<Box<dyn Future<Output = Result<(), ErrBox>>>> {
+ 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<ModuleId>,
pub state: LoadState,
@@ -142,6 +164,41 @@ impl RecursiveModuleLoad {
}
}
+ pub async fn prepare(self) -> (ModuleLoadId, Result<Self, ErrBox>) {
+ 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, _) => {