Browse Source

Add Loaded event to DefaultModuleLoader (#1373)

Jither 2 years ago
parent
commit
1a7b442599

+ 17 - 0
Jint.Tests/Runtime/Modules/DefaultModuleResolverTests.cs → Jint.Tests/Runtime/Modules/DefaultModuleLoaderTests.cs

@@ -35,6 +35,23 @@ public class DefaultModuleLoaderTests
         Assert.StartsWith(exc.Specifier, specifier);
     }
 
+    [Fact]
+    public void ShouldTriggerLoadedEvent()
+    {
+        var loader = new DefaultModuleLoader(ModuleTests.GetBasePath());
+        bool triggered = false;
+        loader.Loaded += (sender, source, module) =>
+        {
+            Assert.Equal(loader, sender);
+            Assert.NotNull(source);
+            Assert.NotNull(module);
+            triggered = true;
+        };
+        var engine = new Engine(options => options.EnableModules(loader));
+        engine.ImportModule("./modules/format-name.js");
+        Assert.True(triggered);
+    }
+
     [Fact]
     public void ShouldResolveBareSpecifiers()
     {

+ 16 - 3
Jint/Runtime/Modules/DefaultModuleLoader.cs

@@ -5,9 +5,19 @@ namespace Jint.Runtime.Modules;
 
 public sealed class DefaultModuleLoader : IModuleLoader
 {
+    public delegate void ModuleLoadedEventHandler(object sender, string source, Module module);
+
     private readonly Uri _basePath;
     private readonly bool _restrictToBasePath;
 
+    /// <summary>
+    /// The Loaded event is triggered after a module is loaded and parsed.
+    /// </summary>
+    /// <remarks>
+    /// The event is not triggered if a module was loaded but failed to parse.
+    /// </remarks>
+    public event ModuleLoadedEventHandler? Loaded;
+
     public DefaultModuleLoader(string basePath) : this(basePath, true)
     {
 
@@ -125,22 +135,25 @@ public sealed class DefaultModuleLoader : IModuleLoader
 
         var code = File.ReadAllText(fileName);
 
+        var source = resolved.Uri.LocalPath;
         Module module;
         try
         {
-            module = new JavaScriptParser().ParseModule(code, source: resolved.Uri.LocalPath);
+            module = new JavaScriptParser().ParseModule(code, source);
         }
         catch (ParserException ex)
         {
-            ExceptionHelper.ThrowSyntaxError(engine.Realm, $"Error while loading module: error in module '{resolved.Uri.LocalPath}': {ex.Error}");
+            ExceptionHelper.ThrowSyntaxError(engine.Realm, $"Error while loading module: error in module '{source}': {ex.Error}");
             module = null;
         }
         catch (Exception)
         {
-            ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {resolved.Uri?.LocalPath}", (Location) default);
+            ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {source}", (Location) default);
             module = null;
         }
 
+        Loaded?.Invoke(this, source, module);
+
         return module;
     }