JSC::JSInternalPromise* JSDOMWindowBase::moduleLoaderFetch(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleKey)
{
    JSDOMWindowBase* thisObject = JSC::jsCast<JSDOMWindowBase*>(globalObject);
    if (RefPtr<Document> document = thisObject->wrapped().document())
        return document->moduleLoader()->fetch(globalObject, exec, moduleKey);
    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);
    return deferred->reject(exec, jsUndefined());
}
JSC::JSInternalPromise* JSModuleLoader::fetch(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue)
{
    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);

    if (moduleKeyValue.isSymbol())
        return deferred->reject(exec, JSC::createTypeError(exec, "Symbol module key should be already fulfilled with the inlined resource."));

    if (!moduleKeyValue.isString())
        return deferred->reject(exec, JSC::createTypeError(exec, "Module key is not Symbol or String."));

    URL completedUrl(URL(), asString(moduleKeyValue)->value(exec));
    if (!completedUrl.isValid())
        return deferred->reject(exec, JSC::createTypeError(exec, "Module key is an invalid URL."));

    // FIXME: Implement the module fetcher.

    return deferred->promise();
}
JSC::JSInternalPromise* JSModuleLoader::resolve(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleNameValue, JSC::JSValue importerModuleKey)
{
    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);

    // We use a Symbol as a special purpose; It means this module is an inline module.
    // So there is no correct URL to retrieve the module source code. If the module name
    // value is a Symbol, it is used directly as a module key.
    //
    // FIXME: Using symbols for an inline module is a current implementation details of WebKit.
    // Once the spec of this part is specified, we will recast these part.
    if (moduleNameValue.isSymbol())
        return deferred->resolve(exec, moduleNameValue);

    if (!moduleNameValue.isString())
        return deferred->reject(exec, JSC::createTypeError(exec, "Module name is not Symbol or String."));

    String moduleName = asString(moduleNameValue)->value(exec);

    // Now, we consider the given moduleName as the same to the `import "..."` in the module code.
    // We use the completed URL as the unique module key.
    URL completedUrl;

    if (importerModuleKey.isSymbol())
        completedUrl = m_document.completeURL(moduleName);
    else if (importerModuleKey.isUndefined())
        completedUrl = m_document.completeURL(moduleName);
    else if (importerModuleKey.isString()) {
        URL importerModuleUrl(URL(), asString(importerModuleKey)->value(exec));
        if (!importerModuleUrl.isValid())
            return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is an invalid URL."));
        completedUrl = m_document.completeURL(moduleName, importerModuleUrl);
    } else
        return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is not Symbol or String."));

    if (!completedUrl.isValid())
        return deferred->reject(exec, JSC::createTypeError(exec, "Module name constructs an invalid URL."));

    return deferred->resolve(exec, jsString(exec, completedUrl.string()));
}