UNPKG

oc-client-browser

Version:
75 lines (64 loc) 1.64 kB
// @ts-check export class LJS { loaded = new Set(); errors = new Set(); parse(url) { const [path, hash] = url.split("#"); const isModule = path.startsWith("module:"); const src = path.replace(/^module:/, ""); const [fallback, id] = (hash?.split("=") || []).reduce( (a, p) => (p.startsWith("=") ? [p.slice(1), a[1]] : [a[0], p]), [], ); return { src, isModule, fallback, id }; } async load(...args) { for (const arg of args) { Array.isArray(arg) ? await Promise.all(arg.map((a) => this._load(a))) : typeof arg === "function" ? await arg() : await this._load(arg); } return this; } async _load(url) { if (this.loaded.has(url)) return; try { url.endsWith(".css") ? await this.css(url) : await this.js(url); this.loaded.add(url); } catch (err) { for (const fn of this.errors) { fn(url); } throw err; } } js(url) { const { src, isModule, fallback } = this.parse(url); return new Promise((resolve, reject) => { const script = document.createElement("script"); script.type = isModule ? "module" : "text/javascript"; script.src = src; script.onload = resolve; script.onerror = () => fallback ? this._load(fallback).then(resolve).catch(reject) : reject(); document.head.append(script); }); } css(url) { const { src } = this.parse(url); return new Promise((resolve, reject) => { const link = document.createElement("link"); link.rel = "stylesheet"; link.href = src; link.onload = resolve; link.onerror = reject; document.head.append(link); }); } onError(fn) { this.errors.add(fn); return this; } }