@simple-product/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +175 -0
- package/dist/chunk-7F2GKQLH.mjs +216 -0
- package/dist/index.d.mts +85 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +241 -0
- package/dist/index.mjs +10 -0
- package/dist/react.d.mts +82 -0
- package/dist/react.d.ts +82 -0
- package/dist/react.js +313 -0
- package/dist/react.mjs +80 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# @simple-product/sdk
|
|
2
|
+
|
|
3
|
+
Track users and product usage with Simple Product.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @simple-product/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { SimpleProduct } from '@simple-product/sdk';
|
|
15
|
+
|
|
16
|
+
// Initialize once in your app
|
|
17
|
+
const sp = new SimpleProduct({
|
|
18
|
+
apiKey: 'sk_your_api_key',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Identify users when they sign in
|
|
22
|
+
sp.identify({
|
|
23
|
+
userId: user.id,
|
|
24
|
+
email: user.email,
|
|
25
|
+
name: user.name,
|
|
26
|
+
company: user.company,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// That's it! Analytics are now tracked automatically.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## How It Works
|
|
33
|
+
|
|
34
|
+
The SDK automatically sends a **heartbeat event once per day** per user. This single event powers:
|
|
35
|
+
|
|
36
|
+
- **DAU/WAU/MAU** - Daily, weekly, monthly active users
|
|
37
|
+
- **Retention** - Cohort retention analysis
|
|
38
|
+
- **Stickiness** - DAU/MAU engagement ratio
|
|
39
|
+
|
|
40
|
+
No configuration needed. Just identify your users and analytics happen automatically.
|
|
41
|
+
|
|
42
|
+
## API Reference
|
|
43
|
+
|
|
44
|
+
### `new SimpleProduct(config)`
|
|
45
|
+
|
|
46
|
+
Create a new SDK instance.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const sp = new SimpleProduct({
|
|
50
|
+
apiKey: 'sk_your_api_key', // Required
|
|
51
|
+
endpoint: 'https://...', // Optional, defaults to production
|
|
52
|
+
disableAutoHeartbeat: false, // Optional, disable auto-tracking
|
|
53
|
+
debug: false, // Optional, enable console logging
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `sp.identify(params)`
|
|
58
|
+
|
|
59
|
+
Identify a user. Call this when a user signs in.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
sp.identify({
|
|
63
|
+
userId: 'user_123', // Required - your internal user ID
|
|
64
|
+
email: 'user@example.com', // Optional
|
|
65
|
+
name: 'Jane Doe', // Optional
|
|
66
|
+
company: 'Acme Inc', // Optional
|
|
67
|
+
traits: { // Optional - any additional data
|
|
68
|
+
plan: 'pro',
|
|
69
|
+
role: 'admin',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `sp.track(event, properties?)`
|
|
75
|
+
|
|
76
|
+
Track a custom event.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
sp.track('feature_used', {
|
|
80
|
+
feature: 'export_report',
|
|
81
|
+
format: 'csv',
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `sp.reset()`
|
|
86
|
+
|
|
87
|
+
Reset the user. Call this when a user signs out.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
sp.reset();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `sp.destroy()`
|
|
94
|
+
|
|
95
|
+
Clean up SDK resources. Call this if you need to remove the SDK.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
sp.destroy();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## React Integration (Recommended)
|
|
102
|
+
|
|
103
|
+
The easiest way to integrate is with our React provider:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
// app/providers.tsx
|
|
107
|
+
'use client';
|
|
108
|
+
|
|
109
|
+
import { SimpleProductProvider } from '@simple-product/sdk/react';
|
|
110
|
+
|
|
111
|
+
export function Providers({ children, user }) {
|
|
112
|
+
return (
|
|
113
|
+
<SimpleProductProvider
|
|
114
|
+
apiKey={process.env.NEXT_PUBLIC_SP_API_KEY!}
|
|
115
|
+
user={user ? {
|
|
116
|
+
id: user.id,
|
|
117
|
+
email: user.email,
|
|
118
|
+
name: user.name,
|
|
119
|
+
} : null}
|
|
120
|
+
>
|
|
121
|
+
{children}
|
|
122
|
+
</SimpleProductProvider>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The provider automatically:
|
|
128
|
+
- Calls `identify()` when user changes
|
|
129
|
+
- Sends heartbeats once per day
|
|
130
|
+
- Resets on logout
|
|
131
|
+
|
|
132
|
+
### Track Custom Events
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { useSimpleProduct } from '@simple-product/sdk/react';
|
|
136
|
+
|
|
137
|
+
function MyComponent() {
|
|
138
|
+
const { track } = useSimpleProduct();
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<button onClick={() => track('button_clicked', { button: 'signup' })}>
|
|
142
|
+
Sign Up
|
|
143
|
+
</button>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Manual Setup
|
|
149
|
+
|
|
150
|
+
If you're not using React, you can use the SDK directly:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { SimpleProduct } from '@simple-product/sdk';
|
|
154
|
+
|
|
155
|
+
const sp = new SimpleProduct({
|
|
156
|
+
apiKey: process.env.NEXT_PUBLIC_SP_API_KEY!,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// When user logs in
|
|
160
|
+
sp.identify({
|
|
161
|
+
userId: user.id,
|
|
162
|
+
email: user.email,
|
|
163
|
+
name: user.name,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Track custom events
|
|
167
|
+
sp.track('feature_used', { feature: 'export' });
|
|
168
|
+
|
|
169
|
+
// On logout
|
|
170
|
+
sp.reset();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var STORAGE_KEY_PREFIX = "sp_sdk_";
|
|
3
|
+
var HEARTBEAT_STORAGE_KEY = `${STORAGE_KEY_PREFIX}last_heartbeat`;
|
|
4
|
+
var USER_ID_STORAGE_KEY = `${STORAGE_KEY_PREFIX}user_id`;
|
|
5
|
+
var ANONYMOUS_ID_STORAGE_KEY = `${STORAGE_KEY_PREFIX}anonymous_id`;
|
|
6
|
+
var SimpleProduct = class {
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.userId = null;
|
|
9
|
+
this.heartbeatInterval = null;
|
|
10
|
+
this.visibilityHandler = null;
|
|
11
|
+
this.apiKey = config.apiKey;
|
|
12
|
+
this.endpoint = config.endpoint || "https://simpleproduct.io/api/v1";
|
|
13
|
+
this.debug = config.debug || false;
|
|
14
|
+
this.disableAutoHeartbeat = config.disableAutoHeartbeat || false;
|
|
15
|
+
this.anonymousId = this.getOrCreateAnonymousId();
|
|
16
|
+
this.userId = this.getStoredUserId();
|
|
17
|
+
if (!this.disableAutoHeartbeat && typeof window !== "undefined") {
|
|
18
|
+
this.startHeartbeat();
|
|
19
|
+
}
|
|
20
|
+
this.log("Initialized", { userId: this.userId, anonymousId: this.anonymousId });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Identify a user - call this when a user signs in
|
|
24
|
+
*/
|
|
25
|
+
identify(params) {
|
|
26
|
+
this.userId = params.userId;
|
|
27
|
+
this.storeUserId(params.userId);
|
|
28
|
+
this.log("Identify", params);
|
|
29
|
+
this.sendRequest("/people", {
|
|
30
|
+
method: "POST",
|
|
31
|
+
body: {
|
|
32
|
+
externalId: params.userId,
|
|
33
|
+
email: params.email,
|
|
34
|
+
name: params.name,
|
|
35
|
+
company: params.company,
|
|
36
|
+
...params.traits
|
|
37
|
+
}
|
|
38
|
+
}).catch((err) => this.log("Identify error", err));
|
|
39
|
+
this.sendHeartbeat();
|
|
40
|
+
}
|
|
41
|
+
track(eventOrParams, properties) {
|
|
42
|
+
const event = typeof eventOrParams === "string" ? eventOrParams : eventOrParams.event;
|
|
43
|
+
const props = typeof eventOrParams === "string" ? properties : eventOrParams.properties;
|
|
44
|
+
this.log("Track", { event, properties: props });
|
|
45
|
+
this.sendRequest("/events", {
|
|
46
|
+
method: "POST",
|
|
47
|
+
body: {
|
|
48
|
+
event,
|
|
49
|
+
userId: this.userId,
|
|
50
|
+
anonymousId: this.anonymousId,
|
|
51
|
+
properties: props,
|
|
52
|
+
context: this.getContext()
|
|
53
|
+
}
|
|
54
|
+
}).catch((err) => this.log("Track error", err));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Reset the user - call this when a user signs out
|
|
58
|
+
*/
|
|
59
|
+
reset() {
|
|
60
|
+
this.userId = null;
|
|
61
|
+
this.clearStoredUserId();
|
|
62
|
+
this.anonymousId = this.generateAnonymousId();
|
|
63
|
+
this.storeAnonymousId(this.anonymousId);
|
|
64
|
+
this.log("Reset");
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Manually send a heartbeat (usually not needed - happens automatically)
|
|
68
|
+
*/
|
|
69
|
+
heartbeat() {
|
|
70
|
+
this.sendHeartbeat();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Clean up SDK resources
|
|
74
|
+
*/
|
|
75
|
+
destroy() {
|
|
76
|
+
if (this.heartbeatInterval) {
|
|
77
|
+
clearInterval(this.heartbeatInterval);
|
|
78
|
+
this.heartbeatInterval = null;
|
|
79
|
+
}
|
|
80
|
+
if (this.visibilityHandler && typeof document !== "undefined") {
|
|
81
|
+
document.removeEventListener("visibilitychange", this.visibilityHandler);
|
|
82
|
+
this.visibilityHandler = null;
|
|
83
|
+
}
|
|
84
|
+
this.log("Destroyed");
|
|
85
|
+
}
|
|
86
|
+
// --- Private methods ---
|
|
87
|
+
startHeartbeat() {
|
|
88
|
+
this.sendHeartbeatIfNeeded();
|
|
89
|
+
this.heartbeatInterval = setInterval(() => {
|
|
90
|
+
this.sendHeartbeatIfNeeded();
|
|
91
|
+
}, 5 * 60 * 1e3);
|
|
92
|
+
this.visibilityHandler = () => {
|
|
93
|
+
if (document.visibilityState === "visible") {
|
|
94
|
+
this.sendHeartbeatIfNeeded();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
98
|
+
}
|
|
99
|
+
sendHeartbeatIfNeeded() {
|
|
100
|
+
if (!this.userId) {
|
|
101
|
+
this.log("Skipping heartbeat - no user identified");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const today = this.getTodayString();
|
|
105
|
+
const lastHeartbeat = this.getLastHeartbeatDate();
|
|
106
|
+
if (lastHeartbeat === today) {
|
|
107
|
+
this.log("Skipping heartbeat - already sent today");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this.sendHeartbeat();
|
|
111
|
+
}
|
|
112
|
+
sendHeartbeat() {
|
|
113
|
+
if (!this.userId) {
|
|
114
|
+
this.log("Cannot send heartbeat - no user identified");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const today = this.getTodayString();
|
|
118
|
+
this.log("Sending heartbeat");
|
|
119
|
+
this.sendRequest("/events", {
|
|
120
|
+
method: "POST",
|
|
121
|
+
body: {
|
|
122
|
+
event: "sp_heartbeat",
|
|
123
|
+
userId: this.userId,
|
|
124
|
+
anonymousId: this.anonymousId,
|
|
125
|
+
context: this.getContext()
|
|
126
|
+
}
|
|
127
|
+
}).then(() => {
|
|
128
|
+
this.storeLastHeartbeatDate(today);
|
|
129
|
+
this.log("Heartbeat sent successfully");
|
|
130
|
+
}).catch((err) => this.log("Heartbeat error", err));
|
|
131
|
+
}
|
|
132
|
+
async sendRequest(path, options) {
|
|
133
|
+
const url = `${this.endpoint}${path}`;
|
|
134
|
+
const response = await fetch(url, {
|
|
135
|
+
method: options.method,
|
|
136
|
+
headers: {
|
|
137
|
+
"Content-Type": "application/json",
|
|
138
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
139
|
+
},
|
|
140
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
const error = await response.text();
|
|
144
|
+
throw new Error(`API error: ${response.status} ${error}`);
|
|
145
|
+
}
|
|
146
|
+
return response.json();
|
|
147
|
+
}
|
|
148
|
+
getContext() {
|
|
149
|
+
if (typeof window === "undefined") {
|
|
150
|
+
return {};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
userAgent: navigator.userAgent,
|
|
154
|
+
page: {
|
|
155
|
+
url: window.location.href,
|
|
156
|
+
title: document.title,
|
|
157
|
+
referrer: document.referrer
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
getTodayString() {
|
|
162
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
163
|
+
}
|
|
164
|
+
getLastHeartbeatDate() {
|
|
165
|
+
if (typeof localStorage === "undefined") return null;
|
|
166
|
+
return localStorage.getItem(HEARTBEAT_STORAGE_KEY);
|
|
167
|
+
}
|
|
168
|
+
storeLastHeartbeatDate(date) {
|
|
169
|
+
if (typeof localStorage === "undefined") return;
|
|
170
|
+
localStorage.setItem(HEARTBEAT_STORAGE_KEY, date);
|
|
171
|
+
}
|
|
172
|
+
getStoredUserId() {
|
|
173
|
+
if (typeof localStorage === "undefined") return null;
|
|
174
|
+
return localStorage.getItem(USER_ID_STORAGE_KEY);
|
|
175
|
+
}
|
|
176
|
+
storeUserId(userId) {
|
|
177
|
+
if (typeof localStorage === "undefined") return;
|
|
178
|
+
localStorage.setItem(USER_ID_STORAGE_KEY, userId);
|
|
179
|
+
}
|
|
180
|
+
clearStoredUserId() {
|
|
181
|
+
if (typeof localStorage === "undefined") return;
|
|
182
|
+
localStorage.removeItem(USER_ID_STORAGE_KEY);
|
|
183
|
+
localStorage.removeItem(HEARTBEAT_STORAGE_KEY);
|
|
184
|
+
}
|
|
185
|
+
getOrCreateAnonymousId() {
|
|
186
|
+
if (typeof localStorage === "undefined") {
|
|
187
|
+
return this.generateAnonymousId();
|
|
188
|
+
}
|
|
189
|
+
const stored = localStorage.getItem(ANONYMOUS_ID_STORAGE_KEY);
|
|
190
|
+
if (stored) return stored;
|
|
191
|
+
const id = this.generateAnonymousId();
|
|
192
|
+
this.storeAnonymousId(id);
|
|
193
|
+
return id;
|
|
194
|
+
}
|
|
195
|
+
storeAnonymousId(id) {
|
|
196
|
+
if (typeof localStorage === "undefined") return;
|
|
197
|
+
localStorage.setItem(ANONYMOUS_ID_STORAGE_KEY, id);
|
|
198
|
+
}
|
|
199
|
+
generateAnonymousId() {
|
|
200
|
+
return "anon_" + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
201
|
+
}
|
|
202
|
+
log(message, data) {
|
|
203
|
+
if (!this.debug) return;
|
|
204
|
+
console.log(`[SimpleProduct] ${message}`, data !== void 0 ? data : "");
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
function createSimpleProduct(config) {
|
|
208
|
+
return new SimpleProduct(config);
|
|
209
|
+
}
|
|
210
|
+
var index_default = SimpleProduct;
|
|
211
|
+
|
|
212
|
+
export {
|
|
213
|
+
SimpleProduct,
|
|
214
|
+
createSimpleProduct,
|
|
215
|
+
index_default
|
|
216
|
+
};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Product SDK
|
|
3
|
+
*
|
|
4
|
+
* Track users and product usage with minimal setup.
|
|
5
|
+
* Automatically sends heartbeat events (once per day) to power analytics.
|
|
6
|
+
*/
|
|
7
|
+
interface SimpleProductConfig {
|
|
8
|
+
/** Your API key (starts with sk_) */
|
|
9
|
+
apiKey: string;
|
|
10
|
+
/** API endpoint (defaults to https://simpleproduct.io/api/v1) */
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/** Disable automatic heartbeat tracking (default: false) */
|
|
13
|
+
disableAutoHeartbeat?: boolean;
|
|
14
|
+
/** Enable debug logging (default: false) */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface IdentifyParams {
|
|
18
|
+
/** Unique user ID from your system */
|
|
19
|
+
userId: string;
|
|
20
|
+
/** User's email address */
|
|
21
|
+
email?: string;
|
|
22
|
+
/** User's display name */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** Company/organization name */
|
|
25
|
+
company?: string;
|
|
26
|
+
/** Any additional traits */
|
|
27
|
+
traits?: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
interface TrackParams {
|
|
30
|
+
/** Event name (e.g., "feature_used", "button_clicked") */
|
|
31
|
+
event: string;
|
|
32
|
+
/** Event properties */
|
|
33
|
+
properties?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
declare class SimpleProduct {
|
|
36
|
+
private apiKey;
|
|
37
|
+
private endpoint;
|
|
38
|
+
private debug;
|
|
39
|
+
private userId;
|
|
40
|
+
private anonymousId;
|
|
41
|
+
private disableAutoHeartbeat;
|
|
42
|
+
private heartbeatInterval;
|
|
43
|
+
private visibilityHandler;
|
|
44
|
+
constructor(config: SimpleProductConfig);
|
|
45
|
+
/**
|
|
46
|
+
* Identify a user - call this when a user signs in
|
|
47
|
+
*/
|
|
48
|
+
identify(params: IdentifyParams): void;
|
|
49
|
+
/**
|
|
50
|
+
* Track a custom event
|
|
51
|
+
*/
|
|
52
|
+
track(event: string, properties?: Record<string, unknown>): void;
|
|
53
|
+
track(params: TrackParams): void;
|
|
54
|
+
/**
|
|
55
|
+
* Reset the user - call this when a user signs out
|
|
56
|
+
*/
|
|
57
|
+
reset(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Manually send a heartbeat (usually not needed - happens automatically)
|
|
60
|
+
*/
|
|
61
|
+
heartbeat(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Clean up SDK resources
|
|
64
|
+
*/
|
|
65
|
+
destroy(): void;
|
|
66
|
+
private startHeartbeat;
|
|
67
|
+
private sendHeartbeatIfNeeded;
|
|
68
|
+
private sendHeartbeat;
|
|
69
|
+
private sendRequest;
|
|
70
|
+
private getContext;
|
|
71
|
+
private getTodayString;
|
|
72
|
+
private getLastHeartbeatDate;
|
|
73
|
+
private storeLastHeartbeatDate;
|
|
74
|
+
private getStoredUserId;
|
|
75
|
+
private storeUserId;
|
|
76
|
+
private clearStoredUserId;
|
|
77
|
+
private getOrCreateAnonymousId;
|
|
78
|
+
private storeAnonymousId;
|
|
79
|
+
private generateAnonymousId;
|
|
80
|
+
private log;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare function createSimpleProduct(config: SimpleProductConfig): SimpleProduct;
|
|
84
|
+
|
|
85
|
+
export { type IdentifyParams, SimpleProduct, type SimpleProductConfig, type TrackParams, createSimpleProduct, SimpleProduct as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Product SDK
|
|
3
|
+
*
|
|
4
|
+
* Track users and product usage with minimal setup.
|
|
5
|
+
* Automatically sends heartbeat events (once per day) to power analytics.
|
|
6
|
+
*/
|
|
7
|
+
interface SimpleProductConfig {
|
|
8
|
+
/** Your API key (starts with sk_) */
|
|
9
|
+
apiKey: string;
|
|
10
|
+
/** API endpoint (defaults to https://simpleproduct.io/api/v1) */
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/** Disable automatic heartbeat tracking (default: false) */
|
|
13
|
+
disableAutoHeartbeat?: boolean;
|
|
14
|
+
/** Enable debug logging (default: false) */
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface IdentifyParams {
|
|
18
|
+
/** Unique user ID from your system */
|
|
19
|
+
userId: string;
|
|
20
|
+
/** User's email address */
|
|
21
|
+
email?: string;
|
|
22
|
+
/** User's display name */
|
|
23
|
+
name?: string;
|
|
24
|
+
/** Company/organization name */
|
|
25
|
+
company?: string;
|
|
26
|
+
/** Any additional traits */
|
|
27
|
+
traits?: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
interface TrackParams {
|
|
30
|
+
/** Event name (e.g., "feature_used", "button_clicked") */
|
|
31
|
+
event: string;
|
|
32
|
+
/** Event properties */
|
|
33
|
+
properties?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
declare class SimpleProduct {
|
|
36
|
+
private apiKey;
|
|
37
|
+
private endpoint;
|
|
38
|
+
private debug;
|
|
39
|
+
private userId;
|
|
40
|
+
private anonymousId;
|
|
41
|
+
private disableAutoHeartbeat;
|
|
42
|
+
private heartbeatInterval;
|
|
43
|
+
private visibilityHandler;
|
|
44
|
+
constructor(config: SimpleProductConfig);
|
|
45
|
+
/**
|
|
46
|
+
* Identify a user - call this when a user signs in
|
|
47
|
+
*/
|
|
48
|
+
identify(params: IdentifyParams): void;
|
|
49
|
+
/**
|
|
50
|
+
* Track a custom event
|
|
51
|
+
*/
|
|
52
|
+
track(event: string, properties?: Record<string, unknown>): void;
|
|
53
|
+
track(params: TrackParams): void;
|
|
54
|
+
/**
|
|
55
|
+
* Reset the user - call this when a user signs out
|
|
56
|
+
*/
|
|
57
|
+
reset(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Manually send a heartbeat (usually not needed - happens automatically)
|
|
60
|
+
*/
|
|
61
|
+
heartbeat(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Clean up SDK resources
|
|
64
|
+
*/
|
|
65
|
+
destroy(): void;
|
|
66
|
+
private startHeartbeat;
|
|
67
|
+
private sendHeartbeatIfNeeded;
|
|
68
|
+
private sendHeartbeat;
|
|
69
|
+
private sendRequest;
|
|
70
|
+
private getContext;
|
|
71
|
+
private getTodayString;
|
|
72
|
+
private getLastHeartbeatDate;
|
|
73
|
+
private storeLastHeartbeatDate;
|
|
74
|
+
private getStoredUserId;
|
|
75
|
+
private storeUserId;
|
|
76
|
+
private clearStoredUserId;
|
|
77
|
+
private getOrCreateAnonymousId;
|
|
78
|
+
private storeAnonymousId;
|
|
79
|
+
private generateAnonymousId;
|
|
80
|
+
private log;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare function createSimpleProduct(config: SimpleProductConfig): SimpleProduct;
|
|
84
|
+
|
|
85
|
+
export { type IdentifyParams, SimpleProduct, type SimpleProductConfig, type TrackParams, createSimpleProduct, SimpleProduct as default };
|