@inferevents/sdk 0.1.3 → 0.1.5
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 +140 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/package.json +4 -3
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @inferevents/sdk
|
|
2
|
+
|
|
3
|
+
Event collection SDK for [Infer](https://infer.events) — analytics designed for AI agents, not dashboards.
|
|
4
|
+
|
|
5
|
+
3KB. Zero dependencies. Auto-tracks page views, clicks, sessions, and errors out of the box.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @inferevents/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { init, track, identify } from "@inferevents/sdk";
|
|
17
|
+
|
|
18
|
+
init({
|
|
19
|
+
projectId: "pk_write_...", // your write key (safe to embed in client JS)
|
|
20
|
+
autoTrack: true, // auto-tracks page views, clicks, sessions, errors
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Track custom events
|
|
24
|
+
track("signup_completed", { plan: "pro" });
|
|
25
|
+
|
|
26
|
+
// Identify a user (links anonymous activity to a known user)
|
|
27
|
+
identify("user_123", { email: "alice@example.com" });
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
### `init(config)`
|
|
33
|
+
|
|
34
|
+
Initialize the SDK. Must be called before other methods (events queued before init are replayed automatically).
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
init({
|
|
38
|
+
projectId: string; // Required. Your write key (pk_write_...)
|
|
39
|
+
endpoint?: string; // API endpoint (default: https://api.infer.events)
|
|
40
|
+
autoTrack?: boolean; // Enable auto-tracking (default: false)
|
|
41
|
+
batchSize?: number; // Events per batch (default: 20)
|
|
42
|
+
flushInterval?: number; // Flush interval in ms (default: 10000)
|
|
43
|
+
debug?: boolean; // Console logging (default: false)
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### `track(eventName, properties?)`
|
|
48
|
+
|
|
49
|
+
Track a custom event.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
track("purchase", { amount: 49.99, currency: "USD" });
|
|
53
|
+
track("feature_used", { feature: "export" });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `identify(userId, traits?)`
|
|
57
|
+
|
|
58
|
+
Link the current anonymous user to a known user ID. All past and future events are associated with this identity.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
identify("user_123", { name: "Alice", plan: "pro" });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `page(name?)`
|
|
65
|
+
|
|
66
|
+
Track a page view. Called automatically if `autoTrack: true`.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
page("Pricing");
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `screen(name)`
|
|
73
|
+
|
|
74
|
+
Track a screen view (React Native / mobile).
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
screen("Settings");
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `flush()`
|
|
81
|
+
|
|
82
|
+
Manually flush the event queue. Events are batched and sent automatically, but you can force a flush.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
await flush();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `reset()`
|
|
89
|
+
|
|
90
|
+
Clear the current user identity. Use on logout to start a new anonymous session.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
reset();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `destroy()`
|
|
97
|
+
|
|
98
|
+
Tear down the SDK, clear timers and listeners.
|
|
99
|
+
|
|
100
|
+
## Auto-tracking
|
|
101
|
+
|
|
102
|
+
When `autoTrack: true`, the SDK automatically captures:
|
|
103
|
+
|
|
104
|
+
| Event | Trigger |
|
|
105
|
+
|-------|---------|
|
|
106
|
+
| `page_view` | Page navigation (History API) |
|
|
107
|
+
| `session_start` | New browser session |
|
|
108
|
+
| `click` | Clicks on interactive elements (buttons, links) |
|
|
109
|
+
| `form_submit` | Form submissions |
|
|
110
|
+
| `error` | Uncaught JavaScript errors |
|
|
111
|
+
|
|
112
|
+
## Context
|
|
113
|
+
|
|
114
|
+
Every event includes auto-collected context:
|
|
115
|
+
|
|
116
|
+
| Field | Source |
|
|
117
|
+
|-------|--------|
|
|
118
|
+
| `browser` | User agent |
|
|
119
|
+
| `os` | Parsed from UA (macOS, Windows, iOS, Android, Linux) |
|
|
120
|
+
| `device_type` | Mobile, Tablet, or Desktop |
|
|
121
|
+
| `page_url` | `window.location.href` |
|
|
122
|
+
| `pathname` | `window.location.pathname` |
|
|
123
|
+
| `referrer` | `document.referrer` |
|
|
124
|
+
| `locale` | `navigator.language` |
|
|
125
|
+
| `timezone` | `Intl.DateTimeFormat` timezone |
|
|
126
|
+
| `screen_width` / `screen_height` | Screen dimensions |
|
|
127
|
+
|
|
128
|
+
Server-side geo enrichment (country, city, region) is added at ingestion time.
|
|
129
|
+
|
|
130
|
+
## How it works
|
|
131
|
+
|
|
132
|
+
- Events are queued in memory and flushed every 10 seconds (or when batch size is reached)
|
|
133
|
+
- On page unload, queued events are sent via `fetch` with `keepalive: true`
|
|
134
|
+
- Unflushed events are persisted to `localStorage` and restored on next page load
|
|
135
|
+
- Failed sends are retried with exponential backoff
|
|
136
|
+
- Each event gets a UUID for deduplication (server-side `ON CONFLICT DO NOTHING`)
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var h=false;function
|
|
2
|
-
exports.destroy=
|
|
1
|
+
'use strict';var h=false;function E(e){h=e;}function a(e,...t){h&&console.log(`[infer] ${e}`,...t);}function g(e,...t){h&&console.warn(`[infer] ${e}`,...t);}function w(e,...t){h&&console.error(`[infer] ${e}`,...t);}var I="infer_event_queue",p=1e3,i=[];function _(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function T(e){i.length>=p&&(g("Queue full, dropping oldest event"),i.shift()),i.push(e),a(`Queued event: ${e.event_name} (${i.length} in queue)`);}function S(e){return i.splice(0,e)}function m(){return i.length}function l(e){i=[...e,...i],i.length>p&&(i=i.slice(i.length-p));}function d(){let e=_();if(!(!e||i.length===0))try{e.setItem(I,JSON.stringify(i)),a("Persisted queue to localStorage:",i.length);}catch{}}function C(){let e=_();if(e)try{let t=e.getItem(I);if(t){let n=JSON.parse(t);Array.isArray(n)&&(i=[...n,...i],i.length>p&&(i=i.slice(i.length-p)),a("Restored queue from localStorage:",n.length)),e.removeItem(I);}}catch{}}var Q="0.1.0";function $(){return typeof window<"u"&&typeof document<"u"}function A(){let e={platform:"web",sdk_version:Q};if(!$())return e;typeof navigator<"u"&&(e.browser=navigator.userAgent,e.locale=navigator.language),typeof screen<"u"&&(e.screen_width=screen.width,e.screen_height=screen.height);try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone;}catch{}return e.page_url=window.location.href,e.pathname=window.location.pathname,e.page_title=document.title,e.referrer=document.referrer||void 0,e.os=q(navigator.userAgent),e.device_type=D(navigator.userAgent),e}function q(e){return /Windows/.test(e)?"Windows":/Mac OS X/.test(e)?"macOS":/Android/.test(e)?"Android":/iPhone|iPad|iPod/.test(e)?"iOS":/Linux/.test(e)?"Linux":/CrOS/.test(e)?"ChromeOS":"Unknown"}function D(e){return /Mobi|Android.*Mobile|iPhone|iPod/.test(e)?"Mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(e)?"Tablet":"Desktop"}var k="infer_anonymous_id",u=null,y=null,v={};function x(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function R(){if(u)return u;let e=x();if(e){let t=e.getItem(k);if(t)return u=t,u}if(u=crypto.randomUUID(),a("Generated anonymous_id:",u),e)try{e.setItem(k,u);}catch{}return u}function L(){return y}function N(e,t){y=e,t&&(v={...v,...t}),a("Identity set:",y,v);}function z(){y=null,v={},u=null;let e=x();if(e)try{e.removeItem(k);}catch{}}var O="infer_session_last_active";var U={pageView:true,session:true,click:true,formSubmit:true,error:true};function j(e){return e===false?null:e===true?{...U}:{...U,...e}}function M(e,t){if(typeof window>"u")return ()=>{};let n=[];return t.session&&B(e),t.pageView&&n.push(F(e)),t.click&&n.push(Y(e)),t.formSubmit&&n.push(V(e)),t.error&&n.push(H(e)),()=>{for(let r of n)r();}}function B(e){try{let t=Date.now(),n=sessionStorage.getItem(O);(!n||t-Number(n)>18e5)&&e.trackInternal("session_start",{}),sessionStorage.setItem(O,String(t));}catch{}}function F(e){e.trackInternal("page_view",{url:window.location.href,path:window.location.pathname,title:document.title});let t=history.pushState.bind(history),n=history.replaceState.bind(history),r=()=>{e.trackInternal("page_view",{url:window.location.href,path:window.location.pathname,title:document.title});};return history.pushState=function(...o){t(...o),r();},history.replaceState=function(...o){n(...o),r();},window.addEventListener("popstate",r),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",r);}}function Y(e){let t=n=>{let r=n.target;if(!r)return;let o=r.closest("a, button, [role='button'], input[type='submit']");if(!o)return;let c={tag:o.tagName.toLowerCase()};o.id&&(c.element_id=o.id),o.className&&typeof o.className=="string"&&(c.element_class=o.className),o.tagName==="A"&&(c.href=o.href),e.trackInternal("click",c);};return document.addEventListener("click",t,{capture:true}),()=>document.removeEventListener("click",t,{capture:true})}function V(e){let t=n=>{let r=n.target;if(!r)return;let o={};r.id&&(o.form_id=r.id),r.action&&(o.form_action=r.action),r.method&&(o.form_method=r.method.toUpperCase()),e.trackInternal("form_submit",o);};return document.addEventListener("submit",t,{capture:true}),()=>document.removeEventListener("submit",t,{capture:true})}function H(e){let t=r=>{e.trackInternal("error",{message:r.message||"Unknown error",filename:r.filename||null,lineno:r.lineno||null,colno:r.colno||null});},n=r=>{let o=r.reason instanceof Error?r.reason.message:typeof r.reason=="string"?r.reason:"Unhandled promise rejection";e.trackInternal("error",{message:o,type:"unhandledrejection"});};return window.addEventListener("error",t),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",t),window.removeEventListener("unhandledrejection",n);}}var J="https://api.infer.events",K=20,X=1e4,Z=3e4,W=1e3,P=5,b=class{config;flushTimer=null;teardownAutoTrack=null;flushing=false;retryCount=0;disabled=false;constructor(t){if(!t.projectId||typeof t.projectId!="string")throw new Error("[infer] projectId is required");if(E(t.debug??false),this.config={projectId:t.projectId,endpoint:t.endpoint??J,batchSize:t.batchSize??K,flushInterval:t.flushInterval??X},a("Initialized with config:",this.config),C(),this.flushTimer=setInterval(()=>{this.flush();},this.config.flushInterval),typeof window<"u"){let r=()=>{d(),this.sendBeacon();};window.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&r();}),window.addEventListener("pagehide",r);}let n=j(t.autoTrack??false);n&&(this.teardownAutoTrack=M(this,n));}track(t,n){this.enqueueEvent("track",t,n??{});}identify(t,n){N(t,n),this.enqueueEvent("identify","identify",n??{});}page(t){let n={};t&&(n.name=t),typeof window<"u"&&(n.url=window.location.href,n.path=window.location.pathname,n.title=document.title),this.enqueueEvent("page","page_view",n);}screen(t){this.enqueueEvent("screen","screen_view",{name:t});}trackInternal(t,n){this.enqueueEvent("track",t,n);}async flush(){if(this.disabled||this.flushing||m()===0)return;this.flushing=true;let t=S(this.config.batchSize);a(`Flushing ${t.length} events`);try{let n=await fetch(`${this.config.endpoint}/v1/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.projectId}`},body:JSON.stringify({events:t})});n.ok?(this.retryCount=0,a(`Flushed ${t.length} events successfully`)):n.status>=500?(g(`Server error ${n.status}, will retry`),l(t),this.scheduleRetry()):w(`Client error ${n.status}, dropping batch`);}catch(n){if(this.retryCount>=P){w(`Cannot connect to ${this.config.endpoint} after ${P} attempts. If your site uses a Content Security Policy, add ${this.config.endpoint} to connect-src. Events will be dropped until the page is reloaded.`),this.disabled=true;return}g("Network error, will retry:",n),l(t),this.scheduleRetry();}finally{this.flushing=false;}m()>0&&this.flush();}destroy(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.teardownAutoTrack&&(this.teardownAutoTrack(),this.teardownAutoTrack=null),d();}enqueueEvent(t,n,r){let o={event_id:crypto.randomUUID(),project_id:this.config.projectId,anonymous_id:R(),event_name:n,event_type:t,properties:r,context:A(),timestamp:new Date().toISOString()},c=L();c&&(o.user_id=c),T(o),m()>=this.config.batchSize&&this.flush();}sendBeacon(){let t=S(this.config.batchSize);if(t.length!==0)try{fetch(`${this.config.endpoint}/v1/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.projectId}`},body:JSON.stringify({events:t}),keepalive:!0}).then(n=>{n.ok?a(`Beacon sent ${t.length} events`):(l(t),d());}).catch(()=>{l(t),d();});}catch{l(t),d();}}scheduleRetry(){this.retryCount++;let t=Math.min(W*Math.pow(2,this.retryCount-1)+Math.random()*1e3,Z);a(`Retry #${this.retryCount} in ${Math.round(t)}ms`),setTimeout(()=>{this.flush();},t);}};var s=null,f=[];function ge(e){s&&s.destroy(),s=new b(e);for(let t of f)switch(t.type){case "track":s.track(...t.args);break;case "identify":s.identify(...t.args);break;case "page":s.page(...t.args);break;case "screen":s.screen(...t.args);break}return f=[],s}function pe(e,t){if(!s){f.push({type:"track",args:[e,t]});return}s.track(e,t);}function he(e,t){if(!s){f.push({type:"identify",args:[e,t]});return}s.identify(e,t);}function me(e){if(!s){f.push({type:"page",args:[e]});return}s.page(e);}function ve(e){if(!s){f.push({type:"screen",args:[e]});return}s.screen(e);}async function ye(){s&&await s.flush();}function be(){s&&(s.destroy(),s=null);}
|
|
2
|
+
exports.destroy=be;exports.flush=ye;exports.identify=he;exports.init=ge;exports.page=me;exports.reset=z;exports.screen=ve;exports.track=pe;
|
package/dist/index.d.cts
CHANGED
|
@@ -20,6 +20,7 @@ declare class InferClient {
|
|
|
20
20
|
private teardownAutoTrack;
|
|
21
21
|
private flushing;
|
|
22
22
|
private retryCount;
|
|
23
|
+
private disabled;
|
|
23
24
|
constructor(config: InferConfig);
|
|
24
25
|
track(eventName: string, properties?: Record<string, string | number | boolean | null>): void;
|
|
25
26
|
identify(newUserId: string, traits?: Record<string, string | number | boolean | null>): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ declare class InferClient {
|
|
|
20
20
|
private teardownAutoTrack;
|
|
21
21
|
private flushing;
|
|
22
22
|
private retryCount;
|
|
23
|
+
private disabled;
|
|
23
24
|
constructor(config: InferConfig);
|
|
24
25
|
track(eventName: string, properties?: Record<string, string | number | boolean | null>): void;
|
|
25
26
|
identify(newUserId: string, traits?: Record<string, string | number | boolean | null>): void;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var h=false;function
|
|
2
|
-
export{
|
|
1
|
+
var h=false;function E(e){h=e;}function a(e,...t){h&&console.log(`[infer] ${e}`,...t);}function g(e,...t){h&&console.warn(`[infer] ${e}`,...t);}function w(e,...t){h&&console.error(`[infer] ${e}`,...t);}var I="infer_event_queue",p=1e3,i=[];function _(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function T(e){i.length>=p&&(g("Queue full, dropping oldest event"),i.shift()),i.push(e),a(`Queued event: ${e.event_name} (${i.length} in queue)`);}function S(e){return i.splice(0,e)}function m(){return i.length}function l(e){i=[...e,...i],i.length>p&&(i=i.slice(i.length-p));}function d(){let e=_();if(!(!e||i.length===0))try{e.setItem(I,JSON.stringify(i)),a("Persisted queue to localStorage:",i.length);}catch{}}function C(){let e=_();if(e)try{let t=e.getItem(I);if(t){let n=JSON.parse(t);Array.isArray(n)&&(i=[...n,...i],i.length>p&&(i=i.slice(i.length-p)),a("Restored queue from localStorage:",n.length)),e.removeItem(I);}}catch{}}var Q="0.1.0";function $(){return typeof window<"u"&&typeof document<"u"}function A(){let e={platform:"web",sdk_version:Q};if(!$())return e;typeof navigator<"u"&&(e.browser=navigator.userAgent,e.locale=navigator.language),typeof screen<"u"&&(e.screen_width=screen.width,e.screen_height=screen.height);try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone;}catch{}return e.page_url=window.location.href,e.pathname=window.location.pathname,e.page_title=document.title,e.referrer=document.referrer||void 0,e.os=q(navigator.userAgent),e.device_type=D(navigator.userAgent),e}function q(e){return /Windows/.test(e)?"Windows":/Mac OS X/.test(e)?"macOS":/Android/.test(e)?"Android":/iPhone|iPad|iPod/.test(e)?"iOS":/Linux/.test(e)?"Linux":/CrOS/.test(e)?"ChromeOS":"Unknown"}function D(e){return /Mobi|Android.*Mobile|iPhone|iPod/.test(e)?"Mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(e)?"Tablet":"Desktop"}var k="infer_anonymous_id",u=null,y=null,v={};function x(){try{return typeof localStorage<"u"?localStorage:null}catch{return null}}function R(){if(u)return u;let e=x();if(e){let t=e.getItem(k);if(t)return u=t,u}if(u=crypto.randomUUID(),a("Generated anonymous_id:",u),e)try{e.setItem(k,u);}catch{}return u}function L(){return y}function N(e,t){y=e,t&&(v={...v,...t}),a("Identity set:",y,v);}function z(){y=null,v={},u=null;let e=x();if(e)try{e.removeItem(k);}catch{}}var O="infer_session_last_active";var U={pageView:true,session:true,click:true,formSubmit:true,error:true};function j(e){return e===false?null:e===true?{...U}:{...U,...e}}function M(e,t){if(typeof window>"u")return ()=>{};let n=[];return t.session&&B(e),t.pageView&&n.push(F(e)),t.click&&n.push(Y(e)),t.formSubmit&&n.push(V(e)),t.error&&n.push(H(e)),()=>{for(let r of n)r();}}function B(e){try{let t=Date.now(),n=sessionStorage.getItem(O);(!n||t-Number(n)>18e5)&&e.trackInternal("session_start",{}),sessionStorage.setItem(O,String(t));}catch{}}function F(e){e.trackInternal("page_view",{url:window.location.href,path:window.location.pathname,title:document.title});let t=history.pushState.bind(history),n=history.replaceState.bind(history),r=()=>{e.trackInternal("page_view",{url:window.location.href,path:window.location.pathname,title:document.title});};return history.pushState=function(...o){t(...o),r();},history.replaceState=function(...o){n(...o),r();},window.addEventListener("popstate",r),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",r);}}function Y(e){let t=n=>{let r=n.target;if(!r)return;let o=r.closest("a, button, [role='button'], input[type='submit']");if(!o)return;let c={tag:o.tagName.toLowerCase()};o.id&&(c.element_id=o.id),o.className&&typeof o.className=="string"&&(c.element_class=o.className),o.tagName==="A"&&(c.href=o.href),e.trackInternal("click",c);};return document.addEventListener("click",t,{capture:true}),()=>document.removeEventListener("click",t,{capture:true})}function V(e){let t=n=>{let r=n.target;if(!r)return;let o={};r.id&&(o.form_id=r.id),r.action&&(o.form_action=r.action),r.method&&(o.form_method=r.method.toUpperCase()),e.trackInternal("form_submit",o);};return document.addEventListener("submit",t,{capture:true}),()=>document.removeEventListener("submit",t,{capture:true})}function H(e){let t=r=>{e.trackInternal("error",{message:r.message||"Unknown error",filename:r.filename||null,lineno:r.lineno||null,colno:r.colno||null});},n=r=>{let o=r.reason instanceof Error?r.reason.message:typeof r.reason=="string"?r.reason:"Unhandled promise rejection";e.trackInternal("error",{message:o,type:"unhandledrejection"});};return window.addEventListener("error",t),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",t),window.removeEventListener("unhandledrejection",n);}}var J="https://api.infer.events",K=20,X=1e4,Z=3e4,W=1e3,P=5,b=class{config;flushTimer=null;teardownAutoTrack=null;flushing=false;retryCount=0;disabled=false;constructor(t){if(!t.projectId||typeof t.projectId!="string")throw new Error("[infer] projectId is required");if(E(t.debug??false),this.config={projectId:t.projectId,endpoint:t.endpoint??J,batchSize:t.batchSize??K,flushInterval:t.flushInterval??X},a("Initialized with config:",this.config),C(),this.flushTimer=setInterval(()=>{this.flush();},this.config.flushInterval),typeof window<"u"){let r=()=>{d(),this.sendBeacon();};window.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&r();}),window.addEventListener("pagehide",r);}let n=j(t.autoTrack??false);n&&(this.teardownAutoTrack=M(this,n));}track(t,n){this.enqueueEvent("track",t,n??{});}identify(t,n){N(t,n),this.enqueueEvent("identify","identify",n??{});}page(t){let n={};t&&(n.name=t),typeof window<"u"&&(n.url=window.location.href,n.path=window.location.pathname,n.title=document.title),this.enqueueEvent("page","page_view",n);}screen(t){this.enqueueEvent("screen","screen_view",{name:t});}trackInternal(t,n){this.enqueueEvent("track",t,n);}async flush(){if(this.disabled||this.flushing||m()===0)return;this.flushing=true;let t=S(this.config.batchSize);a(`Flushing ${t.length} events`);try{let n=await fetch(`${this.config.endpoint}/v1/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.projectId}`},body:JSON.stringify({events:t})});n.ok?(this.retryCount=0,a(`Flushed ${t.length} events successfully`)):n.status>=500?(g(`Server error ${n.status}, will retry`),l(t),this.scheduleRetry()):w(`Client error ${n.status}, dropping batch`);}catch(n){if(this.retryCount>=P){w(`Cannot connect to ${this.config.endpoint} after ${P} attempts. If your site uses a Content Security Policy, add ${this.config.endpoint} to connect-src. Events will be dropped until the page is reloaded.`),this.disabled=true;return}g("Network error, will retry:",n),l(t),this.scheduleRetry();}finally{this.flushing=false;}m()>0&&this.flush();}destroy(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.teardownAutoTrack&&(this.teardownAutoTrack(),this.teardownAutoTrack=null),d();}enqueueEvent(t,n,r){let o={event_id:crypto.randomUUID(),project_id:this.config.projectId,anonymous_id:R(),event_name:n,event_type:t,properties:r,context:A(),timestamp:new Date().toISOString()},c=L();c&&(o.user_id=c),T(o),m()>=this.config.batchSize&&this.flush();}sendBeacon(){let t=S(this.config.batchSize);if(t.length!==0)try{fetch(`${this.config.endpoint}/v1/events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.projectId}`},body:JSON.stringify({events:t}),keepalive:!0}).then(n=>{n.ok?a(`Beacon sent ${t.length} events`):(l(t),d());}).catch(()=>{l(t),d();});}catch{l(t),d();}}scheduleRetry(){this.retryCount++;let t=Math.min(W*Math.pow(2,this.retryCount-1)+Math.random()*1e3,Z);a(`Retry #${this.retryCount} in ${Math.round(t)}ms`),setTimeout(()=>{this.flush();},t);}};var s=null,f=[];function ge(e){s&&s.destroy(),s=new b(e);for(let t of f)switch(t.type){case "track":s.track(...t.args);break;case "identify":s.identify(...t.args);break;case "page":s.page(...t.args);break;case "screen":s.screen(...t.args);break}return f=[],s}function pe(e,t){if(!s){f.push({type:"track",args:[e,t]});return}s.track(e,t);}function he(e,t){if(!s){f.push({type:"identify",args:[e,t]});return}s.identify(e,t);}function me(e){if(!s){f.push({type:"page",args:[e]});return}s.page(e);}function ve(e){if(!s){f.push({type:"screen",args:[e]});return}s.screen(e);}async function ye(){s&&await s.flush();}function be(){s&&(s.destroy(),s=null);}
|
|
2
|
+
export{be as destroy,ye as flush,he as identify,ge as init,me as page,z as reset,ve as screen,pe as track};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inferevents/sdk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Event collection SDK for Infer — analytics designed for AI agents, not dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"dist"
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md"
|
|
23
24
|
],
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "tsup",
|