@caspingus/lt
Version:
A utility library of helpers and extensions useful when working with Learnosity APIs.
147 lines (146 loc) • 4.13 kB
JavaScript
import e from "./logger.js";
import { t } from "./extensionsRegistry-Cf-XVCyU.js";
import { n } from "./extensionsFactory-hk5ijx1G.js";
//#region src/utils/initExtensions.js
var r = () => performance.now(), i = null;
function a() {
return i ||= window.__LT_PERF = window.__LT_PERF || [], i;
}
function o(e, t) {
e && a().push(t);
}
function s(e, { limit: t = 50 } = {}) {
if (!e || !i || !i.length) return;
let n = 10 ** 3, r = (e) => Number.isFinite(e) ? Math.round((e + 2 ** -52) * n) / n : e, a = (e, t) => e.reduce((e, n) => e + (Number.isFinite(n[t]) ? n[t] : 0), 0), o = /* @__PURE__ */ new Map();
for (let e of i) o.has(e.id) || o.set(e.id, []), o.get(e.id).push(e);
let s = [];
for (let [e, t] of o) {
if (e === "__init__") continue;
let n = {
id: e,
importMs: 0,
cssMs: 0,
runMs: 0,
totalMs: 0
};
for (let e of t) e.phase === "import" ? n.importMs += e.ms : e.phase === "css" ? n.cssMs += e.ms : e.phase === "run" && (n.runMs += e.ms);
n.totalMs = n.importMs + n.cssMs + n.runMs, s.push(n);
}
s.sort((e, t) => t.totalMs - e.totalMs);
let c = s.slice(0, t).map((e) => ({
id: e.id,
importMs: r(e.importMs),
cssMs: r(e.cssMs),
runMs: r(e.runMs),
totalMs: r(e.totalMs)
}));
c.push({
id: "TOTAL",
importMs: r(a(s, "importMs")),
cssMs: r(a(s, "cssMs")),
runMs: r(a(s, "runMs")),
totalMs: r(a(s, "totalMs"))
}), console.groupCollapsed("[LT] extension performance"), console.table(c, [
"id",
"importMs",
"cssMs",
"runMs",
"totalMs"
]), console.groupEnd();
}
function c(e, t = "lt-extensions") {
if (!e || typeof document > "u") return;
let n = document.head.querySelector(`style#${t}`);
n || (n = document.createElement("style"), n.id = t, n.setAttribute("data-style", "LT Extension Styles"), document.head.append(n)), n.textContent = e;
}
function l(e) {
return typeof e == "string" ? {
id: e,
args: []
} : e || { id: "" };
}
async function u(e, n, i) {
let a = t[e]?.[n];
if (!a) throw Error(`[LT] Unknown extension id "${n}"`);
let s = r(), c = await a();
if (o(i, {
id: n,
phase: "import",
ms: r() - s
}), c[n]?.run) return c[n];
if (c.default?.run) return c.default;
for (let e of Object.values(c)) if (e && typeof e.run == "function") return e;
throw Error(`[LT] Extension "${n}" does not export a runnable module`);
}
function d(t, n, i) {
let a = r(), s = "";
try {
typeof n.getStyles == "function" ? s = String(n.getStyles() || "") : typeof n.styles == "string" && (s = n.styles || "");
} catch (n) {
e.warn(`[LT] getStyles() threw for "${t}"`, n);
} finally {
i && s && o(!0, {
id: t,
phase: "css",
ms: r() - a
});
}
return s;
}
async function f(t, i, a, { mode: f = "sequential", collectCSS: p = !0, dedupeCSS: m = !0, mountId: h = "lt-extensions", perf: g = !1, perfLimit: _ = 50, security: v = {}, request: y = {} } = {}) {
let b = r();
n(t, v, y);
let x = (i || []).map(l);
t.extensions ||= {};
let S = [], C = /* @__PURE__ */ new Set(), w = (e) => Array.isArray(e) ? e : e === void 0 ? [] : [e];
async function T({ id: e, args: n = [] }) {
let i = await u(a, e, g);
t.extensions[e] = i;
let s = r();
try {
let e = i.run(...w(n));
e && typeof e.then == "function" && await e;
} finally {
o(g, {
id: e,
phase: "run",
ms: r() - s
});
}
if (p) {
let t = d(e, i, g).trim();
t && (!m || !C.has(e)) && (S.push(`/* ${e} */\n${t}`), m && C.add(e));
}
}
if (f === "parallel") {
let t = x.map((t) => T(t).catch((n) => e.error(`[LT] Failed to init extension "${t.id}"`, n)));
await Promise.allSettled(t);
} else for (let t of x) try {
await T(t);
} catch (n) {
e.error(`[LT] Failed to init extension "${t.id}"`, n);
}
if (p && S.length) {
let e = r();
c(S.join("\n\n"), h), o(g, {
id: "__init__",
phase: "css:inject",
ms: r() - e
});
}
if (a === "assessment" && t.eventBus) {
let e = r();
t.eventBus.markReady(), o(g, {
id: "__init__",
phase: "eventBus:ready",
ms: r() - e
});
}
o(g, {
id: "__init__",
phase: "total",
ms: r() - b
}), s(g, { limit: _ });
}
//#endregion
export { f as runExtensions };