public override async Task <Document> LoadDocumentAsync(DocumentSettings settings, DocumentInfo?sourceInfo, string specifier, DocumentCategory category, DocumentContextCallback contextCallback) { var alias = ResourceModuleUtils.GetResourceAlias(specifier); if (alias is object) { var resource = await _resourceManager.GetResourceAsync(alias); if (resource is object) { var script = _resourceScriptFactory.CreateFromExtension(resource, Path.GetExtension(alias)); if (script is object) { return(new StringDocument(new DocumentInfo(specifier) { Category = ModuleCategory.Standard }, script)); } } } throw new FileNotFoundException($"The resource {alias} was not found"); //return await _defaultLoader.LoadDocumentAsync(settings, sourceInfo, specifier, category, contextCallback); }
/// <summary> /// User implemented callback to fetch additional imported modules in ES modules. /// </summary> /// <remarks> /// The callback is invoked on the current runtime execution thread, therefore execution is blocked until /// the callback completes. Notify the host to fetch the dependent module. This is the "import" part /// before HostResolveImportedModule in ES6 spec. This notifies the host that the referencing module has /// the specified module dependency, and the host needs to retrieve the module back. /// /// Callback should: /// 1. Check if the requested module has been requested before - if yes return the existing /// module record /// 2. If no create and initialize a new module record with JsInitializeModuleRecord to /// return and schedule a call to JsParseModuleSource for the new record. /// </remarks> /// <param name="referencingModule">The referencing module that is requesting the dependent module.</param> /// <param name="specifier">The specifier coming from the module source code.</param> /// <param name="dependentModuleRecord">The ModuleRecord of the dependent module. If the module was requested /// before from other source, return the existing ModuleRecord, otherwise /// return a newly created ModuleRecord.</param> /// <returns> /// Returns a <c>JsNoError</c> if the operation succeeded an error code otherwise. /// </returns> /// <see cref="JavaScriptFetchImportedModuleCallBack"/> private JavaScriptErrorCode LoadModuleImpl(JavaScriptModuleRecord referencingModule, JavaScriptValue specifier, out JavaScriptModuleRecord dependentModuleRecord) { var specifierString = specifier.ToString(); if (_moduleLeases.TryGetValue(specifierString, out var lease)) { dependentModuleRecord = lease.Module; return(JavaScriptErrorCode.NoError); } var alias = ResourceModuleUtils.GetResourceAlias(specifierString); if (alias is null) { dependentModuleRecord = JavaScriptModuleRecord.Initialize(referencingModule, specifier); dependentModuleRecord.HostUrl = specifierString; // Only for debugging dependentModuleRecord.Exception = JavaScriptValue.CreateTypeError($"Failed to resolve module for specifier '{specifierString}'"); _moduleLeases.Add(specifierString, new ModuleLease(dependentModuleRecord)); dependentModuleRecord = _moduleLeases[specifierString].Module; return(JavaScriptErrorCode.NoError); } dependentModuleRecord = JavaScriptModuleRecord.Initialize(referencingModule, specifier); dependentModuleRecord.HostUrl = specifierString; // Only for debugging _moduleLeases.Add(specifierString, new ModuleLease(dependentModuleRecord)); // Fire off a task in the threadpool Task.Run(async() => { var module = _moduleLeases[specifierString].Module; try { var resource = await _resourceManager.GetResourceAsync(alias); if (resource is object) { var script = _resourceScriptFactory.CreateFromExtension(resource, Path.GetExtension(specifierString)); _dispatcher.Invoke(() => { using (_context.GetScope()) { module.ParseSource(script); } }); } else { _dispatcher.Invoke(() => { using (_context.GetScope()) { ThrowModuleException(module, JavaScriptValue.CreateError($"Could not find the resource '{specifierString}'")); } }); } } catch (Exception e) { _dispatcher.Invoke(() => { using (_context.GetScope()) { ThrowModuleException(module, JavaScriptValue.CreateError(e.Message)); } }); } void ThrowModuleException(JavaScriptModuleRecord module, JavaScriptValue error) { error.AddRef(); module.Exception = error; if (!JavaScriptContext.HasException) { JavaScriptContext.SetException(error); } try { Native.ThrowIfError(JavaScriptErrorCode.ScriptException); } catch (Exception e) { OnResourceLoadError?.Invoke(e); } finally { error.Release(); } } }); return(JavaScriptErrorCode.NoError); }