UNPKG

@croct/plug

Version:

A fully-featured devkit for building natively personalized applications.

167 lines (166 loc) 5.91 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var playground_exports = {}; __export(playground_exports, { PlaygroundPlugin: () => PlaygroundPlugin, factory: () => factory }); module.exports = __toCommonJS(playground_exports); var import_error = require("@croct/sdk/error"); var import_evaluatorFacade = require("@croct/sdk/facade/evaluatorFacade"); var import_constants = require('./constants.cjs'); const CONNECTION_PARAMETER = "__cplay"; class PlaygroundPlugin { constructor(configuration) { this.sdkVersion = configuration.sdkVersion; this.appId = configuration.appId; this.connectionId = configuration.connectionId; this.tab = configuration.tab; this.contextFactory = configuration.contextFactory; this.storage = configuration.storage; this.eventSubscriber = configuration.eventSubscriber; this.cidAssigner = configuration.cidAssigner; this.tokenProvider = configuration.tokenProvider; this.logger = configuration.logger; } enable() { const connectionId = this.resolveConnectionId(); if (connectionId === null) { return; } this.syncListener = () => this.cidAssigner.assignCid().then((cid) => { this.syncToken(connectionId, cid); }).catch((error) => { this.logger.warn(`Sync failed: ${(0, import_error.formatCause)(error)}`); }); this.eventSubscriber.addListener("tokenChanged", this.syncListener); this.tab.addListener("urlChange", this.syncListener); return this.syncListener(); } resolveConnectionId() { if (this.connectionId !== void 0) { this.logger.debug("Connection ID passed in configuration"); return this.connectionId; } const url = new URL(this.tab.url); let connectionId = url.searchParams.get(CONNECTION_PARAMETER); if (connectionId === null || connectionId === "") { this.logger.debug("No connection ID found in URL"); connectionId = this.storage.getItem("connectionId"); this.logger.debug( connectionId !== null ? "Previous connection ID found" : "No previous connection ID found" ); return connectionId; } this.logger.debug("Connection ID found in URL"); this.storage.setItem("connectionId", connectionId); return connectionId; } disable() { if (this.syncListener !== void 0) { this.eventSubscriber.removeListener("tokenChanged", this.syncListener); this.tab.removeListener("urlChange", this.syncListener); delete this.syncListener; } } syncToken(connectionId, cid) { const iframe = document.createElement("iframe"); iframe.setAttribute("src", import_constants.PLAYGROUND_CONNECT_URL); iframe.setAttribute("sandbox", "allow-scripts allow-same-origin"); iframe.style.visibility = "hidden"; iframe.style.opacity = "0"; iframe.style.border = "0"; iframe.style.width = "0"; iframe.style.height = "0"; const context = this.createContext(); iframe.onload = () => { if (iframe.contentWindow === null) { if (document.body.contains(iframe)) { document.body.removeChild(iframe); } this.logger.warn("Sync handshake failed"); return; } const listener = (event) => { if (event.origin !== import_constants.PLAYGROUND_ORIGIN || event.data !== connectionId) { return; } window.removeEventListener("message", listener); if (document.body.contains(iframe)) { document.body.removeChild(iframe); } this.logger.debug("Sync completed"); }; window.addEventListener("message", listener); const payload = { appId: this.appId, connectionId, sdkVersion: this.sdkVersion, tabId: this.tab.id, cid, token: this.tokenProvider.getToken()?.toString() ?? null, context }; iframe.contentWindow.postMessage(payload, import_constants.PLAYGROUND_ORIGIN); this.logger.debug("Waiting for sync acknowledgment..."); }; this.logger.debug("Sync started"); const connect = () => { document.body.appendChild(iframe); }; if (document.body === null) { document.addEventListener("DOMContentLoaded", connect); } else { connect(); } } createContext() { const { page, campaign, timeZone } = this.contextFactory.createContext(); const context = {}; if (page !== void 0) { context.page = page; } if (campaign !== void 0) { context.campaign = campaign; } if (timeZone !== void 0) { context.timeZone = timeZone; } return context; } } const factory = (props) => { const { sdk, options } = props; return new PlaygroundPlugin({ sdkVersion: sdk.version, appId: sdk.appId, connectionId: options.connectionId, tab: sdk.tab, storage: sdk.getTabStorage(), tokenProvider: sdk.userTokenStore, cidAssigner: sdk.cidAssigner, contextFactory: new import_evaluatorFacade.TabContextFactory(sdk.tab), eventSubscriber: sdk.eventManager, logger: sdk.getLogger() }); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PlaygroundPlugin, factory });