@shware/analytics 5.1.1 → 6.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.
- package/dist/hooks/use-app-analytics.cjs +7 -6
- package/dist/hooks/use-app-analytics.cjs.map +1 -1
- package/dist/hooks/use-app-analytics.mjs +4 -3
- package/dist/hooks/use-app-analytics.mjs.map +1 -1
- package/dist/hooks/use-web-analytics.cjs +14 -13
- package/dist/hooks/use-web-analytics.cjs.map +1 -1
- package/dist/hooks/use-web-analytics.mjs +7 -6
- package/dist/hooks/use-web-analytics.mjs.map +1 -1
- package/dist/native/setup.cjs +0 -1
- package/dist/native/setup.cjs.map +1 -1
- package/dist/native/setup.mjs +0 -1
- package/dist/native/setup.mjs.map +1 -1
- package/dist/schema/index.cjs +0 -5
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +0 -20
- package/dist/schema/index.d.cts.map +1 -1
- package/dist/schema/index.d.mts +0 -20
- package/dist/schema/index.d.mts.map +1 -1
- package/dist/schema/index.mjs +0 -5
- package/dist/schema/index.mjs.map +1 -1
- package/dist/server/action-source.cjs +28 -0
- package/dist/server/action-source.cjs.map +1 -0
- package/dist/server/action-source.d.cts +20 -0
- package/dist/server/action-source.d.cts.map +1 -0
- package/dist/server/action-source.d.mts +20 -0
- package/dist/server/action-source.d.mts.map +1 -0
- package/dist/server/action-source.mjs +27 -0
- package/dist/server/action-source.mjs.map +1 -0
- package/dist/server/index.d.cts +2 -1
- package/dist/server/index.d.mts +2 -1
- package/dist/server/meta-conversions-api.cjs +12 -8
- package/dist/server/meta-conversions-api.cjs.map +1 -1
- package/dist/server/meta-conversions-api.d.cts +4 -3
- package/dist/server/meta-conversions-api.d.cts.map +1 -1
- package/dist/server/meta-conversions-api.d.mts +4 -3
- package/dist/server/meta-conversions-api.d.mts.map +1 -1
- package/dist/server/meta-conversions-api.mjs +12 -8
- package/dist/server/meta-conversions-api.mjs.map +1 -1
- package/dist/server/openai-conversions-api.cjs +7 -6
- package/dist/server/openai-conversions-api.cjs.map +1 -1
- package/dist/server/openai-conversions-api.d.cts +3 -2
- package/dist/server/openai-conversions-api.d.cts.map +1 -1
- package/dist/server/openai-conversions-api.d.mts +3 -2
- package/dist/server/openai-conversions-api.d.mts.map +1 -1
- package/dist/server/openai-conversions-api.mjs +7 -6
- package/dist/server/openai-conversions-api.mjs.map +1 -1
- package/dist/server/reddit-conversions-api.cjs +6 -4
- package/dist/server/reddit-conversions-api.cjs.map +1 -1
- package/dist/server/reddit-conversions-api.d.cts +3 -2
- package/dist/server/reddit-conversions-api.d.cts.map +1 -1
- package/dist/server/reddit-conversions-api.d.mts +3 -2
- package/dist/server/reddit-conversions-api.d.mts.map +1 -1
- package/dist/server/reddit-conversions-api.mjs +6 -4
- package/dist/server/reddit-conversions-api.mjs.map +1 -1
- package/dist/setup/session.cjs +28 -2
- package/dist/setup/session.cjs.map +1 -1
- package/dist/setup/session.d.cts +25 -2
- package/dist/setup/session.d.cts.map +1 -1
- package/dist/setup/session.d.mts +25 -2
- package/dist/setup/session.d.mts.map +1 -1
- package/dist/setup/session.mjs +28 -2
- package/dist/setup/session.mjs.map +1 -1
- package/dist/track/index.cjs +23 -12
- package/dist/track/index.cjs.map +1 -1
- package/dist/track/index.d.cts.map +1 -1
- package/dist/track/index.d.mts.map +1 -1
- package/dist/track/index.mjs +18 -7
- package/dist/track/index.mjs.map +1 -1
- package/dist/track/types.d.cts +0 -1
- package/dist/track/types.d.cts.map +1 -1
- package/dist/track/types.d.mts +0 -1
- package/dist/track/types.d.mts.map +1 -1
- package/dist/web/index.cjs +0 -3
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts.map +1 -1
- package/dist/web/index.d.mts.map +1 -1
- package/dist/web/index.mjs +0 -3
- package/dist/web/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.mjs","names":["uuidv7"],"sources":["../../src/setup/session.ts"],"sourcesContent":["import { v7 as uuidv7 } from 'uuid';\n\nexport const SESSION_TIMEOUT = 30 * 60 * 1000;\n\nclass Session {\n private id: string;\n private startTime: number;\n private lastActiveTime: number;\n private accumulatedTime: number;\n\n private active: boolean;\n private visible: boolean;\n private focused: boolean;\n\n constructor() {\n this.id = uuidv7();\n this.startTime = Date.now();\n this.lastActiveTime = Date.now();\n this.accumulatedTime = 0;\n\n this.active = true;\n this.visible = typeof document !== 'undefined' ? document.visibilityState === 'visible' : true;\n this.focused = typeof document !== 'undefined' ? document.hasFocus() : true;\n }\n\n getId = () => this.id;\n\n isActive = () => this.active;\n isVisible = () => this.visible;\n isFocused = () => this.focused;\n isExpired = () => Date.now() - this.lastActiveTime > SESSION_TIMEOUT;\n\n updateLastActiveTime = () => {\n this.lastActiveTime = Date.now();\n };\n\n updateActive = (active: boolean) => {\n this.active = active;\n };\n\n refresh = () => {\n this.id = uuidv7();\n this.lastActiveTime = Date.now();\n };\n\n updateAccumulator = () => {\n const now = Date.now();\n if (this.focused && this.visible && this.active) {\n const delta = now - this.startTime;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n this.accumulatedTime += delta;\n }\n }\n this.startTime = now;\n };\n\n focus = () => {\n this.updateAccumulator();\n this.updateLastActiveTime();\n this.focused = true;\n };\n\n blur = () => {\n this.updateAccumulator();\n this.focused = false;\n };\n\n pageshow = () => {\n this.updateAccumulator();\n this.updateLastActiveTime();\n this.active = true;\n };\n\n pagehide = () => {\n this.updateAccumulator();\n this.active = false;\n };\n\n visibilitychange = (state: DocumentVisibilityState) => {\n this.updateAccumulator();\n if (state === 'visible') {\n this.updateLastActiveTime();\n }\n this.visible = state === 'visible';\n };\n\n flush = () => {\n this.updateAccumulator();\n const engagementTime = this.accumulatedTime;\n this.accumulatedTime = 0;\n return engagementTime;\n };\n}\n\nexport
|
|
1
|
+
{"version":3,"file":"session.mjs","names":["uuidv7"],"sources":["../../src/setup/session.ts"],"sourcesContent":["import { v7 as uuidv7 } from 'uuid';\n\nexport const SESSION_TIMEOUT = 30 * 60 * 1000;\n\nclass Session {\n private id: string;\n private startTime: number;\n private lastActiveTime: number;\n private accumulatedTime: number;\n\n private active: boolean;\n private visible: boolean;\n private focused: boolean;\n\n constructor() {\n this.id = uuidv7();\n this.startTime = Date.now();\n this.lastActiveTime = Date.now();\n this.accumulatedTime = 0;\n\n this.active = true;\n this.visible = typeof document !== 'undefined' ? document.visibilityState === 'visible' : true;\n this.focused = typeof document !== 'undefined' ? document.hasFocus() : true;\n }\n\n getId = () => this.id;\n\n isActive = () => this.active;\n isVisible = () => this.visible;\n isFocused = () => this.focused;\n isExpired = () => Date.now() - this.lastActiveTime > SESSION_TIMEOUT;\n\n updateLastActiveTime = () => {\n this.lastActiveTime = Date.now();\n };\n\n updateActive = (active: boolean) => {\n this.active = active;\n };\n\n refresh = () => {\n this.id = uuidv7();\n this.lastActiveTime = Date.now();\n };\n\n updateAccumulator = () => {\n const now = Date.now();\n if (this.focused && this.visible && this.active) {\n const delta = now - this.startTime;\n if (delta > 0 && delta < SESSION_TIMEOUT) {\n this.accumulatedTime += delta;\n }\n }\n this.startTime = now;\n };\n\n focus = () => {\n this.updateAccumulator();\n this.updateLastActiveTime();\n this.focused = true;\n };\n\n blur = () => {\n this.updateAccumulator();\n this.focused = false;\n };\n\n pageshow = () => {\n this.updateAccumulator();\n this.updateLastActiveTime();\n this.active = true;\n };\n\n pagehide = () => {\n this.updateAccumulator();\n this.active = false;\n };\n\n visibilitychange = (state: DocumentVisibilityState) => {\n this.updateAccumulator();\n if (state === 'visible') {\n this.updateLastActiveTime();\n }\n this.visible = state === 'visible';\n };\n\n flush = () => {\n this.updateAccumulator();\n const engagementTime = this.accumulatedTime;\n this.accumulatedTime = 0;\n return engagementTime;\n };\n}\n\nlet session: Session | undefined;\n\n/**\n * The session, built the first time something asks for it.\n *\n * Deliberately not a module-scope `new Session()`. The constructor calls\n * `uuidv7()`, `uuid` draws its bytes from `crypto.getRandomValues`, and\n * Cloudflare Workers reject that outside a request handler:\n *\n * Disallowed operation called within global scope. Asynchronous I/O\n * (ex: fetch() or connect()), setting a timeout, and generating random\n * values are not allowed within global scope.\n *\n * Module scope in a Worker is evaluated once when the isolate boots and is\n * then shared by every request that isolate serves, so a random value drawn\n * there would be the same for all of them — which is why the runtime refuses\n * to produce one. A host that server-renders on Workers reaches this module\n * through `track()` on the server as well, and the throw happened as the\n * isolate booted, taking down every route before a component rendered.\n *\n * Everything here is per-visitor browser or app state, so deferring the\n * construction costs nothing and buys two things: the server bundle can be\n * evaluated, and `startTime` marks when the session actually began rather\n * than when the isolate happened to start.\n */\nexport function getSession() {\n return (session ??= new Session());\n}\n"],"mappings":";;AAEA,MAAa,kBAAkB,OAAU;AAEzC,IAAM,UAAN,MAAc;CAUZ,cAAc;EAWA,KAAA,cAAA,KAAK;EAEF,KAAA,iBAAA,KAAK;EACJ,KAAA,kBAAA,KAAK;EACL,KAAA,kBAAA,KAAK;EACL,KAAA,kBAAA,KAAK,IAAI,IAAI,KAAK,iBAAiB;EAExB,KAAA,6BAAA;GAC3B,KAAK,iBAAiB,KAAK,IAAI;EACjC;EAEgB,KAAA,gBAAA,WAAoB;GAClC,KAAK,SAAS;EAChB;EAEgB,KAAA,gBAAA;GACd,KAAK,KAAKA,GAAO;GACjB,KAAK,iBAAiB,KAAK,IAAI;EACjC;EAE0B,KAAA,0BAAA;GACxB,MAAM,MAAM,KAAK,IAAI;GACrB,IAAI,KAAK,WAAW,KAAK,WAAW,KAAK,QAAQ;IAC/C,MAAM,QAAQ,MAAM,KAAK;IACzB,IAAI,QAAQ,KAAK,QAAA,MACf,KAAK,mBAAmB;GAE5B;GACA,KAAK,YAAY;EACnB;EAEc,KAAA,cAAA;GACZ,KAAK,kBAAkB;GACvB,KAAK,qBAAqB;GAC1B,KAAK,UAAU;EACjB;EAEa,KAAA,aAAA;GACX,KAAK,kBAAkB;GACvB,KAAK,UAAU;EACjB;EAEiB,KAAA,iBAAA;GACf,KAAK,kBAAkB;GACvB,KAAK,qBAAqB;GAC1B,KAAK,SAAS;EAChB;EAEiB,KAAA,iBAAA;GACf,KAAK,kBAAkB;GACvB,KAAK,SAAS;EAChB;EAEoB,KAAA,oBAAA,UAAmC;GACrD,KAAK,kBAAkB;GACvB,IAAI,UAAU,WACZ,KAAK,qBAAqB;GAE5B,KAAK,UAAU,UAAU;EAC3B;EAEc,KAAA,cAAA;GACZ,KAAK,kBAAkB;GACvB,MAAM,iBAAiB,KAAK;GAC5B,KAAK,kBAAkB;GACvB,OAAO;EACT;EA5EE,KAAK,KAAKA,GAAO;EACjB,KAAK,YAAY,KAAK,IAAI;EAC1B,KAAK,iBAAiB,KAAK,IAAI;EAC/B,KAAK,kBAAkB;EAEvB,KAAK,SAAS;EACd,KAAK,UAAU,OAAO,aAAa,cAAc,SAAS,oBAAoB,YAAY;EAC1F,KAAK,UAAU,OAAO,aAAa,cAAc,SAAS,SAAS,IAAI;CACzE;AAqEF;AAEA,IAAI;;;;;;;;;;;;;;;;;;;;;;;;AAyBJ,SAAgB,aAAa;CAC3B,OAAQ,YAAY,IAAI,QAAQ;AAClC"}
|
package/dist/track/index.cjs
CHANGED
|
@@ -6,24 +6,34 @@ const require_visitor_index = require("../visitor/index.cjs");
|
|
|
6
6
|
let _shware_utils = require("@shware/utils");
|
|
7
7
|
//#region src/track/index.ts
|
|
8
8
|
const defaultOptions = { enableThirdPartyTracking: true };
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
let tokenBucket;
|
|
10
|
+
/**
|
|
11
|
+
* The rate limiter, built on the first send rather than at module scope: its
|
|
12
|
+
* constructor starts a refill `setInterval`, and Cloudflare Workers refuse to
|
|
13
|
+
* set a timer outside a request handler for the same reason they refuse to
|
|
14
|
+
* generate random values there — see `setup/session.ts`.
|
|
15
|
+
*/
|
|
16
|
+
function getTokenBucket() {
|
|
17
|
+
return tokenBucket ??= new _shware_utils.TokenBucket({
|
|
18
|
+
rate: 1,
|
|
19
|
+
capacity: 20,
|
|
20
|
+
requested: 2
|
|
21
|
+
});
|
|
22
|
+
}
|
|
14
23
|
async function sendEvents(events) {
|
|
15
24
|
try {
|
|
16
25
|
if (events.length === 0) return;
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
const session = require_setup_session.getSession();
|
|
27
|
+
if (session.isExpired()) {
|
|
28
|
+
session.refresh();
|
|
19
29
|
events.unshift({
|
|
20
30
|
name: "session_start",
|
|
21
31
|
properties: {},
|
|
22
32
|
options: { enableThirdPartyTracking: false },
|
|
23
33
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
24
34
|
});
|
|
25
|
-
} else
|
|
26
|
-
await
|
|
35
|
+
} else session.updateLastActiveTime();
|
|
36
|
+
await getTokenBucket().removeTokens();
|
|
27
37
|
const tags = await require_setup_index.config.getTags();
|
|
28
38
|
const visitor_id = (await require_visitor_index.getVisitor()).id;
|
|
29
39
|
const dto = events.map((event) => ({
|
|
@@ -31,7 +41,7 @@ async function sendEvents(events) {
|
|
|
31
41
|
properties: event.properties,
|
|
32
42
|
tags,
|
|
33
43
|
visitor_id,
|
|
34
|
-
session_id:
|
|
44
|
+
session_id: session.getId(),
|
|
35
45
|
platform: require_setup_index.config.platform,
|
|
36
46
|
environment: require_setup_index.config.environment,
|
|
37
47
|
timestamp: event.timestamp
|
|
@@ -98,13 +108,14 @@ async function trackAsync(name, properties, options = defaultOptions) {
|
|
|
98
108
|
}
|
|
99
109
|
function sendBeacon(name, properties) {
|
|
100
110
|
if (!require_setup_index.cache.tags || !require_setup_index.cache.visitor) return;
|
|
101
|
-
require_setup_session.
|
|
111
|
+
const session = require_setup_session.getSession();
|
|
112
|
+
session.updateLastActiveTime();
|
|
102
113
|
const dto = [{
|
|
103
114
|
name,
|
|
104
115
|
properties,
|
|
105
116
|
tags: require_setup_index.cache.tags,
|
|
106
117
|
visitor_id: require_setup_index.cache.visitor.id,
|
|
107
|
-
session_id:
|
|
118
|
+
session_id: session.getId(),
|
|
108
119
|
platform: require_setup_index.config.platform,
|
|
109
120
|
environment: require_setup_index.config.environment,
|
|
110
121
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
package/dist/track/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["TokenBucket","
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["TokenBucket","getSession","config","getVisitor","IGNORED_EVENTS","cache"],"sources":["../../src/track/index.ts"],"sourcesContent":["import { TokenBucket, fetch } from '@shware/utils';\nimport type { CreateTrackEventDTO } from '../schema/index';\nimport { cache, config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { getVisitor } from '../visitor/index';\nimport type { EventName, TrackEventResponse, TrackName, TrackProperties } from './types';\n\nexport interface TrackOptions {\n enableThirdPartyTracking?: boolean;\n onSucceed?: (response?: TrackEventResponse[number]) => void;\n onError?: (error: unknown) => void;\n}\n\nconst defaultOptions: TrackOptions = { enableThirdPartyTracking: true };\n\nlet tokenBucket: TokenBucket | undefined;\n\n/**\n * The rate limiter, built on the first send rather than at module scope: its\n * constructor starts a refill `setInterval`, and Cloudflare Workers refuse to\n * set a timer outside a request handler for the same reason they refuse to\n * generate random values there — see `setup/session.ts`.\n */\nfunction getTokenBucket() {\n return (tokenBucket ??= new TokenBucket({ rate: 1, capacity: 20, requested: 2 }));\n}\n\ntype Item = {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n name: TrackName<any>;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n properties: TrackProperties<any>;\n timestamp: string;\n options: TrackOptions;\n};\n\nasync function sendEvents(events: Item[]) {\n try {\n if (events.length === 0) return;\n\n const session = getSession();\n if (session.isExpired()) {\n session.refresh();\n events.unshift({\n name: 'session_start',\n properties: {},\n options: { enableThirdPartyTracking: false },\n timestamp: new Date().toISOString(),\n });\n } else {\n session.updateLastActiveTime();\n }\n\n await getTokenBucket().removeTokens();\n\n const tags = await config.getTags();\n const visitor_id = (await getVisitor()).id;\n\n const dto: CreateTrackEventDTO = events.map((event) => ({\n name: event.name,\n properties: event.properties,\n tags,\n visitor_id,\n session_id: session.getId(),\n platform: config.platform,\n environment: config.environment,\n timestamp: event.timestamp,\n }));\n\n const response = await fetch(`${config.endpoint}/events`, {\n method: 'POST',\n credentials: 'include',\n headers: await config.getHeaders(),\n body: JSON.stringify(dto),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send track event: ${response.status} ${await response.text()}`);\n }\n\n const data = (await response.json()) as TrackEventResponse;\n\n let index = 0;\n while (events.length > 0) {\n const event = events.shift();\n if (!event) {\n index++;\n continue;\n }\n const { options, name, properties } = event;\n const eventId = data[index].id;\n options.onSucceed?.({ id: eventId });\n index++;\n if (!options.enableThirdPartyTracking || IGNORED_EVENTS.includes(name)) {\n continue;\n }\n config.thirdPartyTrackers.forEach((tracker) => tracker(name, properties, eventId));\n }\n } catch (e: unknown) {\n if (e instanceof Error) console.log(e.message);\n events.forEach((event) => event.options.onError?.(e));\n }\n}\n\nconst batch = 10;\nconst delay = 2000;\nconst list: Item[] = [];\nlet timer: ReturnType<typeof setTimeout> | null = null;\n\nexport function track<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>,\n options: TrackOptions = defaultOptions\n) {\n list.push({ name, properties, options, timestamp: new Date().toISOString() });\n if (list.length >= batch) {\n const copy = [...list];\n list.length = 0;\n void sendEvents(copy);\n return;\n }\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const copy = [...list];\n list.length = 0;\n void sendEvents(copy);\n }, delay);\n}\n\nexport async function trackAsync<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>,\n options: TrackOptions = defaultOptions\n) {\n await sendEvents([{ name, properties, options, timestamp: new Date().toISOString() }]);\n}\n\nexport function sendBeacon<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>\n) {\n if (!cache.tags || !cache.visitor) return;\n\n const session = getSession();\n session.updateLastActiveTime();\n\n const dto: CreateTrackEventDTO = [\n {\n name,\n properties,\n tags: cache.tags,\n visitor_id: cache.visitor.id,\n session_id: session.getId(),\n platform: config.platform,\n environment: config.environment,\n timestamp: new Date().toISOString(),\n },\n ];\n const blob = new Blob([JSON.stringify(dto)], { type: 'application/json' });\n const success = navigator.sendBeacon(`${config.endpoint}/events`, blob);\n if (success) return;\n console.warn('Failed to send beacon', name, properties);\n}\n"],"mappings":";;;;;;;AAcA,MAAM,iBAA+B,EAAE,0BAA0B,KAAK;AAEtE,IAAI;;;;;;;AAQJ,SAAS,iBAAiB;CACxB,OAAQ,gBAAgB,IAAIA,cAAAA,YAAY;EAAE,MAAM;EAAG,UAAU;EAAI,WAAW;CAAE,CAAC;AACjF;AAWA,eAAe,WAAW,QAAgB;CACxC,IAAI;EACF,IAAI,OAAO,WAAW,GAAG;EAEzB,MAAM,UAAUC,sBAAAA,WAAW;EAC3B,IAAI,QAAQ,UAAU,GAAG;GACvB,QAAQ,QAAQ;GAChB,OAAO,QAAQ;IACb,MAAM;IACN,YAAY,CAAC;IACb,SAAS,EAAE,0BAA0B,MAAM;IAC3C,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;GACpC,CAAC;EACH,OACE,QAAQ,qBAAqB;EAG/B,MAAM,eAAe,CAAC,CAAC,aAAa;EAEpC,MAAM,OAAO,MAAMC,oBAAAA,OAAO,QAAQ;EAClC,MAAM,cAAc,MAAMC,sBAAAA,WAAW,EAAA,CAAG;EAExC,MAAM,MAA2B,OAAO,KAAK,WAAW;GACtD,MAAM,MAAM;GACZ,YAAY,MAAM;GAClB;GACA;GACA,YAAY,QAAQ,MAAM;GAC1B,UAAUD,oBAAAA,OAAO;GACjB,aAAaA,oBAAAA,OAAO;GACpB,WAAW,MAAM;EACnB,EAAE;EAEF,MAAM,WAAW,OAAA,GAAA,cAAA,MAAA,CAAY,GAAGA,oBAAAA,OAAO,SAAS,UAAU;GACxD,QAAQ;GACR,aAAa;GACb,SAAS,MAAMA,oBAAAA,OAAO,WAAW;GACjC,MAAM,KAAK,UAAU,GAAG;EAC1B,CAAC;EAED,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,+BAA+B,SAAS,OAAO,GAAG,MAAM,SAAS,KAAK,GAAG;EAG3F,MAAM,OAAQ,MAAM,SAAS,KAAK;EAElC,IAAI,QAAQ;EACZ,OAAO,OAAO,SAAS,GAAG;GACxB,MAAM,QAAQ,OAAO,MAAM;GAC3B,IAAI,CAAC,OAAO;IACV;IACA;GACF;GACA,MAAM,EAAE,SAAS,MAAM,eAAe;GACtC,MAAM,UAAU,KAAK,MAAM,CAAC;GAC5B,QAAQ,YAAY,EAAE,IAAI,QAAQ,CAAC;GACnC;GACA,IAAI,CAAC,QAAQ,4BAA4BE,qCAAAA,eAAe,SAAS,IAAI,GACnE;GAEF,oBAAA,OAAO,mBAAmB,SAAS,YAAY,QAAQ,MAAM,YAAY,OAAO,CAAC;EACnF;CACF,SAAS,GAAY;EACnB,IAAI,aAAa,OAAO,QAAQ,IAAI,EAAE,OAAO;EAC7C,OAAO,SAAS,UAAU,MAAM,QAAQ,UAAU,CAAC,CAAC;CACtD;AACF;AAEA,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd,MAAM,OAAe,CAAC;AACtB,IAAI,QAA8C;AAElD,SAAgB,MACd,MACA,YACA,UAAwB,gBACxB;CACA,KAAK,KAAK;EAAE;EAAM;EAAY;EAAS,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;CAAE,CAAC;CAC5E,IAAI,KAAK,UAAU,OAAO;EACxB,MAAM,OAAO,CAAC,GAAG,IAAI;EACrB,KAAK,SAAS;EACd,WAAgB,IAAI;EACpB;CACF;CACA,IAAI,OAAO,aAAa,KAAK;CAC7B,QAAQ,iBAAiB;EACvB,QAAQ;EACR,MAAM,OAAO,CAAC,GAAG,IAAI;EACrB,KAAK,SAAS;EACd,WAAgB,IAAI;CACtB,GAAG,KAAK;AACV;AAEA,eAAsB,WACpB,MACA,YACA,UAAwB,gBACxB;CACA,MAAM,WAAW,CAAC;EAAE;EAAM;EAAY;EAAS,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;CAAE,CAAC,CAAC;AACvF;AAEA,SAAgB,WACd,MACA,YACA;CACA,IAAI,CAACC,oBAAAA,MAAM,QAAQ,CAACA,oBAAAA,MAAM,SAAS;CAEnC,MAAM,UAAUJ,sBAAAA,WAAW;CAC3B,QAAQ,qBAAqB;CAE7B,MAAM,MAA2B,CAC/B;EACE;EACA;EACA,MAAMI,oBAAAA,MAAM;EACZ,YAAYA,oBAAAA,MAAM,QAAQ;EAC1B,YAAY,QAAQ,MAAM;EAC1B,UAAUH,oBAAAA,OAAO;EACjB,aAAaA,oBAAAA,OAAO;EACpB,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;CACpC,CACF;CACA,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,mBAAmB,CAAC;CAEzE,IADgB,UAAU,WAAW,GAAGA,oBAAAA,OAAO,SAAS,UAAU,IACxD,GAAG;CACb,QAAQ,KAAK,yBAAyB,MAAM,UAAU;AACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/track/index.ts"],"mappings":";;UAQiB;EACf;EACA,aAAa,WAAW;EACxB,WAAW;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/track/index.ts"],"mappings":";;UAQiB;EACf;EACA,aAAa,WAAW;EACxB,WAAW;;iBAmGG,MAAM,UAAU,YAAY,WAC1C,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B,UAAS;iBAkBW,WAAW,UAAU,YAAY,WACrD,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B,UAAS,eAA6B;iBAKxB,WAAW,UAAU,YAAY,WAC/C,MAAM,UAAU,IAChB,aAAa,gBAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/track/index.ts"],"mappings":";;UAQiB;EACf;EACA,aAAa,WAAW;EACxB,WAAW;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/track/index.ts"],"mappings":";;UAQiB;EACf;EACA,aAAa,WAAW;EACxB,WAAW;;iBAmGG,MAAM,UAAU,YAAY,WAC1C,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B,UAAS;iBAkBW,WAAW,UAAU,YAAY,WACrD,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B,UAAS,eAA6B;iBAKxB,WAAW,UAAU,YAAY,WAC/C,MAAM,UAAU,IAChB,aAAa,gBAAgB"}
|
package/dist/track/index.mjs
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { cache, config } from "../setup/index.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { getSession } from "../setup/session.mjs";
|
|
3
3
|
import { IGNORED_EVENTS } from "../third-parties/ignored-events.mjs";
|
|
4
4
|
import { getVisitor } from "../visitor/index.mjs";
|
|
5
5
|
import { TokenBucket, fetch } from "@shware/utils";
|
|
6
6
|
//#region src/track/index.ts
|
|
7
7
|
const defaultOptions = { enableThirdPartyTracking: true };
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
let tokenBucket;
|
|
9
|
+
/**
|
|
10
|
+
* The rate limiter, built on the first send rather than at module scope: its
|
|
11
|
+
* constructor starts a refill `setInterval`, and Cloudflare Workers refuse to
|
|
12
|
+
* set a timer outside a request handler for the same reason they refuse to
|
|
13
|
+
* generate random values there — see `setup/session.ts`.
|
|
14
|
+
*/
|
|
15
|
+
function getTokenBucket() {
|
|
16
|
+
return tokenBucket ??= new TokenBucket({
|
|
17
|
+
rate: 1,
|
|
18
|
+
capacity: 20,
|
|
19
|
+
requested: 2
|
|
20
|
+
});
|
|
21
|
+
}
|
|
13
22
|
async function sendEvents(events) {
|
|
14
23
|
try {
|
|
15
24
|
if (events.length === 0) return;
|
|
25
|
+
const session = getSession();
|
|
16
26
|
if (session.isExpired()) {
|
|
17
27
|
session.refresh();
|
|
18
28
|
events.unshift({
|
|
@@ -22,7 +32,7 @@ async function sendEvents(events) {
|
|
|
22
32
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23
33
|
});
|
|
24
34
|
} else session.updateLastActiveTime();
|
|
25
|
-
await
|
|
35
|
+
await getTokenBucket().removeTokens();
|
|
26
36
|
const tags = await config.getTags();
|
|
27
37
|
const visitor_id = (await getVisitor()).id;
|
|
28
38
|
const dto = events.map((event) => ({
|
|
@@ -97,6 +107,7 @@ async function trackAsync(name, properties, options = defaultOptions) {
|
|
|
97
107
|
}
|
|
98
108
|
function sendBeacon(name, properties) {
|
|
99
109
|
if (!cache.tags || !cache.visitor) return;
|
|
110
|
+
const session = getSession();
|
|
100
111
|
session.updateLastActiveTime();
|
|
101
112
|
const dto = [{
|
|
102
113
|
name,
|
package/dist/track/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/track/index.ts"],"sourcesContent":["import { TokenBucket, fetch } from '@shware/utils';\nimport type { CreateTrackEventDTO } from '../schema/index';\nimport { cache, config } from '../setup/index';\nimport {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/track/index.ts"],"sourcesContent":["import { TokenBucket, fetch } from '@shware/utils';\nimport type { CreateTrackEventDTO } from '../schema/index';\nimport { cache, config } from '../setup/index';\nimport { getSession } from '../setup/session';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { getVisitor } from '../visitor/index';\nimport type { EventName, TrackEventResponse, TrackName, TrackProperties } from './types';\n\nexport interface TrackOptions {\n enableThirdPartyTracking?: boolean;\n onSucceed?: (response?: TrackEventResponse[number]) => void;\n onError?: (error: unknown) => void;\n}\n\nconst defaultOptions: TrackOptions = { enableThirdPartyTracking: true };\n\nlet tokenBucket: TokenBucket | undefined;\n\n/**\n * The rate limiter, built on the first send rather than at module scope: its\n * constructor starts a refill `setInterval`, and Cloudflare Workers refuse to\n * set a timer outside a request handler for the same reason they refuse to\n * generate random values there — see `setup/session.ts`.\n */\nfunction getTokenBucket() {\n return (tokenBucket ??= new TokenBucket({ rate: 1, capacity: 20, requested: 2 }));\n}\n\ntype Item = {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n name: TrackName<any>;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n properties: TrackProperties<any>;\n timestamp: string;\n options: TrackOptions;\n};\n\nasync function sendEvents(events: Item[]) {\n try {\n if (events.length === 0) return;\n\n const session = getSession();\n if (session.isExpired()) {\n session.refresh();\n events.unshift({\n name: 'session_start',\n properties: {},\n options: { enableThirdPartyTracking: false },\n timestamp: new Date().toISOString(),\n });\n } else {\n session.updateLastActiveTime();\n }\n\n await getTokenBucket().removeTokens();\n\n const tags = await config.getTags();\n const visitor_id = (await getVisitor()).id;\n\n const dto: CreateTrackEventDTO = events.map((event) => ({\n name: event.name,\n properties: event.properties,\n tags,\n visitor_id,\n session_id: session.getId(),\n platform: config.platform,\n environment: config.environment,\n timestamp: event.timestamp,\n }));\n\n const response = await fetch(`${config.endpoint}/events`, {\n method: 'POST',\n credentials: 'include',\n headers: await config.getHeaders(),\n body: JSON.stringify(dto),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send track event: ${response.status} ${await response.text()}`);\n }\n\n const data = (await response.json()) as TrackEventResponse;\n\n let index = 0;\n while (events.length > 0) {\n const event = events.shift();\n if (!event) {\n index++;\n continue;\n }\n const { options, name, properties } = event;\n const eventId = data[index].id;\n options.onSucceed?.({ id: eventId });\n index++;\n if (!options.enableThirdPartyTracking || IGNORED_EVENTS.includes(name)) {\n continue;\n }\n config.thirdPartyTrackers.forEach((tracker) => tracker(name, properties, eventId));\n }\n } catch (e: unknown) {\n if (e instanceof Error) console.log(e.message);\n events.forEach((event) => event.options.onError?.(e));\n }\n}\n\nconst batch = 10;\nconst delay = 2000;\nconst list: Item[] = [];\nlet timer: ReturnType<typeof setTimeout> | null = null;\n\nexport function track<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>,\n options: TrackOptions = defaultOptions\n) {\n list.push({ name, properties, options, timestamp: new Date().toISOString() });\n if (list.length >= batch) {\n const copy = [...list];\n list.length = 0;\n void sendEvents(copy);\n return;\n }\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n const copy = [...list];\n list.length = 0;\n void sendEvents(copy);\n }, delay);\n}\n\nexport async function trackAsync<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>,\n options: TrackOptions = defaultOptions\n) {\n await sendEvents([{ name, properties, options, timestamp: new Date().toISOString() }]);\n}\n\nexport function sendBeacon<T extends EventName = EventName>(\n name: TrackName<T>,\n properties?: TrackProperties<T>\n) {\n if (!cache.tags || !cache.visitor) return;\n\n const session = getSession();\n session.updateLastActiveTime();\n\n const dto: CreateTrackEventDTO = [\n {\n name,\n properties,\n tags: cache.tags,\n visitor_id: cache.visitor.id,\n session_id: session.getId(),\n platform: config.platform,\n environment: config.environment,\n timestamp: new Date().toISOString(),\n },\n ];\n const blob = new Blob([JSON.stringify(dto)], { type: 'application/json' });\n const success = navigator.sendBeacon(`${config.endpoint}/events`, blob);\n if (success) return;\n console.warn('Failed to send beacon', name, properties);\n}\n"],"mappings":"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"}
|
package/dist/track/types.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/track/types.ts"],"mappings":";;KAEY;KACA,YAAY;KAEZ,UAAU,UAAU,YAAY,aAAa,gBAAgB,iBACrE,IACA;KACQ,gBAAgB,UAAU,YAAY,aAAa,gBAAgB,iBAC3E,eAAe,KACf,OAAO,mBAAmB;KAElB;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe,yBAAyB;EACxC;EACA;EACA;EACA;EACA;IAAa;IAAc;IAAe;;EAE1C;EACA;;KAGU,qBAAqB,UAAU,WACzC,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA
|
|
1
|
+
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/track/types.ts"],"mappings":";;KAEY;KACA,YAAY;KAEZ,UAAU,UAAU,YAAY,aAAa,gBAAgB,iBACrE,IACA;KACQ,gBAAgB,UAAU,YAAY,aAAa,gBAAgB,iBAC3E,eAAe,KACf,OAAO,mBAAmB;KAElB;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe,yBAAyB;EACxC;EACA;EACA;EACA;EACA;IAAa;IAAc;IAAe;;EAE1C;EACA;;KAGU,qBAAqB,UAAU,WACzC,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA;;UAGe;;;;;;;EAOf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;;EAEA;EACA;;EAEA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;UAQe;;EAEf;;;;;;;;;;;;EAqCA;;;;;;EAuDA;;EAMA;;EAEA;;EAEA;;EAEA;;EAUA;;EAEA;;UAGe,kBAEb,cACA,YACA,SACA,iBACA,YACA,iBACA;EACF;GACC;;UAGc,WAAW,UAAU,YAAY;EAChD;EACA,MAAM,UAAU;EAChB,MAAM;EACN;EACA;EACA,UAAU;EACV,aAAa;EACb,aAAa,gBAAgB;EAC7B;;KAGU;;EAEV"}
|
package/dist/track/types.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/track/types.ts"],"mappings":";;KAEY;KACA,YAAY;KAEZ,UAAU,UAAU,YAAY,aAAa,gBAAgB,iBACrE,IACA;KACQ,gBAAgB,UAAU,YAAY,aAAa,gBAAgB,iBAC3E,eAAe,KACf,OAAO,mBAAmB;KAElB;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe,yBAAyB;EACxC;EACA;EACA;EACA;EACA;IAAa;IAAc;IAAe;;EAE1C;EACA;;KAGU,qBAAqB,UAAU,WACzC,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/track/types.ts"],"mappings":";;KAEY;KACA,YAAY;KAEZ,UAAU,UAAU,YAAY,aAAa,gBAAgB,iBACrE,IACA;KACQ,gBAAgB,UAAU,YAAY,aAAa,gBAAgB,iBAC3E,eAAe,KACf,OAAO,mBAAmB;KAElB;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe,yBAAyB;EACxC;EACA;EACA;EACA;EACA;IAAa;IAAc;IAAe;;EAE1C;EACA;;KAGU,qBAAqB,UAAU,WACzC,MAAM,UAAU,IAChB,aAAa,gBAAgB,IAC7B;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;EACA;;UAGe;EACf;EACA;EACA;;UAGe;EACf;EACA;;UAGe;;;;;;;EAOf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;;EAEA;EACA;;EAEA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;UAQe;;EAEf;;;;;;;;;;;;EAqCA;;;;;;EAuDA;;EAMA;;EAEA;;EAEA;;EAEA;;EAUA;;EAEA;;UAGe,kBAEb,cACA,YACA,SACA,iBACA,YACA,iBACA;EACF;GACC;;UAGc,WAAW,UAAU,YAAY;EAChD;EACA,MAAM,UAAU;EAChB,MAAM;EACN;EACA;EACA,UAAU;EACV,aAAa;EACb,aAAa,gBAAgB;EAC7B;;KAGU;;EAEV"}
|
package/dist/web/index.cjs
CHANGED
|
@@ -31,7 +31,6 @@ async function getTags() {
|
|
|
31
31
|
browser: `${browser.name} ${browser.version}`,
|
|
32
32
|
browser_name: browser.name,
|
|
33
33
|
browser_version: browser.version,
|
|
34
|
-
platform: "web",
|
|
35
34
|
device: platform.model,
|
|
36
35
|
device_id: getDeviceId(),
|
|
37
36
|
device_type: platform.type,
|
|
@@ -43,8 +42,6 @@ async function getTags() {
|
|
|
43
42
|
release: require_setup_index.config.release,
|
|
44
43
|
language: navigator.language,
|
|
45
44
|
time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
46
|
-
environment: process.env.NODE_ENV === "development" ? "development" : "production",
|
|
47
|
-
source: "web",
|
|
48
45
|
source_url: window.location.href,
|
|
49
46
|
page_referrer: document.referrer || void 0,
|
|
50
47
|
fbc: parsed._fbc ?? void 0,
|
package/dist/web/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["keys","Bowser","getLink","config"],"sources":["../../src/web/index.ts"],"sourcesContent":["import Bowser from 'bowser';\nimport { parseCookie } from 'cookie';\nimport { v4 as uuidv4 } from 'uuid';\nimport { keys } from '../constants/storage';\nimport { getLink } from '../link/index';\nimport { type Storage, cache, config } from '../setup/index';\nimport type { TrackTags } from '../track/types';\n\nexport function getDeviceId() {\n const cached = localStorage.getItem(keys.device_id);\n if (cached) return cached;\n // lib.dom types `crypto.randomUUID` as always present, but it is missing in\n // insecure contexts and older browsers, so probe it before use.\n const id = (crypto as Partial<Crypto>).randomUUID ? crypto.randomUUID() : uuidv4();\n localStorage.setItem(keys.device_id, id);\n return id;\n}\n\nexport async function getTags() {\n const parser = Bowser.getParser(window.navigator.userAgent);\n const params = new URLSearchParams(window.location.search);\n const os = parser.getOS();\n const browser = parser.getBrowser();\n const platform = parser.getPlatform();\n const parsed = parseCookie(document.cookie);\n\n const linkId = params.get('s');\n const link = linkId ? await getLink(linkId) : null;\n\n const tags: TrackTags = {\n os: `${os.name} ${os.version}`,\n os_name: os.name,\n os_version: os.version,\n browser: `${browser.name} ${browser.version}`,\n browser_name: browser.name,\n browser_version: browser.version,\n
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["keys","Bowser","getLink","config"],"sources":["../../src/web/index.ts"],"sourcesContent":["import Bowser from 'bowser';\nimport { parseCookie } from 'cookie';\nimport { v4 as uuidv4 } from 'uuid';\nimport { keys } from '../constants/storage';\nimport { getLink } from '../link/index';\nimport { type Storage, cache, config } from '../setup/index';\nimport type { TrackTags } from '../track/types';\n\nexport function getDeviceId() {\n const cached = localStorage.getItem(keys.device_id);\n if (cached) return cached;\n // lib.dom types `crypto.randomUUID` as always present, but it is missing in\n // insecure contexts and older browsers, so probe it before use.\n const id = (crypto as Partial<Crypto>).randomUUID ? crypto.randomUUID() : uuidv4();\n localStorage.setItem(keys.device_id, id);\n return id;\n}\n\nexport async function getTags() {\n const parser = Bowser.getParser(window.navigator.userAgent);\n const params = new URLSearchParams(window.location.search);\n const os = parser.getOS();\n const browser = parser.getBrowser();\n const platform = parser.getPlatform();\n const parsed = parseCookie(document.cookie);\n\n const linkId = params.get('s');\n const link = linkId ? await getLink(linkId) : null;\n\n const tags: TrackTags = {\n os: `${os.name} ${os.version}`,\n os_name: os.name,\n os_version: os.version,\n browser: `${browser.name} ${browser.version}`,\n browser_name: browser.name,\n browser_version: browser.version,\n device: platform.model,\n device_id: getDeviceId(),\n device_type: platform.type,\n device_vendor: platform.vendor,\n device_pixel_ratio: window.devicePixelRatio,\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n screen_resolution: `${window.screen.width}x${window.screen.height}`,\n release: config.release,\n language: navigator.language,\n time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n source_url: window.location.href,\n page_referrer: document.referrer || undefined,\n // Meta Ads — _fbc is set server-side (see @shware/analytics/server resolveClickIdCookies)\n fbc: parsed._fbc ?? undefined,\n fbp: parsed._fbp,\n fbclid: params.get('fbclid') ?? undefined,\n ad_id: params.get('ad_id') ?? undefined,\n ad_name: params.get('ad_name') ?? undefined,\n adset_id: params.get('adset_id') ?? undefined,\n adset_name: params.get('adset_name') ?? undefined,\n campaign_id: params.get('campaign_id') ?? undefined,\n campaign_name: params.get('campaign_name') ?? undefined,\n placement: params.get('placement') ?? undefined,\n site_source_name: params.get('site_source_name') ?? undefined,\n // Google Ads\n gclid: params.get('gclid') ?? undefined,\n gclsrc: params.get('gclsrc') ?? undefined,\n gad_source: params.get('gad_source') ?? undefined,\n gad_campaignid: params.get('gad_campaignid') ?? undefined,\n // Reddit Ads — _rdt_cid is set server-side (see @shware/analytics/server resolveClickIdCookies)\n rdt_cid: params.get('rdt_cid') ?? parsed._rdt_cid ?? undefined,\n rdt_uuid: parsed._rdt_uuid,\n // LinkedIn Ads: get click id from url params or first-party cookie\n li_fat_id: params.get('li_fat_id') ?? parsed.li_fat_id ?? undefined,\n // click ids\n dclid: params.get('dclid') ?? undefined,\n ko_click_id: params.get('ko_click_id') ?? undefined,\n msclkid: params.get('msclkid') ?? undefined,\n sccid: params.get('sccid') ?? undefined,\n ttclid: params.get('ttclid') ?? undefined,\n twclid: params.get('twclid') ?? undefined,\n wbraid: params.get('wbraid') ?? undefined,\n yclid: params.get('yclid') ?? undefined,\n // utm params\n utm_source: link?.utm_source ?? params.get('utm_source') ?? undefined,\n utm_medium: link?.utm_medium ?? params.get('utm_medium') ?? undefined,\n utm_campaign: link?.utm_campaign ?? params.get('utm_campaign') ?? undefined,\n utm_term: link?.utm_term ?? params.get('utm_term') ?? undefined,\n utm_content: link?.utm_content ?? params.get('utm_content') ?? undefined,\n utm_id: link?.utm_id ?? params.get('utm_id') ?? undefined,\n utm_source_platform:\n link?.utm_source_platform ?? params.get('utm_source_platform') ?? undefined,\n utm_creative_format:\n link?.utm_creative_format ?? params.get('utm_creative_format') ?? undefined,\n utm_marketing_tactic:\n link?.utm_marketing_tactic ?? params.get('utm_marketing_tactic') ?? undefined,\n };\n\n cache.tags = tags;\n return tags;\n}\n\nconst map = new Map<string, string>();\n\nexport const storage: Storage = {\n getItem: (key) => {\n try {\n return localStorage.getItem(key);\n } catch {\n console.error('localStorage is not available');\n return map.get(key) ?? null;\n }\n },\n setItem: (key, value) => {\n try {\n localStorage.setItem(key, value);\n } catch {\n console.error('localStorage is not available');\n map.set(key, value);\n }\n },\n};\n"],"mappings":"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"}
|
package/dist/web/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/web/index.ts"],"mappings":";;;iBAQgB;iBAUM,WAAO,QAAA;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/web/index.ts"],"mappings":";;;iBAQgB;iBAUM,WAAO,QAAA;cAmFhB,SAAS"}
|
package/dist/web/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/web/index.ts"],"mappings":";;;iBAQgB;iBAUM,WAAO,QAAA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/web/index.ts"],"mappings":";;;iBAQgB;iBAUM,WAAO,QAAA;cAmFhB,SAAS"}
|
package/dist/web/index.mjs
CHANGED
|
@@ -30,7 +30,6 @@ async function getTags() {
|
|
|
30
30
|
browser: `${browser.name} ${browser.version}`,
|
|
31
31
|
browser_name: browser.name,
|
|
32
32
|
browser_version: browser.version,
|
|
33
|
-
platform: "web",
|
|
34
33
|
device: platform.model,
|
|
35
34
|
device_id: getDeviceId(),
|
|
36
35
|
device_type: platform.type,
|
|
@@ -42,8 +41,6 @@ async function getTags() {
|
|
|
42
41
|
release: config.release,
|
|
43
42
|
language: navigator.language,
|
|
44
43
|
time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
45
|
-
environment: process.env.NODE_ENV === "development" ? "development" : "production",
|
|
46
|
-
source: "web",
|
|
47
44
|
source_url: window.location.href,
|
|
48
45
|
page_referrer: document.referrer || void 0,
|
|
49
46
|
fbc: parsed._fbc ?? void 0,
|
package/dist/web/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["uuidv4","Bowser"],"sources":["../../src/web/index.ts"],"sourcesContent":["import Bowser from 'bowser';\nimport { parseCookie } from 'cookie';\nimport { v4 as uuidv4 } from 'uuid';\nimport { keys } from '../constants/storage';\nimport { getLink } from '../link/index';\nimport { type Storage, cache, config } from '../setup/index';\nimport type { TrackTags } from '../track/types';\n\nexport function getDeviceId() {\n const cached = localStorage.getItem(keys.device_id);\n if (cached) return cached;\n // lib.dom types `crypto.randomUUID` as always present, but it is missing in\n // insecure contexts and older browsers, so probe it before use.\n const id = (crypto as Partial<Crypto>).randomUUID ? crypto.randomUUID() : uuidv4();\n localStorage.setItem(keys.device_id, id);\n return id;\n}\n\nexport async function getTags() {\n const parser = Bowser.getParser(window.navigator.userAgent);\n const params = new URLSearchParams(window.location.search);\n const os = parser.getOS();\n const browser = parser.getBrowser();\n const platform = parser.getPlatform();\n const parsed = parseCookie(document.cookie);\n\n const linkId = params.get('s');\n const link = linkId ? await getLink(linkId) : null;\n\n const tags: TrackTags = {\n os: `${os.name} ${os.version}`,\n os_name: os.name,\n os_version: os.version,\n browser: `${browser.name} ${browser.version}`,\n browser_name: browser.name,\n browser_version: browser.version,\n
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["uuidv4","Bowser"],"sources":["../../src/web/index.ts"],"sourcesContent":["import Bowser from 'bowser';\nimport { parseCookie } from 'cookie';\nimport { v4 as uuidv4 } from 'uuid';\nimport { keys } from '../constants/storage';\nimport { getLink } from '../link/index';\nimport { type Storage, cache, config } from '../setup/index';\nimport type { TrackTags } from '../track/types';\n\nexport function getDeviceId() {\n const cached = localStorage.getItem(keys.device_id);\n if (cached) return cached;\n // lib.dom types `crypto.randomUUID` as always present, but it is missing in\n // insecure contexts and older browsers, so probe it before use.\n const id = (crypto as Partial<Crypto>).randomUUID ? crypto.randomUUID() : uuidv4();\n localStorage.setItem(keys.device_id, id);\n return id;\n}\n\nexport async function getTags() {\n const parser = Bowser.getParser(window.navigator.userAgent);\n const params = new URLSearchParams(window.location.search);\n const os = parser.getOS();\n const browser = parser.getBrowser();\n const platform = parser.getPlatform();\n const parsed = parseCookie(document.cookie);\n\n const linkId = params.get('s');\n const link = linkId ? await getLink(linkId) : null;\n\n const tags: TrackTags = {\n os: `${os.name} ${os.version}`,\n os_name: os.name,\n os_version: os.version,\n browser: `${browser.name} ${browser.version}`,\n browser_name: browser.name,\n browser_version: browser.version,\n device: platform.model,\n device_id: getDeviceId(),\n device_type: platform.type,\n device_vendor: platform.vendor,\n device_pixel_ratio: window.devicePixelRatio,\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n screen_resolution: `${window.screen.width}x${window.screen.height}`,\n release: config.release,\n language: navigator.language,\n time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n source_url: window.location.href,\n page_referrer: document.referrer || undefined,\n // Meta Ads — _fbc is set server-side (see @shware/analytics/server resolveClickIdCookies)\n fbc: parsed._fbc ?? undefined,\n fbp: parsed._fbp,\n fbclid: params.get('fbclid') ?? undefined,\n ad_id: params.get('ad_id') ?? undefined,\n ad_name: params.get('ad_name') ?? undefined,\n adset_id: params.get('adset_id') ?? undefined,\n adset_name: params.get('adset_name') ?? undefined,\n campaign_id: params.get('campaign_id') ?? undefined,\n campaign_name: params.get('campaign_name') ?? undefined,\n placement: params.get('placement') ?? undefined,\n site_source_name: params.get('site_source_name') ?? undefined,\n // Google Ads\n gclid: params.get('gclid') ?? undefined,\n gclsrc: params.get('gclsrc') ?? undefined,\n gad_source: params.get('gad_source') ?? undefined,\n gad_campaignid: params.get('gad_campaignid') ?? undefined,\n // Reddit Ads — _rdt_cid is set server-side (see @shware/analytics/server resolveClickIdCookies)\n rdt_cid: params.get('rdt_cid') ?? parsed._rdt_cid ?? undefined,\n rdt_uuid: parsed._rdt_uuid,\n // LinkedIn Ads: get click id from url params or first-party cookie\n li_fat_id: params.get('li_fat_id') ?? parsed.li_fat_id ?? undefined,\n // click ids\n dclid: params.get('dclid') ?? undefined,\n ko_click_id: params.get('ko_click_id') ?? undefined,\n msclkid: params.get('msclkid') ?? undefined,\n sccid: params.get('sccid') ?? undefined,\n ttclid: params.get('ttclid') ?? undefined,\n twclid: params.get('twclid') ?? undefined,\n wbraid: params.get('wbraid') ?? undefined,\n yclid: params.get('yclid') ?? undefined,\n // utm params\n utm_source: link?.utm_source ?? params.get('utm_source') ?? undefined,\n utm_medium: link?.utm_medium ?? params.get('utm_medium') ?? undefined,\n utm_campaign: link?.utm_campaign ?? params.get('utm_campaign') ?? undefined,\n utm_term: link?.utm_term ?? params.get('utm_term') ?? undefined,\n utm_content: link?.utm_content ?? params.get('utm_content') ?? undefined,\n utm_id: link?.utm_id ?? params.get('utm_id') ?? undefined,\n utm_source_platform:\n link?.utm_source_platform ?? params.get('utm_source_platform') ?? undefined,\n utm_creative_format:\n link?.utm_creative_format ?? params.get('utm_creative_format') ?? undefined,\n utm_marketing_tactic:\n link?.utm_marketing_tactic ?? params.get('utm_marketing_tactic') ?? undefined,\n };\n\n cache.tags = tags;\n return tags;\n}\n\nconst map = new Map<string, string>();\n\nexport const storage: Storage = {\n getItem: (key) => {\n try {\n return localStorage.getItem(key);\n } catch {\n console.error('localStorage is not available');\n return map.get(key) ?? null;\n }\n },\n setItem: (key, value) => {\n try {\n localStorage.setItem(key, value);\n } catch {\n console.error('localStorage is not available');\n map.set(key, value);\n }\n },\n};\n"],"mappings":"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"}
|