@revenuecat/purchases-ui-js
Version:
Web components for Paywalls. Powered by RevenueCat
62 lines (61 loc) • 2.65 kB
JavaScript
export { FIT_MESSAGE, RESIZE_MESSAGE, } from "@revenuecat/workflow-web-components-sdk";
/** Base origin the versioned SDK builds are served from. */
export const SDK_BASE_URL = "https://sdk.revenuecat-static.com";
/** Stable, rolling per-major URL of the host bridge ESM build. */
export function hostSdkUrl(protocolVersion) {
return `${SDK_BASE_URL}/v${protocolVersion}/rc-host.js`;
}
// The bare dynamic import. `@vite-ignore` / `webpackIgnore` keep bundlers from
// resolving the absolute CDN URL at build time; the browser fetches it at runtime.
const defaultImporter = (url) => import(/* @vite-ignore */ /* webpackIgnore: true */ url);
let importer = defaultImporter;
// Memoize per protocol major: the module is stable for the page's lifetime and
// multiple web views sharing a `protocol_version` should import it once.
const moduleCache = new Map();
function assertValidProtocolVersion(protocolVersion) {
if (!Number.isInteger(protocolVersion) || protocolVersion < 1) {
throw new Error(`invalid web_view protocol_version: ${protocolVersion}`);
}
}
function importHostModule(protocolVersion) {
const cached = moduleCache.get(protocolVersion);
if (cached)
return cached;
const url = hostSdkUrl(protocolVersion);
const promise = importer(url).then((module) => {
const createHostBridge = module
.createHostBridge;
if (typeof createHostBridge !== "function") {
throw new Error(`rc-host.js at ${url} does not export createHostBridge`);
}
return { createHostBridge };
});
// Don't cache a rejected import so a later mount can retry (e.g. after a
// transient network failure).
promise.catch(() => {
if (moduleCache.get(protocolVersion) === promise) {
moduleCache.delete(protocolVersion);
}
});
moduleCache.set(protocolVersion, promise);
return promise;
}
/**
* Resolve `createHostBridge` for a protocol major from the CDN. Rejects if the
* module can't be loaded or doesn't export the factory, so callers can degrade to
* a render-only iframe.
*/
export async function loadCreateHostBridge(protocolVersion) {
assertValidProtocolVersion(protocolVersion);
const { createHostBridge } = await importHostModule(protocolVersion);
return createHostBridge;
}
/**
* Override the module importer (and clear the cache). Intended for tests, which
* inject a fake so no real network/module resolution happens. Pass `null` to
* restore the default dynamic import.
*/
export function __setHostModuleImporterForTests(fn) {
importer = fn ?? defaultImporter;
moduleCache.clear();
}