diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d0fb0e7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +# 1.0.0 (2026-06-05) diff --git a/dist/RoktPayPlus-Kit.common.js b/dist/RoktPayPlus-Kit.common.js new file mode 100644 index 0000000..6f32ae8 --- /dev/null +++ b/dist/RoktPayPlus-Kit.common.js @@ -0,0 +1,2 @@ +"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s="RoktPayPlus",l=184,E={PageView:3,PageEvent:4},i={INITIATED:"initiated",STEP_COMPLETE:"stepComplete",APPROVED:"approved",PENDING:"pending",LOGGED_IN:"loggedIn",ACCOUNT_CREATED:"accountCreated",OFFER_SAVED:"offerSaved",PURCHASE_COMPLETED:"purchaseCompleted",FORM_SUBMITTED:"formSubmitted",PENDING_SUCCESS:"pendingSuccess",CLOSE:"close",REMOVE_LOADING_OVERLAY:"removeLoadingOverlay"},m="conversion",p=[{setting:"approvedEventName",signal:i.APPROVED},{setting:"pendingEventName",signal:i.PENDING},{setting:"loggedInEventName",signal:i.LOGGED_IN},{setting:"accountCreatedEventName",signal:i.ACCOUNT_CREATED},{setting:"offerSavedEventName",signal:i.OFFER_SAVED},{setting:"purchaseCompletedEventName",signal:i.PURCHASE_COMPLETED},{setting:"formSubmittedEventName",signal:i.FORM_SUBMITTED},{setting:"pendingSuccessEventName",signal:i.PENDING_SUCCESS},{setting:"closeEventName",signal:i.CLOSE},{setting:"removeLoadingOverlayEventName",signal:i.REMOVE_LOADING_OVERLAY}];function g(e){return!e||typeof e!="string"?[]:e.split(",").map(t=>t.trim()).filter(Boolean)}function d(e){const t=g(e.progressionScreenNames),n={};for(const{setting:o,signal:r}of p)for(const f of g(e[o]))n[f]=r;return{progressionScreens:t,progressionConfigured:t.length>0,eventNameToSignal:n,eventConfigured:Object.keys(n).length>0,defaultConversionEventName:e.conversionEventName||m}}function N(e){return e.EventAttributes&&e.EventAttributes.screen_name||e.EventName}function S(){return typeof window>"u"?null:window.parent&&window.parent!==window?window.parent:null}function a(e,t,n){const o=S();if(!o||typeof o.postMessage!="function")return;const r={source:"rokt-payplus-kit",type:e};t!==void 0&&(r.detail=t),n!==void 0&&(r.trigger=n),o.postMessage(r,"*")}function u(e){return e!=null&&typeof e=="object"&&Array.isArray(e)===!1}class c{constructor(){this.name=s,this.id=l,this.isInitialized=!1,this.config=d({})}init(t){return this.config=d(t||{}),a(i.INITIATED,void 0,"SDK forwarder init (app loaded)"),this.isInitialized=!0,"Successfully initialized forwarder: "+s}process(t){if(!this.isInitialized)return"Kit not initialized: "+s;switch(t.EventDataType){case E.PageView:this.handlePageView(t);break;case E.PageEvent:this.handleCustomEvent(t);break}return"Successfully sent to forwarder: "+s}handlePageView(t){const n=N(t);if(!n)return;(!this.config.progressionConfigured||this.config.progressionScreens.indexOf(n)!==-1)&&a(i.STEP_COMPLETE,{step:n},"logPageView('"+n+"')")}handleCustomEvent(t){const n=t.EventName;if(!n)return;const o=this.config.eventNameToSignal[n];if(o){a(o,t.EventAttributes||{},"logEvent('"+n+"')");return}!this.config.eventConfigured&&n===this.config.defaultConversionEventName&&a(i.APPROVED,t.EventAttributes||{},"logEvent('"+n+"', Transaction)")}}function v(){return l}function P(e){if(!u(e)){window.console.log("'config' must be an object. You passed in a "+typeof e);return}u(e.kits)||(e.kits={}),e.kits[s]={constructor:c},window.console.log("Successfully registered "+s+" to your mParticle configuration")}if(typeof window<"u"){const e=window;e.mParticle&&typeof e.mParticle.addForwarder=="function"&&e.mParticle.addForwarder({name:s,constructor:c,getId:v})}exports.RoktPayPlusKit=c;exports.register=P; +//# sourceMappingURL=RoktPayPlus-Kit.common.js.map diff --git a/dist/RoktPayPlus-Kit.common.js.map b/dist/RoktPayPlus-Kit.common.js.map new file mode 100644 index 0000000..3020c1c --- /dev/null +++ b/dist/RoktPayPlus-Kit.common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"RoktPayPlus-Kit.common.js","sources":["../src/RoktPayPlus-Kit.ts"],"sourcesContent":["// Copyright 2026 Rokt Pte Ltd\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n// Rokt Pay+ mParticle web kit.\n//\n// Re-emits the events an advertiser already logs through the mParticle web SDK to the\n// embedding Rokt Pay+ plugin as postMessage signals. Everything lives in this single file.\n//\n// - Page views drive funnel progression (stepComplete), matched on the screen name.\n// - Custom events drive the conversion and other outcomes, matched on the event name.\n// - initiated is emitted once when the kit initializes.\n\nimport type { KitInterface, SDKEvent } from '@mparticle/web-sdk/internal';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst name = 'RoktPayPlus';\n\n// Module ID assigned by mParticle when the kit is registered.\nconst moduleId = 184;\n\n// mParticle message types (SDKEvent.EventDataType values).\nconst MessageType = {\n SessionStart: 1,\n SessionEnd: 2,\n PageView: 3,\n PageEvent: 4,\n} as const;\n\n// The Pay+ signals the Rokt plugin understands. Values match the plugin's MessageEventType.\n// `stepComplete` is the progression signal used by the Pay+ plugin.\nconst SIGNALS = {\n INITIATED: 'initiated',\n STEP_COMPLETE: 'stepComplete',\n APPROVED: 'approved',\n PENDING: 'pending',\n LOGGED_IN: 'loggedIn',\n ACCOUNT_CREATED: 'accountCreated',\n OFFER_SAVED: 'offerSaved',\n PURCHASE_COMPLETED: 'purchaseCompleted',\n FORM_SUBMITTED: 'formSubmitted',\n PENDING_SUCCESS: 'pendingSuccess',\n CLOSE: 'close',\n REMOVE_LOADING_OVERLAY: 'removeLoadingOverlay',\n} as const;\n\nconst DEFAULT_CONVERSION_EVENT_NAME = 'conversion';\n\n// Custom event settings: each maps a custom event name (or comma-separated list) to a signal.\nconst EVENT_SETTING_TO_SIGNAL: ReadonlyArray<{ setting: keyof RoktPayPlusKitSettings; signal: string }> = [\n { setting: 'approvedEventName', signal: SIGNALS.APPROVED },\n { setting: 'pendingEventName', signal: SIGNALS.PENDING },\n { setting: 'loggedInEventName', signal: SIGNALS.LOGGED_IN },\n { setting: 'accountCreatedEventName', signal: SIGNALS.ACCOUNT_CREATED },\n { setting: 'offerSavedEventName', signal: SIGNALS.OFFER_SAVED },\n { setting: 'purchaseCompletedEventName', signal: SIGNALS.PURCHASE_COMPLETED },\n { setting: 'formSubmittedEventName', signal: SIGNALS.FORM_SUBMITTED },\n { setting: 'pendingSuccessEventName', signal: SIGNALS.PENDING_SUCCESS },\n { setting: 'closeEventName', signal: SIGNALS.CLOSE },\n { setting: 'removeLoadingOverlayEventName', signal: SIGNALS.REMOVE_LOADING_OVERLAY },\n];\n\n// ============================================================\n// Types\n// ============================================================\n\n// Settings configured in the mParticle dashboard, delivered to init() as forwarderSettings.\ninterface RoktPayPlusKitSettings {\n progressionScreenNames?: string;\n approvedEventName?: string;\n pendingEventName?: string;\n loggedInEventName?: string;\n accountCreatedEventName?: string;\n offerSavedEventName?: string;\n purchaseCompletedEventName?: string;\n formSubmittedEventName?: string;\n pendingSuccessEventName?: string;\n closeEventName?: string;\n removeLoadingOverlayEventName?: string;\n conversionEventName?: string;\n}\n\ninterface KitConfig {\n progressionScreens: string[];\n progressionConfigured: boolean;\n eventNameToSignal: Record;\n eventConfigured: boolean;\n defaultConversionEventName: string;\n}\n\ninterface RoktSignalMessage {\n source: 'rokt-payplus-kit';\n type: string;\n detail?: Record;\n trigger?: string;\n}\n\n// ============================================================\n// Module-level helpers\n// ============================================================\n\nfunction parseList(value?: string): string[] {\n if (!value || typeof value !== 'string') {\n return [];\n }\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction buildConfig(settings: RoktPayPlusKitSettings): KitConfig {\n const progressionScreens = parseList(settings.progressionScreenNames);\n\n const eventNameToSignal: Record = {};\n for (const { setting, signal } of EVENT_SETTING_TO_SIGNAL) {\n for (const eventName of parseList(settings[setting])) {\n eventNameToSignal[eventName] = signal;\n }\n }\n\n return {\n progressionScreens,\n progressionConfigured: progressionScreens.length > 0,\n eventNameToSignal,\n eventConfigured: Object.keys(eventNameToSignal).length > 0,\n defaultConversionEventName: settings.conversionEventName || DEFAULT_CONVERSION_EVENT_NAME,\n };\n}\n\n// The meaningful screen name lives in the page view's screen_name attribute (the server\n// upload nests this as custom_attributes.screen_name; the top-level page name is generic).\n// Fall back to the event name when the attribute is absent.\nfunction resolveScreenName(event: SDKEvent): string {\n const fromAttr = event.EventAttributes && event.EventAttributes.screen_name;\n return fromAttr || event.EventName;\n}\n\n// Resolve the window the kit should post Pay+ signals to. Pay+ only ever runs inside an\n// iframe, so the kit signals only when framed: window.parent differs from self (which also\n// covers nested frames). On a standalone top-level page parent === self, so this returns null\n// and the kit stays silent instead of messaging its own window.\nfunction getEmbeddingTarget(): Window | null {\n if (typeof window === 'undefined') {\n return null;\n }\n if (window.parent && window.parent !== window) {\n return window.parent;\n }\n return null;\n}\n\n// Emit a Pay+ signal to the embedding parent (the Rokt plugin). No-ops when the page is not\n// framed, so the SDK running on a standalone advertiser page never makes postMessage calls.\nfunction emitSignal(type: string, detail?: Record, trigger?: string): void {\n const target = getEmbeddingTarget();\n if (!target || typeof target.postMessage !== 'function') {\n return;\n }\n const message: RoktSignalMessage = { source: 'rokt-payplus-kit', type };\n if (detail !== undefined) {\n message.detail = detail;\n }\n if (trigger !== undefined) {\n message.trigger = trigger;\n }\n // Demo/POC uses '*'. Production should target the plugin's known origin.\n target.postMessage(message, '*');\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\n// ============================================================\n// Kit\n// ============================================================\n\nclass RoktPayPlusKit implements KitInterface {\n public name = name;\n public id = moduleId;\n public isInitialized = false;\n\n private config: KitConfig = buildConfig({});\n\n public init(settings: Record): string {\n this.config = buildConfig((settings || {}) as RoktPayPlusKitSettings);\n\n // Initialization is the reliable \"app loaded and ready\" moment. The session-start event\n // is not consistently forwarded to a kit that registers during init, so we emit here.\n emitSignal(SIGNALS.INITIATED, undefined, 'SDK forwarder init (app loaded)');\n this.isInitialized = true;\n\n return 'Successfully initialized forwarder: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isInitialized) {\n return 'Kit not initialized: ' + name;\n }\n\n switch (event.EventDataType) {\n case MessageType.PageView:\n this.handlePageView(event);\n break;\n case MessageType.PageEvent:\n this.handleCustomEvent(event);\n break;\n default:\n break;\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n // Page views are funnel progression only. A configured progression screen (or any page\n // view when none are configured) emits stepComplete. A page view is never the conversion.\n private handlePageView(event: SDKEvent): void {\n const screen = resolveScreenName(event);\n if (!screen) {\n return;\n }\n const isStep = !this.config.progressionConfigured || this.config.progressionScreens.indexOf(screen) !== -1;\n if (isStep) {\n emitSignal(SIGNALS.STEP_COMPLETE, { step: screen }, \"logPageView('\" + screen + \"')\");\n }\n }\n\n // Custom events carry the conversion and other outcomes, matched on the event name.\n private handleCustomEvent(event: SDKEvent): void {\n const eventName = event.EventName;\n if (!eventName) {\n return;\n }\n\n const mapped = this.config.eventNameToSignal[eventName];\n if (mapped) {\n emitSignal(mapped, event.EventAttributes || {}, \"logEvent('\" + eventName + \"')\");\n return;\n }\n\n if (!this.config.eventConfigured && eventName === this.config.defaultConversionEventName) {\n emitSignal(SIGNALS.APPROVED, event.EventAttributes || {}, \"logEvent('\" + eventName + \"', Transaction)\");\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n if (!isObject(config.kits)) {\n config.kits = {};\n }\n config.kits[name] = { constructor: RoktPayPlusKit };\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined') {\n const w = window as unknown as { mParticle?: { addForwarder?: (c: unknown) => void } };\n if (w.mParticle && typeof w.mParticle.addForwarder === 'function') {\n w.mParticle.addForwarder({ name, constructor: RoktPayPlusKit, getId });\n }\n}\n\nexport { register, RoktPayPlusKit };\nexport type { RoktPayPlusKitSettings };\n"],"names":["name","moduleId","MessageType","SIGNALS","DEFAULT_CONVERSION_EVENT_NAME","EVENT_SETTING_TO_SIGNAL","parseList","value","s","buildConfig","settings","progressionScreens","eventNameToSignal","setting","signal","eventName","resolveScreenName","event","getEmbeddingTarget","emitSignal","type","detail","trigger","target","message","isObject","val","RoktPayPlusKit","screen","mapped","getId","register","config","w"],"mappings":"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"} \ No newline at end of file diff --git a/dist/RoktPayPlus-Kit.d.ts b/dist/RoktPayPlus-Kit.d.ts new file mode 100644 index 0000000..764c72e --- /dev/null +++ b/dist/RoktPayPlus-Kit.d.ts @@ -0,0 +1,34 @@ +import { KitInterface } from '@mparticle/web-sdk/internal'; +import { SDKEvent } from '@mparticle/web-sdk/internal'; + +export declare function register(config: { + kits?: Record; +}): void; + +export declare class RoktPayPlusKit implements KitInterface { + name: string; + id: number; + isInitialized: boolean; + private config; + init(settings: Record): string; + process(event: SDKEvent): string; + private handlePageView; + private handleCustomEvent; +} + +export declare interface RoktPayPlusKitSettings { + progressionScreenNames?: string; + approvedEventName?: string; + pendingEventName?: string; + loggedInEventName?: string; + accountCreatedEventName?: string; + offerSavedEventName?: string; + purchaseCompletedEventName?: string; + formSubmittedEventName?: string; + pendingSuccessEventName?: string; + closeEventName?: string; + removeLoadingOverlayEventName?: string; + conversionEventName?: string; +} + +export { } diff --git a/dist/RoktPayPlus-Kit.esm.js b/dist/RoktPayPlus-Kit.esm.js new file mode 100644 index 0000000..aabfd69 --- /dev/null +++ b/dist/RoktPayPlus-Kit.esm.js @@ -0,0 +1,121 @@ +const s = "RoktPayPlus"; +const c = { + PageView: 3, + PageEvent: 4 +}, i = { + INITIATED: "initiated", + STEP_COMPLETE: "stepComplete", + APPROVED: "approved", + PENDING: "pending", + LOGGED_IN: "loggedIn", + ACCOUNT_CREATED: "accountCreated", + OFFER_SAVED: "offerSaved", + PURCHASE_COMPLETED: "purchaseCompleted", + FORM_SUBMITTED: "formSubmitted", + PENDING_SUCCESS: "pendingSuccess", + CLOSE: "close", + REMOVE_LOADING_OVERLAY: "removeLoadingOverlay" +}, f = "conversion", m = [ + { setting: "approvedEventName", signal: i.APPROVED }, + { setting: "pendingEventName", signal: i.PENDING }, + { setting: "loggedInEventName", signal: i.LOGGED_IN }, + { setting: "accountCreatedEventName", signal: i.ACCOUNT_CREATED }, + { setting: "offerSavedEventName", signal: i.OFFER_SAVED }, + { setting: "purchaseCompletedEventName", signal: i.PURCHASE_COMPLETED }, + { setting: "formSubmittedEventName", signal: i.FORM_SUBMITTED }, + { setting: "pendingSuccessEventName", signal: i.PENDING_SUCCESS }, + { setting: "closeEventName", signal: i.CLOSE }, + { setting: "removeLoadingOverlayEventName", signal: i.REMOVE_LOADING_OVERLAY } +]; +function E(e) { + return !e || typeof e != "string" ? [] : e.split(",").map((t) => t.trim()).filter(Boolean); +} +function d(e) { + const t = E(e.progressionScreenNames), n = {}; + for (const { setting: o, signal: r } of m) + for (const l of E(e[o])) + n[l] = r; + return { + progressionScreens: t, + progressionConfigured: t.length > 0, + eventNameToSignal: n, + eventConfigured: Object.keys(n).length > 0, + defaultConversionEventName: e.conversionEventName || f + }; +} +function p(e) { + return e.EventAttributes && e.EventAttributes.screen_name || e.EventName; +} +function N() { + return typeof window > "u" ? null : window.parent && window.parent !== window ? window.parent : null; +} +function a(e, t, n) { + const o = N(); + if (!o || typeof o.postMessage != "function") + return; + const r = { source: "rokt-payplus-kit", type: e }; + t !== void 0 && (r.detail = t), n !== void 0 && (r.trigger = n), o.postMessage(r, "*"); +} +function g(e) { + return e != null && typeof e == "object" && Array.isArray(e) === !1; +} +class u { + constructor() { + this.name = s, this.id = 184, this.isInitialized = !1, this.config = d({}); + } + init(t) { + return this.config = d(t || {}), a(i.INITIATED, void 0, "SDK forwarder init (app loaded)"), this.isInitialized = !0, "Successfully initialized forwarder: " + s; + } + process(t) { + if (!this.isInitialized) + return "Kit not initialized: " + s; + switch (t.EventDataType) { + case c.PageView: + this.handlePageView(t); + break; + case c.PageEvent: + this.handleCustomEvent(t); + break; + } + return "Successfully sent to forwarder: " + s; + } + // Page views are funnel progression only. A configured progression screen (or any page + // view when none are configured) emits stepComplete. A page view is never the conversion. + handlePageView(t) { + const n = p(t); + if (!n) + return; + (!this.config.progressionConfigured || this.config.progressionScreens.indexOf(n) !== -1) && a(i.STEP_COMPLETE, { step: n }, "logPageView('" + n + "')"); + } + // Custom events carry the conversion and other outcomes, matched on the event name. + handleCustomEvent(t) { + const n = t.EventName; + if (!n) + return; + const o = this.config.eventNameToSignal[n]; + if (o) { + a(o, t.EventAttributes || {}, "logEvent('" + n + "')"); + return; + } + !this.config.eventConfigured && n === this.config.defaultConversionEventName && a(i.APPROVED, t.EventAttributes || {}, "logEvent('" + n + "', Transaction)"); + } +} +function S() { + return 184; +} +function v(e) { + if (!g(e)) { + window.console.log("'config' must be an object. You passed in a " + typeof e); + return; + } + g(e.kits) || (e.kits = {}), e.kits[s] = { constructor: u }, window.console.log("Successfully registered " + s + " to your mParticle configuration"); +} +if (typeof window < "u") { + const e = window; + e.mParticle && typeof e.mParticle.addForwarder == "function" && e.mParticle.addForwarder({ name: s, constructor: u, getId: S }); +} +export { + u as RoktPayPlusKit, + v as register +}; +//# sourceMappingURL=RoktPayPlus-Kit.esm.js.map diff --git a/dist/RoktPayPlus-Kit.esm.js.map b/dist/RoktPayPlus-Kit.esm.js.map new file mode 100644 index 0000000..2c07214 --- /dev/null +++ b/dist/RoktPayPlus-Kit.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"RoktPayPlus-Kit.esm.js","sources":["../src/RoktPayPlus-Kit.ts"],"sourcesContent":["// Copyright 2026 Rokt Pte Ltd\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n// Rokt Pay+ mParticle web kit.\n//\n// Re-emits the events an advertiser already logs through the mParticle web SDK to the\n// embedding Rokt Pay+ plugin as postMessage signals. Everything lives in this single file.\n//\n// - Page views drive funnel progression (stepComplete), matched on the screen name.\n// - Custom events drive the conversion and other outcomes, matched on the event name.\n// - initiated is emitted once when the kit initializes.\n\nimport type { KitInterface, SDKEvent } from '@mparticle/web-sdk/internal';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst name = 'RoktPayPlus';\n\n// Module ID assigned by mParticle when the kit is registered.\nconst moduleId = 184;\n\n// mParticle message types (SDKEvent.EventDataType values).\nconst MessageType = {\n SessionStart: 1,\n SessionEnd: 2,\n PageView: 3,\n PageEvent: 4,\n} as const;\n\n// The Pay+ signals the Rokt plugin understands. Values match the plugin's MessageEventType.\n// `stepComplete` is the progression signal used by the Pay+ plugin.\nconst SIGNALS = {\n INITIATED: 'initiated',\n STEP_COMPLETE: 'stepComplete',\n APPROVED: 'approved',\n PENDING: 'pending',\n LOGGED_IN: 'loggedIn',\n ACCOUNT_CREATED: 'accountCreated',\n OFFER_SAVED: 'offerSaved',\n PURCHASE_COMPLETED: 'purchaseCompleted',\n FORM_SUBMITTED: 'formSubmitted',\n PENDING_SUCCESS: 'pendingSuccess',\n CLOSE: 'close',\n REMOVE_LOADING_OVERLAY: 'removeLoadingOverlay',\n} as const;\n\nconst DEFAULT_CONVERSION_EVENT_NAME = 'conversion';\n\n// Custom event settings: each maps a custom event name (or comma-separated list) to a signal.\nconst EVENT_SETTING_TO_SIGNAL: ReadonlyArray<{ setting: keyof RoktPayPlusKitSettings; signal: string }> = [\n { setting: 'approvedEventName', signal: SIGNALS.APPROVED },\n { setting: 'pendingEventName', signal: SIGNALS.PENDING },\n { setting: 'loggedInEventName', signal: SIGNALS.LOGGED_IN },\n { setting: 'accountCreatedEventName', signal: SIGNALS.ACCOUNT_CREATED },\n { setting: 'offerSavedEventName', signal: SIGNALS.OFFER_SAVED },\n { setting: 'purchaseCompletedEventName', signal: SIGNALS.PURCHASE_COMPLETED },\n { setting: 'formSubmittedEventName', signal: SIGNALS.FORM_SUBMITTED },\n { setting: 'pendingSuccessEventName', signal: SIGNALS.PENDING_SUCCESS },\n { setting: 'closeEventName', signal: SIGNALS.CLOSE },\n { setting: 'removeLoadingOverlayEventName', signal: SIGNALS.REMOVE_LOADING_OVERLAY },\n];\n\n// ============================================================\n// Types\n// ============================================================\n\n// Settings configured in the mParticle dashboard, delivered to init() as forwarderSettings.\ninterface RoktPayPlusKitSettings {\n progressionScreenNames?: string;\n approvedEventName?: string;\n pendingEventName?: string;\n loggedInEventName?: string;\n accountCreatedEventName?: string;\n offerSavedEventName?: string;\n purchaseCompletedEventName?: string;\n formSubmittedEventName?: string;\n pendingSuccessEventName?: string;\n closeEventName?: string;\n removeLoadingOverlayEventName?: string;\n conversionEventName?: string;\n}\n\ninterface KitConfig {\n progressionScreens: string[];\n progressionConfigured: boolean;\n eventNameToSignal: Record;\n eventConfigured: boolean;\n defaultConversionEventName: string;\n}\n\ninterface RoktSignalMessage {\n source: 'rokt-payplus-kit';\n type: string;\n detail?: Record;\n trigger?: string;\n}\n\n// ============================================================\n// Module-level helpers\n// ============================================================\n\nfunction parseList(value?: string): string[] {\n if (!value || typeof value !== 'string') {\n return [];\n }\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction buildConfig(settings: RoktPayPlusKitSettings): KitConfig {\n const progressionScreens = parseList(settings.progressionScreenNames);\n\n const eventNameToSignal: Record = {};\n for (const { setting, signal } of EVENT_SETTING_TO_SIGNAL) {\n for (const eventName of parseList(settings[setting])) {\n eventNameToSignal[eventName] = signal;\n }\n }\n\n return {\n progressionScreens,\n progressionConfigured: progressionScreens.length > 0,\n eventNameToSignal,\n eventConfigured: Object.keys(eventNameToSignal).length > 0,\n defaultConversionEventName: settings.conversionEventName || DEFAULT_CONVERSION_EVENT_NAME,\n };\n}\n\n// The meaningful screen name lives in the page view's screen_name attribute (the server\n// upload nests this as custom_attributes.screen_name; the top-level page name is generic).\n// Fall back to the event name when the attribute is absent.\nfunction resolveScreenName(event: SDKEvent): string {\n const fromAttr = event.EventAttributes && event.EventAttributes.screen_name;\n return fromAttr || event.EventName;\n}\n\n// Resolve the window the kit should post Pay+ signals to. Pay+ only ever runs inside an\n// iframe, so the kit signals only when framed: window.parent differs from self (which also\n// covers nested frames). On a standalone top-level page parent === self, so this returns null\n// and the kit stays silent instead of messaging its own window.\nfunction getEmbeddingTarget(): Window | null {\n if (typeof window === 'undefined') {\n return null;\n }\n if (window.parent && window.parent !== window) {\n return window.parent;\n }\n return null;\n}\n\n// Emit a Pay+ signal to the embedding parent (the Rokt plugin). No-ops when the page is not\n// framed, so the SDK running on a standalone advertiser page never makes postMessage calls.\nfunction emitSignal(type: string, detail?: Record, trigger?: string): void {\n const target = getEmbeddingTarget();\n if (!target || typeof target.postMessage !== 'function') {\n return;\n }\n const message: RoktSignalMessage = { source: 'rokt-payplus-kit', type };\n if (detail !== undefined) {\n message.detail = detail;\n }\n if (trigger !== undefined) {\n message.trigger = trigger;\n }\n // Demo/POC uses '*'. Production should target the plugin's known origin.\n target.postMessage(message, '*');\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\n// ============================================================\n// Kit\n// ============================================================\n\nclass RoktPayPlusKit implements KitInterface {\n public name = name;\n public id = moduleId;\n public isInitialized = false;\n\n private config: KitConfig = buildConfig({});\n\n public init(settings: Record): string {\n this.config = buildConfig((settings || {}) as RoktPayPlusKitSettings);\n\n // Initialization is the reliable \"app loaded and ready\" moment. The session-start event\n // is not consistently forwarded to a kit that registers during init, so we emit here.\n emitSignal(SIGNALS.INITIATED, undefined, 'SDK forwarder init (app loaded)');\n this.isInitialized = true;\n\n return 'Successfully initialized forwarder: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isInitialized) {\n return 'Kit not initialized: ' + name;\n }\n\n switch (event.EventDataType) {\n case MessageType.PageView:\n this.handlePageView(event);\n break;\n case MessageType.PageEvent:\n this.handleCustomEvent(event);\n break;\n default:\n break;\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n // Page views are funnel progression only. A configured progression screen (or any page\n // view when none are configured) emits stepComplete. A page view is never the conversion.\n private handlePageView(event: SDKEvent): void {\n const screen = resolveScreenName(event);\n if (!screen) {\n return;\n }\n const isStep = !this.config.progressionConfigured || this.config.progressionScreens.indexOf(screen) !== -1;\n if (isStep) {\n emitSignal(SIGNALS.STEP_COMPLETE, { step: screen }, \"logPageView('\" + screen + \"')\");\n }\n }\n\n // Custom events carry the conversion and other outcomes, matched on the event name.\n private handleCustomEvent(event: SDKEvent): void {\n const eventName = event.EventName;\n if (!eventName) {\n return;\n }\n\n const mapped = this.config.eventNameToSignal[eventName];\n if (mapped) {\n emitSignal(mapped, event.EventAttributes || {}, \"logEvent('\" + eventName + \"')\");\n return;\n }\n\n if (!this.config.eventConfigured && eventName === this.config.defaultConversionEventName) {\n emitSignal(SIGNALS.APPROVED, event.EventAttributes || {}, \"logEvent('\" + eventName + \"', Transaction)\");\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n if (!isObject(config.kits)) {\n config.kits = {};\n }\n config.kits[name] = { constructor: RoktPayPlusKit };\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined') {\n const w = window as unknown as { mParticle?: { addForwarder?: (c: unknown) => void } };\n if (w.mParticle && typeof w.mParticle.addForwarder === 'function') {\n w.mParticle.addForwarder({ name, constructor: RoktPayPlusKit, getId });\n }\n}\n\nexport { register, RoktPayPlusKit };\nexport type { RoktPayPlusKitSettings };\n"],"names":["name","MessageType","SIGNALS","DEFAULT_CONVERSION_EVENT_NAME","EVENT_SETTING_TO_SIGNAL","parseList","value","s","buildConfig","settings","progressionScreens","eventNameToSignal","setting","signal","eventName","resolveScreenName","event","getEmbeddingTarget","emitSignal","type","detail","trigger","target","message","isObject","val","RoktPayPlusKit","screen","mapped","getId","register","config","w"],"mappings":"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"} \ No newline at end of file diff --git a/dist/RoktPayPlus-Kit.iife.js b/dist/RoktPayPlus-Kit.iife.js new file mode 100644 index 0000000..43d456c --- /dev/null +++ b/dist/RoktPayPlus-Kit.iife.js @@ -0,0 +1,2 @@ +var RoktPayPlusKit=(function(a){"use strict";const s="RoktPayPlus",d={PageView:3,PageEvent:4},i={INITIATED:"initiated",STEP_COMPLETE:"stepComplete",APPROVED:"approved",PENDING:"pending",LOGGED_IN:"loggedIn",ACCOUNT_CREATED:"accountCreated",OFFER_SAVED:"offerSaved",PURCHASE_COMPLETED:"purchaseCompleted",FORM_SUBMITTED:"formSubmitted",PENDING_SUCCESS:"pendingSuccess",CLOSE:"close",REMOVE_LOADING_OVERLAY:"removeLoadingOverlay"},f="conversion",m=[{setting:"approvedEventName",signal:i.APPROVED},{setting:"pendingEventName",signal:i.PENDING},{setting:"loggedInEventName",signal:i.LOGGED_IN},{setting:"accountCreatedEventName",signal:i.ACCOUNT_CREATED},{setting:"offerSavedEventName",signal:i.OFFER_SAVED},{setting:"purchaseCompletedEventName",signal:i.PURCHASE_COMPLETED},{setting:"formSubmittedEventName",signal:i.FORM_SUBMITTED},{setting:"pendingSuccessEventName",signal:i.PENDING_SUCCESS},{setting:"closeEventName",signal:i.CLOSE},{setting:"removeLoadingOverlayEventName",signal:i.REMOVE_LOADING_OVERLAY}];function E(e){return!e||typeof e!="string"?[]:e.split(",").map(t=>t.trim()).filter(Boolean)}function g(e){const t=E(e.progressionScreenNames),n={};for(const{setting:o,signal:r}of m)for(const P of E(e[o]))n[P]=r;return{progressionScreens:t,progressionConfigured:t.length>0,eventNameToSignal:n,eventConfigured:Object.keys(n).length>0,defaultConversionEventName:e.conversionEventName||f}}function p(e){return e.EventAttributes&&e.EventAttributes.screen_name||e.EventName}function N(){return typeof window>"u"?null:window.parent&&window.parent!==window?window.parent:null}function c(e,t,n){const o=N();if(!o||typeof o.postMessage!="function")return;const r={source:"rokt-payplus-kit",type:e};t!==void 0&&(r.detail=t),n!==void 0&&(r.trigger=n),o.postMessage(r,"*")}function l(e){return e!=null&&typeof e=="object"&&Array.isArray(e)===!1}class u{constructor(){this.name=s,this.id=184,this.isInitialized=!1,this.config=g({})}init(t){return this.config=g(t||{}),c(i.INITIATED,void 0,"SDK forwarder init (app loaded)"),this.isInitialized=!0,"Successfully initialized forwarder: "+s}process(t){if(!this.isInitialized)return"Kit not initialized: "+s;switch(t.EventDataType){case d.PageView:this.handlePageView(t);break;case d.PageEvent:this.handleCustomEvent(t);break}return"Successfully sent to forwarder: "+s}handlePageView(t){const n=p(t);if(!n)return;(!this.config.progressionConfigured||this.config.progressionScreens.indexOf(n)!==-1)&&c(i.STEP_COMPLETE,{step:n},"logPageView('"+n+"')")}handleCustomEvent(t){const n=t.EventName;if(!n)return;const o=this.config.eventNameToSignal[n];if(o){c(o,t.EventAttributes||{},"logEvent('"+n+"')");return}!this.config.eventConfigured&&n===this.config.defaultConversionEventName&&c(i.APPROVED,t.EventAttributes||{},"logEvent('"+n+"', Transaction)")}}function S(){return 184}function v(e){if(!l(e)){window.console.log("'config' must be an object. You passed in a "+typeof e);return}l(e.kits)||(e.kits={}),e.kits[s]={constructor:u},window.console.log("Successfully registered "+s+" to your mParticle configuration")}if(typeof window<"u"){const e=window;e.mParticle&&typeof e.mParticle.addForwarder=="function"&&e.mParticle.addForwarder({name:s,constructor:u,getId:S})}return a.RoktPayPlusKit=u,a.register=v,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"}),a})({}); +//# sourceMappingURL=RoktPayPlus-Kit.iife.js.map diff --git a/dist/RoktPayPlus-Kit.iife.js.map b/dist/RoktPayPlus-Kit.iife.js.map new file mode 100644 index 0000000..8569854 --- /dev/null +++ b/dist/RoktPayPlus-Kit.iife.js.map @@ -0,0 +1 @@ +{"version":3,"file":"RoktPayPlus-Kit.iife.js","sources":["../src/RoktPayPlus-Kit.ts"],"sourcesContent":["// Copyright 2026 Rokt Pte Ltd\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n// Rokt Pay+ mParticle web kit.\n//\n// Re-emits the events an advertiser already logs through the mParticle web SDK to the\n// embedding Rokt Pay+ plugin as postMessage signals. Everything lives in this single file.\n//\n// - Page views drive funnel progression (stepComplete), matched on the screen name.\n// - Custom events drive the conversion and other outcomes, matched on the event name.\n// - initiated is emitted once when the kit initializes.\n\nimport type { KitInterface, SDKEvent } from '@mparticle/web-sdk/internal';\n\n// ============================================================\n// Constants\n// ============================================================\n\nconst name = 'RoktPayPlus';\n\n// Module ID assigned by mParticle when the kit is registered.\nconst moduleId = 184;\n\n// mParticle message types (SDKEvent.EventDataType values).\nconst MessageType = {\n SessionStart: 1,\n SessionEnd: 2,\n PageView: 3,\n PageEvent: 4,\n} as const;\n\n// The Pay+ signals the Rokt plugin understands. Values match the plugin's MessageEventType.\n// `stepComplete` is the progression signal used by the Pay+ plugin.\nconst SIGNALS = {\n INITIATED: 'initiated',\n STEP_COMPLETE: 'stepComplete',\n APPROVED: 'approved',\n PENDING: 'pending',\n LOGGED_IN: 'loggedIn',\n ACCOUNT_CREATED: 'accountCreated',\n OFFER_SAVED: 'offerSaved',\n PURCHASE_COMPLETED: 'purchaseCompleted',\n FORM_SUBMITTED: 'formSubmitted',\n PENDING_SUCCESS: 'pendingSuccess',\n CLOSE: 'close',\n REMOVE_LOADING_OVERLAY: 'removeLoadingOverlay',\n} as const;\n\nconst DEFAULT_CONVERSION_EVENT_NAME = 'conversion';\n\n// Custom event settings: each maps a custom event name (or comma-separated list) to a signal.\nconst EVENT_SETTING_TO_SIGNAL: ReadonlyArray<{ setting: keyof RoktPayPlusKitSettings; signal: string }> = [\n { setting: 'approvedEventName', signal: SIGNALS.APPROVED },\n { setting: 'pendingEventName', signal: SIGNALS.PENDING },\n { setting: 'loggedInEventName', signal: SIGNALS.LOGGED_IN },\n { setting: 'accountCreatedEventName', signal: SIGNALS.ACCOUNT_CREATED },\n { setting: 'offerSavedEventName', signal: SIGNALS.OFFER_SAVED },\n { setting: 'purchaseCompletedEventName', signal: SIGNALS.PURCHASE_COMPLETED },\n { setting: 'formSubmittedEventName', signal: SIGNALS.FORM_SUBMITTED },\n { setting: 'pendingSuccessEventName', signal: SIGNALS.PENDING_SUCCESS },\n { setting: 'closeEventName', signal: SIGNALS.CLOSE },\n { setting: 'removeLoadingOverlayEventName', signal: SIGNALS.REMOVE_LOADING_OVERLAY },\n];\n\n// ============================================================\n// Types\n// ============================================================\n\n// Settings configured in the mParticle dashboard, delivered to init() as forwarderSettings.\ninterface RoktPayPlusKitSettings {\n progressionScreenNames?: string;\n approvedEventName?: string;\n pendingEventName?: string;\n loggedInEventName?: string;\n accountCreatedEventName?: string;\n offerSavedEventName?: string;\n purchaseCompletedEventName?: string;\n formSubmittedEventName?: string;\n pendingSuccessEventName?: string;\n closeEventName?: string;\n removeLoadingOverlayEventName?: string;\n conversionEventName?: string;\n}\n\ninterface KitConfig {\n progressionScreens: string[];\n progressionConfigured: boolean;\n eventNameToSignal: Record;\n eventConfigured: boolean;\n defaultConversionEventName: string;\n}\n\ninterface RoktSignalMessage {\n source: 'rokt-payplus-kit';\n type: string;\n detail?: Record;\n trigger?: string;\n}\n\n// ============================================================\n// Module-level helpers\n// ============================================================\n\nfunction parseList(value?: string): string[] {\n if (!value || typeof value !== 'string') {\n return [];\n }\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction buildConfig(settings: RoktPayPlusKitSettings): KitConfig {\n const progressionScreens = parseList(settings.progressionScreenNames);\n\n const eventNameToSignal: Record = {};\n for (const { setting, signal } of EVENT_SETTING_TO_SIGNAL) {\n for (const eventName of parseList(settings[setting])) {\n eventNameToSignal[eventName] = signal;\n }\n }\n\n return {\n progressionScreens,\n progressionConfigured: progressionScreens.length > 0,\n eventNameToSignal,\n eventConfigured: Object.keys(eventNameToSignal).length > 0,\n defaultConversionEventName: settings.conversionEventName || DEFAULT_CONVERSION_EVENT_NAME,\n };\n}\n\n// The meaningful screen name lives in the page view's screen_name attribute (the server\n// upload nests this as custom_attributes.screen_name; the top-level page name is generic).\n// Fall back to the event name when the attribute is absent.\nfunction resolveScreenName(event: SDKEvent): string {\n const fromAttr = event.EventAttributes && event.EventAttributes.screen_name;\n return fromAttr || event.EventName;\n}\n\n// Resolve the window the kit should post Pay+ signals to. Pay+ only ever runs inside an\n// iframe, so the kit signals only when framed: window.parent differs from self (which also\n// covers nested frames). On a standalone top-level page parent === self, so this returns null\n// and the kit stays silent instead of messaging its own window.\nfunction getEmbeddingTarget(): Window | null {\n if (typeof window === 'undefined') {\n return null;\n }\n if (window.parent && window.parent !== window) {\n return window.parent;\n }\n return null;\n}\n\n// Emit a Pay+ signal to the embedding parent (the Rokt plugin). No-ops when the page is not\n// framed, so the SDK running on a standalone advertiser page never makes postMessage calls.\nfunction emitSignal(type: string, detail?: Record, trigger?: string): void {\n const target = getEmbeddingTarget();\n if (!target || typeof target.postMessage !== 'function') {\n return;\n }\n const message: RoktSignalMessage = { source: 'rokt-payplus-kit', type };\n if (detail !== undefined) {\n message.detail = detail;\n }\n if (trigger !== undefined) {\n message.trigger = trigger;\n }\n // Demo/POC uses '*'. Production should target the plugin's known origin.\n target.postMessage(message, '*');\n}\n\nfunction isObject(val: unknown): val is Record {\n return val != null && typeof val === 'object' && Array.isArray(val) === false;\n}\n\n// ============================================================\n// Kit\n// ============================================================\n\nclass RoktPayPlusKit implements KitInterface {\n public name = name;\n public id = moduleId;\n public isInitialized = false;\n\n private config: KitConfig = buildConfig({});\n\n public init(settings: Record): string {\n this.config = buildConfig((settings || {}) as RoktPayPlusKitSettings);\n\n // Initialization is the reliable \"app loaded and ready\" moment. The session-start event\n // is not consistently forwarded to a kit that registers during init, so we emit here.\n emitSignal(SIGNALS.INITIATED, undefined, 'SDK forwarder init (app loaded)');\n this.isInitialized = true;\n\n return 'Successfully initialized forwarder: ' + name;\n }\n\n public process(event: SDKEvent): string {\n if (!this.isInitialized) {\n return 'Kit not initialized: ' + name;\n }\n\n switch (event.EventDataType) {\n case MessageType.PageView:\n this.handlePageView(event);\n break;\n case MessageType.PageEvent:\n this.handleCustomEvent(event);\n break;\n default:\n break;\n }\n\n return 'Successfully sent to forwarder: ' + name;\n }\n\n // Page views are funnel progression only. A configured progression screen (or any page\n // view when none are configured) emits stepComplete. A page view is never the conversion.\n private handlePageView(event: SDKEvent): void {\n const screen = resolveScreenName(event);\n if (!screen) {\n return;\n }\n const isStep = !this.config.progressionConfigured || this.config.progressionScreens.indexOf(screen) !== -1;\n if (isStep) {\n emitSignal(SIGNALS.STEP_COMPLETE, { step: screen }, \"logPageView('\" + screen + \"')\");\n }\n }\n\n // Custom events carry the conversion and other outcomes, matched on the event name.\n private handleCustomEvent(event: SDKEvent): void {\n const eventName = event.EventName;\n if (!eventName) {\n return;\n }\n\n const mapped = this.config.eventNameToSignal[eventName];\n if (mapped) {\n emitSignal(mapped, event.EventAttributes || {}, \"logEvent('\" + eventName + \"')\");\n return;\n }\n\n if (!this.config.eventConfigured && eventName === this.config.defaultConversionEventName) {\n emitSignal(SIGNALS.APPROVED, event.EventAttributes || {}, \"logEvent('\" + eventName + \"', Transaction)\");\n }\n }\n}\n\n// ============================================================\n// Kit registration\n// ============================================================\n\nfunction getId(): number {\n return moduleId;\n}\n\nfunction register(config: { kits?: Record }): void {\n if (!isObject(config)) {\n window.console.log(\"'config' must be an object. You passed in a \" + typeof config);\n return;\n }\n if (!isObject(config.kits)) {\n config.kits = {};\n }\n config.kits[name] = { constructor: RoktPayPlusKit };\n window.console.log('Successfully registered ' + name + ' to your mParticle configuration');\n}\n\nif (typeof window !== 'undefined') {\n const w = window as unknown as { mParticle?: { addForwarder?: (c: unknown) => void } };\n if (w.mParticle && typeof w.mParticle.addForwarder === 'function') {\n w.mParticle.addForwarder({ name, constructor: RoktPayPlusKit, getId });\n }\n}\n\nexport { register, RoktPayPlusKit };\nexport type { RoktPayPlusKitSettings };\n"],"names":["name","MessageType","SIGNALS","DEFAULT_CONVERSION_EVENT_NAME","EVENT_SETTING_TO_SIGNAL","parseList","value","s","buildConfig","settings","progressionScreens","eventNameToSignal","setting","signal","eventName","resolveScreenName","event","getEmbeddingTarget","emitSignal","type","detail","trigger","target","message","isObject","val","RoktPayPlusKit","screen","mapped","getId","register","config","w"],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6da62b7..cda4c27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mparticle/web-rokt-pay-plus-kit", - "version": "0.1.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mparticle/web-rokt-pay-plus-kit", - "version": "0.1.0", + "version": "1.0.0", "license": "Apache-2.0", "dependencies": { "@mparticle/web-sdk": "^2.62.0" diff --git a/package.json b/package.json index 97d01ad..6bb0764 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mparticle/web-rokt-pay-plus-kit", - "version": "0.1.0", + "version": "1.0.0", "description": "mParticle web kit that re-emits the events an advertiser already logs to the embedding Rokt Pay+ plugin via postMessage.", "main": "dist/RoktPayPlus-Kit.common.js", "module": "dist/RoktPayPlus-Kit.esm.js",