@xylabs/pixel 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/UniqueUserId.d.cts.map +1 -1
- package/dist/browser/UniqueUserId.d.mts.map +1 -1
- package/dist/browser/UniqueUserId.d.ts.map +1 -1
- package/dist/browser/index.cjs +1 -2
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +1 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/neutral/UniqueUserId.d.cts.map +1 -1
- package/dist/neutral/UniqueUserId.d.mts.map +1 -1
- package/dist/neutral/UniqueUserId.d.ts.map +1 -1
- package/dist/neutral/index.cjs +1 -2
- package/dist/neutral/index.cjs.map +1 -1
- package/dist/neutral/index.js +1 -2
- package/dist/neutral/index.js.map +1 -1
- package/dist/node/UniqueUserId.d.cts.map +1 -1
- package/dist/node/UniqueUserId.d.mts.map +1 -1
- package/dist/node/UniqueUserId.d.ts.map +1 -1
- package/dist/node/index.cjs +1 -2
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +1 -2
- package/dist/node/index.js.map +1 -1
- package/package.json +2 -3
- package/src/UniqueUserId.ts +1 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
package/dist/browser/index.cjs
CHANGED
|
@@ -110,7 +110,6 @@ var Referrer = class _Referrer {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/UniqueUserId.ts
|
|
113
|
-
var import_randombytes = __toESM(require("randombytes"), 1);
|
|
114
113
|
var UniqueUserId = class _UniqueUserId {
|
|
115
114
|
static localStorageId = "_coin_cid";
|
|
116
115
|
id;
|
|
@@ -122,7 +121,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
122
121
|
return this.id;
|
|
123
122
|
}
|
|
124
123
|
generateId() {
|
|
125
|
-
return
|
|
124
|
+
return crypto.randomUUID();
|
|
126
125
|
}
|
|
127
126
|
};
|
|
128
127
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","randomBytes","md5","Cookies"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","md5","Cookies"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -68,7 +68,6 @@ var Referrer = class _Referrer {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// src/UniqueUserId.ts
|
|
71
|
-
import randomBytes from "randombytes";
|
|
72
71
|
var UniqueUserId = class _UniqueUserId {
|
|
73
72
|
static localStorageId = "_coin_cid";
|
|
74
73
|
id;
|
|
@@ -80,7 +79,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
80
79
|
return this.id;
|
|
81
80
|
}
|
|
82
81
|
generateId() {
|
|
83
|
-
return
|
|
82
|
+
return crypto.randomUUID();
|
|
84
83
|
}
|
|
85
84
|
};
|
|
86
85
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
package/dist/neutral/index.cjs
CHANGED
|
@@ -110,7 +110,6 @@ var Referrer = class _Referrer {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/UniqueUserId.ts
|
|
113
|
-
var import_randombytes = __toESM(require("randombytes"), 1);
|
|
114
113
|
var UniqueUserId = class _UniqueUserId {
|
|
115
114
|
static localStorageId = "_coin_cid";
|
|
116
115
|
id;
|
|
@@ -122,7 +121,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
122
121
|
return this.id;
|
|
123
122
|
}
|
|
124
123
|
generateId() {
|
|
125
|
-
return
|
|
124
|
+
return crypto.randomUUID();
|
|
126
125
|
}
|
|
127
126
|
};
|
|
128
127
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","randomBytes","md5","Cookies"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","md5","Cookies"]}
|
package/dist/neutral/index.js
CHANGED
|
@@ -68,7 +68,6 @@ var Referrer = class _Referrer {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// src/UniqueUserId.ts
|
|
71
|
-
import randomBytes from "randombytes";
|
|
72
71
|
var UniqueUserId = class _UniqueUserId {
|
|
73
72
|
static localStorageId = "_coin_cid";
|
|
74
73
|
id;
|
|
@@ -80,7 +79,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
80
79
|
return this.id;
|
|
81
80
|
}
|
|
82
81
|
generateId() {
|
|
83
|
-
return
|
|
82
|
+
return crypto.randomUUID();
|
|
84
83
|
}
|
|
85
84
|
};
|
|
86
85
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UniqueUserId.d.ts","sourceRoot":"","sources":["../../src/UniqueUserId.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAc;IAC3C,EAAE,EAAE,MAAM,CAAA;;IAOV,QAAQ;IAIR,OAAO,CAAC,UAAU;CAGnB"}
|
package/dist/node/index.cjs
CHANGED
|
@@ -110,7 +110,6 @@ var Referrer = class _Referrer {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/UniqueUserId.ts
|
|
113
|
-
var import_randombytes = __toESM(require("randombytes"), 1);
|
|
114
113
|
var UniqueUserId = class _UniqueUserId {
|
|
115
114
|
static localStorageId = "_coin_cid";
|
|
116
115
|
id;
|
|
@@ -122,7 +121,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
122
121
|
return this.id;
|
|
123
122
|
}
|
|
124
123
|
generateId() {
|
|
125
|
-
return
|
|
124
|
+
return crypto.randomUUID();
|
|
126
125
|
}
|
|
127
126
|
};
|
|
128
127
|
|
package/dist/node/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","randomBytes","md5","Cookies"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["export * from './Api/index.js'\nexport * from './FunnelStartedFields.js'\nexport * from './Pixel.js'\nexport * from './Referrer.js'\nexport * from './TestStartedFields.js'\nexport * from './UniqueUserId.js'\nexport * from './UserClickFields.js'\nexport * from './UserEventHandler.js'\nexport * from './UtmFields.js'\nexport * from './ViewContentFields.js'\nexport * from './XyLabsTrackingEventJson.js'\nexport * from './XyUserEventHandler.js'\n","import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":["axios","md5","Cookies"]}
|
package/dist/node/index.js
CHANGED
|
@@ -68,7 +68,6 @@ var Referrer = class _Referrer {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// src/UniqueUserId.ts
|
|
71
|
-
import randomBytes from "randombytes";
|
|
72
71
|
var UniqueUserId = class _UniqueUserId {
|
|
73
72
|
static localStorageId = "_coin_cid";
|
|
74
73
|
id;
|
|
@@ -80,7 +79,7 @@ var UniqueUserId = class _UniqueUserId {
|
|
|
80
79
|
return this.id;
|
|
81
80
|
}
|
|
82
81
|
generateId() {
|
|
83
|
-
return
|
|
82
|
+
return crypto.randomUUID();
|
|
84
83
|
}
|
|
85
84
|
};
|
|
86
85
|
|
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","import randomBytes from 'randombytes'\n\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return randomBytes(16).toString('base64')\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/Api/Api.ts","../../src/Pixel.ts","../../src/getSystemInfo.ts","../../src/Referrer.ts","../../src/UniqueUserId.ts","../../src/UtmFields.ts","../../src/UserEventHandler.ts","../../src/XyUserEventHandler.ts"],"sourcesContent":["import axios from 'axios'\n\nimport { UserEvent } from './UserEvent.js'\n\nconst apiBaseUri: Record<string, string> = {\n beta: 'https://pixel.xylabs.com',\n local: 'http://localhost:3030',\n prod: 'https://pixel.xylabs.com',\n}\n\nexport class PixelApi {\n private endPoint: string\n\n /* baseUri can either be a preset (prod, beta, local), or a specific uri */\n constructor(baseUri = 'prod') {\n this.endPoint = apiBaseUri[baseUri] ? `${apiBaseUri[baseUri]}/t/event/queue` : baseUri\n }\n\n async trackEvents(events: UserEvent[]) {\n return (await axios.post(this.endPoint, events)).data\n }\n}\n","import { assertEx } from '@xylabs/assert'\nimport { Mutex } from 'async-mutex'\nimport Cookies from 'js-cookie'\nimport md5 from 'md5'\n\nimport { PixelApi, UserEvent } from './Api/index.js'\nimport { ExIds } from './ExIds.js'\nimport { getSystemInfo } from './getSystemInfo.js'\nimport { Referrer } from './Referrer.js'\nimport { UniqueUserId } from './UniqueUserId.js'\nimport { UtmFields } from './UtmFields.js'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid = new UniqueUserId().id\n email?: string\n email_hash?: string | null\n exids?: ExIds\n pixelId?: string\n\n queue: UserEvent[] = []\n\n private queueMutex = new Mutex()\n\n private constructor(pixelId: string) {\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n static get instance(): XyPixel {\n return assertEx(this._instance, 'XyPixel uninitialized')\n }\n\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n if (XyPixel.utmFieldsObj === undefined) {\n XyPixel.utmFieldsObj = new UtmFields()\n }\n return XyPixel.utmFieldsObj\n }\n\n identify(email?: string) {\n this.email = email\n this.email_hash = email ? md5(email) : undefined\n if (this.email_hash) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n async send<T extends Record<string, unknown>>(event: string, fields?: T, eventId?: string) {\n this.updateFbId()\n const utm = XyPixel.utmFields().update()\n const referrer = new Referrer()\n this.queue.push({\n cid: this.cid,\n create_time: Date.now(),\n email_hash: this.email_hash ?? undefined,\n event,\n event_id: eventId,\n exids: this.exids,\n fields,\n host: document.location.host,\n pathname: document.location.pathname,\n pixel: this.pixelId,\n referrer: referrer.toJson(),\n system: getSystemInfo(),\n utm,\n })\n await this.tryFlushQueue()\n }\n\n private async tryFlushQueue() {\n await this.queueMutex.runExclusive(async () => {\n if (this.queue.length === 0) return\n const api = XyPixel.api\n if (api) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events) {\n //put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: Cookies.get('_fbc'),\n fbp: Cookies.get('_fbp'),\n ga: Cookies.get('_ga'),\n gclid: Cookies.get('_gcl_aw'),\n rdt_uid: Cookies.get('rdt_uid'),\n scid: Cookies.get('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n","import { parse } from 'bowser'\n\nimport { UserEventSystem } from './Api/index.js'\n\nlet systemInfo: UserEventSystem | undefined\n\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo || parse(window.navigator.userAgent)\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex}`)\n }\n return systemInfo\n}\n","export class Referrer {\n private static storageId = '_coin_referrer'\n local: string\n session: string\n constructor() {\n this.session = this.getFromSession() ?? document.referrer\n sessionStorage.setItem(Referrer.storageId, this.session)\n this.local = this.getFromLocal() ?? document.referrer\n window.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n toJson() {\n if ((this.local && this.local.length > 0) || (this.session && this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = window.localStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value && value.length > 0) {\n return value\n }\n }\n}\n","export class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = window.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n window.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n","import { isEqual } from '@xylabs/lodash'\n\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = window.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n this.fields = JSON.parse(storedString)\n } catch {\n this.fields = []\n }\n //this clears the old object version if needed\n if (!Array.isArray(this.fields)) {\n this.fields = []\n }\n this.update()\n window.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?')[1]?.split('&') ?? []\n parsedQueryString.map((item) => {\n const [fullKey, value] = item.split('=')\n const [keyCategory, keyName] = fullKey.split('_')\n if (keyCategory === 'utm') {\n record[keyName] = value\n }\n })\n return Object.keys(record).length > 0 ? record : null\n }\n\n toString() {\n return JSON.stringify(this.fields)\n }\n\n //check the query string and if there an new/updated utm values, add them to the fields\n update() {\n const record = this.getUtmRecord()\n if (record && !isEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport abstract class UserEventHandler<T> {\n abstract funnelStarted(fields: T | FunnelStartedFields): Promise<void>\n abstract testStarted(fields: T | TestStartedFields): Promise<void>\n abstract userClick(fields: T | UserClickFields): Promise<void>\n abstract viewContent(fields: T | ViewContentFields): Promise<void>\n}\n","import { FunnelStartedFields } from './FunnelStartedFields.js'\nimport { XyPixel } from './Pixel.js'\nimport { TestStartedFields } from './TestStartedFields.js'\nimport { UserClickFields } from './UserClickFields.js'\nimport { UserEventHandler } from './UserEventHandler.js'\nimport { ViewContentFields } from './ViewContentFields.js'\n\nexport class XyUserEventHandler<T extends Record<string, unknown>> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', fields)\n }\n\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', fields)\n }\n\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', fields)\n }\n\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', fields)\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
"bowser": "^2.11.0",
|
|
16
16
|
"js-cookie": "^3.0.5",
|
|
17
17
|
"lodash-es": "^4.17.21",
|
|
18
|
-
"md5": "^2.3.0"
|
|
19
|
-
"randombytes": "^2.1.0"
|
|
18
|
+
"md5": "^2.3.0"
|
|
20
19
|
},
|
|
21
20
|
"peerDependencies": {
|
|
22
21
|
"axios": "^1.2"
|
|
@@ -89,7 +88,7 @@
|
|
|
89
88
|
"url": "https://github.com/xylabs/sdk-pixel-js.git"
|
|
90
89
|
},
|
|
91
90
|
"sideEffects": false,
|
|
92
|
-
"version": "1.
|
|
91
|
+
"version": "1.7.0",
|
|
93
92
|
"packageManager": "yarn@4.3.1",
|
|
94
93
|
"type": "module"
|
|
95
94
|
}
|
package/src/UniqueUserId.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import randomBytes from 'randombytes'
|
|
2
|
-
|
|
3
1
|
export class UniqueUserId {
|
|
4
2
|
private static localStorageId = '_coin_cid'
|
|
5
3
|
id: string
|
|
@@ -14,6 +12,6 @@ export class UniqueUserId {
|
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
private generateId() {
|
|
17
|
-
return
|
|
15
|
+
return crypto.randomUUID()
|
|
18
16
|
}
|
|
19
17
|
}
|