UNPKG

@descope/sdk-mixins

Version:
114 lines (111 loc) 7.31 kB
import { __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib'; import { createSingletonMixin, compose, pathJoin } from '@descope/sdk-helpers'; import { loggerMixin } from '../loggerMixin/loggerMixin.js'; import { ASSETS_FOLDER, BASE_CONTENT_URL, OVERRIDE_CONTENT_URL, BASE_CONTENT_URL_FALLBACK } from './constants.js'; import { projectIdMixin } from '../projectIdMixin.js'; import { baseUrlMixin } from '../baseUrlMixin.js'; import { fetchWithFallbacks } from './fetchWithFallbacks.js'; function getResourceUrl({ projectId, filename, assetsFolder = ASSETS_FOLDER, baseUrl = BASE_CONTENT_URL, }) { const url = new URL(baseUrl); url.pathname = pathJoin(url.pathname, projectId, assetsFolder, filename); // we want to keep the baseUrl so we can use it later url.baseUrl = baseUrl; return url; } const staticResourcesMixin = createSingletonMixin((superclass) => { var _StaticResourcesMixinClass_instances, _StaticResourcesMixinClass_lastBaseUrl, _StaticResourcesMixinClass_workingBaseUrl, _StaticResourcesMixinClass_failedUrls, _StaticResourcesMixinClass_getResourceUrls, _StaticResourcesMixinClass_createResourceUrl, _a; const BaseClass = compose(loggerMixin, projectIdMixin, baseUrlMixin)(superclass); // the logic should be as following: // 1. if there is a local storage override, use it // 2. otherwise, if there is a base-static-url attribute, use it // 3. otherwise, try to use base-url // 4. otherwise, try to use default content url (BASE_CONTENT_URL) // 5. otherwise, try to use the fallback content url (BASE_CONTENT_URL_FALLBACK) // For steps 3-5: if the url is valid, keep using it, and if not, don't try it anymore return _a = class StaticResourcesMixinClass extends BaseClass { constructor() { super(...arguments); _StaticResourcesMixinClass_instances.add(this); _StaticResourcesMixinClass_lastBaseUrl.set(this, void 0); _StaticResourcesMixinClass_workingBaseUrl.set(this, void 0); _StaticResourcesMixinClass_failedUrls.set(this, new Set()); } async fetchStaticResource(filename, format) { const resourceUrls = __classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_getResourceUrls).call(this, filename); // Cache the working URL and mark failed URLs const onSuccess = !Array.isArray(resourceUrls) ? null : (index) => { const { baseUrl } = resourceUrls[index]; __classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, baseUrl, "f"); // Mark all URLs before this one as failed for (let i = 0; i < index; i++) { const failedUrl = resourceUrls[i].baseUrl; __classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").add(failedUrl); } }; try { const res = await fetchWithFallbacks(resourceUrls, { cache: 'default' }, { logger: this.logger, onSuccess }); return { body: await res[format](), headers: Object.fromEntries(res.headers.entries()), }; } catch (e) { this.logger.error(e.message); } } get baseStaticUrl() { return this.getAttribute('base-static-url') || ''; } }, _StaticResourcesMixinClass_lastBaseUrl = new WeakMap(), _StaticResourcesMixinClass_workingBaseUrl = new WeakMap(), _StaticResourcesMixinClass_failedUrls = new WeakMap(), _StaticResourcesMixinClass_instances = new WeakSet(), _StaticResourcesMixinClass_getResourceUrls = function _StaticResourcesMixinClass_getResourceUrls(filename) { const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl; // Steps 1-2: Override URL or base-static-url takes precedence if (overrideUrl) { return __classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, overrideUrl); } // Reset state if base-url changed if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_lastBaseUrl, "f") !== this.baseUrl) { __classPrivateFieldSet(this, _StaticResourcesMixinClass_lastBaseUrl, this.baseUrl, "f"); __classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, undefined, "f"); __classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").clear(); } // Build URL list based on cached state or fallback chain const urls = []; if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f")) { // Use cached working URL urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, __classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f"))); // Add fallback only for BASE_CONTENT_URL (for resilience) if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f") === BASE_CONTENT_URL) { urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL_FALLBACK)); } } else { // Build fallback chain: try URLs that haven't failed yet const baseUrlWithPages = this.baseUrl + '/pages'; if (this.baseUrl && !__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(baseUrlWithPages)) { urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, baseUrlWithPages)); } if (!__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(BASE_CONTENT_URL)) { urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL)); } urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL_FALLBACK)); } return urls.length === 1 ? urls[0] : urls; }, _StaticResourcesMixinClass_createResourceUrl = function _StaticResourcesMixinClass_createResourceUrl(filename, baseUrl) { return getResourceUrl({ projectId: this.projectId, filename, baseUrl, }); }, _a; }); export { getResourceUrl, staticResourcesMixin }; //# sourceMappingURL=staticResourcesMixin.js.map