@xylabs/pixel 6.1.3 → 7.0.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Api.d.ts","sourceRoot":"","sources":["../../../src/Api/Api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQ/C,wEAAwE;AACxE,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAQ;gBAGZ,OAAO,SAAS;IAI5B;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"Api.d.ts","sourceRoot":"","sources":["../../../src/Api/Api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAQ/C,wEAAwE;AACxE,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAQ;gBAGZ,OAAO,SAAS;IAI5B;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE;CAItC"}
|
package/dist/browser/Pixel.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class XyPixel {
|
|
|
25
25
|
static init(pixelId: string): XyPixel;
|
|
26
26
|
/**
|
|
27
27
|
* Replaces the default PixelApi instance used for sending events.
|
|
28
|
-
* @param
|
|
28
|
+
* @param API - The PixelApi instance to use
|
|
29
29
|
*/
|
|
30
30
|
static selectApi(api: PixelApi): void;
|
|
31
31
|
private static utmFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pixel.d.ts","sourceRoot":"","sources":["../../src/Pixel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAGhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAwBvC,6FAA6F;AAC7F,qBAAa,OAAO;IAClB,MAAM,CAAC,GAAG,WAAiB;IAE3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAS;IAClC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAW;IAEtC,GAAG,
|
|
1
|
+
{"version":3,"file":"Pixel.d.ts","sourceRoot":"","sources":["../../src/Pixel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAGhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAwBvC,6FAA6F;AAC7F,qBAAa,OAAO;IAClB,MAAM,CAAC,GAAG,WAAiB;IAE3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAS;IAClC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAW;IAEtC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,KAAK,EAAE,SAAS,EAAE,CAAK;IAEvB,OAAO,CAAC,UAAU,CAAc;IAEhC,OAAO;IAOP,+EAA+E;IAC/E,MAAM,KAAK,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM;IAK3B;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ;IAI9B,OAAO,CAAC,MAAM,CAAC,SAAS,CAGvB;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM;IAQvB;;;;;OAKG;IACG,IAAI,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM;YAsB9D,aAAa;IAqB3B,OAAO,CAAC,UAAU;CAWnB"}
|
package/dist/browser/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ var apiBaseUri = {
|
|
|
8
8
|
};
|
|
9
9
|
var PixelApi = class {
|
|
10
10
|
endPoint;
|
|
11
|
-
/* baseUri can either be a preset (prod, beta, local), or a specific
|
|
11
|
+
/* baseUri can either be a preset (prod, beta, local), or a specific URI */
|
|
12
12
|
constructor(baseUri = "prod") {
|
|
13
13
|
this.endPoint = isUndefined(apiBaseUri[baseUri]) ? baseUri : `${apiBaseUri[baseUri]}/t/event/queue`;
|
|
14
14
|
}
|
|
@@ -18,7 +18,8 @@ var PixelApi = class {
|
|
|
18
18
|
* @returns The response data from the API
|
|
19
19
|
*/
|
|
20
20
|
async trackEvents(events) {
|
|
21
|
-
|
|
21
|
+
const response = await fetchJsonPost(this.endPoint, events);
|
|
22
|
+
return response.data;
|
|
22
23
|
}
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -27,11 +28,11 @@ import { assertEx } from "@xylabs/assert";
|
|
|
27
28
|
import { Mutex } from "async-mutex";
|
|
28
29
|
|
|
29
30
|
// src/getSystemInfo.ts
|
|
30
|
-
var
|
|
31
|
+
var cache = {};
|
|
31
32
|
var firstMatch = (value, expressions) => {
|
|
32
33
|
for (const expression of expressions) {
|
|
33
34
|
const match = expression.exec(value);
|
|
34
|
-
if (match?.[1]) return match[1].replaceAll("_", ".");
|
|
35
|
+
if (match?.[1] !== void 0 && match[1] !== "") return match[1].replaceAll("_", ".");
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
var browserFromUserAgentData = (userAgentData) => {
|
|
@@ -102,11 +103,11 @@ var parseSystemInfo = () => {
|
|
|
102
103
|
};
|
|
103
104
|
var getSystemInfo = () => {
|
|
104
105
|
try {
|
|
105
|
-
systemInfo
|
|
106
|
+
cache.systemInfo ??= parseSystemInfo();
|
|
106
107
|
} catch (ex) {
|
|
107
108
|
console.log(`getSystemInfo Error: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
108
109
|
}
|
|
109
|
-
return systemInfo;
|
|
110
|
+
return cache.systemInfo;
|
|
110
111
|
};
|
|
111
112
|
|
|
112
113
|
// src/md5Raw.ts
|
|
@@ -199,7 +200,8 @@ var getRoundValues = (index, state) => {
|
|
|
199
200
|
return { f: c ^ (b | ~d), g: 7 * index % 16 };
|
|
200
201
|
};
|
|
201
202
|
var buildPaddedMessage = (value) => {
|
|
202
|
-
const
|
|
203
|
+
const encoder = new TextEncoder();
|
|
204
|
+
const message = encoder.encode(value);
|
|
203
205
|
const bitLength = BigInt(message.length) * 8n;
|
|
204
206
|
const paddingLength = (56 - (message.length + 1) % 64 + 64) % 64;
|
|
205
207
|
const bytes = new Uint8Array(message.length + 1 + paddingLength + 8);
|
|
@@ -384,7 +386,7 @@ var XyPixel = class _XyPixel {
|
|
|
384
386
|
static api = new PixelApi();
|
|
385
387
|
static _instance;
|
|
386
388
|
static utmFieldsObj;
|
|
387
|
-
cid
|
|
389
|
+
cid;
|
|
388
390
|
email;
|
|
389
391
|
email_hash;
|
|
390
392
|
exids;
|
|
@@ -392,6 +394,8 @@ var XyPixel = class _XyPixel {
|
|
|
392
394
|
queue = [];
|
|
393
395
|
queueMutex = new Mutex();
|
|
394
396
|
constructor(pixelId) {
|
|
397
|
+
const uniqueUserId = new UniqueUserId();
|
|
398
|
+
this.cid = uniqueUserId.id;
|
|
395
399
|
this.pixelId = pixelId;
|
|
396
400
|
this.email_hash = localStorage.getItem(emailHashLocalStorageName);
|
|
397
401
|
}
|
|
@@ -410,7 +414,7 @@ var XyPixel = class _XyPixel {
|
|
|
410
414
|
}
|
|
411
415
|
/**
|
|
412
416
|
* Replaces the default PixelApi instance used for sending events.
|
|
413
|
-
* @param
|
|
417
|
+
* @param API - The PixelApi instance to use
|
|
414
418
|
*/
|
|
415
419
|
static selectApi(api) {
|
|
416
420
|
this.api = api;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Api/Api.ts", "../../src/Pixel.ts", "../../src/getSystemInfo.ts", "../../src/md5Raw.ts", "../../src/Referrer.ts", "../../src/UniqueUserId.ts", "../../src/UtmFields.ts", "../../src/UserEventHandler.ts", "../../src/XyUserEventHandler.ts"],
|
|
4
|
-
"sourcesContent": ["import { fetchJsonPost } from '@xylabs/fetch'\nimport { isUndefined } from '@xylabs/typeof'\n\nimport type { UserEvent } from './UserEvent.ts'\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\n/** HTTP client for sending tracking events to the XY Labs pixel API. */\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 = isUndefined(apiBaseUri[baseUri]) ? baseUri : `${apiBaseUri[baseUri]}/t/event/queue`\n }\n\n /**\n * Sends an array of user events to the tracking API.\n * @param events - The events to submit\n * @returns The response data from the API\n */\n async trackEvents(events: UserEvent[]) {\n return (await fetchJsonPost(this.endPoint, events)).data\n }\n}\n", "import { assertEx } from '@xylabs/assert'\nimport type { JsonObject } from '@xylabs/object'\nimport { Mutex } from 'async-mutex'\n\nimport type { UserEvent } from './Api/index.ts'\nimport { PixelApi } from './Api/index.ts'\nimport type { ExIds } from './ExIds.ts'\nimport { getSystemInfo } from './getSystemInfo.ts'\nimport { md5Raw } from './md5Raw.ts'\nimport { Referrer } from './Referrer.ts'\nimport { UniqueUserId } from './UniqueUserId.ts'\nimport { UtmFields } from './UtmFields.ts'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nconst getCookieValue = (name: string): string | undefined => {\n const encodedName = encodeURIComponent(name)\n const cookie = globalThis.document?.cookie\n if (cookie === undefined || cookie.length === 0) return undefined\n const cookies = cookie.split('; ')\n for (const item of cookies) {\n const separatorIndex = item.indexOf('=')\n const key = separatorIndex === -1 ? item : item.slice(0, separatorIndex)\n if (key === encodedName || key === name) {\n const value = separatorIndex === -1 ? '' : item.slice(separatorIndex + 1)\n return decodeURIComponent(value)\n }\n }\n}\n\n/** Singleton pixel tracker that queues and sends user events to the XY Labs tracking API. */\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 /** Returns the singleton XyPixel instance, throwing if not yet initialized. */\n static get instance(): XyPixel {\n return assertEx(this._instance, () => 'XyPixel uninitialized')\n }\n\n /**\n * Initializes the XyPixel singleton with the given pixel ID.\n * @param pixelId - The pixel identifier for this tracking instance\n * @returns The newly created XyPixel instance\n */\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n /**\n * Replaces the default PixelApi instance used for sending events.\n * @param api - The PixelApi instance to use\n */\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n this.utmFieldsObj ??= new UtmFields()\n return this.utmFieldsObj\n }\n\n /**\n * Associates an email address with this pixel instance, hashing it for privacy.\n * @param email - The email address to identify the user with\n */\n identify(email?: string) {\n this.email = email\n this.email_hash = (email !== undefined && email.length > 0) ? md5Raw(email) : undefined\n if (this.email_hash !== undefined) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n /**\n * Queues a tracking event and attempts to flush the queue to the API.\n * @param event - The event name\n * @param fields - Optional event-specific fields\n * @param eventId - Optional unique event identifier\n */\n async send<T extends JsonObject>(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 !== undefined) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events !== undefined) {\n // put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: getCookieValue('_fbc'),\n fbp: getCookieValue('_fbp'),\n ga: getCookieValue('_ga'),\n gclid: getCookieValue('_gcl_aw'),\n rdt_uid: getCookieValue('rdt_uid'),\n scid: getCookieValue('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n", "import type { UserEventSystem } from './Api/index.ts'\n\ninterface UserAgentBrand {\n brand: string\n version: string\n}\n\ninterface NavigatorUserAgentDataLike {\n brands?: UserAgentBrand[]\n mobile?: boolean\n platform?: string\n}\n\ntype NavigatorWithUserAgentData = Navigator & {\n userAgentData?: NavigatorUserAgentDataLike\n}\n\nlet systemInfo: UserEventSystem | undefined\n\nconst firstMatch = (value: string, expressions: RegExp[]) => {\n for (const expression of expressions) {\n const match = expression.exec(value)\n if (match?.[1]) return match[1].replaceAll('_', '.')\n }\n}\n\nconst browserFromUserAgentData = (userAgentData?: NavigatorUserAgentDataLike) => {\n const brands = userAgentData?.brands ?? []\n return brands.find(({ brand }) => !/not.?a.?brand/i.test(brand) && brand !== 'Chromium') ?? brands.find(({ brand }) => brand === 'Chromium')\n}\n\nconst parseBrowser = (userAgent: string, userAgentData?: NavigatorUserAgentDataLike): UserEventSystem['browser'] => {\n const brand = browserFromUserAgentData(userAgentData)\n if (brand !== undefined) return { name: brand.brand, version: brand.version }\n\n const browserParsers: [RegExp, string][] = [\n [/Edg\\/([\\d.]+)/, 'Microsoft Edge'],\n [/OPR\\/([\\d.]+)/, 'Opera'],\n [/Firefox\\/([\\d.]+)/, 'Firefox'],\n [/Chrome\\/([\\d.]+)/, 'Chrome'],\n [/Version\\/([\\d.]+).*Safari\\//, 'Safari'],\n ]\n\n for (const [expression, name] of browserParsers) {\n const version = firstMatch(userAgent, [expression])\n if (version !== undefined) return { name, version }\n }\n\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parseEngine = (userAgent: string): UserEventSystem['engine'] => {\n if (/Chrome\\/|Chromium\\/|Edg\\/|OPR\\//.test(userAgent)) {\n return { name: 'Blink' }\n }\n\n const webkitVersion = firstMatch(userAgent, [/AppleWebKit\\/([\\d.]+)/])\n if (webkitVersion !== undefined) return { name: 'WebKit', version: webkitVersion }\n\n const geckoVersion = firstMatch(userAgent, [/Gecko\\/([\\d.]+)/])\n if (geckoVersion !== undefined) return { name: 'Gecko', version: geckoVersion }\n\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parseOS = (userAgent: string, userAgentData?: NavigatorUserAgentDataLike): UserEventSystem['os'] => {\n const platform = userAgentData?.platform\n if (platform !== undefined && platform.length > 0) return { name: platform }\n\n const osParsers: [RegExp, string][] = [\n [/Windows NT ([\\d.]+)/, 'Windows'],\n [/Android ([\\d.]+)/, 'Android'],\n [/(?:iPhone|iPad|iPod).*OS ([\\d_]+)/, 'iOS'],\n [/Mac OS X ([\\d_]+)/, 'macOS'],\n ]\n\n for (const [expression, name] of osParsers) {\n const version = firstMatch(userAgent, [expression])\n if (version !== undefined) return { name, version }\n }\n\n if (userAgent.includes('Linux')) return { name: 'Linux' }\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parsePlatform = (navigator: NavigatorWithUserAgentData, userAgent: string): UserEventSystem['platform'] => {\n const type = navigator.userAgentData?.mobile === true || /Android|Mobi|iPhone|iPad|iPod/i.test(userAgent) ? 'mobile' : 'desktop'\n const platform = navigator.userAgentData?.platform\n const vendor = navigator.vendor ?? ''\n\n return {\n type,\n vendor: vendor.length > 0 ? vendor : platform,\n }\n}\n\nconst parseSystemInfo = (): UserEventSystem | undefined => {\n const navigator = globalThis.navigator as NavigatorWithUserAgentData | undefined\n const userAgent = navigator?.userAgent ?? ''\n\n if (navigator === undefined || (userAgent.length === 0 && navigator.userAgentData === undefined)) return undefined\n\n return {\n browser: parseBrowser(userAgent, navigator.userAgentData),\n engine: parseEngine(userAgent),\n os: parseOS(userAgent, navigator.userAgentData),\n platform: parsePlatform(navigator, userAgent),\n }\n}\n\n/**\n * Returns parsed browser, OS, and engine information from the user agent string.\n * Results are cached after the first call.\n * @returns The parsed system info, or undefined if parsing fails\n */\nexport const getSystemInfo = () => {\n try {\n systemInfo = systemInfo ?? parseSystemInfo()\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex instanceof Error ? ex.message : String(ex)}`)\n }\n return systemInfo\n}\n", "interface Md5State {\n a: number\n b: number\n c: number\n d: number\n}\n\nconst shiftAmounts = [\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n]\n\nconst constants = Array.from(\n { length: 64 },\n (_, index) => Math.trunc(Math.abs(Math.sin(index + 1)) * 4_294_967_296) >>> 0,\n)\n\nconst initialState: Md5State = {\n a: 1_732_584_193,\n b: 4_023_233_417,\n c: 2_562_383_102,\n d: 271_733_878,\n}\n\nconst leftRotate = (value: number, shift: number) => ((value << shift) | (value >>> (32 - shift))) >>> 0\n\nconst getRoundValues = (index: number, state: Md5State): { f: number; g: number } => {\n const {\n b, c, d,\n } = state\n\n if (index < 16) return { f: (b & c) | (~b & d), g: index }\n if (index < 32) return { f: (d & b) | (~d & c), g: (5 * index + 1) % 16 }\n if (index < 48) return { f: b ^ c ^ d, g: (3 * index + 5) % 16 }\n return { f: c ^ (b | ~d), g: (7 * index) % 16 }\n}\n\nconst buildPaddedMessage = (value: string) => {\n const message = new TextEncoder().encode(value)\n const bitLength = BigInt(message.length) * 8n\n const paddingLength = (56 - ((message.length + 1) % 64) + 64) % 64\n const bytes = new Uint8Array(message.length + 1 + paddingLength + 8)\n bytes.set(message)\n bytes[message.length] = 0x80\n\n const view = new DataView(bytes.buffer)\n view.setUint32(bytes.length - 8, Number(bitLength & 4_294_967_295n), true)\n view.setUint32(bytes.length - 4, Number((bitLength >> 32n) & 4_294_967_295n), true)\n return view\n}\n\nconst readWords = (view: DataView, offset: number) => {\n return Array.from({ length: 16 }, (_, index) => view.getUint32(offset + index * 4, true))\n}\n\nconst hashBlock = (view: DataView, offset: number, state: Md5State): Md5State => {\n const words = readWords(view, offset)\n const working = { ...state }\n\n for (let index = 0; index < 64; index++) {\n const { f, g } = getRoundValues(index, working)\n const previousD = working.d\n working.d = working.c\n working.c = working.b\n working.b = (working.b + leftRotate((working.a + f + constants[index] + words[g]) >>> 0, shiftAmounts[index])) >>> 0\n working.a = previousD\n }\n\n return {\n a: (state.a + working.a) >>> 0,\n b: (state.b + working.b) >>> 0,\n c: (state.c + working.c) >>> 0,\n d: (state.d + working.d) >>> 0,\n }\n}\n\nconst digestToRawString = ({\n a, b, c, d,\n}: Md5State) => {\n const bytes = new Uint8Array(16)\n const view = new DataView(bytes.buffer)\n for (const [index, word] of [a, b, c, d].entries()) {\n view.setUint32(index * 4, word, true)\n }\n return String.fromCodePoint(...bytes)\n}\n\n/** Returns SparkMD5-compatible raw MD5 output for a UTF-8 string. */\nexport const md5Raw = (value: string) => {\n const view = buildPaddedMessage(value)\n let state = initialState\n for (let offset = 0; offset < view.byteLength; offset += 64) {\n state = hashBlock(view, offset, state)\n }\n return digestToRawString(state)\n}\n", "/** Tracks and persists the document referrer in both session and local storage. */\nexport 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 globalThis.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n /**\n * Returns the referrer data as a JSON object, or undefined if both values are empty.\n * @returns An object with local and session referrer strings, or undefined\n */\n toJson() {\n if ((this.local.length > 0) || (this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = globalThis.localStorage.getItem(Referrer.storageId)\n if (value !== null && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value !== null && value.length > 0) {\n return value\n }\n }\n}\n", "/** Generates and persists a unique user identifier in localStorage. */\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = globalThis.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n globalThis.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n /** Returns the unique user ID as a string. */\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n", "const isStringRecord = (value: unknown): value is Record<string, string> =>\n typeof value === 'object' && value !== null && Object.values(value).every(item => typeof item === 'string')\n\nconst isStringRecordArray = (value: unknown): value is Record<string, string>[] =>\n Array.isArray(value) && value.every(isStringRecord)\n\nconst recordsEqual = (left: Record<string, string> | undefined, right: Record<string, string>): boolean => {\n if (left === undefined) return false\n const leftEntries = Object.entries(left)\n if (leftEntries.length !== Object.keys(right).length) return false\n return leftEntries.every(([key, value]) => right[key] === value)\n}\n\n/** Tracks UTM campaign parameters from query strings, persisting history in localStorage. */\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = globalThis.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n const storedFields: unknown = JSON.parse(storedString)\n this.fields = isStringRecordArray(storedFields) ? storedFields : []\n } catch {\n this.fields = []\n }\n this.update()\n globalThis.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n /**\n * Parses UTM parameters from the current URL query string.\n * @returns A record of UTM key-value pairs, or null if none are present\n */\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?', 2)[1]?.split('&') ?? []\n for (const item of parsedQueryString) {\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 /** Returns the UTM fields history as a JSON string. */\n toString() {\n return JSON.stringify(this.fields)\n }\n\n /**\n * Checks the query string for new UTM values and appends them to the history if changed.\n * @returns The current UTM fields array, or undefined if empty\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 && !recordsEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n", "import type { EmptyObject } from '@xylabs/object'\nimport type { Promisable } from '@xylabs/promise'\n\nimport type { FunnelStartedFields } from './FunnelStartedFields.ts'\nimport type { TestStartedFields } from './TestStartedFields.ts'\nimport type { UserClickFields } from './UserClickFields.ts'\nimport type { ViewContentFields } from './ViewContentFields.ts'\n\n/** Abstract base class for handling user tracking events. */\nexport abstract class UserEventHandler<TData extends EmptyObject> {\n /** Tracks a funnel-started event. */\n abstract funnelStarted<T extends TData>(fields: T | FunnelStartedFields): Promisable<void>\n /** Tracks a test-started event. */\n abstract testStarted<T extends TData>(fields: T | TestStartedFields): Promisable<void>\n /** Tracks a user click event. */\n abstract userClick<T extends TData>(fields: T | UserClickFields): Promisable<void>\n /** Tracks a view-content event. */\n abstract viewContent<T extends TData>(fields: T | ViewContentFields): Promisable<void>\n}\n", "import { type EmptyObject, toSafeJsonObject } from '@xylabs/object'\n\nimport type { FunnelStartedFields } from './FunnelStartedFields.ts'\nimport { XyPixel } from './Pixel.ts'\nimport type { PurchaseFields } from './PurchaseFields.ts'\nimport type { TestStartedFields } from './TestStartedFields.ts'\nimport type { UserClickFields } from './UserClickFields.ts'\nimport { UserEventHandler } from './UserEventHandler.ts'\nimport type { ViewContentFields } from './ViewContentFields.ts'\n\n/** Concrete event handler that sends tracking events through the XyPixel singleton. */\nexport class XyUserEventHandler<T extends EmptyObject = EmptyObject> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n /** Sends a funnel-started event via the pixel API. */\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a purchase event via the pixel API. */\n async purchase(fields: T | PurchaseFields) {\n return await XyPixel.instance.send('Purchase', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a test-started event via the pixel API. */\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a user click event via the pixel API. */\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a view-content event via the pixel API. */\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', toSafeJsonObject(fields, [], 10))\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { fetchJsonPost } from '@xylabs/fetch'\nimport { isUndefined } from '@xylabs/typeof'\n\nimport type { UserEvent } from './UserEvent.ts'\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\n/** HTTP client for sending tracking events to the XY Labs pixel API. */\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 = isUndefined(apiBaseUri[baseUri]) ? baseUri : `${apiBaseUri[baseUri]}/t/event/queue`\n }\n\n /**\n * Sends an array of user events to the tracking API.\n * @param events - The events to submit\n * @returns The response data from the API\n */\n async trackEvents(events: UserEvent[]) {\n const response = await fetchJsonPost(this.endPoint, events)\n return response.data\n }\n}\n", "import { assertEx } from '@xylabs/assert'\nimport type { JsonObject } from '@xylabs/object'\nimport { Mutex } from 'async-mutex'\n\nimport type { UserEvent } from './Api/index.ts'\nimport { PixelApi } from './Api/index.ts'\nimport type { ExIds } from './ExIds.ts'\nimport { getSystemInfo } from './getSystemInfo.ts'\nimport { md5Raw } from './md5Raw.ts'\nimport { Referrer } from './Referrer.ts'\nimport { UniqueUserId } from './UniqueUserId.ts'\nimport { UtmFields } from './UtmFields.ts'\n\nconst emailHashLocalStorageName = 'xy_email_hash'\n\nconst getCookieValue = (name: string): string | undefined => {\n const encodedName = encodeURIComponent(name)\n const cookie = globalThis.document?.cookie\n if (cookie === undefined || cookie.length === 0) return undefined\n const cookies = cookie.split('; ')\n for (const item of cookies) {\n const separatorIndex = item.indexOf('=')\n const key = separatorIndex === -1 ? item : item.slice(0, separatorIndex)\n if (key === encodedName || key === name) {\n const value = separatorIndex === -1 ? '' : item.slice(separatorIndex + 1)\n return decodeURIComponent(value)\n }\n }\n}\n\n/** Singleton pixel tracker that queues and sends user events to the XY Labs tracking API. */\nexport class XyPixel {\n static api = new PixelApi()\n\n private static _instance?: XyPixel\n private static utmFieldsObj: UtmFields\n\n cid: string\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 const uniqueUserId = new UniqueUserId()\n this.cid = uniqueUserId.id\n this.pixelId = pixelId\n this.email_hash = localStorage.getItem(emailHashLocalStorageName)\n }\n\n /** Returns the singleton XyPixel instance, throwing if not yet initialized. */\n static get instance(): XyPixel {\n return assertEx(this._instance, () => 'XyPixel uninitialized')\n }\n\n /**\n * Initializes the XyPixel singleton with the given pixel ID.\n * @param pixelId - The pixel identifier for this tracking instance\n * @returns The newly created XyPixel instance\n */\n static init(pixelId: string) {\n this._instance = new XyPixel(pixelId)\n return this._instance\n }\n\n /**\n * Replaces the default PixelApi instance used for sending events.\n * @param API - The PixelApi instance to use\n */\n static selectApi(api: PixelApi) {\n this.api = api\n }\n\n private static utmFields = () => {\n this.utmFieldsObj ??= new UtmFields()\n return this.utmFieldsObj\n }\n\n /**\n * Associates an email address with this pixel instance, hashing it for privacy.\n * @param email - The email address to identify the user with\n */\n identify(email?: string) {\n this.email = email\n this.email_hash = (email !== undefined && email.length > 0) ? md5Raw(email) : undefined\n if (this.email_hash !== undefined) {\n localStorage.setItem(emailHashLocalStorageName, this.email_hash)\n }\n }\n\n /**\n * Queues a tracking event and attempts to flush the queue to the API.\n * @param event - The event name\n * @param fields - Optional event-specific fields\n * @param eventId - Optional unique event identifier\n */\n async send<T extends JsonObject>(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 !== undefined) {\n const events = this.queue\n this.queue = []\n try {\n await api.trackEvents(events)\n } catch (ex) {\n if (events !== undefined) {\n // put it back since it failed\n this.queue = [...this.queue, ...events]\n }\n\n console.error(ex)\n }\n }\n })\n }\n\n private updateFbId() {\n this.exids = {\n fbc: getCookieValue('_fbc'),\n fbp: getCookieValue('_fbp'),\n ga: getCookieValue('_ga'),\n gclid: getCookieValue('_gcl_aw'),\n rdt_uid: getCookieValue('rdt_uid'),\n scid: getCookieValue('_scid'),\n tt_sessionId: sessionStorage.getItem('tt_sessionId') ?? undefined,\n }\n }\n}\n", "import type { UserEventSystem } from './Api/index.ts'\n\ninterface UserAgentBrand {\n brand: string\n version: string\n}\n\ninterface NavigatorUserAgentDataLike {\n brands?: UserAgentBrand[]\n mobile?: boolean\n platform?: string\n}\n\ntype NavigatorWithUserAgentData = Navigator & {\n userAgentData?: NavigatorUserAgentDataLike\n}\n\nconst cache: { systemInfo?: UserEventSystem } = {}\n\nconst firstMatch = (value: string, expressions: RegExp[]) => {\n for (const expression of expressions) {\n const match = expression.exec(value)\n if (match?.[1] !== undefined && match[1] !== '') return match[1].replaceAll('_', '.')\n }\n}\n\nconst browserFromUserAgentData = (userAgentData?: NavigatorUserAgentDataLike) => {\n const brands = userAgentData?.brands ?? []\n return brands.find(({ brand }) => !/not.?a.?brand/i.test(brand) && brand !== 'Chromium') ?? brands.find(({ brand }) => brand === 'Chromium')\n}\n\nconst parseBrowser = (userAgent: string, userAgentData?: NavigatorUserAgentDataLike): UserEventSystem['browser'] => {\n const brand = browserFromUserAgentData(userAgentData)\n if (brand !== undefined) return { name: brand.brand, version: brand.version }\n\n const browserParsers: [RegExp, string][] = [\n [/Edg\\/([\\d.]+)/, 'Microsoft Edge'],\n [/OPR\\/([\\d.]+)/, 'Opera'],\n [/Firefox\\/([\\d.]+)/, 'Firefox'],\n [/Chrome\\/([\\d.]+)/, 'Chrome'],\n [/Version\\/([\\d.]+).*Safari\\//, 'Safari'],\n ]\n\n for (const [expression, name] of browserParsers) {\n const version = firstMatch(userAgent, [expression])\n if (version !== undefined) return { name, version }\n }\n\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parseEngine = (userAgent: string): UserEventSystem['engine'] => {\n if (/Chrome\\/|Chromium\\/|Edg\\/|OPR\\//.test(userAgent)) {\n return { name: 'Blink' }\n }\n\n const webkitVersion = firstMatch(userAgent, [/AppleWebKit\\/([\\d.]+)/])\n if (webkitVersion !== undefined) return { name: 'WebKit', version: webkitVersion }\n\n const geckoVersion = firstMatch(userAgent, [/Gecko\\/([\\d.]+)/])\n if (geckoVersion !== undefined) return { name: 'Gecko', version: geckoVersion }\n\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parseOS = (userAgent: string, userAgentData?: NavigatorUserAgentDataLike): UserEventSystem['os'] => {\n const platform = userAgentData?.platform\n if (platform !== undefined && platform.length > 0) return { name: platform }\n\n const osParsers: [RegExp, string][] = [\n [/Windows NT ([\\d.]+)/, 'Windows'],\n [/Android ([\\d.]+)/, 'Android'],\n [/(?:iPhone|iPad|iPod).*OS ([\\d_]+)/, 'iOS'],\n [/Mac OS X ([\\d_]+)/, 'macOS'],\n ]\n\n for (const [expression, name] of osParsers) {\n const version = firstMatch(userAgent, [expression])\n if (version !== undefined) return { name, version }\n }\n\n if (userAgent.includes('Linux')) return { name: 'Linux' }\n return userAgent.length > 0 ? { name: 'Unknown' } : undefined\n}\n\nconst parsePlatform = (navigator: NavigatorWithUserAgentData, userAgent: string): UserEventSystem['platform'] => {\n const type = navigator.userAgentData?.mobile === true || /Android|Mobi|iPhone|iPad|iPod/i.test(userAgent) ? 'mobile' : 'desktop'\n const platform = navigator.userAgentData?.platform\n const vendor = navigator.vendor ?? ''\n\n return {\n type,\n vendor: vendor.length > 0 ? vendor : platform,\n }\n}\n\nconst parseSystemInfo = (): UserEventSystem | undefined => {\n const navigator = globalThis.navigator as NavigatorWithUserAgentData | undefined\n const userAgent = navigator?.userAgent ?? ''\n\n if (navigator === undefined || (userAgent.length === 0 && navigator.userAgentData === undefined)) return undefined\n\n return {\n browser: parseBrowser(userAgent, navigator.userAgentData),\n engine: parseEngine(userAgent),\n os: parseOS(userAgent, navigator.userAgentData),\n platform: parsePlatform(navigator, userAgent),\n }\n}\n\n/**\n * Returns parsed browser, OS, and engine information from the user agent string.\n * Results are cached after the first call.\n * @returns The parsed system info, or undefined if parsing fails\n */\nexport const getSystemInfo = () => {\n try {\n cache.systemInfo ??= parseSystemInfo()\n } catch (ex) {\n console.log(`getSystemInfo Error: ${ex instanceof Error ? ex.message : String(ex)}`)\n }\n return cache.systemInfo\n}\n", "interface Md5State {\n a: number\n b: number\n c: number\n d: number\n}\n\nconst shiftAmounts = [\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 7,\n 12,\n 17,\n 22,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 5,\n 9,\n 14,\n 20,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 4,\n 11,\n 16,\n 23,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n 6,\n 10,\n 15,\n 21,\n]\n\nconst constants = Array.from(\n { length: 64 },\n (_, index) => Math.trunc(Math.abs(Math.sin(index + 1)) * 4_294_967_296) >>> 0,\n)\n\nconst initialState: Md5State = {\n a: 1_732_584_193,\n b: 4_023_233_417,\n c: 2_562_383_102,\n d: 271_733_878,\n}\n\nconst leftRotate = (value: number, shift: number) => ((value << shift) | (value >>> (32 - shift))) >>> 0\n\nconst getRoundValues = (index: number, state: Md5State): { f: number; g: number } => {\n const {\n b, c, d,\n } = state\n\n if (index < 16) return { f: (b & c) | (~b & d), g: index }\n if (index < 32) return { f: (d & b) | (~d & c), g: (5 * index + 1) % 16 }\n if (index < 48) return { f: b ^ c ^ d, g: (3 * index + 5) % 16 }\n return { f: c ^ (b | ~d), g: (7 * index) % 16 }\n}\n\nconst buildPaddedMessage = (value: string) => {\n const encoder = new TextEncoder()\n const message = encoder.encode(value)\n const bitLength = BigInt(message.length) * 8n\n const paddingLength = (56 - ((message.length + 1) % 64) + 64) % 64\n const bytes = new Uint8Array(message.length + 1 + paddingLength + 8)\n bytes.set(message)\n bytes[message.length] = 0x80\n\n const view = new DataView(bytes.buffer)\n view.setUint32(bytes.length - 8, Number(bitLength & 4_294_967_295n), true)\n view.setUint32(bytes.length - 4, Number((bitLength >> 32n) & 4_294_967_295n), true)\n return view\n}\n\nconst readWords = (view: DataView, offset: number) => {\n return Array.from({ length: 16 }, (_, index) => view.getUint32(offset + index * 4, true))\n}\n\nconst hashBlock = (view: DataView, offset: number, state: Md5State): Md5State => {\n const words = readWords(view, offset)\n const working = { ...state }\n\n for (let index = 0; index < 64; index++) {\n const { f, g } = getRoundValues(index, working)\n const previousD = working.d\n working.d = working.c\n working.c = working.b\n working.b = (working.b + leftRotate((working.a + f + constants[index] + words[g]) >>> 0, shiftAmounts[index])) >>> 0\n working.a = previousD\n }\n\n return {\n a: (state.a + working.a) >>> 0,\n b: (state.b + working.b) >>> 0,\n c: (state.c + working.c) >>> 0,\n d: (state.d + working.d) >>> 0,\n }\n}\n\nconst digestToRawString = ({\n a, b, c, d,\n}: Md5State) => {\n const bytes = new Uint8Array(16)\n const view = new DataView(bytes.buffer)\n for (const [index, word] of [a, b, c, d].entries()) {\n view.setUint32(index * 4, word, true)\n }\n return String.fromCodePoint(...bytes)\n}\n\n/** Returns SparkMD5-compatible raw MD5 output for a UTF-8 string. */\nexport const md5Raw = (value: string) => {\n const view = buildPaddedMessage(value)\n let state = initialState\n for (let offset = 0; offset < view.byteLength; offset += 64) {\n state = hashBlock(view, offset, state)\n }\n return digestToRawString(state)\n}\n", "/** Tracks and persists the document referrer in both session and local storage. */\nexport 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 globalThis.localStorage.setItem(Referrer.storageId, this.local)\n }\n\n /**\n * Returns the referrer data as a JSON object, or undefined if both values are empty.\n * @returns An object with local and session referrer strings, or undefined\n */\n toJson() {\n if ((this.local.length > 0) || (this.session.length > 0)) {\n return {\n local: this.local,\n session: this.session,\n }\n }\n }\n\n private getFromLocal() {\n const value = globalThis.localStorage.getItem(Referrer.storageId)\n if (value !== null && value.length > 0) {\n return value\n }\n }\n\n private getFromSession() {\n const value = sessionStorage.getItem(Referrer.storageId)\n if (value !== null && value.length > 0) {\n return value\n }\n }\n}\n", "/** Generates and persists a unique user identifier in localStorage. */\nexport class UniqueUserId {\n private static localStorageId = '_coin_cid'\n id: string\n\n constructor() {\n this.id = globalThis.localStorage.getItem(UniqueUserId.localStorageId) ?? this.generateId()\n globalThis.localStorage.setItem(UniqueUserId.localStorageId, this.id)\n }\n\n /** Returns the unique user ID as a string. */\n toString() {\n return this.id\n }\n\n private generateId() {\n return crypto.randomUUID()\n }\n}\n", "const isStringRecord = (value: unknown): value is Record<string, string> =>\n typeof value === 'object' && value !== null && Object.values(value).every(item => typeof item === 'string')\n\nconst isStringRecordArray = (value: unknown): value is Record<string, string>[] =>\n Array.isArray(value) && value.every(isStringRecord)\n\nconst recordsEqual = (left: Record<string, string> | undefined, right: Record<string, string>): boolean => {\n if (left === undefined) return false\n const leftEntries = Object.entries(left)\n if (leftEntries.length !== Object.keys(right).length) return false\n return leftEntries.every(([key, value]) => right[key] === value)\n}\n\n/** Tracks UTM campaign parameters from query strings, persisting history in localStorage. */\nexport class UtmFields {\n private static localStorageId = '_coin_utm'\n fields: Record<string, string>[] = []\n constructor() {\n const storedString = globalThis.localStorage.getItem(UtmFields.localStorageId) ?? '[]'\n try {\n const storedFields: unknown = JSON.parse(storedString)\n this.fields = isStringRecordArray(storedFields) ? storedFields : []\n } catch {\n this.fields = []\n }\n this.update()\n globalThis.localStorage.setItem(UtmFields.localStorageId, JSON.stringify(this.fields))\n }\n\n /**\n * Parses UTM parameters from the current URL query string.\n * @returns A record of UTM key-value pairs, or null if none are present\n */\n getUtmRecord = () => {\n const record: Record<string, string> = {}\n const parsedQueryString = document.location.search.split('?', 2)[1]?.split('&') ?? []\n for (const item of parsedQueryString) {\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 /** Returns the UTM fields history as a JSON string. */\n toString() {\n return JSON.stringify(this.fields)\n }\n\n /**\n * Checks the query string for new UTM values and appends them to the history if changed.\n * @returns The current UTM fields array, or undefined if empty\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 && !recordsEqual(this.fields.at(-1), record)) {\n this.fields.push(record)\n }\n return this.fields ?? undefined\n }\n}\n", "import type { EmptyObject } from '@xylabs/object'\nimport type { Promisable } from '@xylabs/promise'\n\nimport type { FunnelStartedFields } from './FunnelStartedFields.ts'\nimport type { TestStartedFields } from './TestStartedFields.ts'\nimport type { UserClickFields } from './UserClickFields.ts'\nimport type { ViewContentFields } from './ViewContentFields.ts'\n\n/** Abstract base class for handling user tracking events. */\nexport abstract class UserEventHandler<TData extends EmptyObject> {\n /** Tracks a funnel-started event. */\n abstract funnelStarted<T extends TData>(fields: T | FunnelStartedFields): Promisable<void>\n /** Tracks a test-started event. */\n abstract testStarted<T extends TData>(fields: T | TestStartedFields): Promisable<void>\n /** Tracks a user click event. */\n abstract userClick<T extends TData>(fields: T | UserClickFields): Promisable<void>\n /** Tracks a view-content event. */\n abstract viewContent<T extends TData>(fields: T | ViewContentFields): Promisable<void>\n}\n", "import { type EmptyObject, toSafeJsonObject } from '@xylabs/object'\n\nimport type { FunnelStartedFields } from './FunnelStartedFields.ts'\nimport { XyPixel } from './Pixel.ts'\nimport type { PurchaseFields } from './PurchaseFields.ts'\nimport type { TestStartedFields } from './TestStartedFields.ts'\nimport type { UserClickFields } from './UserClickFields.ts'\nimport { UserEventHandler } from './UserEventHandler.ts'\nimport type { ViewContentFields } from './ViewContentFields.ts'\n\n/** Concrete event handler that sends tracking events through the XyPixel singleton. */\nexport class XyUserEventHandler<T extends EmptyObject = EmptyObject> extends UserEventHandler<T> {\n constructor() {\n super()\n }\n\n /** Sends a funnel-started event via the pixel API. */\n async funnelStarted(fields: T | FunnelStartedFields) {\n return await XyPixel.instance.send('FunnelStarted', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a purchase event via the pixel API. */\n async purchase(fields: T | PurchaseFields) {\n return await XyPixel.instance.send('Purchase', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a test-started event via the pixel API. */\n async testStarted(fields: T | TestStartedFields) {\n return await XyPixel.instance.send('TestStarted', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a user click event via the pixel API. */\n async userClick(fields: T | UserClickFields) {\n return await XyPixel.instance.send('ViewPage', toSafeJsonObject(fields, [], 10))\n }\n\n /** Sends a view-content event via the pixel API. */\n async viewContent(fields: T | ViewContentFields) {\n return await XyPixel.instance.send('ViewContent', toSafeJsonObject(fields, [], 10))\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"md5Raw.d.ts","sourceRoot":"","sources":["../../src/md5Raw.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"md5Raw.d.ts","sourceRoot":"","sources":["../../src/md5Raw.ts"],"names":[],"mappings":"AAsJA,qEAAqE;AACrE,eAAO,MAAM,MAAM,GAAI,OAAO,MAAM,WAOnC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xylabs/pixel",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Event Client for xylabs ESB",
|
|
5
5
|
"homepage": "https://xylabs.com",
|
|
6
6
|
"bugs": {
|
|
@@ -38,21 +38,23 @@
|
|
|
38
38
|
"README.md"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@xylabs/
|
|
42
|
-
"@xylabs/
|
|
43
|
-
"@xylabs/
|
|
44
|
-
"@xylabs/
|
|
45
|
-
"@xylabs/typeof": "~
|
|
41
|
+
"@xylabs/assert": "~7.0.0",
|
|
42
|
+
"@xylabs/fetch": "~7.0.0",
|
|
43
|
+
"@xylabs/object": "~7.0.0",
|
|
44
|
+
"@xylabs/promise": "~7.0.0",
|
|
45
|
+
"@xylabs/typeof": "~7.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@xylabs/toolchain": "^8.1
|
|
49
|
-
"@xylabs/tsconfig": "^8.1
|
|
50
|
-
"@xylabs/tsconfig-dom": "^8.1
|
|
48
|
+
"@xylabs/toolchain": "^8.4.1",
|
|
49
|
+
"@xylabs/tsconfig": "^8.4.1",
|
|
50
|
+
"@xylabs/tsconfig-dom": "^8.4.1",
|
|
51
51
|
"async-mutex": "^0.5.0",
|
|
52
|
-
"
|
|
52
|
+
"browserslist": "4.28.4",
|
|
53
|
+
"eslint": "^10.5.0",
|
|
54
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
53
55
|
"typescript": "^6.0.3",
|
|
54
|
-
"vite": "^8.0
|
|
55
|
-
"vitest": "^4.1.
|
|
56
|
+
"vite": "^8.1.0",
|
|
57
|
+
"vitest": "^4.1.9",
|
|
56
58
|
"zod": "^4.4.3"
|
|
57
59
|
},
|
|
58
60
|
"peerDependencies": {
|