UNPKG

nstdlib-nightly

Version:

Node.js standard library converted to runtime-agnostic ES modules.

128 lines (114 loc) 4.05 kB
// Source: https://github.com/nodejs/node/blob/65eff1eb/lib/internal/modules/esm/module_map.js import { kImplicitTypeAttribute } from "nstdlib/lib/internal/modules/esm/assert"; import { codes as __codes__ } from "nstdlib/lib/internal/errors"; import { validateString } from "nstdlib/lib/internal/validators"; import * as __hoisted_internal_modules_esm_module_job__ from "nstdlib/lib/internal/modules/esm/module_job"; const { ERR_INVALID_ARG_TYPE } = __codes__; /** * Cache the results of the `resolve` step of the module resolution and loading process. * Future resolutions of the same input (specifier, parent URL and import attributes) * must return the same result if the first attempt was successful, per * https://tc39.es/ecma262/#sec-HostLoadImportedModule. * This cache is *not* used when custom loaders are registered. */ class ResolveCache extends Map { constructor(i) { super(i); } // eslint-disable-line no-useless-constructor /** * Generates the internal serialized cache key and returns it along the actual cache object. * * It is exposed to allow more efficient read and overwrite a cache entry. * @param {string} specifier * @param {Record<string,string>} importAttributes * @returns {string} */ serializeKey(specifier, importAttributes) { // To serialize the ModuleRequest (specifier + list of import attributes), // we need to sort the attributes by key, then stringifying, // so that different import statements with the same attributes are always treated // as identical. const keys = Object.keys(importAttributes); if (keys.length === 0) { return specifier + "::"; } return ( specifier + "::" + Array.prototype.join.call( Array.prototype.map.call( Array.prototype.sort.call(keys), (key) => JSONStringify(key) + JSONStringify(importAttributes[key]), ), ",", ) ); } #getModuleCachedImports(parentURL) { let internalCache = super.get(parentURL); if (internalCache == null) { super.set(parentURL, (internalCache = { __proto__: null })); } return internalCache; } /** * @param {string} serializedKey * @param {string} parentURL * @returns {import('./loader').ModuleExports | Promise<import('./loader').ModuleExports>} */ get(serializedKey, parentURL) { return this.#getModuleCachedImports(parentURL)[serializedKey]; } /** * @param {string} serializedKey * @param {string} parentURL * @param {{ format: string, url: URL['href'] }} result */ set(serializedKey, parentURL, result) { this.#getModuleCachedImports(parentURL)[serializedKey] = result; return this; } has(serializedKey, parentURL) { return serializedKey in this.#getModuleCachedImports(parentURL); } } /** * Cache the results of the `load` step of the module resolution and loading process. */ class LoadCache extends Map { constructor(i) { super(i); } // eslint-disable-line no-useless-constructor get(url, type = kImplicitTypeAttribute) { validateString(url, "url"); validateString(type, "type"); return super.get(url)?.[type]; } set(url, type = kImplicitTypeAttribute, job) { validateString(url, "url"); validateString(type, "type"); const { ModuleJobBase } = __hoisted_internal_modules_esm_module_job__; if (job instanceof ModuleJobBase !== true && typeof job !== "function") { throw new ERR_INVALID_ARG_TYPE("job", "ModuleJob", job); } { /* debug */ } const cachedJobsForUrl = super.get(url) ?? { __proto__: null }; cachedJobsForUrl[type] = job; return super.set(url, cachedJobsForUrl); } has(url, type = kImplicitTypeAttribute) { validateString(url, "url"); validateString(type, "type"); return super.get(url)?.[type] !== undefined; } delete(url, type = kImplicitTypeAttribute) { const cached = super.get(url); if (cached) { cached[type] = undefined; } } } export { LoadCache }; export { ResolveCache };