@mixdive/browser 0.1.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/LICENSE +201 -0
- package/README.md +18 -0
- package/dist/index.cjs +438 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +82 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +430 -0
- package/dist/index.js.map +1 -0
- package/dist/mixdive.js +2 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ids.ts","../src/session.ts","../src/storage.ts","../src/transport.ts","../src/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// A 32-hex random id — the device id and the session id both use it. Random,\n// never derived from anything about the browser: Mixdive does no\n// fingerprinting, and the server never generates either id.\nexport function generateId(): string {\n let hex = ''\n try {\n const buf = new Uint8Array(16)\n crypto.getRandomValues(buf)\n for (let i = 0; i < 16; i++) hex += (buf[i]! + 256).toString(16).slice(1)\n return hex\n } catch {\n // no WebCrypto — fall back to Math.random\n }\n for (let i = 0; i < 32; i++) hex += Math.floor(Math.random() * 16).toString(16)\n return hex\n}\n","// Session and acquisition logic, pure and injected so it is testable without\n// a browser. The rules are the collection addendum's (docs/collection-addendum.md\n// in the server repository), the same ones the reference GTM tag implements:\n// 30 idle minutes end a session, a landing with a *different* utm_source\n// starts a new one, and the session's acquisition rides on every item.\n\n/** 30 minutes of inactivity end a session. */\nexport const IDLE_MS = 30 * 60 * 1000\n\nexport interface Acquisition {\n /** External landing referrer, query-stripped; empty when same-site or absent. */\n ref: string\n us: string\n um: string\n uc: string\n}\n\nexport interface Session extends Acquisition {\n id: string\n start: number\n last: number\n}\n\nexport interface Context {\n language?: string\n resolution?: string\n density?: number\n referrer?: string\n utm_source?: string\n utm_medium?: string\n utm_campaign?: string\n}\n\n/** What the landing page says about how the visitor arrived. */\nexport function landingAcquisition(loc: { host: string; search: string }, referrer: string): Acquisition {\n const a: Acquisition = { ref: '', us: '', um: '', uc: '' }\n try {\n if (referrer) {\n const m = /^[a-z]+:\\/\\/([^/]+)/i.exec(referrer)\n if (m && m[1]!.toLowerCase() !== loc.host.toLowerCase()) {\n a.ref = referrer.split('?')[0]!.slice(0, 256)\n }\n }\n const q = loc.search.replace(/^\\?/, '').split('&')\n for (const part of q) {\n const eq = part.indexOf('=')\n const k = eq < 0 ? part : part.slice(0, eq)\n const raw = eq < 0 ? '' : part.slice(eq + 1)\n let v = ''\n try {\n v = decodeURIComponent(raw.replace(/\\+/g, ' ')).slice(0, 128)\n } catch {\n v = raw.slice(0, 128)\n }\n if (k === 'utm_source') a.us = v\n if (k === 'utm_medium') a.um = v\n if (k === 'utm_campaign') a.uc = v\n }\n } catch {\n // never let acquisition parsing break a send\n }\n return a\n}\n\n/**\n * The session an item at `now` belongs to: the current one touched, or a new\n * one when there is none, when it went idle, or when this landing carries a\n * different campaign (a new campaign click never rides an old session).\n */\nexport function nextSession(current: Session | null, landing: Acquisition, now: number, genId: () => string): Session {\n const newUtm = !!landing.us && !!current && current.us !== landing.us\n let s = current\n if (!s || now - s.last > IDLE_MS || newUtm) {\n s = { id: genId(), start: now, last: now, ref: landing.ref, us: landing.us, um: landing.um, uc: landing.uc }\n }\n s.last = now\n return s\n}\n\nexport function parseSession(raw: string | null): Session | null {\n if (!raw) return null\n try {\n const s = JSON.parse(raw) as Partial<Session>\n if (s && typeof s.id === 'string' && typeof s.start === 'number' && typeof s.last === 'number') {\n return { id: s.id, start: s.start, last: s.last, ref: s.ref || '', us: s.us || '', um: s.um || '', uc: s.uc || '' }\n }\n } catch {\n // corrupt storage — start over\n }\n return null\n}\n\n/** The context object sent on every item: client tech plus the session's acquisition. */\nexport function contextOf(\n s: Acquisition,\n env: { language?: string; width?: number; height?: number; density?: number },\n): Context {\n const c: Context = {}\n if (env.language) c.language = String(env.language).slice(0, 16)\n if (env.width && env.height) c.resolution = `${env.width}x${env.height}`\n if (env.density) c.density = env.density\n if (s.ref) c.referrer = s.ref\n if (s.us) c.utm_source = s.us\n if (s.um) c.utm_medium = s.um\n if (s.uc) c.utm_campaign = s.uc\n return c\n}\n","// Storage that never throws. localStorage when the browser allows it; an\n// in-memory fallback when it is blocked (private mode, storage permissions),\n// so one pageload still coheres — events from it share one device and one\n// session — while nothing survives the pageload. Industry-standard degradation.\nexport interface Storage {\n get(key: string): string | null\n set(key: string, value: string): void\n remove(key: string): void\n}\n\nexport function createStorage(): Storage {\n const memory = new Map<string, string>()\n return {\n get(key) {\n try {\n const v = window.localStorage.getItem(key)\n if (v !== null) return v\n } catch {\n // blocked — fall through to memory\n }\n return memory.get(key) ?? null\n },\n set(key, value) {\n memory.set(key, value)\n try {\n window.localStorage.setItem(key, value)\n } catch {\n // blocked — memory only\n }\n },\n remove(key) {\n memory.delete(key)\n try {\n window.localStorage.removeItem(key)\n } catch {\n // blocked\n }\n },\n }\n}\n","// Delivery. Two shapes, both fire-and-forget:\n//\n// - beacon: `navigator.sendBeacon` with a text/plain body and the API key in\n// the query string — preflight-free, and queued by the browser so it\n// survives navigation and unload. `fetch(keepalive)` is the fallback.\n// - headers: a JSON fetch with `X-Api-Key` (and `X-App-Version`), used only\n// when the caller configured an app version — headers cost a CORS\n// preflight, which the server answers.\n//\n// Failures never reach the caller: analytics must not break the host page.\nexport type Debug = (message: string, ...rest: unknown[]) => void\n\nexport interface Transport {\n send(url: string, body: string, headers?: Record<string, string>): void\n}\n\nexport function createTransport(debug: Debug): Transport {\n return {\n send(url, body, headers) {\n if (!headers) {\n const nav = typeof navigator !== 'undefined' ? navigator : undefined\n if (nav && typeof nav.sendBeacon === 'function') {\n try {\n if (nav.sendBeacon(url, new Blob([body], { type: 'text/plain' }))) return\n } catch {\n // beacon refused (size, scheme) — fall through to fetch\n }\n }\n }\n if (typeof fetch !== 'function') {\n debug('no fetch available; dropped', url)\n return\n }\n try {\n const init: RequestInit = { method: 'POST', body, keepalive: true }\n if (headers) init.headers = { 'Content-Type': 'application/json', ...headers }\n const p = fetch(url, init)\n if (p && typeof p.then === 'function') {\n p.then(\n (r) => {\n if (!r.ok) debug(`${r.status} from ${url}`)\n },\n (e: unknown) => debug('send failed', e),\n )\n }\n } catch (e) {\n debug('send failed', e)\n }\n },\n }\n}\n","// The client. One instance owns the visitor identity (device id), the\n// session, the signed-in user, the auto page views and the session_end\n// beacon, and turns every public call into one POST to the Mixdive ingest\n// API — exactly the fields docs/ingest-api.md (server repository) defines,\n// nothing invented.\n//\n// Rules the whole file lives by:\n// - Never throw into the host page. Every public call is wrapped.\n// - Never block. Sends are beacons or keepalive fetches, fire-and-forget.\n// - Never invent identities. Device and session ids are random, minted here;\n// user ids are the caller's. The server generates neither.\n// - Off is safe: no key, no server, or an automated browser → every call is a\n// silent no-op (one console notice for a misconfiguration, none for bots).\nimport { generateId } from './ids'\nimport { IDLE_MS, contextOf, landingAcquisition, nextSession, parseSession, type Acquisition, type Session } from './session'\nimport { createStorage } from './storage'\nimport { createTransport, type Debug } from './transport'\nimport type { InitOptions, Mixdive, Properties, TrackOptions, UserProfile } from './types'\n\nexport const VERSION: string = typeof __MIXDIVE_VERSION__ === 'string' ? __MIXDIVE_VERSION__ : '0.0.0'\n\n/** localStorage keys — name them in your storage declarations (docs: consent). */\nexport const STORAGE_KEYS = { device: 'mx_did', session: 'mx_ses', user: 'mx_uid' } as const\n\nconst MAX_BUFFER = 200\nconst MAX_COUNT = 1_000_000\nconst PROFILE_STRINGS = ['name', 'username', 'email', 'organization', 'phone', 'picture', 'gender'] as const\n\ninterface Settings {\n key: string\n server: string\n autoPageViews: boolean\n appVersion: string\n debug: boolean\n}\n\nexport function createMixdive(): Mixdive {\n const storage = createStorage()\n let settings: Settings | null = null\n let off = false\n let buffer: Array<() => void> = []\n let landing: Acquisition = { ref: '', us: '', um: '', uc: '' }\n let memSession: Session | null = null\n let deviceId: string | null = null\n let userId: string | null = null\n let prevPath: string | null = null\n\n const debug: Debug = (message, ...rest) => {\n if (settings && settings.debug) {\n try {\n console.log('[mixdive]', message, ...rest)\n } catch {\n // no console\n }\n }\n }\n const transport = createTransport(debug)\n\n const hasDom = () => typeof window !== 'undefined' && typeof document !== 'undefined'\n\n // ---- identity -----------------------------------------------------------\n\n function device(): string {\n if (deviceId) return deviceId\n let id = storage.get(STORAGE_KEYS.device)\n if (!id) {\n id = generateId()\n storage.set(STORAGE_KEYS.device, id)\n }\n deviceId = id\n return id\n }\n\n function readSession(): Session | null {\n return memSession ?? parseSession(storage.get(STORAGE_KEYS.session))\n }\n\n function writeSession(s: Session): void {\n memSession = s\n storage.set(STORAGE_KEYS.session, JSON.stringify(s))\n }\n\n /** The session this moment belongs to — renewed when idle or on a new campaign. */\n function session(now: number): Session {\n const s = nextSession(readSession(), landing, now, generateId)\n writeSession(s)\n return s\n }\n\n function context(s: Acquisition) {\n const env: { language?: string; width?: number; height?: number; density?: number } = {}\n try {\n if (navigator.language) env.language = navigator.language\n } catch {\n // no navigator\n }\n try {\n env.width = screen.width\n env.height = screen.height\n } catch {\n // no screen\n }\n try {\n if (window.devicePixelRatio) env.density = window.devicePixelRatio\n } catch {\n // no window\n }\n return contextOf(s, env)\n }\n\n // ---- delivery -----------------------------------------------------------\n\n /**\n * One POST. `beacon` forces the header-free transport even when an app\n * version is configured — session_end must be able to leave during unload,\n * and a header variant has no reliable beacon equivalent.\n */\n function post(path: string, payload: Record<string, unknown>, beacon = false): void {\n const st = settings!\n const body = JSON.stringify(payload)\n if (st.appVersion && !beacon) {\n transport.send(st.server + path, body, { 'X-Api-Key': st.key, 'X-App-Version': st.appVersion })\n } else {\n transport.send(st.server + path + '?api_key=' + encodeURIComponent(st.key), body)\n }\n debug('sent', path, payload)\n }\n\n /** The gate every public call passes: off → drop; not started → buffer; else run, contained. */\n function run(fn: () => void): void {\n if (off) return\n if (!settings) {\n if (buffer.length >= MAX_BUFFER) buffer.shift()\n buffer.push(fn)\n return\n }\n try {\n fn()\n } catch (e) {\n debug('call failed', e)\n }\n }\n\n // ---- items --------------------------------------------------------------\n\n function trackNow(eventKey: string, properties?: Properties, options?: TrackOptions): void {\n if (typeof eventKey !== 'string' || !eventKey.trim() || eventKey.indexOf('gtm.') === 0) {\n debug('ignored event key', eventKey)\n return\n }\n const s = session(Date.now())\n const payload: Record<string, unknown> = {\n event_key: eventKey,\n device_id: device(),\n session_id: s.id,\n context: context(s),\n }\n if (userId) payload.user_id = userId\n if (properties && typeof properties === 'object') payload.properties = properties\n if (options && typeof options === 'object') {\n if (typeof options.id === 'string' && options.id) payload.id = options.id\n const { count, sum, duration } = options\n if (typeof count === 'number' && Number.isInteger(count) && count > 1 && count <= MAX_COUNT) {\n payload.count = count\n } else if (count !== undefined && count !== 1) {\n debug('ignored count (whole number 2…1000000)', count)\n }\n if (typeof sum === 'number' && Number.isFinite(sum) && sum !== 0) payload.sum = sum\n if (typeof duration === 'number' && Number.isFinite(duration) && duration > 0) payload.duration = duration\n }\n post('/ingest/event', payload)\n }\n\n function pageViewNow(url?: string): void {\n let path = typeof url === 'string' && url ? url : ''\n if (!path) {\n try {\n path = location.pathname || '/'\n } catch {\n path = '/'\n }\n }\n if (path === prevPath) return // router replay — one view, not two\n const props: Properties = { url: path }\n try {\n if (document.title) props.title = String(document.title).slice(0, 256)\n } catch {\n // no document\n }\n let ref = prevPath\n if (!ref) {\n try {\n if (document.referrer) ref = document.referrer.split('?')[0]!.slice(0, 256)\n } catch {\n // no document\n }\n }\n if (ref) props.referrer = ref\n prevPath = path\n trackNow('page_view', props)\n }\n\n function profilePayload(id: string, profile?: UserProfile): Record<string, unknown> {\n const p: Record<string, unknown> = { user_id: id, device_id: device() }\n if (profile && typeof profile === 'object') {\n for (const k of PROFILE_STRINGS) {\n const v = profile[k]\n if (typeof v === 'string' && v) p[k] = v\n }\n const y = profile.birthYear\n if (typeof y === 'number' && Number.isInteger(y) && y > 0) p.birth_year = y\n if (profile.custom && typeof profile.custom === 'object') p.custom = profile.custom\n }\n return p\n }\n\n function identifyNow(id: string, profile?: UserProfile): void {\n if (typeof id !== 'string' || !id.trim()) {\n debug('ignored user id', id)\n return\n }\n userId = id\n storage.set(STORAGE_KEYS.user, id)\n post('/ingest/user', profilePayload(id, profile))\n }\n\n // ---- session lifecycle --------------------------------------------------\n\n function endSession(): void {\n try {\n const s = readSession()\n if (!s) return\n const now = Date.now()\n const end = now - s.last > IDLE_MS ? s.last : now // never bill idle time\n const duration = Math.max(0, Math.round((end - s.start) / 1000))\n post(\n '/ingest/event',\n {\n event_key: 'session_end',\n id: s.id + ':end', // deterministic: repeated beacons collapse server-side, $max widens\n device_id: device(),\n session_id: s.id,\n context: context(s),\n properties: { duration },\n },\n true,\n )\n } catch (e) {\n debug('session_end failed', e)\n }\n }\n\n function warmSession(): void {\n const s = readSession()\n if (s) {\n s.last = Date.now()\n writeSession(s)\n }\n }\n\n function installListeners(): void {\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') endSession()\n else warmSession() // returning to a background tab keeps its session warm\n })\n window.addEventListener('pagehide', endSession)\n }\n\n function installHistoryHooks(): void {\n const h = window.history\n // After the URL changed, on the next tick — so a router that sets\n // document.title synchronously after navigating is already done.\n const schedule = () => {\n setTimeout(() => run(() => pageViewNow()), 0)\n }\n for (const m of ['pushState', 'replaceState'] as const) {\n const orig = h[m]\n if (typeof orig !== 'function') continue\n h[m] = function (this: History, ...args: Parameters<History['pushState']>) {\n const r = orig.apply(this, args)\n schedule()\n return r\n }\n }\n window.addEventListener('popstate', schedule)\n }\n\n // ---- public -------------------------------------------------------------\n\n function init(options: InitOptions): void {\n if (!hasDom()) return // server-side rendering: nothing to start\n if (settings) {\n debug('init called again; the first call wins')\n return\n }\n const key = options && typeof options.key === 'string' ? options.key.trim() : ''\n const server = options && typeof options.server === 'string' ? options.server.trim().replace(/\\/+$/, '') : ''\n if (!key || !/^https?:\\/\\/[^/]+/i.test(server)) {\n off = true\n buffer = []\n try {\n console.warn('[mixdive] off: init needs an API key and the server origin (https://analytics.example.com)')\n } catch {\n // no console\n }\n return\n }\n if (typeof navigator !== 'undefined' && navigator.webdriver) {\n off = true // automated browsers and test runners send nothing, by design\n buffer = []\n return\n }\n settings = {\n key,\n server,\n autoPageViews: options.autoPageViews !== false,\n appVersion: typeof options.appVersion === 'string' ? options.appVersion.slice(0, 64) : '',\n debug: !!options.debug,\n }\n landing = landingAcquisition(location, document.referrer)\n userId = storage.get(STORAGE_KEYS.user)\n installListeners()\n // Calls made before init go first — an identify buffered from app code\n // should be on the first page view.\n const pending = buffer\n buffer = []\n for (const fn of pending) run(fn)\n if (settings.autoPageViews) {\n installHistoryHooks()\n run(() => pageViewNow())\n }\n debug('started', { server, autoPageViews: settings.autoPageViews, version: VERSION })\n }\n\n function reset(): void {\n storage.remove(STORAGE_KEYS.device)\n storage.remove(STORAGE_KEYS.session)\n storage.remove(STORAGE_KEYS.user)\n memSession = null\n deviceId = null\n userId = null\n }\n\n return {\n init,\n track: (eventKey, properties, options) => run(() => trackNow(eventKey, properties, options)),\n pageView: (url) => run(() => pageViewNow(url)),\n identify: (id) => run(() => identifyNow(id)),\n setUser: (id, profile) => run(() => identifyNow(id, profile)),\n login: (method) => run(() => trackNow('login', method ? { method } : undefined)),\n signUp: (method) => run(() => trackNow('sign_up', method ? { method } : undefined)),\n reset,\n get version() {\n return VERSION\n },\n }\n}\n","// @mixdive/browser — the Mixdive browser SDK.\n//\n// import { mixdive } from '@mixdive/browser'\n// mixdive.init({ key: 'mx_…', server: 'https://analytics.example.com' })\n// mixdive.track('checkout_completed', { plan: 'team' })\n//\n// `mixdive` is the one client an app needs. `createMixdive` builds another\n// for the rare case of two servers on one page (and for tests).\nimport { createMixdive } from './client'\n\nexport { createMixdive, STORAGE_KEYS, VERSION } from './client'\nexport type { InitOptions, Mixdive, Properties, PropertyValue, TrackOptions, UserProfile } from './types'\n\nexport const mixdive = createMixdive()\nexport default mixdive\n"]}
|
package/dist/mixdive.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! Mixdive web tag v0.1.0 · https://github.com/mixdive/mixdive-js · Apache-2.0 */
|
|
2
|
+
"use strict";(()=>{var Z=Object.defineProperty;var R=Object.getOwnPropertySymbols;var K=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var T=(i,t,n)=>t in i?Z(i,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):i[t]=n,E=(i,t)=>{for(var n in t||(t={}))K.call(t,n)&&T(i,n,t[n]);if(R)for(var n of R(t))ee.call(t,n)&&T(i,n,t[n]);return i};function I(){let i="";try{let t=new Uint8Array(16);crypto.getRandomValues(t);for(let n=0;n<16;n++)i+=(t[n]+256).toString(16).slice(1);return i}catch(t){}for(let t=0;t<32;t++)i+=Math.floor(Math.random()*16).toString(16);return i}function L(i,t){let n={ref:"",us:"",um:"",uc:""};try{if(t){let a=/^[a-z]+:\/\/([^/]+)/i.exec(t);a&&a[1].toLowerCase()!==i.host.toLowerCase()&&(n.ref=t.split("?")[0].slice(0,256))}let u=i.search.replace(/^\?/,"").split("&");for(let a of u){let f=a.indexOf("="),g=f<0?a:a.slice(0,f),m=f<0?"":a.slice(f+1),s="";try{s=decodeURIComponent(m.replace(/\+/g," ")).slice(0,128)}catch(d){s=m.slice(0,128)}g==="utm_source"&&(n.us=s),g==="utm_medium"&&(n.um=s),g==="utm_campaign"&&(n.uc=s)}}catch(u){}return n}function D(i,t,n,u){let a=!!t.us&&!!i&&i.us!==t.us,f=i;return(!f||n-f.last>18e5||a)&&(f={id:u(),start:n,last:n,ref:t.ref,us:t.us,um:t.um,uc:t.uc}),f.last=n,f}function N(i){if(!i)return null;try{let t=JSON.parse(i);if(t&&typeof t.id=="string"&&typeof t.start=="number"&&typeof t.last=="number")return{id:t.id,start:t.start,last:t.last,ref:t.ref||"",us:t.us||"",um:t.um||"",uc:t.uc||""}}catch(t){}return null}function U(i,t){let n={};return t.language&&(n.language=String(t.language).slice(0,16)),t.width&&t.height&&(n.resolution=`${t.width}x${t.height}`),t.density&&(n.density=t.density),i.ref&&(n.referrer=i.ref),i.us&&(n.utm_source=i.us),i.um&&(n.utm_medium=i.um),i.uc&&(n.utm_campaign=i.uc),n}function C(){let i=new Map;return{get(t){var n;try{let u=window.localStorage.getItem(t);if(u!==null)return u}catch(u){}return(n=i.get(t))!=null?n:null},set(t,n){i.set(t,n);try{window.localStorage.setItem(t,n)}catch(u){}},remove(t){i.delete(t);try{window.localStorage.removeItem(t)}catch(n){}}}}function H(i){return{send(t,n,u){if(!u){let a=typeof navigator!="undefined"?navigator:void 0;if(a&&typeof a.sendBeacon=="function")try{if(a.sendBeacon(t,new Blob([n],{type:"text/plain"})))return}catch(f){}}if(typeof fetch!="function"){i("no fetch available; dropped",t);return}try{let a={method:"POST",body:n,keepalive:!0};u&&(a.headers=E({"Content-Type":"application/json"},u));let f=fetch(t,a);f&&typeof f.then=="function"&&f.then(g=>{g.ok||i(`${g.status} from ${t}`)},g=>i("send failed",g))}catch(a){i("send failed",a)}}}}var j="0.1.0",h={device:"mx_did",session:"mx_ses",user:"mx_uid"},ne=200,ie=1e6,re=["name","username","email","organization","phone","picture","gender"];function X(){let i=C(),t=null,n=!1,u=[],a={ref:"",us:"",um:"",uc:""},f=null,g=null,m=null,s=null,d=(e,...r)=>{if(t&&t.debug)try{console.log("[mixdive]",e,...r)}catch(o){}},v=H(d),V=()=>typeof window!="undefined"&&typeof document!="undefined";function b(){if(g)return g;let e=i.get(h.device);return e||(e=I(),i.set(h.device,e)),g=e,e}function k(){return f!=null?f:N(i.get(h.session))}function A(e){f=e,i.set(h.session,JSON.stringify(e))}function B(e){let r=D(k(),a,e,I);return A(r),r}function P(e){let r={};try{navigator.language&&(r.language=navigator.language)}catch(o){}try{r.width=screen.width,r.height=screen.height}catch(o){}try{window.devicePixelRatio&&(r.density=window.devicePixelRatio)}catch(o){}return U(e,r)}function _(e,r,o=!1){let c=t,l=JSON.stringify(r);c.appVersion&&!o?v.send(c.server+e,l,{"X-Api-Key":c.key,"X-App-Version":c.appVersion}):v.send(c.server+e+"?api_key="+encodeURIComponent(c.key),l),d("sent",e,r)}function y(e){if(!n){if(!t){u.length>=ne&&u.shift(),u.push(e);return}try{e()}catch(r){d("call failed",r)}}}function w(e,r,o){if(typeof e!="string"||!e.trim()||e.indexOf("gtm.")===0){d("ignored event key",e);return}let c=B(Date.now()),l={event_key:e,device_id:b(),session_id:c.id,context:P(c)};if(m&&(l.user_id=m),r&&typeof r=="object"&&(l.properties=r),o&&typeof o=="object"){typeof o.id=="string"&&o.id&&(l.id=o.id);let{count:p,sum:x,duration:S}=o;typeof p=="number"&&Number.isInteger(p)&&p>1&&p<=ie?l.count=p:p!==void 0&&p!==1&&d("ignored count (whole number 2\u20261000000)",p),typeof x=="number"&&Number.isFinite(x)&&x!==0&&(l.sum=x),typeof S=="number"&&Number.isFinite(S)&&S>0&&(l.duration=S)}_("/ingest/event",l)}function M(e){let r=typeof e=="string"&&e?e:"";if(!r)try{r=location.pathname||"/"}catch(l){r="/"}if(r===s)return;let o={url:r};try{document.title&&(o.title=String(document.title).slice(0,256))}catch(l){}let c=s;if(!c)try{document.referrer&&(c=document.referrer.split("?")[0].slice(0,256))}catch(l){}c&&(o.referrer=c),s=r,w("page_view",o)}function G(e,r){let o={user_id:e,device_id:b()};if(r&&typeof r=="object"){for(let l of re){let p=r[l];typeof p=="string"&&p&&(o[l]=p)}let c=r.birthYear;typeof c=="number"&&Number.isInteger(c)&&c>0&&(o.birth_year=c),r.custom&&typeof r.custom=="object"&&(o.custom=r.custom)}return o}function O(e,r){if(typeof e!="string"||!e.trim()){d("ignored user id",e);return}m=e,i.set(h.user,e),_("/ingest/user",G(e,r))}function q(){try{let e=k();if(!e)return;let r=Date.now(),o=r-e.last>18e5?e.last:r,c=Math.max(0,Math.round((o-e.start)/1e3));_("/ingest/event",{event_key:"session_end",id:e.id+":end",device_id:b(),session_id:e.id,context:P(e),properties:{duration:c}},!0)}catch(e){d("session_end failed",e)}}function J(){let e=k();e&&(e.last=Date.now(),A(e))}function z(){document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?q():J()}),window.addEventListener("pagehide",q)}function Y(){let e=window.history,r=()=>{setTimeout(()=>y(()=>M()),0)};for(let o of["pushState","replaceState"]){let c=e[o];typeof c=="function"&&(e[o]=function(...l){let p=c.apply(this,l);return r(),p})}window.addEventListener("popstate",r)}function W(e){if(!V())return;if(t){d("init called again; the first call wins");return}let r=e&&typeof e.key=="string"?e.key.trim():"",o=e&&typeof e.server=="string"?e.server.trim().replace(/\/+$/,""):"";if(!r||!/^https?:\/\/[^/]+/i.test(o)){n=!0,u=[];try{console.warn("[mixdive] off: init needs an API key and the server origin (https://analytics.example.com)")}catch(l){}return}if(typeof navigator!="undefined"&&navigator.webdriver){n=!0,u=[];return}t={key:r,server:o,autoPageViews:e.autoPageViews!==!1,appVersion:typeof e.appVersion=="string"?e.appVersion.slice(0,64):"",debug:!!e.debug},a=L(location,document.referrer),m=i.get(h.user),z();let c=u;u=[];for(let l of c)y(l);t.autoPageViews&&(Y(),y(()=>M())),d("started",{server:o,autoPageViews:t.autoPageViews,version:j})}function Q(){i.remove(h.device),i.remove(h.session),i.remove(h.user),f=null,g=null,m=null}return{init:W,track:(e,r,o)=>y(()=>w(e,r,o)),pageView:e=>y(()=>M(e)),identify:e=>y(()=>O(e)),setUser:(e,r)=>y(()=>O(e,r)),login:e=>y(()=>w("login",e?{method:e}:void 0)),signUp:e=>y(()=>w("sign_up",e?{method:e}:void 0)),reset:Q,get version(){return j}}}var F=["init","track","pageView","identify","setUser","login","signUp","reset"];function $(i,t){let n=i.mixdive;if(n&&n.loaded)return null;let u=X(),a=(s,d)=>{typeof s=="string"&&F.indexOf(s)>=0&&u[s](...d)},f=s=>{try{let d=Array.prototype.slice.call(s);a(d[0],d.slice(1))}catch(d){}},g=function(s,...d){a(s,d)};for(let s of F)g[s]=(...d)=>a(s,d);Object.defineProperty(g,"version",{get:()=>u.version}),g.loaded=!0,g.q={push:f},i.mixdive=g;let m=n&&n.q&&typeof n.q.length=="number"?Array.prototype.slice.call(n.q):[];for(let s of m)f(s);if(t){let s=t.dataset,d=s.key||"",v=s.server||"";if(!v)try{v=new URL(t.src,i.location.href).origin}catch(V){}d&&u.init({key:d,server:v,autoPageViews:s.autoPageViews!=="false",appVersion:s.appVersion||void 0,debug:s.debug==="true"})}return u}$(window,document.currentScript);})();
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mixdive/browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Mixdive browser SDK — the web tag and the npm client for self-hosted product analytics.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://github.com/mixdive/mixdive-js#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/mixdive/mixdive-js.git",
|
|
10
|
+
"directory": "packages/browser"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/mixdive/mixdive-js/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mixdive",
|
|
15
|
+
"analytics",
|
|
16
|
+
"product-analytics",
|
|
17
|
+
"web-analytics",
|
|
18
|
+
"self-hosted",
|
|
19
|
+
"privacy"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"./dist/mixdive.js"
|
|
24
|
+
],
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/index.d.cts",
|
|
36
|
+
"default": "./dist/index.cjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"./tag": "./dist/mixdive.js",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
50
|
+
"prepublishOnly": "npm run build"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|