UNPKG

blazor-micro-frontends

Version:

Streamlined creation and integration of micro frontends using ASP.NET Blazor (Server/WebAssembly).

294 lines (293 loc) 9.59 kB
class u { get retryMaximumCount() { return this.retryMaximun; } get retryIntervallInMilliseconds() { return this.retryIntervall; } constructor(e, t) { this.retryMaximun = e, this.retryIntervall = t, this.isReconnectCanceled = !1; } async onConnectionDownAsync() { this.showReconnectModel(), await this.tryReconnectAsync(); } onConnectionUp() { this.isReconnectCanceled = !0, this.hideReconnectModel(); } showReconnectModel() { this.updateReconnectModal((e) => { const t = e.classList; t.contains("components-reconnect-modal-visible") || (this.resetReconnectModal(e), t.add("components-reconnect-modal-visible")); }); } hideReconnectModel() { this.updateReconnectModal((e) => { const t = e.classList; t.contains("components-reconnect-modal-visible") && (t.remove("components-reconnect-modal-visible"), this.resetReconnectModal(e)); }); } updateReconnectModal(e) { this.reconnectionModals = document.querySelectorAll(".components-reconnect-modal"), this.reconnectionModals.forEach((t) => { e(t); }); } async tryReconnectAsync() { this.isReconnectCanceled = !1; for (let e = 0; e < this.retryMaximun; e++) { if (this.isReconnectCanceled) return; this.updateReconnectText(e); try { if (await window.Blazor.reconnect()) return; this.showReloadButton(); return; } catch { } await new Promise((t) => setTimeout(t, this.retryIntervall)); } this.showReloadButton(); } showReloadButton() { this.updateReconnectModal((e) => { this.hideReconnectSpinner(e), this.hideReconnectText(e); const t = e.querySelector(".components-reconnect-button"); if (!t) return; const n = t.classList; n.contains("components-reconnect-button-visible") || n.add("components-reconnect-button-visible"); }); } updateReconnectText(e) { const t = this.retryMaximun - e; this.updateReconnectModal((n) => { const o = n.querySelector(".components-reconnect-count"); o && (o.innerHTML = t.toString()); }); } hideReconnectSpinner(e) { const t = e.querySelector(".components-reconnect-spinner"); if (!t) return; const n = t.classList; n.contains("components-reconnect-spinner-hidden") || n.add("components-reconnect-spinner-hidden"); } hideReconnectText(e) { const t = e.querySelector(".components-reconnect-count"); if (!t) return; const n = t.classList; n.contains("components-reconnect-count-hidden") || n.add("components-reconnect-count-hidden"); } resetReconnectModal(e) { const t = e.querySelector(".components-reconnect-spinner"), n = e.querySelector(".components-reconnect-count"); if (!n || !t) return; t.classList.remove("components-reconnect-spinner-hidden"), n.classList.remove("components-reconnect-count-hidden"), n.innerHTML = ""; } } async function a(s, e, t = !0) { return new Promise((n, o) => { const r = document.createElement("script"), c = () => { t && document.body.removeChild(r); }; r.crossOrigin = "anonymous", r.async = !0, r.src = s, r.onload = () => { c(), n(); }, r.onerror = () => { c(), o(new Error("Failed to load script.")); }, e == null || e(r), document.body.appendChild(r); }); } async function h(s, e) { if (!e) return; const t = `${s}${e}.modules.json`, n = await fetch(t, { headers: { "Content-Type": "application/json" } }); if (!n.ok) return; const o = await n.json(); await Promise.all(o.map(async (r) => { await a(`${s}${r}`, (c) => { c.type = "module"; }); })); } class d { constructor(e) { this.pathBase = e; } async startAsync(e) { if (!this.blazorScript) { console.error("No blazor script available."); return; } await a(this.blazorScript, (n) => { n.setAttribute("autostart", "false"); }); const t = e ?? this.getDefaultOptions(); window.Blazor.start(t); } } class w extends d { constructor(e, t) { super(e), this.transport = t ? 4 : 5, this.blazorScript = `${this.pathBase}_framework/blazor.server.js`; } useModulesLoader(e) { return this.moduleName = e, this; } setReconnectSettings(e, t) { return this.retryMaximun = e, this.retryIntervall = t, this; } getDefaultOptions() { const e = new u(this.retryMaximun ?? 10, this.retryIntervall ?? 1e3); return { initializers: { beforeStart: [() => h(this.pathBase, this.moduleName)] }, configureSignalR: (t) => t.withUrl(`${this.pathBase}_blazor`, this.transport), reconnectionOptions: { maxRetries: e.retryMaximumCount, retryIntervalMilliseconds: e.retryIntervallInMilliseconds }, reconnectionHandler: { onConnectionDown: () => e.onConnectionDownAsync(), onConnectionUp: () => e.onConnectionUp() } }; } } function p(s, e, t, n, o) { if (e === "manifest") return S(n, s); const r = new URL(s, document.baseURI), i = new URL(n, r).toString(); return !o || location.hostname === "localhost" || e === "dotnetjs" || e === "configuration" ? i : z(e, i, o); } async function S(s, e) { var i; const t = await fetch(s, { cache: "no-cache" }); if (!t.ok || e.length < 2) return t; const n = await t.json(), o = new URL(document.baseURI), r = e.replace(o.pathname, ""); if ((i = n.resources) != null && i.libraryInitializers) { const y = n.resources.libraryInitializers, l = {}; for (const [m, f] of Object.entries(y)) { const b = `${r}${m}`; l[b] = f; } n.resources.libraryInitializers = l; } const c = "application/json"; return new Response(JSON.stringify(n), { headers: { "content-type": c } }); } async function z(s, e, t) { const n = await fetch(`${e}${t.extension}`, { cache: "no-cache" }); if (!n.ok) return fetch(e); const o = await n.arrayBuffer(), r = new Int8Array(o), c = t.decode(r), i = s === "dotnetwasm" ? "application/wasm" : "application/octet-stream"; return new Response(c, { headers: { "content-type": i } }); } class C extends d { constructor(e) { super(e), this.blazorScript = `${this.pathBase}_framework/blazor.webassembly.js`; } useDecoder(e, t) { return this.decoder = { decode: e, extension: t }, this; } getDefaultOptions() { return { loadBootResource: (e, t, n) => p(this.pathBase, e, t, n, this.decoder) }; } } class v extends w { constructor(e, t) { super(e, t), this.blazorScript = `${this.pathBase}_framework/blazor.web.js`; } useDecoder(e, t) { return this.decoder = { decode: e, extension: t }, this; } getDefaultOptions() { const e = new u(this.retryMaximun ?? 10, this.retryIntervall ?? 1e3); return { circuit: { initializers: { beforeStart: [() => h(this.pathBase, this.moduleName)] }, configureSignalR: (t) => t.withUrl(`${this.pathBase}_blazor`, this.transport), reconnectionOptions: { maxRetries: e.retryMaximumCount, retryIntervalMilliseconds: e.retryIntervallInMilliseconds }, reconnectionHandler: { onConnectionDown: () => e.onConnectionDownAsync(), onConnectionUp: () => e.onConnectionUp() } }, webAssembly: { loadBootResource: (t, n, o) => p(this.pathBase, t, n, o, this.decoder) } }; } } async function R(s, e) { return new Promise((t, n) => { const o = document.createElement("link"); o.crossOrigin = "anonymous", o.rel = "stylesheet", o.href = s, o.onload = () => t(), o.onerror = () => { const r = "Failed to load style."; n(new Error(r)); }, document.head.appendChild(o); }); } class g { constructor(e, t) { this.longPolling = !1, this.basePath = e, this.crossOrigin = t ?? "anonymous", this.blazorScripts = /* @__PURE__ */ new Map(), this.blazorStyles = /* @__PURE__ */ new Map(); } useScripts(...e) { return e.forEach((t) => { const n = `${this.basePath}${t}`, o = `body script[src="${n}"]`; this.blazorScripts.set(n, o); }), this; } useStyles(...e) { return e.forEach((t) => { const n = `${this.basePath}${t}`, o = `head link[href="${n}"]`; this.blazorStyles.set(n, o); }), this; } useLongPolling() { return this.longPolling = !0, this; } async initializeAsync() { if (this.blazorScripts.size < 1) { console.warn("No scripts are added."); return; } const e = this.blazorScripts.keys().next(); if (!(await fetch(e.value)).ok) return console.warn("The service is currently unavailable."), Promise.resolve(void 0); for (const [n, o] of this.blazorStyles) await this.addStylesAsync(n, o); for (const [n, o] of this.blazorScripts) await this.addScriptAsync(n, o); } addScriptAsync(e, t) { return document.querySelector(t) ? Promise.resolve() : a(e, (o) => { o.crossOrigin = this.crossOrigin, o.setAttribute("data-base-path", this.getScriptBasePath()), this.longPolling && o.setAttribute("data-long-polling", "true"); }, !1); } getScriptBasePath() { const e = new URL(document.baseURI).pathname; let t = this.basePath; return t.startsWith(e) && (t = t.slice(e.length)), t.startsWith("/") ? t : `/${t}`; } addStylesAsync(e, t) { return document.querySelector(t) ? Promise.resolve() : R(e); } } export { g as BlazorInitializerClient, w as BlazorInitializerServer, C as BlazorInitializerWasm, v as BlazorInitializerWeb };