poulet 0.1.0 → 0.1.2
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/README.md +4 -6
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -51
- package/dist/react.d.ts +1 -51
- package/dist/react.global.js +25 -0
- package/dist/react.global.js.map +1 -0
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/package.json +23 -4
package/README.md
CHANGED
|
@@ -34,15 +34,13 @@
|
|
|
34
34
|
### NPM
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
npm install
|
|
38
|
-
# ou
|
|
39
|
-
yarn add @poulet/metrics
|
|
37
|
+
npm install poulet
|
|
40
38
|
```
|
|
41
39
|
|
|
42
40
|
### CDN
|
|
43
41
|
|
|
44
42
|
```html
|
|
45
|
-
<script src="https://cdn.jsdelivr.net/npm
|
|
43
|
+
<script src="https://cdn.jsdelivr.net/npm/poulet/dist/index.global.js" defer></script>
|
|
46
44
|
<script>
|
|
47
45
|
window.PouletMetrics.init({
|
|
48
46
|
projectKey: 'PUB_DEMO',
|
|
@@ -61,7 +59,7 @@ yarn add @poulet/metrics
|
|
|
61
59
|
### Vanilla (site classique)
|
|
62
60
|
|
|
63
61
|
```html
|
|
64
|
-
<script src="https://cdn.jsdelivr.net/npm
|
|
62
|
+
<script src="https://cdn.jsdelivr.net/npm/poulet/dist/index.global.js" defer></script>
|
|
65
63
|
<script>
|
|
66
64
|
window.PouletMetrics.init({
|
|
67
65
|
projectKey: 'PUB_123',
|
|
@@ -92,7 +90,7 @@ yarn add @poulet/metrics
|
|
|
92
90
|
```tsx
|
|
93
91
|
import React from 'react';
|
|
94
92
|
import { createRoot } from 'react-dom/client';
|
|
95
|
-
import { MetricsProvider, useMetrics } from '
|
|
93
|
+
import { MetricsProvider, useMetrics } from 'poulet/react';
|
|
96
94
|
|
|
97
95
|
function Demo() {
|
|
98
96
|
const { trackEvent, reportBug, setConsent } = useMetrics();
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';var s=()=>Date.now();var A=(e,t,n)=>(e.addEventListener(t,n,{passive:true}),()=>e.removeEventListener(t,n)),f=(e,t)=>(document.addEventListener(e,t,{passive:true}),()=>document.removeEventListener(e,t));var C=(e,t=.1)=>{let n=e*t;return e+(Math.random()*2-1)*n},E=e=>{if(!e||typeof e!="object")return e;let t=["email","phone","password","ssn"],n=Array.isArray(e)?[]:{};for(let o of Object.keys(e)){if(t.includes(o.toLowerCase()))continue;let i=e[o];n[o]=typeof i=="object"?E(i):i;}return n},y=(...e)=>{window.__POULET_DEBUG__&&console.log("[poulet]",...e);},_=e=>Uint8Array.from(atob(e),t=>t.charCodeAt(0));var B=Date.now(),L=[],M=()=>B,O=()=>{T();let e=()=>{B=Date.now();},t=f("mousemove",e),n=f("keydown",e),o=f("scroll",e),i=f("touchstart",e),c=A(window,"focus",e),g=A(window,"blur",e),U=f("visibilitychange",e);L=[t,n,o,i,c,g,U];},T=()=>{L.forEach(e=>e()),L=[];};var u="poulet_leader_session",d=false,F=e=>{let t=localStorage.getItem(u);return t?(d=t===e,d):(localStorage.setItem(u,e),d=true,true)},R=e=>{localStorage.getItem(u)===e&&localStorage.removeItem(u),d=false;};var q=(e,t)=>{let n=o=>{if(o.key!==u)return;let i=localStorage.getItem(u);i?(d=i===e,t(d)):(localStorage.setItem(u,e),t(true),d=true);};return window.addEventListener("storage",n),()=>window.removeEventListener("storage",n)},K=()=>{var e;return {ua:navigator.userAgent,tz:(e=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?e:"UTC",dpr:window.devicePixelRatio||1}};var m=false,k=false,S="pending",H=true,z=e=>{H=e;},N=e=>{S=e,H&&typeof navigator!="undefined"&&navigator.doNotTrack==="1"&&(m=false,k=false,S="denied");},V=e=>{typeof e.analytics=="boolean"&&(m=e.analytics,S=m?"granted":"denied"),typeof e.replay=="boolean"&&(k=e.replay);},W=()=>({analytics:m,replay:k,state:S}),D=()=>m===true;var p,x=[],j=false;async function X(e){if(!(!p.hmacPublicKey||!("crypto"in window)))try{let t=_(p.hmacPublicKey),n=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,new TextEncoder().encode(e));return btoa(String.fromCharCode(...new Uint8Array(o)))}catch(t){return}}async function $(e){let t=e.map(c=>E(c)),n=JSON.stringify({projectKey:p.projectKey,items:t}),o=await X(n);if(navigator.sendBeacon&&!p.debug){let c={type:"application/json"},g=new Blob([n],c);if(navigator.sendBeacon(p.endpoint+"/ingest",g))return true}return (await fetch(p.endpoint+"/ingest",{method:"POST",headers:{"Content-Type":"application/json",...o?{"x-signature":o}:{}},body:n})).ok}function G(e){p=e,window.addEventListener("online",b),setInterval(b,5e3);}function l(e){x.push(e),x.length>=10&&b();}async function b(){if(!(j||x.length===0)){j=true;try{let e=x.splice(0,20);await $(e)||(x.unshift(...e),y("flush failed, will retry"));}catch(e){y("flush error",e);}finally{j=false;}}}var a,r=null,v=null,h,J={projectKey:"",endpoint:"",consent:{default:"pending"},user:{},billing:{heartbeatSec:15,idleSec:60,maxHoursPerDay:6},privacy:{piiFilter:true,dntRespect:true,countryHint:"FR"},security:{hmacPublicKey:void 0},features:{bugReporter:true,replay:false,sentryBridge:false},sampling:{heartbeats:1,events:1,bugs:1},debug:false};function Y(e){a={...J,...e,consent:{...J.consent,...e.consent}},window.__POULET_DEBUG__=!!a.debug,G({endpoint:a.endpoint,projectKey:a.projectKey,hmacPublicKey:a.security.hmacPublicKey,debug:a.debug});}function I(){if(r)return;let e=crypto.randomUUID(),t=K();r={sessionId:e,startedAt:s(),lastActivityAt:s(),active:true,leader:F(e)},h&&h(),h=q(e,o=>{r&&(r.leader=o);}),O();let n={type:"session.start",sessionId:e,ts:s(),projectKey:a.projectKey,ua:t.ua,tz:t.tz,dpr:t.dpr,consentFlags:{analytics:D(),replay:false}};l(n),ee(),y("session opened",e);}function P(e){if(!r)return;Z(),T(),R(r.sessionId);let t={type:"session.end",sessionId:r.sessionId,ts:s(),reason:e};l(t),b(),h&&h(),r=null,y("session closed",e);}function ee(){Z();let e=()=>{if(!r||!D())return;let t=s()-M()>=a.billing.idleSec*1e3,n=document.visibilityState==="visible",o=n&&!t&&r.leader,i=K();if(Math.random()<=a.sampling.heartbeats&&o){let g={type:"heartbeat",sessionId:r.sessionId,ts:s(),active:true,vis:n,idle:false,jitter:Math.random(),ua:i.ua,tz:i.tz,dpr:i.dpr,purpose:"billing"};l(g);}let c=C(a.billing.heartbeatSec*1e3,.1);v=window.setTimeout(e,c);};v=window.setTimeout(e,C(a.billing.heartbeatSec*1e3,.1));}function Z(){v&&(clearTimeout(v),v=null);}var w=()=>{var e;return (e=r==null?void 0:r.sessionId)!=null?e:null};function te(e){let t=w();if(!t)return;let n={type:"bug",sessionId:t,ts:s(),title:e.title,description:e.description,severity:e.severity,hasCapture:!!(e.attachments&&e.attachments.length>0),purpose:"diagnostics"};l(n);}var Q=false;function Ee(e){var t,n,o,i;Q||(z((n=(t=e.privacy)==null?void 0:t.dntRespect)!=null?n:true),N((i=(o=e.consent)==null?void 0:o.default)!=null?i:"pending"),Y(e),document.visibilityState==="visible"&&I(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&I();}),addEventListener("pagehide",()=>P("pagehide")),Q=true);}function Le(e){V(e),document.visibilityState==="visible"&&I();}function Te(e,t){let n=w();if(!n)return;let o={type:"event",sessionId:n,ts:s(),name:e,props:t,purpose:"diagnostics"};l(o);}function Ke(){P("shutdown");}function ke(){return w()}function De(){P("shutdown");}var je=W;exports._consentFlags=je;exports.forgetMe=De;exports.getSessionId=ke;exports.init=Ee;exports.reportBug=te;exports.setConsent=Le;exports.shutdown=Ke;exports.trackEvent=Te;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts"],"sourcesContent":["// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n","// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n"],"mappings":"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","names":["src_exports","__export","_consentFlags","forgetMe","getSessionId","init","reportBug","setConsent","shutdown","trackEvent","__toCommonJS","now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","onDoc","un2","un3","un4","un5","on","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","sessionId","onChange","listener","e","LS_KEY","now","newLeader","leader","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","base64ToArrayBuffer","key","sig","e","postBatch","items","sanitized","i","filterPII","headers","blob","initTransport","config","flush","enqueue","payload","batch","log","config","session","hbTimer","unStorage","DEFAULTS","configure","cfg","initTransport","openSession","id","fp","fingerprintLite","now","becomeLeaderIfFree","handleStorageLeadership","lead","startActivityTracking","startPayload","analyticsOn","enqueue","scheduleHeartbeats","log","closeSession","reason","stopHeartbeats","stopActivityTracking","relinquishLeadership","endPayload","flush","loop","idle","getLastActivity","vis","active","hb","next","jitterMs","getSessionIdSafe","_a","reportBug","payload","sessionId","getSessionIdSafe","p","now","enqueue","initialized","init","cfg","_a","_b","_c","_d","setDNTPolicy","initConsent","configure","openSession","closeSession","setConsent","flags","trackEvent","name","props","sessionId","getSessionIdSafe","ev","now","enqueue","shutdown","getSessionId","forgetMe","_consentFlags","consentFlags"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts","../src/index.ts"],"names":["now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","un2","un3","un4","un5","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","onChange","listener","e","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","key","sig","postBatch","items","sanitized","i","headers","blob","initTransport","config","flush","enqueue","payload","batch","session","hbTimer","unStorage","DEFAULTS","configure","openSession","id","fp","lead","startPayload","scheduleHeartbeats","closeSession","reason","stopHeartbeats","endPayload","loop","idle","vis","active","hb","next","getSessionIdSafe","reportBug","p","initialized","init","_b","_c","_d","trackEvent","name","props","ev","shutdown","getSessionId","forgetMe","_consentFlags"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n","// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n"]}
|
package/dist/index.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
var Poulet=(function(exports){'use strict';var s=()=>Date.now();var A=(e,t,n)=>(e.addEventListener(t,n,{passive:true}),()=>e.removeEventListener(t,n)),f=(e,t)=>(document.addEventListener(e,t,{passive:true}),()=>document.removeEventListener(e,t));var C=(e,t=.1)=>{let n=e*t;return e+(Math.random()*2-1)*n},E=e=>{if(!e||typeof e!="object")return e;let t=["email","phone","password","ssn"],n=Array.isArray(e)?[]:{};for(let o of Object.keys(e)){if(t.includes(o.toLowerCase()))continue;let i=e[o];n[o]=typeof i=="object"?E(i):i;}return n},y=(...e)=>{window.__POULET_DEBUG__&&console.log("[poulet]",...e);},_=e=>Uint8Array.from(atob(e),t=>t.charCodeAt(0));var B=Date.now(),L=[],M=()=>B,O=()=>{T();let e=()=>{B=Date.now();},t=f("mousemove",e),n=f("keydown",e),o=f("scroll",e),i=f("touchstart",e),c=A(window,"focus",e),g=A(window,"blur",e),U=f("visibilitychange",e);L=[t,n,o,i,c,g,U];},T=()=>{L.forEach(e=>e()),L=[];};var u="poulet_leader_session",d=false,F=e=>{let t=localStorage.getItem(u);return t?(d=t===e,d):(localStorage.setItem(u,e),d=true,true)},R=e=>{localStorage.getItem(u)===e&&localStorage.removeItem(u),d=false;};var q=(e,t)=>{let n=o=>{if(o.key!==u)return;let i=localStorage.getItem(u);i?(d=i===e,t(d)):(localStorage.setItem(u,e),t(true),d=true);};return window.addEventListener("storage",n),()=>window.removeEventListener("storage",n)},K=()=>{var e;return {ua:navigator.userAgent,tz:(e=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?e:"UTC",dpr:window.devicePixelRatio||1}};var m=false,k=false,S="pending",H=true,z=e=>{H=e;},N=e=>{S=e,H&&typeof navigator!="undefined"&&navigator.doNotTrack==="1"&&(m=false,k=false,S="denied");},V=e=>{typeof e.analytics=="boolean"&&(m=e.analytics,S=m?"granted":"denied"),typeof e.replay=="boolean"&&(k=e.replay);},W=()=>({analytics:m,replay:k,state:S}),D=()=>m===true;var p,x=[],j=false;async function X(e){if(!(!p.hmacPublicKey||!("crypto"in window)))try{let t=_(p.hmacPublicKey),n=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,new TextEncoder().encode(e));return btoa(String.fromCharCode(...new Uint8Array(o)))}catch(t){return}}async function $(e){let t=e.map(c=>E(c)),n=JSON.stringify({projectKey:p.projectKey,items:t}),o=await X(n);if(navigator.sendBeacon&&!p.debug){let c={type:"application/json"},g=new Blob([n],c);if(navigator.sendBeacon(p.endpoint+"/ingest",g))return true}return (await fetch(p.endpoint+"/ingest",{method:"POST",headers:{"Content-Type":"application/json",...o?{"x-signature":o}:{}},body:n})).ok}function G(e){p=e,window.addEventListener("online",b),setInterval(b,5e3);}function l(e){x.push(e),x.length>=10&&b();}async function b(){if(!(j||x.length===0)){j=true;try{let e=x.splice(0,20);await $(e)||(x.unshift(...e),y("flush failed, will retry"));}catch(e){y("flush error",e);}finally{j=false;}}}var a,r=null,v=null,h,J={projectKey:"",endpoint:"",consent:{default:"pending"},user:{},billing:{heartbeatSec:15,idleSec:60,maxHoursPerDay:6},privacy:{piiFilter:true,dntRespect:true,countryHint:"FR"},security:{hmacPublicKey:void 0},features:{bugReporter:true,replay:false,sentryBridge:false},sampling:{heartbeats:1,events:1,bugs:1},debug:false};function Y(e){a={...J,...e,consent:{...J.consent,...e.consent}},window.__POULET_DEBUG__=!!a.debug,G({endpoint:a.endpoint,projectKey:a.projectKey,hmacPublicKey:a.security.hmacPublicKey,debug:a.debug});}function I(){if(r)return;let e=crypto.randomUUID(),t=K();r={sessionId:e,startedAt:s(),lastActivityAt:s(),active:true,leader:F(e)},h&&h(),h=q(e,o=>{r&&(r.leader=o);}),O();let n={type:"session.start",sessionId:e,ts:s(),projectKey:a.projectKey,ua:t.ua,tz:t.tz,dpr:t.dpr,consentFlags:{analytics:D(),replay:false}};l(n),ee(),y("session opened",e);}function P(e){if(!r)return;Z(),T(),R(r.sessionId);let t={type:"session.end",sessionId:r.sessionId,ts:s(),reason:e};l(t),b(),h&&h(),r=null,y("session closed",e);}function ee(){Z();let e=()=>{if(!r||!D())return;let t=s()-M()>=a.billing.idleSec*1e3,n=document.visibilityState==="visible",o=n&&!t&&r.leader,i=K();if(Math.random()<=a.sampling.heartbeats&&o){let g={type:"heartbeat",sessionId:r.sessionId,ts:s(),active:true,vis:n,idle:false,jitter:Math.random(),ua:i.ua,tz:i.tz,dpr:i.dpr,purpose:"billing"};l(g);}let c=C(a.billing.heartbeatSec*1e3,.1);v=window.setTimeout(e,c);};v=window.setTimeout(e,C(a.billing.heartbeatSec*1e3,.1));}function Z(){v&&(clearTimeout(v),v=null);}var w=()=>{var e;return (e=r==null?void 0:r.sessionId)!=null?e:null};function te(e){let t=w();if(!t)return;let n={type:"bug",sessionId:t,ts:s(),title:e.title,description:e.description,severity:e.severity,hasCapture:!!(e.attachments&&e.attachments.length>0),purpose:"diagnostics"};l(n);}var Q=false;function Ee(e){var t,n,o,i;Q||(z((n=(t=e.privacy)==null?void 0:t.dntRespect)!=null?n:true),N((i=(o=e.consent)==null?void 0:o.default)!=null?i:"pending"),Y(e),document.visibilityState==="visible"&&I(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&I();}),addEventListener("pagehide",()=>P("pagehide")),Q=true);}function Le(e){V(e),document.visibilityState==="visible"&&I();}function Te(e,t){let n=w();if(!n)return;let o={type:"event",sessionId:n,ts:s(),name:e,props:t,purpose:"diagnostics"};l(o);}function Ke(){P("shutdown");}function ke(){return w()}function De(){P("shutdown");}var je=W;exports._consentFlags=je;exports.forgetMe=De;exports.getSessionId=ke;exports.init=Ee;exports.reportBug=te;exports.setConsent=Le;exports.shutdown=Ke;exports.trackEvent=Te;return exports;})({});//# sourceMappingURL=index.global.js.map
|
|
2
2
|
//# sourceMappingURL=index.global.js.map
|
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts"],"sourcesContent":["// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n","// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n"],"mappings":"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","names":["src_exports","__export","_consentFlags","forgetMe","getSessionId","init","reportBug","setConsent","shutdown","trackEvent","now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","onDoc","un2","un3","un4","un5","on","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","sessionId","onChange","listener","e","LS_KEY","now","newLeader","leader","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","base64ToArrayBuffer","key","sig","e","postBatch","items","sanitized","i","filterPII","headers","blob","initTransport","config","flush","enqueue","payload","batch","log","config","session","hbTimer","unStorage","DEFAULTS","configure","cfg","initTransport","openSession","id","fp","fingerprintLite","now","becomeLeaderIfFree","handleStorageLeadership","lead","startActivityTracking","startPayload","analyticsOn","enqueue","scheduleHeartbeats","log","closeSession","reason","stopHeartbeats","stopActivityTracking","relinquishLeadership","endPayload","flush","loop","idle","getLastActivity","vis","active","hb","next","jitterMs","getSessionIdSafe","_a","reportBug","payload","sessionId","getSessionIdSafe","p","now","enqueue","initialized","init","cfg","_a","_b","_c","_d","setDNTPolicy","initConsent","configure","openSession","closeSession","setConsent","flags","trackEvent","name","props","sessionId","getSessionIdSafe","ev","now","enqueue","shutdown","getSessionId","forgetMe","_consentFlags","consentFlags"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts","../src/index.ts"],"names":["now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","un2","un3","un4","un5","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","onChange","listener","e","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","key","sig","postBatch","items","sanitized","i","headers","blob","initTransport","config","flush","enqueue","payload","batch","session","hbTimer","unStorage","DEFAULTS","configure","openSession","id","fp","lead","startPayload","scheduleHeartbeats","closeSession","reason","stopHeartbeats","endPayload","loop","idle","vis","active","hb","next","getSessionIdSafe","reportBug","p","initialized","init","_b","_c","_d","trackEvent","name","props","ev","shutdown","getSessionId","forgetMe","_consentFlags"],"mappings":"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","file":"index.global.js","sourcesContent":["// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n","// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var s=()=>Date.now();var A=(e,t,n)=>(e.addEventListener(t,n,{passive
|
|
1
|
+
var s=()=>Date.now();var A=(e,t,n)=>(e.addEventListener(t,n,{passive:true}),()=>e.removeEventListener(t,n)),f=(e,t)=>(document.addEventListener(e,t,{passive:true}),()=>document.removeEventListener(e,t));var C=(e,t=.1)=>{let n=e*t;return e+(Math.random()*2-1)*n},E=e=>{if(!e||typeof e!="object")return e;let t=["email","phone","password","ssn"],n=Array.isArray(e)?[]:{};for(let o of Object.keys(e)){if(t.includes(o.toLowerCase()))continue;let i=e[o];n[o]=typeof i=="object"?E(i):i;}return n},y=(...e)=>{window.__POULET_DEBUG__&&console.log("[poulet]",...e);},_=e=>Uint8Array.from(atob(e),t=>t.charCodeAt(0));var B=Date.now(),L=[],M=()=>B,O=()=>{T();let e=()=>{B=Date.now();},t=f("mousemove",e),n=f("keydown",e),o=f("scroll",e),i=f("touchstart",e),c=A(window,"focus",e),g=A(window,"blur",e),U=f("visibilitychange",e);L=[t,n,o,i,c,g,U];},T=()=>{L.forEach(e=>e()),L=[];};var u="poulet_leader_session",d=false,F=e=>{let t=localStorage.getItem(u);return t?(d=t===e,d):(localStorage.setItem(u,e),d=true,true)},R=e=>{localStorage.getItem(u)===e&&localStorage.removeItem(u),d=false;};var q=(e,t)=>{let n=o=>{if(o.key!==u)return;let i=localStorage.getItem(u);i?(d=i===e,t(d)):(localStorage.setItem(u,e),t(true),d=true);};return window.addEventListener("storage",n),()=>window.removeEventListener("storage",n)},K=()=>{var e;return {ua:navigator.userAgent,tz:(e=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?e:"UTC",dpr:window.devicePixelRatio||1}};var m=false,k=false,S="pending",H=true,z=e=>{H=e;},N=e=>{S=e,H&&typeof navigator!="undefined"&&navigator.doNotTrack==="1"&&(m=false,k=false,S="denied");},V=e=>{typeof e.analytics=="boolean"&&(m=e.analytics,S=m?"granted":"denied"),typeof e.replay=="boolean"&&(k=e.replay);},W=()=>({analytics:m,replay:k,state:S}),D=()=>m===true;var p,x=[],j=false;async function X(e){if(!(!p.hmacPublicKey||!("crypto"in window)))try{let t=_(p.hmacPublicKey),n=await crypto.subtle.importKey("raw",t,{name:"HMAC",hash:"SHA-256"},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,new TextEncoder().encode(e));return btoa(String.fromCharCode(...new Uint8Array(o)))}catch(t){return}}async function $(e){let t=e.map(c=>E(c)),n=JSON.stringify({projectKey:p.projectKey,items:t}),o=await X(n);if(navigator.sendBeacon&&!p.debug){let c={type:"application/json"},g=new Blob([n],c);if(navigator.sendBeacon(p.endpoint+"/ingest",g))return true}return (await fetch(p.endpoint+"/ingest",{method:"POST",headers:{"Content-Type":"application/json",...o?{"x-signature":o}:{}},body:n})).ok}function G(e){p=e,window.addEventListener("online",b),setInterval(b,5e3);}function l(e){x.push(e),x.length>=10&&b();}async function b(){if(!(j||x.length===0)){j=true;try{let e=x.splice(0,20);await $(e)||(x.unshift(...e),y("flush failed, will retry"));}catch(e){y("flush error",e);}finally{j=false;}}}var a,r=null,v=null,h,J={projectKey:"",endpoint:"",consent:{default:"pending"},user:{},billing:{heartbeatSec:15,idleSec:60,maxHoursPerDay:6},privacy:{piiFilter:true,dntRespect:true,countryHint:"FR"},security:{hmacPublicKey:void 0},features:{bugReporter:true,replay:false,sentryBridge:false},sampling:{heartbeats:1,events:1,bugs:1},debug:false};function Y(e){a={...J,...e,consent:{...J.consent,...e.consent}},window.__POULET_DEBUG__=!!a.debug,G({endpoint:a.endpoint,projectKey:a.projectKey,hmacPublicKey:a.security.hmacPublicKey,debug:a.debug});}function I(){if(r)return;let e=crypto.randomUUID(),t=K();r={sessionId:e,startedAt:s(),lastActivityAt:s(),active:true,leader:F(e)},h&&h(),h=q(e,o=>{r&&(r.leader=o);}),O();let n={type:"session.start",sessionId:e,ts:s(),projectKey:a.projectKey,ua:t.ua,tz:t.tz,dpr:t.dpr,consentFlags:{analytics:D(),replay:false}};l(n),ee(),y("session opened",e);}function P(e){if(!r)return;Z(),T(),R(r.sessionId);let t={type:"session.end",sessionId:r.sessionId,ts:s(),reason:e};l(t),b(),h&&h(),r=null,y("session closed",e);}function ee(){Z();let e=()=>{if(!r||!D())return;let t=s()-M()>=a.billing.idleSec*1e3,n=document.visibilityState==="visible",o=n&&!t&&r.leader,i=K();if(Math.random()<=a.sampling.heartbeats&&o){let g={type:"heartbeat",sessionId:r.sessionId,ts:s(),active:true,vis:n,idle:false,jitter:Math.random(),ua:i.ua,tz:i.tz,dpr:i.dpr,purpose:"billing"};l(g);}let c=C(a.billing.heartbeatSec*1e3,.1);v=window.setTimeout(e,c);};v=window.setTimeout(e,C(a.billing.heartbeatSec*1e3,.1));}function Z(){v&&(clearTimeout(v),v=null);}var w=()=>{var e;return (e=r==null?void 0:r.sessionId)!=null?e:null};function te(e){let t=w();if(!t)return;let n={type:"bug",sessionId:t,ts:s(),title:e.title,description:e.description,severity:e.severity,hasCapture:!!(e.attachments&&e.attachments.length>0),purpose:"diagnostics"};l(n);}var Q=false;function Ee(e){var t,n,o,i;Q||(z((n=(t=e.privacy)==null?void 0:t.dntRespect)!=null?n:true),N((i=(o=e.consent)==null?void 0:o.default)!=null?i:"pending"),Y(e),document.visibilityState==="visible"&&I(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&I();}),addEventListener("pagehide",()=>P("pagehide")),Q=true);}function Le(e){V(e),document.visibilityState==="visible"&&I();}function Te(e,t){let n=w();if(!n)return;let o={type:"event",sessionId:n,ts:s(),name:e,props:t,purpose:"diagnostics"};l(o);}function Ke(){P("shutdown");}function ke(){return w()}function De(){P("shutdown");}var je=W;export{je as _consentFlags,De as forgetMe,ke as getSessionId,Ee as init,te as reportBug,Le as setConsent,Ke as shutdown,Te as trackEvent};//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts","../src/index.ts"],"sourcesContent":["// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n","// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n"],"mappings":"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","names":["now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","onDoc","un2","un3","un4","un5","on","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","sessionId","onChange","listener","e","LS_KEY","now","newLeader","leader","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","base64ToArrayBuffer","key","sig","e","postBatch","items","sanitized","i","filterPII","headers","blob","initTransport","config","flush","enqueue","payload","batch","log","config","session","hbTimer","unStorage","DEFAULTS","configure","cfg","initTransport","openSession","id","fp","fingerprintLite","now","becomeLeaderIfFree","handleStorageLeadership","lead","startActivityTracking","startPayload","analyticsOn","enqueue","scheduleHeartbeats","log","closeSession","reason","stopHeartbeats","stopActivityTracking","relinquishLeadership","endPayload","flush","loop","idle","getLastActivity","vis","active","hb","next","jitterMs","getSessionIdSafe","_a","reportBug","payload","sessionId","getSessionIdSafe","p","now","enqueue","initialized","init","cfg","_a","_b","_c","_d","setDNTPolicy","initConsent","configure","openSession","closeSession","setConsent","flags","trackEvent","name","props","sessionId","getSessionIdSafe","ev","now","enqueue","shutdown","getSessionId","forgetMe","_consentFlags","consentFlags"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/activity.ts","../src/antifraud.ts","../src/consent.ts","../src/transport.ts","../src/core.ts","../src/bug.ts","../src/index.ts"],"names":["now","on","t","type","fn","onDoc","jitterMs","baseMs","pct","delta","filterPII","o","SUSPICIOUS","out","k","v","log","args","base64ToArrayBuffer","b64","c","lastActivity","unsub","getLastActivity","startActivityTracking","stopActivityTracking","touch","un1","un2","un3","un4","un5","un6","un7","f","LS_KEY","leader","becomeLeaderIfFree","sessionId","current","relinquishLeadership","handleStorageLeadership","onChange","listener","e","fingerprintLite","_a","analyticsAllowed","replayAllowed","state","dntRespected","setDNTPolicy","respect","initConsent","defaultState","setConsent","flags","consentFlags","analyticsOn","cfg","queue","flushing","sign","body","keyData","key","sig","postBatch","items","sanitized","i","headers","blob","initTransport","config","flush","enqueue","payload","batch","session","hbTimer","unStorage","DEFAULTS","configure","openSession","id","fp","lead","startPayload","scheduleHeartbeats","closeSession","reason","stopHeartbeats","endPayload","loop","idle","vis","active","hb","next","getSessionIdSafe","reportBug","p","initialized","init","_b","_c","_d","trackEvent","name","props","ev","shutdown","getSessionId","forgetMe","_consentFlags"],"mappings":"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","file":"index.js","sourcesContent":["// src/utils.ts\nexport const now = () => Date.now();\n\nexport const uuid = (): string =>\n (crypto?.randomUUID?.() ?? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (crypto.getRandomValues(new Uint8Array(1))[0] & 0xf) >> 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n }));\n\nexport const isVisible = () => typeof document !== 'undefined' && document.visibilityState === 'visible';\n\nexport const on = <K extends keyof WindowEventMap>(t: Window, type: K, fn: (e: WindowEventMap[K]) => void) => {\n t.addEventListener(type, fn as any, { passive: true });\n return () => t.removeEventListener(type, fn as any);\n};\n\nexport const onDoc = <K extends keyof DocumentEventMap>(type: K, fn: (e: DocumentEventMap[K]) => void) => {\n document.addEventListener(type, fn as any, { passive: true });\n return () => document.removeEventListener(type, fn as any);\n};\n\nexport const clamp = (n: number, min: number, max: number) => Math.max(min, Math.min(max, n));\n\nexport const jitterMs = (baseMs: number, pct = 0.1) => {\n const delta = baseMs * pct;\n return baseMs + (Math.random() * 2 - 1) * delta;\n};\n\nexport const filterPII = (o: any): any => {\n if (!o || typeof o !== 'object') return o;\n const SUSPICIOUS = ['email', 'phone', 'password', 'ssn'];\n const out: any = Array.isArray(o) ? [] : {};\n for (const k of Object.keys(o)) {\n if (SUSPICIOUS.includes(k.toLowerCase())) continue;\n const v = (o as any)[k];\n out[k] = typeof v === 'object' ? filterPII(v) : v;\n }\n return out;\n};\n\nexport const log = (...args: any[]) => {\n if ((window as any).__POULET_DEBUG__) console.log('[poulet]', ...args);\n};\n\nexport const base64ToArrayBuffer = (b64: string) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));\n","// src/activity.ts\nimport { isVisible, onDoc, on } from './utils';\n\nlet lastActivity = Date.now();\nlet unsub: Array<() => void> = [];\n\nexport const getLastActivity = () => lastActivity;\n\nexport const startActivityTracking = () => {\n stopActivityTracking();\n const touch = () => { lastActivity = Date.now(); };\n const un1 = onDoc('mousemove', touch);\n const un2 = onDoc('keydown', touch);\n const un3 = onDoc('scroll', touch);\n const un4 = onDoc('touchstart', touch);\n const un5 = on(window, 'focus', touch);\n const un6 = on(window, 'blur', touch);\n const un7 = onDoc('visibilitychange' as any, touch);\n unsub = [un1, un2, un3, un4, un5, un6, un7];\n};\n\nexport const stopActivityTracking = () => {\n unsub.forEach((f) => f());\n unsub = [];\n};\n\nexport const isActive = (idleSec: number) => {\n const idleMs = idleSec * 1000;\n return isVisible() && (Date.now() - lastActivity) < idleMs;\n};\n","// src/antifraud.ts\nconst LS_KEY = 'poulet_leader_session';\nlet leader = false;\n\nexport const becomeLeaderIfFree = (sessionId: string): boolean => {\n const current = localStorage.getItem(LS_KEY);\n if (!current) {\n localStorage.setItem(LS_KEY, sessionId);\n leader = true;\n return true;\n }\n leader = current === sessionId;\n return leader;\n};\n\nexport const relinquishLeadership = (sessionId: string) => {\n const current = localStorage.getItem(LS_KEY);\n if (current === sessionId) {\n localStorage.removeItem(LS_KEY);\n }\n leader = false;\n};\n\nexport const isLeader = () => leader;\n\nexport const handleStorageLeadership = (sessionId: string, onChange: (isLeader: boolean)=>void) => {\n const listener = (e: StorageEvent) => {\n if (e.key !== LS_KEY) return;\n const now = localStorage.getItem(LS_KEY);\n const newLeader = now === sessionId || !now;\n if (!now) { // try claim\n localStorage.setItem(LS_KEY, sessionId);\n onChange(true);\n leader = true;\n } else {\n leader = now === sessionId;\n onChange(leader);\n }\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n};\n\nexport const fingerprintLite = () => ({\n ua: navigator.userAgent,\n tz: Intl.DateTimeFormat().resolvedOptions().timeZone ?? 'UTC',\n dpr: window.devicePixelRatio || 1,\n});\n","// src/consent.ts\nimport type { ConsentState } from './types';\n\nlet analyticsAllowed = false;\nlet replayAllowed = false;\nlet state: ConsentState = 'pending';\nlet dntRespected = true;\n\nexport const setDNTPolicy = (respect: boolean) => { dntRespected = respect; };\n\nexport const initConsent = (defaultState: ConsentState) => {\n state = defaultState;\n if (dntRespected && typeof navigator !== 'undefined' && (navigator as any).doNotTrack === '1') {\n analyticsAllowed = false;\n replayAllowed = false;\n state = 'denied';\n }\n};\n\nexport const setConsent = (flags: { analytics?: boolean; replay?: boolean }) => {\n if (typeof flags.analytics === 'boolean') {\n analyticsAllowed = flags.analytics;\n state = analyticsAllowed ? 'granted' : 'denied';\n }\n if (typeof flags.replay === 'boolean') replayAllowed = flags.replay;\n};\n\nexport const consentFlags = () => ({ analytics: analyticsAllowed, replay: replayAllowed, state });\nexport const analyticsOn = () => analyticsAllowed === true;\nexport const replayOn = () => replayAllowed === true;\n","// src/transport.ts\nimport { base64ToArrayBuffer, filterPII, log } from './utils';\nimport type { OutgoingPayload } from './types';\n\ntype TransportConfig = {\n endpoint: string;\n projectKey: string;\n hmacPublicKey?: string; // base64; optional\n debug?: boolean;\n};\n\nlet cfg: TransportConfig;\nlet queue: OutgoingPayload[] = [];\nlet flushing = false;\n\nasync function sign(body: string): Promise<string | undefined> {\n if (!cfg.hmacPublicKey || !('crypto' in window)) return undefined;\n try {\n const keyData = base64ToArrayBuffer(cfg.hmacPublicKey);\n const key = await crypto.subtle.importKey('raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n const sig = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(body));\n return btoa(String.fromCharCode(...new Uint8Array(sig)));\n } catch {\n return undefined;\n }\n}\n\nasync function postBatch(items: OutgoingPayload[]) {\n const sanitized = items.map((i) => filterPII(i));\n const body = JSON.stringify({ projectKey: cfg.projectKey, items: sanitized });\n const sig = await sign(body);\n\n // Try Beacon first\n if (navigator.sendBeacon && !cfg.debug) {\n const headers = { type: 'application/json' };\n const blob = new Blob([body], headers);\n const ok = navigator.sendBeacon(cfg.endpoint + '/ingest', blob);\n if (ok) return true;\n }\n\n // Fallback fetch\n const res = await fetch(cfg.endpoint + '/ingest', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(sig ? { 'x-signature': sig } : {}) },\n body\n });\n return res.ok;\n}\n\nexport function initTransport(config: TransportConfig) {\n cfg = config;\n window.addEventListener('online', flush);\n setInterval(flush, 5000);\n}\n\nexport function enqueue(payload: OutgoingPayload) {\n queue.push(payload);\n if (queue.length >= 10) void flush();\n}\n\nexport async function flush() {\n if (flushing || queue.length === 0) return;\n flushing = true;\n try {\n const batch = queue.splice(0, 20);\n const ok = await postBatch(batch);\n if (!ok) {\n // put back\n queue.unshift(...batch);\n log('flush failed, will retry');\n }\n } catch (e) {\n log('flush error', e);\n } finally {\n flushing = false;\n }\n}\n","// src/core.ts\nimport { jitterMs, log, now } from './utils';\nimport { startActivityTracking, stopActivityTracking, isActive, getLastActivity } from './activity';\nimport { becomeLeaderIfFree, handleStorageLeadership, relinquishLeadership, isLeader, fingerprintLite } from './antifraud';\nimport { analyticsOn, consentFlags } from './consent';\nimport { initTransport, enqueue, flush } from './transport';\nimport type { Config, SessionState, HeartbeatPayload, SessionStart, SessionEnd } from './types';\n\nlet config: Required<Config>;\nlet session: SessionState | null = null;\nlet hbTimer: number | null = null;\nlet unStorage: (() => void) | undefined;\n\nconst DEFAULTS: Required<Config> = {\n projectKey: '',\n endpoint: '',\n consent: { default: 'pending' },\n user: {},\n billing: { heartbeatSec: 15, idleSec: 60, maxHoursPerDay: 6 },\n privacy: { piiFilter: true, dntRespect: true, countryHint: 'FR' },\n security: { hmacPublicKey: undefined as any },\n features: { bugReporter: true, replay: false, sentryBridge: false },\n sampling: { heartbeats: 1, events: 1, bugs: 1 },\n debug: false,\n};\n\nexport function configure(cfg: Config) {\n config = { ...DEFAULTS, ...cfg, consent: { ...DEFAULTS.consent, ...cfg.consent } } as Required<Config>;\n (window as any).__POULET_DEBUG__ = !!config.debug;\n initTransport({\n endpoint: config.endpoint,\n projectKey: config.projectKey,\n hmacPublicKey: config.security.hmacPublicKey,\n debug: config.debug,\n });\n}\n\nexport function openSession() {\n if (session) return;\n const id = crypto.randomUUID();\n const fp = fingerprintLite();\n session = {\n sessionId: id,\n startedAt: now(),\n lastActivityAt: now(),\n active: true,\n leader: becomeLeaderIfFree(id),\n };\n if (unStorage) unStorage();\n unStorage = handleStorageLeadership(id, (lead) => {\n if (session) session.leader = lead;\n });\n\n startActivityTracking();\n\n const startPayload: SessionStart = {\n type: 'session.start',\n sessionId: id,\n ts: now(),\n projectKey: config.projectKey,\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n consentFlags: { analytics: analyticsOn(), replay: false },\n };\n enqueue(startPayload);\n scheduleHeartbeats();\n log('session opened', id);\n}\n\nexport function closeSession(reason: SessionEnd['reason']) {\n if (!session) return;\n stopHeartbeats();\n stopActivityTracking();\n relinquishLeadership(session.sessionId);\n const endPayload: SessionEnd = { type: 'session.end', sessionId: session.sessionId, ts: now(), reason };\n enqueue(endPayload);\n void flush();\n if (unStorage) unStorage();\n session = null;\n log('session closed', reason);\n}\n\nfunction scheduleHeartbeats() {\n stopHeartbeats();\n const loop = () => {\n if (!session) return;\n if (!analyticsOn()) return; // consent required\n // @ts-ignore\n const idle = (now() - getLastActivity()) >= config.billing.idleSec * 1000;\n const vis = document.visibilityState === 'visible';\n const active = vis && !idle && session.leader;\n const fp = fingerprintLite();\n\n // @ts-ignore\n if (Math.random() <= config.sampling.heartbeats && active) {\n const hb: HeartbeatPayload = {\n type: 'heartbeat',\n sessionId: session.sessionId,\n ts: now(),\n active: true,\n vis,\n idle: false,\n jitter: Math.random(),\n ua: fp.ua,\n tz: fp.tz,\n dpr: fp.dpr,\n purpose: 'billing',\n };\n enqueue(hb);\n }\n\n // @ts-ignore\n const next = jitterMs(config.billing.heartbeatSec * 1000, 0.1);\n hbTimer = window.setTimeout(loop, next);\n };\n // @ts-ignore\n hbTimer = window.setTimeout(loop, jitterMs(config.billing.heartbeatSec * 1000, 0.1));\n}\n\nfunction stopHeartbeats() {\n if (hbTimer) {\n clearTimeout(hbTimer);\n hbTimer = null;\n }\n}\n\nexport const getSessionIdSafe = () => session?.sessionId ?? null;\n","// src/bug.ts\nimport { enqueue } from './transport';\nimport type { BugPayload } from './types';\nimport { now } from './utils';\nimport { getSessionIdSafe } from './core';\n\nexport function reportBug(payload: {\n title: string; description?: string;\n severity?: 'blocker'|'major'|'minor'|'ux';\n attachments?: Blob[];\n}) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const p: BugPayload = {\n type: 'bug',\n sessionId,\n ts: now(),\n title: payload.title,\n description: payload.description,\n severity: payload.severity,\n hasCapture: !!(payload.attachments && payload.attachments.length > 0),\n purpose: 'diagnostics'\n };\n enqueue(p);\n // NOTE: upload des pièces jointes = hors scope core (peut passer par un autre endpoint)\n}\n","// src/index.ts\nimport { configure, openSession, closeSession, getSessionIdSafe } from './core';\nimport { setConsent as _setConsent, initConsent, setDNTPolicy, consentFlags } from './consent';\nimport { enqueue } from './transport';\nimport type { Config, EventPayload } from './types';\nimport { now } from './utils';\nexport * from './types';\nexport { reportBug } from './bug';\n\nlet initialized = false;\n\nexport function init(cfg: Config) {\n if (initialized) return;\n setDNTPolicy(cfg.privacy?.dntRespect ?? true);\n initConsent(cfg.consent?.default ?? 'pending');\n configure(cfg);\n // ouverture paresseuse : dès qu’il y a visibilité/activité\n if (document.visibilityState === 'visible') openSession();\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'visible') openSession();\n });\n // Flush/close sur pagehide\n addEventListener('pagehide', () => closeSession('pagehide'));\n initialized = true;\n}\n\nexport function setConsent(flags: { analytics?: boolean; replay?: boolean }) {\n _setConsent(flags);\n if (document.visibilityState === 'visible') openSession();\n}\n\nexport function trackEvent(name: string, props?: Record<string, unknown>) {\n const sessionId = getSessionIdSafe();\n if (!sessionId) return;\n const ev: EventPayload = {\n type: 'event',\n sessionId,\n ts: now(),\n name,\n props,\n purpose: 'diagnostics',\n };\n enqueue(ev);\n}\n\nexport function shutdown() {\n closeSession('shutdown');\n}\n\nexport function getSessionId() {\n return getSessionIdSafe();\n}\n\nexport function forgetMe() {\n // côté core : rien de persistant par défaut (queue en mémoire).\n // si tu ajoutes IndexedDB/localStorage pour queue offline, purge ici.\n // Pour l’exemple, on ne stocke pas persistantement.\n closeSession('shutdown');\n}\n\nexport const _consentFlags = consentFlags;\n"]}
|