@wordpress/interactivity-router
Version:
Package that exposes state and actions from the `core/router` store, part of the Interactivity API.
217 lines (216 loc) • 6.85 kB
JavaScript
// packages/interactivity-router/src/assets/dynamic-importmap/loader.ts
import * as lexer from "es-module-lexer";
import { fetchModule } from "./fetch.mjs";
import { resolve } from "./resolver.mjs";
var initPromise = lexer.init;
var initialImportMapElement = window.document.querySelector(
"script#wp-importmap[type=importmap]"
);
var initialImportMap = initialImportMapElement ? JSON.parse(initialImportMapElement.text) : { imports: {}, scopes: {} };
var skip = (id) => Object.keys(initialImportMap.imports).includes(id);
var fetchCache = {};
var registry = {};
Object.keys(initialImportMap.imports).forEach((id) => {
registry[id] = {
blobUrl: id
};
});
async function loadAll(load, seen) {
if (load.blobUrl || seen[load.url]) {
return;
}
seen[load.url] = 1;
await load.linkPromise;
await Promise.all(load.deps.map((dep) => loadAll(dep, seen)));
}
function urlJsString(url) {
return `'${url.replace(/'/g, "\\'")}'`;
}
var createBlob = (source, type = "text/javascript") => URL.createObjectURL(new Blob([source], { type }));
function resolveDeps(load, seen) {
if (load.blobUrl || !seen[load.url]) {
return;
}
seen[load.url] = 0;
for (const dep of load.deps) {
resolveDeps(dep, seen);
}
const [imports, exports] = load.analysis;
const source = load.source;
let resolvedSource = "";
if (!imports.length) {
resolvedSource += source;
} else {
let pushStringTo = function(originalIndex) {
while (dynamicImportEndStack.length && dynamicImportEndStack[dynamicImportEndStack.length - 1] < originalIndex) {
const dynamicImportEnd = dynamicImportEndStack.pop();
resolvedSource += `${source.slice(
lastIndex,
dynamicImportEnd
)}, ${urlJsString(load.responseUrl)}`;
lastIndex = dynamicImportEnd;
}
resolvedSource += source.slice(lastIndex, originalIndex);
lastIndex = originalIndex;
};
let lastIndex = 0;
let depIndex = 0;
const dynamicImportEndStack = [];
for (const {
s: start,
ss: statementStart,
se: statementEnd,
d: dynamicImportIndex
} of imports) {
if (dynamicImportIndex === -1) {
const depLoad = load.deps[depIndex++];
let blobUrl = depLoad.blobUrl;
const cycleShell = !blobUrl;
if (cycleShell) {
if (!(blobUrl = depLoad.shellUrl)) {
blobUrl = depLoad.shellUrl = createBlob(
`export function u$_(m){${depLoad.analysis[1].map(({ s, e }, i) => {
const q = depLoad.source[s] === '"' || depLoad.source[s] === "'";
return `e$_${i}=m${q ? `[` : "."}${depLoad.source.slice(s, e)}${q ? `]` : ""}`;
}).join(",")}}${depLoad.analysis[1].length ? `let ${depLoad.analysis[1].map((_, i) => `e$_${i}`).join(",")};` : ""}export {${depLoad.analysis[1].map(
({ s, e }, i) => `e$_${i} as ${depLoad.source.slice(
s,
e
)}`
).join(",")}}
//# sourceURL=${depLoad.responseUrl}?cycle`
);
}
}
pushStringTo(start - 1);
resolvedSource += `/*${source.slice(
start - 1,
statementEnd
)}*/${urlJsString(blobUrl)}`;
if (!cycleShell && depLoad.shellUrl) {
resolvedSource += `;import*as m$_${depIndex} from'${depLoad.blobUrl}';import{u$_ as u$_${depIndex}}from'${depLoad.shellUrl}';u$_${depIndex}(m$_${depIndex})`;
depLoad.shellUrl = void 0;
}
lastIndex = statementEnd;
} else if (dynamicImportIndex === -2) {
throw Error("The import.meta property is not supported.");
} else {
pushStringTo(statementStart);
resolvedSource += `wpInteractivityRouterImport(`;
dynamicImportEndStack.push(statementEnd - 1);
lastIndex = start;
}
}
if (load.shellUrl) {
resolvedSource += `
;import{u$_}from'${load.shellUrl}';try{u$_({${exports.filter((e) => e.ln).map(({ s, e, ln }) => `${source.slice(s, e)}:${ln}`).join(",")}})}catch(_){};
`;
}
pushStringTo(source.length);
}
let hasSourceURL = false;
resolvedSource = resolvedSource.replace(
sourceMapURLRegEx,
(match, isMapping, url) => {
hasSourceURL = !isMapping;
return match.replace(
url,
() => new URL(url, load.responseUrl).toString()
);
}
);
if (!hasSourceURL) {
resolvedSource += "\n//# sourceURL=" + load.responseUrl;
}
load.blobUrl = createBlob(resolvedSource);
load.source = void 0;
}
var sourceMapURLRegEx = /\n\/\/# source(Mapping)?URL=([^\n]+)\s*((;|\/\/[^#][^\n]*)\s*)*$/;
function getOrCreateLoad(url, fetchOpts, parent) {
let load = registry[url];
if (load) {
return load;
}
load = { url };
if (registry[url]) {
let i = 0;
while (registry[load.url + ++i]) {
}
load.url += i;
}
registry[load.url] = load;
load.fetchPromise = (async () => {
let source;
({ responseUrl: load.responseUrl, source } = await (fetchCache[url] || fetchModule(url, fetchOpts, parent)));
try {
load.analysis = lexer.parse(source, load.url);
} catch (e) {
console.error(e);
load.analysis = [[], [], false, false];
}
load.source = source;
return load;
})();
load.linkPromise = load.fetchPromise.then(async () => {
let childFetchOpts = fetchOpts;
load.deps = (await Promise.all(
load.analysis[0].map(async ({ n, d }) => {
if (d !== -1 || !n) {
return void 0;
}
const responseUrl = resolve(
n,
load.responseUrl || load.url
);
if (skip && skip(responseUrl)) {
return { blobUrl: responseUrl };
}
if (childFetchOpts.integrity) {
childFetchOpts = {
...childFetchOpts,
integrity: void 0
};
}
return getOrCreateLoad(
responseUrl,
childFetchOpts,
load.responseUrl
).fetchPromise;
})
)).filter((l) => l);
});
return load;
}
var dynamicImport = (u) => import(
/* webpackIgnore: true */
u
);
async function preloadModule(url, fetchOpts) {
await initPromise;
const load = getOrCreateLoad(url, fetchOpts, null);
const seen = {};
await loadAll(load, seen);
resolveDeps(load, seen);
await Promise.resolve();
return load;
}
async function importPreloadedModule(load) {
const module = await dynamicImport(load.blobUrl);
if (load.shellUrl) {
(await dynamicImport(load.shellUrl)).u$_(module);
}
return module;
}
async function topLevelLoad(url, fetchOpts) {
const load = await preloadModule(url, fetchOpts);
return importPreloadedModule(load);
}
export {
importPreloadedModule,
initPromise,
initialImportMap,
preloadModule,
registry,
topLevelLoad
};
//# sourceMappingURL=loader.mjs.map