//@ts-check const ID = "JadefinIntegrity"; class JadefinIntegrity { /** @type {Map} */ loaded = new Map(); constructor() { this.getOrAdd(ID, import.meta.url, () => this); } /** * @template T * @param {string} id * @param {string} [url] * @param {() => T} [cb] * @returns {T} */ getOrAdd(id, url, cb) { let entry = this.loaded.get(id); if (entry) { if (url && url != entry.url) { window["Jadefin"].log.w(`INTEGRITY CONFLICT for "${id}", loaded vs requested: \n ${entry.url} \n ${url}`); } } else if (!url || !cb) { throw new Error(`"${id}" not loaded`); } else { entry = { url, loaded: cb() }; this.loaded.set(id, entry); } return entry.loaded; } } if (window[ID]) { window[ID].getOrAdd(ID, import.meta.url, () => null); } /** @type {JadefinIntegrity} */ const integrity = window[ID] ??= new JadefinIntegrity(); /** @type {typeof JadefinIntegrity.prototype.getOrAdd} */ export default integrity.getOrAdd.bind(integrity);