@dashgram/javascript 1.0.0 → 1.0.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 +117 -174
- package/dist/core/config.d.ts +1 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +5 -4
- package/dist/core/context.d.ts +4 -8
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +6 -17
- package/dist/core/event-queue.d.ts +4 -4
- package/dist/core/event-queue.d.ts.map +1 -1
- package/dist/dashgram.min.js +2 -0
- package/dist/dashgram.min.js.map +1 -0
- package/dist/errors.d.ts +0 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +0 -10
- package/dist/index.d.ts +3 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -32
- package/dist/trackers/base-tracker.d.ts +3 -3
- package/dist/trackers/base-tracker.d.ts.map +1 -1
- package/dist/trackers/base-tracker.js +1 -4
- package/dist/trackers/core-tracker.d.ts +3 -3
- package/dist/trackers/core-tracker.d.ts.map +1 -1
- package/dist/trackers/core-tracker.js +19 -21
- package/dist/trackers/deep-tracker.d.ts +6 -0
- package/dist/trackers/deep-tracker.d.ts.map +1 -1
- package/dist/trackers/deep-tracker.js +562 -12
- package/dist/trackers/interaction-tracker.d.ts +7 -3
- package/dist/trackers/interaction-tracker.d.ts.map +1 -1
- package/dist/trackers/interaction-tracker.js +142 -37
- package/dist/transport/batch-processor.d.ts +4 -4
- package/dist/transport/batch-processor.d.ts.map +1 -1
- package/dist/transport/batch-processor.js +8 -8
- package/dist/transport/transport.d.ts +4 -3
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/transport/transport.js +17 -24
- package/dist/types/index.d.ts +100 -25
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/device.d.ts +3 -7
- package/dist/utils/device.d.ts.map +1 -1
- package/dist/utils/device.js +19 -53
- package/dist/utils/telegram.d.ts +4 -6
- package/dist/utils/telegram.d.ts.map +1 -1
- package/dist/utils/telegram.js +45 -29
- package/package.json +9 -3
- package/dist/core/session.d.ts +0 -13
- package/dist/core/session.d.ts.map +0 -1
- package/dist/core/session.js +0 -63
package/README.md
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
# Dashgram JavaScript SDK
|
|
2
2
|
|
|
3
|
-
Analytics SDK for Telegram Mini Apps.
|
|
3
|
+
Analytics SDK for **Telegram Mini Apps**. Automatically captures user interactions and sends events to the Dashgram backend.
|
|
4
|
+
|
|
5
|
+
> ⚠️ **Important**: This SDK is designed exclusively for **Telegram Mini Apps** (WebApps).
|
|
6
|
+
> It is **NOT** for Telegram bots. For bot analytics, use the [Python SDK](../sdk-python) or [Go SDK](../go-dashgram).
|
|
4
7
|
|
|
5
8
|
## Installation
|
|
6
9
|
|
|
7
10
|
```bash
|
|
8
11
|
npm install @dashgram/javascript
|
|
12
|
+
# or
|
|
13
|
+
pnpm add @dashgram/javascript
|
|
14
|
+
# or
|
|
15
|
+
yarn add @dashgram/javascript
|
|
9
16
|
```
|
|
10
17
|
|
|
11
18
|
## Quick Start
|
|
@@ -16,241 +23,177 @@ import DashgramMini from "@dashgram/javascript"
|
|
|
16
23
|
// Initialize SDK
|
|
17
24
|
DashgramMini.init({
|
|
18
25
|
projectId: "your-project-id",
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
debug: true // for development
|
|
26
|
+
trackLevel: 2, // 1 = core, 2 = interactions, 3 = deep analytics
|
|
27
|
+
debug: true // Enable in development
|
|
22
28
|
})
|
|
23
29
|
|
|
24
30
|
// Track custom events
|
|
25
|
-
DashgramMini.track("
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
DashgramMini.track("purchase_completed", {
|
|
32
|
+
product_id: "premium-plan",
|
|
33
|
+
price: 9.99,
|
|
34
|
+
currency: "USD"
|
|
28
35
|
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
DashgramMini.
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
```typescript
|
|
41
|
+
DashgramMini.init({
|
|
42
|
+
projectId: "your-project-id", // Required
|
|
43
|
+
trackLevel: 2, // Optional: 1, 2, or 3 (default: 1)
|
|
44
|
+
debug: false, // Optional: enable console logs
|
|
45
|
+
disabled: false, // Optional: disable tracking entirely
|
|
46
|
+
batchSize: 10, // Optional: events per batch
|
|
47
|
+
flushInterval: 5000 // Optional: flush interval in ms
|
|
34
48
|
})
|
|
35
49
|
```
|
|
36
50
|
|
|
37
51
|
## Track Levels
|
|
38
52
|
|
|
39
|
-
### Level 1 — Core (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
53
|
+
### Level 1 — Core (Default)
|
|
54
|
+
|
|
55
|
+
Minimal tracking:
|
|
56
|
+
|
|
57
|
+
| Event | Description |
|
|
58
|
+
| ----------- | --------------------------------- |
|
|
59
|
+
| `app_open` | Mini App opened or became visible |
|
|
60
|
+
| `app_close` | Mini App closed or hidden |
|
|
61
|
+
|
|
62
|
+
### Level 2 — Interactions
|
|
63
|
+
|
|
64
|
+
Adds user interaction tracking:
|
|
65
|
+
|
|
66
|
+
| Event | Description |
|
|
67
|
+
| --------------------- | -------------------------------- |
|
|
68
|
+
| `screen_view` | Page/route navigation |
|
|
69
|
+
| `button_click` | Button clicks |
|
|
70
|
+
| `link_click` | Link clicks (external detection) |
|
|
71
|
+
| `form_submit` | Form submissions |
|
|
72
|
+
| `input_focus` | Input field focus |
|
|
73
|
+
| `input_change` | Input field value changed |
|
|
74
|
+
| `copy` | Text copied to clipboard |
|
|
75
|
+
| `cut` | Text cut to clipboard |
|
|
76
|
+
| `paste` | Text pasted from clipboard |
|
|
77
|
+
| `text_select` | Text selection |
|
|
78
|
+
| `js_error` | JavaScript errors |
|
|
79
|
+
| `unhandled_rejection` | Unhandled Promise rejections |
|
|
80
|
+
|
|
81
|
+
### Level 3 — Deep Analytics
|
|
82
|
+
|
|
83
|
+
Adds performance and Telegram-specific tracking:
|
|
84
|
+
|
|
85
|
+
| Event | Description |
|
|
86
|
+
| -------------------------------- | ------------------------------ |
|
|
87
|
+
| `scroll_depth` | Scroll milestone reached |
|
|
88
|
+
| `element_visible` | Tracked element became visible |
|
|
89
|
+
| `rage_click` | Rapid repeated clicks |
|
|
90
|
+
| `long_task` | JS task >50ms |
|
|
91
|
+
| `web_vital_lcp` | Largest Contentful Paint |
|
|
92
|
+
| `web_vital_fid` | First Input Delay |
|
|
93
|
+
| `web_vital_cls` | Cumulative Layout Shift |
|
|
94
|
+
| `network_status` | Online/offline status |
|
|
95
|
+
| `orientation_change` | Device orientation change |
|
|
96
|
+
| `media_play/pause/ended` | Video/audio events |
|
|
97
|
+
| `telegram_theme_changed` | Telegram theme change |
|
|
98
|
+
| `telegram_viewport_changed` | Viewport size change |
|
|
99
|
+
| `telegram_main_button_clicked` | Main button pressed |
|
|
100
|
+
| `telegram_back_button_clicked` | Back button pressed |
|
|
101
|
+
| `telegram_invoice_closed` | Invoice closed |
|
|
102
|
+
| ...and all other Telegram events | |
|
|
78
103
|
|
|
79
104
|
## API
|
|
80
105
|
|
|
81
106
|
### `DashgramMini.init(config)`
|
|
82
107
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
interface DashgramConfig {
|
|
87
|
-
projectId: string // Project ID from Dashgram dashboard
|
|
88
|
-
apiKey: string // API key for authentication
|
|
89
|
-
trackLevel?: 1 | 2 | 3 // Track level (default: 1)
|
|
90
|
-
apiUrl?: string // API endpoint URL (optional)
|
|
91
|
-
batchSize?: number // Batch size (default: 10)
|
|
92
|
-
flushInterval?: number // Flush interval in ms (default: 5000)
|
|
93
|
-
debug?: boolean // Debug mode (default: false)
|
|
94
|
-
disabled?: boolean // Disable tracking (default: false)
|
|
95
|
-
onError?: (error: DashgramError) => void // Optional error handler
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### `DashgramMini.track(event, properties?)`
|
|
100
|
-
|
|
101
|
-
Tracks a custom event.
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
DashgramMini.track("purchase_completed", {
|
|
105
|
-
product_id: "123",
|
|
106
|
-
amount: 99.99,
|
|
107
|
-
currency: "USD"
|
|
108
|
-
})
|
|
109
|
-
```
|
|
108
|
+
Initialize the SDK. Call once when your app loads.
|
|
110
109
|
|
|
111
|
-
### `DashgramMini.
|
|
110
|
+
### `DashgramMini.track(event, properties)`
|
|
112
111
|
|
|
113
|
-
|
|
112
|
+
Track a custom event.
|
|
114
113
|
|
|
115
114
|
```typescript
|
|
116
|
-
DashgramMini.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
signup_date: "2024-01-01"
|
|
115
|
+
DashgramMini.track("checkout_started", {
|
|
116
|
+
cart_value: 49.99,
|
|
117
|
+
item_count: 3
|
|
120
118
|
})
|
|
121
119
|
```
|
|
122
120
|
|
|
123
121
|
### `DashgramMini.setTrackLevel(level)`
|
|
124
122
|
|
|
125
|
-
|
|
123
|
+
Change the track level at runtime.
|
|
126
124
|
|
|
127
125
|
```typescript
|
|
128
|
-
DashgramMini.setTrackLevel(3) // Enable
|
|
126
|
+
DashgramMini.setTrackLevel(3) // Enable deep analytics
|
|
129
127
|
```
|
|
130
128
|
|
|
131
129
|
### `DashgramMini.flush()`
|
|
132
130
|
|
|
133
|
-
|
|
131
|
+
Force send all pending events.
|
|
134
132
|
|
|
135
133
|
```typescript
|
|
136
134
|
await DashgramMini.flush()
|
|
137
135
|
```
|
|
138
136
|
|
|
139
|
-
### `DashgramMini.reset()`
|
|
140
|
-
|
|
141
|
-
Resets the session and user information.
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
DashgramMini.reset()
|
|
145
|
-
```
|
|
146
|
-
|
|
147
137
|
### `DashgramMini.shutdown()`
|
|
148
138
|
|
|
149
|
-
|
|
139
|
+
Stop tracking and clean up.
|
|
150
140
|
|
|
151
141
|
```typescript
|
|
152
142
|
DashgramMini.shutdown()
|
|
153
143
|
```
|
|
154
144
|
|
|
155
|
-
##
|
|
145
|
+
## User Identification
|
|
156
146
|
|
|
157
|
-
|
|
147
|
+
User identification is handled **automatically** via Telegram's `initData`. The SDK sends the raw `initData` string with every event, allowing the backend to validate and extract user information securely.
|
|
158
148
|
|
|
159
|
-
|
|
160
|
-
<div data-track-visible="hero-banner">
|
|
161
|
-
<!-- Content -->
|
|
162
|
-
</div>
|
|
163
|
-
```
|
|
149
|
+
You do **not** need to call any identify method.
|
|
164
150
|
|
|
165
|
-
|
|
151
|
+
## How It Works
|
|
166
152
|
|
|
167
|
-
|
|
153
|
+
1. SDK captures events based on `trackLevel`
|
|
154
|
+
2. Events are batched for efficiency
|
|
155
|
+
3. Each event includes:
|
|
156
|
+
- `eventId`: UUID for deduplication
|
|
157
|
+
- `type`: Event name
|
|
158
|
+
- `initData`: Raw Telegram initData (for backend validation)
|
|
159
|
+
- `properties`: Custom event data
|
|
160
|
+
- `telemetry`: Platform, user agent, timezone, theme
|
|
161
|
+
- `timestamp`: Unix milliseconds
|
|
162
|
+
4. Events are sent to `POST /v1/{projectId}/webapp/track`
|
|
168
163
|
|
|
169
|
-
|
|
164
|
+
## TypeScript Support
|
|
170
165
|
|
|
171
|
-
|
|
172
|
-
{
|
|
173
|
-
"event": "event_name",
|
|
174
|
-
"properties": { /* custom properties */ },
|
|
175
|
-
"timestamp": "2024-01-01T12:00:00.000Z",
|
|
176
|
-
"source": "auto" | "manual",
|
|
177
|
-
"level": 1 | 2 | 3,
|
|
178
|
-
"session_id": "uuid",
|
|
179
|
-
"user_id": "telegram_user_id | null",
|
|
180
|
-
"context": {
|
|
181
|
-
"platform": "...",
|
|
182
|
-
"app_version": "...",
|
|
183
|
-
"language": "...",
|
|
184
|
-
"screen_width": 1920,
|
|
185
|
-
"screen_height": 1080,
|
|
186
|
-
"viewport_width": 1200,
|
|
187
|
-
"viewport_height": 800,
|
|
188
|
-
"user_agent": "...",
|
|
189
|
-
"timezone": "Europe/Moscow",
|
|
190
|
-
"telegram_version": "...",
|
|
191
|
-
"theme": "dark"
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## TypeScript
|
|
197
|
-
|
|
198
|
-
The SDK is written in TypeScript and includes all types:
|
|
166
|
+
Full TypeScript support with exported types:
|
|
199
167
|
|
|
200
168
|
```typescript
|
|
201
|
-
import
|
|
202
|
-
DashgramConfig,
|
|
203
|
-
EventProperties,
|
|
204
|
-
UserTraits,
|
|
205
|
-
DashgramError,
|
|
206
|
-
InvalidCredentialsError,
|
|
207
|
-
DashgramAPIError,
|
|
208
|
-
NetworkError,
|
|
209
|
-
DashgramConfigurationError
|
|
210
|
-
} from "@dashgram/javascript"
|
|
169
|
+
import type { DashgramConfig, WebAppEvent, EventProperties, TrackLevel } from "@dashgram/javascript"
|
|
211
170
|
```
|
|
212
171
|
|
|
213
172
|
## Error Handling
|
|
214
173
|
|
|
215
|
-
The SDK provides typed error classes for better error handling:
|
|
216
|
-
|
|
217
174
|
```typescript
|
|
218
|
-
import {
|
|
219
|
-
|
|
220
|
-
InvalidCredentialsError,
|
|
221
|
-
DashgramAPIError,
|
|
222
|
-
NetworkError,
|
|
223
|
-
DashgramConfigurationError
|
|
224
|
-
} from "@dashgram/javascript"
|
|
225
|
-
|
|
226
|
-
// Optional error handler callback
|
|
175
|
+
import { DashgramMini, DashgramAPIError, NetworkError } from "@dashgram/javascript"
|
|
176
|
+
|
|
227
177
|
DashgramMini.init({
|
|
228
|
-
projectId: "
|
|
229
|
-
apiKey: "yyy",
|
|
178
|
+
projectId: "your-project-id",
|
|
230
179
|
onError: error => {
|
|
231
|
-
if (error instanceof
|
|
232
|
-
console.
|
|
233
|
-
} else if (error instanceof
|
|
234
|
-
console.
|
|
235
|
-
} else if (error instanceof DashgramConfigurationError) {
|
|
236
|
-
console.error("Configuration error:", error.message)
|
|
180
|
+
if (error instanceof NetworkError) {
|
|
181
|
+
console.log("Network issue:", error.message)
|
|
182
|
+
} else if (error instanceof DashgramAPIError) {
|
|
183
|
+
console.log("API error:", error.statusCode, error.details)
|
|
237
184
|
}
|
|
238
185
|
}
|
|
239
186
|
})
|
|
240
187
|
```
|
|
241
188
|
|
|
242
|
-
##
|
|
243
|
-
|
|
244
|
-
-
|
|
245
|
-
-
|
|
246
|
-
-
|
|
247
|
-
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
- ✅ Throttling and debouncing for performance optimization
|
|
251
|
-
- ✅ Offline mode support
|
|
252
|
-
- ✅ Typed error classes
|
|
253
|
-
- ✅ Optional error handler callback
|
|
189
|
+
## Browser Support
|
|
190
|
+
|
|
191
|
+
- Chrome 64+
|
|
192
|
+
- Firefox 67+
|
|
193
|
+
- Safari 12+
|
|
194
|
+
- Edge 79+
|
|
195
|
+
|
|
196
|
+
Works in all environments that support Telegram Mini Apps.
|
|
254
197
|
|
|
255
198
|
## License
|
|
256
199
|
|
package/dist/core/config.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class Config {
|
|
|
5
5
|
private validate;
|
|
6
6
|
get<K extends keyof Required<Omit<DashgramConfig, "onError">>>(key: K): Required<Omit<DashgramConfig, "onError">>[K];
|
|
7
7
|
getOnError(): DashgramConfig["onError"];
|
|
8
|
+
getTrackUrl(): string;
|
|
8
9
|
setTrackLevel(level: TrackLevel): void;
|
|
9
10
|
getTrackLevel(): TrackLevel;
|
|
10
11
|
isDebug(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAkB1D,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAA6E;gBAE/E,UAAU,EAAE,cAAc;IAYtC,OAAO,CAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAkB1D,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAA6E;gBAE/E,UAAU,EAAE,cAAc;IAYtC,OAAO,CAAC,QAAQ;IAahB,GAAG,CAAC,CAAC,SAAS,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAOpH,UAAU,IAAI,cAAc,CAAC,SAAS,CAAC;IAOvC,WAAW,IAAI,MAAM;IAQrB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAUtC,aAAa,IAAI,UAAU;IAO3B,OAAO,IAAI,OAAO;IAOlB,UAAU,IAAI,OAAO;CAGtB"}
|
package/dist/core/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DashgramConfigurationError } from "../errors";
|
|
2
2
|
const DEFAULT_CONFIG = {
|
|
3
3
|
trackLevel: 1,
|
|
4
|
-
apiUrl: "https://api.dashgram.
|
|
4
|
+
apiUrl: "https://api.dashgram.io/v1",
|
|
5
5
|
batchSize: 10,
|
|
6
6
|
flushInterval: 5000,
|
|
7
7
|
debug: false,
|
|
@@ -19,9 +19,6 @@ export class Config {
|
|
|
19
19
|
if (!this.config.projectId) {
|
|
20
20
|
throw new DashgramConfigurationError("projectId is required");
|
|
21
21
|
}
|
|
22
|
-
if (!this.config.apiKey) {
|
|
23
|
-
throw new DashgramConfigurationError("apiKey is required");
|
|
24
|
-
}
|
|
25
22
|
if (![1, 2, 3].includes(this.config.trackLevel)) {
|
|
26
23
|
throw new DashgramConfigurationError("trackLevel must be 1, 2, or 3");
|
|
27
24
|
}
|
|
@@ -32,6 +29,10 @@ export class Config {
|
|
|
32
29
|
getOnError() {
|
|
33
30
|
return this.config.onError;
|
|
34
31
|
}
|
|
32
|
+
getTrackUrl() {
|
|
33
|
+
const baseUrl = this.config.apiUrl.replace(/\/$/, "");
|
|
34
|
+
return `${baseUrl}/${this.config.projectId}/webapp/track`;
|
|
35
|
+
}
|
|
35
36
|
setTrackLevel(level) {
|
|
36
37
|
if (![1, 2, 3].includes(level)) {
|
|
37
38
|
throw new DashgramConfigurationError("trackLevel must be 1, 2, or 3");
|
package/dist/core/context.d.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Telemetry } from "../types";
|
|
2
2
|
export declare class Context {
|
|
3
|
-
private
|
|
4
|
-
private userId;
|
|
3
|
+
private telemetry;
|
|
5
4
|
constructor();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
getUserId(): string | null;
|
|
9
|
-
setUserId(userId: string): void;
|
|
10
|
-
clearUserId(): void;
|
|
5
|
+
getTelemetry(): Telemetry;
|
|
6
|
+
updateTelemetry(): void;
|
|
11
7
|
}
|
|
12
8
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAMzC,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAW;;IAS5B,YAAY,IAAI,SAAS;IAOzB,eAAe,IAAI,IAAI;CAGxB"}
|
package/dist/core/context.js
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getTelegramUserId } from '../utils/telegram';
|
|
1
|
+
import { getTelemetry } from "../utils/device";
|
|
3
2
|
export class Context {
|
|
4
3
|
constructor() {
|
|
5
|
-
this.
|
|
6
|
-
this.userId = getTelegramUserId();
|
|
4
|
+
this.telemetry = getTelemetry();
|
|
7
5
|
}
|
|
8
|
-
|
|
9
|
-
return { ...this.
|
|
6
|
+
getTelemetry() {
|
|
7
|
+
return { ...this.telemetry };
|
|
10
8
|
}
|
|
11
|
-
|
|
12
|
-
this.
|
|
13
|
-
}
|
|
14
|
-
getUserId() {
|
|
15
|
-
return this.userId;
|
|
16
|
-
}
|
|
17
|
-
setUserId(userId) {
|
|
18
|
-
this.userId = userId;
|
|
19
|
-
}
|
|
20
|
-
clearUserId() {
|
|
21
|
-
this.userId = null;
|
|
9
|
+
updateTelemetry() {
|
|
10
|
+
this.telemetry = getTelemetry();
|
|
22
11
|
}
|
|
23
12
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { WebAppEvent } from "../types";
|
|
2
2
|
export declare class EventQueue {
|
|
3
3
|
private queue;
|
|
4
4
|
private maxSize;
|
|
5
5
|
constructor(maxSize?: number);
|
|
6
|
-
enqueue(event:
|
|
7
|
-
flush():
|
|
8
|
-
peek():
|
|
6
|
+
enqueue(event: WebAppEvent): void;
|
|
7
|
+
flush(): WebAppEvent[];
|
|
8
|
+
peek(): WebAppEvent[];
|
|
9
9
|
size(): number;
|
|
10
10
|
isEmpty(): boolean;
|
|
11
11
|
clear(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../src/core/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../src/core/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAK3C,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,OAAO,CAAQ;gBAEX,OAAO,GAAE,MAAY;IAOjC,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAYjC,KAAK,IAAI,WAAW,EAAE;IAStB,IAAI,IAAI,WAAW,EAAE;IAOrB,IAAI,IAAI,MAAM;IAOd,OAAO,IAAI,OAAO;IAOlB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).DashgramMini={})}(this,function(e){"use strict";class t extends Error{constructor(e){super(e),this.name="DashgramError";const s=Error;"function"==typeof s.captureStackTrace&&s.captureStackTrace(this,t)}}class s extends t{constructor(e,t){super(`Dashgram API error (${e}): ${t}`),this.statusCode=e,this.details=t,this.name="DashgramAPIError";const i=Error;"function"==typeof i.captureStackTrace&&i.captureStackTrace(this,s)}}class i extends t{constructor(e){super(`Network error: ${e.message}`),this.originalError=e,this.name="NetworkError";const t=Error;"function"==typeof t.captureStackTrace&&t.captureStackTrace(this,i)}}class n extends t{constructor(e){super(e),this.name="DashgramConfigurationError";const t=Error;"function"==typeof t.captureStackTrace&&t.captureStackTrace(this,n)}}const r={trackLevel:1,apiUrl:"https://api.dashgram.io/v1",batchSize:10,flushInterval:5e3,debug:!1,disabled:!1};class o{constructor(e){this.config={...r,...e},this.validate()}validate(){if(!this.config.projectId)throw new n("projectId is required");if(![1,2,3].includes(this.config.trackLevel))throw new n("trackLevel must be 1, 2, or 3")}get(e){return this.config[e]}getOnError(){return this.config.onError}getTrackUrl(){return`${this.config.apiUrl.replace(/\/$/,"")}/${this.config.projectId}/webapp/track`}setTrackLevel(e){if(![1,2,3].includes(e))throw new n("trackLevel must be 1, 2, or 3");this.config.trackLevel=e}getTrackLevel(){return this.config.trackLevel}isDebug(){return this.config.debug}isDisabled(){return this.config.disabled}}function c(){if("undefined"==typeof window)return null;const e=window;return e.Telegram?.WebApp||null}function a(){const e=c();return e?.initData||""}function u(){const e=c();return e?.platform||"unknown"}function h(){const e=c();if(e?.colorScheme)return e.colorScheme;if(e?.themeParams?.bg_color){const t=e.themeParams.bg_color;try{const e=parseInt(t.slice(1),16);return.2126*(e>>16&255)+.7152*(e>>8&255)+.0722*(255&e)<128?"dark":"light"}catch{return}}}function d(e,t){const s=c();if(!s||!s.onEvent)return()=>{};try{const i=(s,i)=>{try{t(i)}catch(t){"undefined"!=typeof window&&window.__DASHGRAM_DEBUG__&&console.warn(`[Dashgram] Error in Telegram event callback for ${e}:`,t)}};return s.onEvent(e,i),()=>{try{s.offEvent&&s.offEvent(e,i)}catch{}}}catch{return()=>{}}}function l(){return"undefined"==typeof window?{platform:"unknown"}:{platform:u(),user_agent:navigator.userAgent,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone||void 0,theme:h()}}class p{constructor(){this.telemetry=l()}getTelemetry(){return{...this.telemetry}}updateTelemetry(){this.telemetry=l()}}function g(e,t){let s=null,i=0;return function(...n){const r=Date.now(),o=t-(r-i);o<=0||o>t?(s&&(clearTimeout(s),s=null),i=r,e.apply(this,n)):s||(s=setTimeout(()=>{i=Date.now(),s=null,e.apply(this,n)},o))}}function f(e){try{return JSON.stringify(e)}catch(e){return"{}"}}function b(e){if(e.id)return`#${e.id}`;if(e.className&&"string"==typeof e.className){const t=e.className.trim().split(/\s+/).slice(0,2).join(".");if(t)return`${e.tagName.toLowerCase()}.${t}`}return e.tagName.toLowerCase()}function m(e,t=50){const s=e.textContent?.trim()||"";return s.length>t?s.substring(0,t)+"...":s}class v{constructor(e){this.isOnline=!0,this.pendingRequests=new Set,this.config=e,this.setupOnlineListener()}setupOnlineListener(){"undefined"!=typeof window&&(window.addEventListener("online",()=>{this.isOnline=!0,this.log("Connection restored")}),window.addEventListener("offline",()=>{this.isOnline=!1,this.log("Connection lost")}),this.isOnline=navigator.onLine)}buildPayload(e){return{origin:("undefined"==typeof window?"":window.location.origin)||void 0,updates:e}}async send(e){if(0===e.length)return;if(this.config.isDisabled())return void this.log("Tracking disabled, skipping send");if(!this.isOnline)return void this.log("Offline, skipping send");const t=this.sendRequest(e);this.pendingRequests.add(t);try{await t}catch(e){this.logError("Failed to send events:",e);const t=this.config.getOnError();if(t)try{e instanceof s||e instanceof i?t(e):e instanceof Error&&t(new i(e))}catch(e){this.logError("Error in onError callback:",e)}}finally{this.pendingRequests.delete(t)}}async sendRequest(e){const t=this.config.getTrackUrl(),n=this.buildPayload(e);try{const i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:f(n),keepalive:!0});if(!i.ok){let e=i.statusText;try{const t=await i.json();e=t.details||t.message||e}catch{}throw new s(i.status,e)}this.log(`Sent ${e.length} events successfully`)}catch(e){if(e instanceof s)throw e;if(e instanceof Error)throw new i(e);throw new i(new Error(String(e)))}}sendBeacon(e){if(0===e.length)return!0;if(this.config.isDisabled())return!0;if("undefined"==typeof navigator||!navigator.sendBeacon)return!1;const t=this.config.getTrackUrl(),s=this.buildPayload(e),i=new Blob([f(s)],{type:"application/json"}),n=navigator.sendBeacon(t,i);return this.log(`sendBeacon ${n?"succeeded":"failed"} for ${e.length} events`),n}async flush(){await Promise.all(Array.from(this.pendingRequests))}log(...e){this.config.isDebug()&&console.log("[Dashgram Transport]",...e)}logError(...e){this.config.isDebug()&&console.error("[Dashgram Transport]",...e)}}class _{constructor(e=100){this.queue=[],this.maxSize=e}enqueue(e){this.queue.push(e),this.queue.length>this.maxSize&&this.queue.shift()}flush(){const e=[...this.queue];return this.queue=[],e}peek(){return[...this.queue]}size(){return this.queue.length}isEmpty(){return 0===this.queue.length}clear(){this.queue=[]}}class k{constructor(e,t){this.flushTimer=null,this.isStarted=!1,this.config=e,this.transport=t,this.queue=new _(200)}start(){this.isStarted||(this.isStarted=!0,this.scheduleFlush(),this.setupPageUnloadHandler())}stop(){this.isStarted=!1,this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)}addEvent(e){this.queue.enqueue(e);const t=this.config.get("batchSize");this.queue.size()>=t&&this.flush()}scheduleFlush(){this.flushTimer&&clearTimeout(this.flushTimer);const e=this.config.get("flushInterval");this.flushTimer=setTimeout(()=>{this.flush(),this.isStarted&&this.scheduleFlush()},e)}flush(){const e=this.queue.flush();e.length>0&&this.transport.send(e)}async flushAsync(){const e=this.queue.flush();e.length>0&&await this.transport.send(e),await this.transport.flush()}setupPageUnloadHandler(){if("undefined"==typeof window)return;const e=()=>{const e=this.queue.flush();e.length>0&&this.transport.sendBeacon(e)};window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&e()}),window.addEventListener("pagehide",e),window.addEventListener("beforeunload",e)}}class w{constructor(e,t,s){this.isActive=!1,this.config=e,this.trackCallback=t,this.level=s}start(){if(this.isActive)return;this.config.getTrackLevel()>=this.level&&(this.isActive=!0,this.setup(),this.log(`Started (level ${this.level})`))}stop(){this.isActive&&(this.isActive=!1,this.teardown(),this.log("Stopped"))}track(e,t={}){this.isActive&&this.trackCallback(e,t)}log(...e){this.config.isDebug()&&console.log(`[Dashgram ${this.constructor.name}]`,...e)}}class y extends w{constructor(e,t){super(e,t,1),this.unsubscribers=[],this.hasTrackedAppOpen=!1}setup(){"undefined"!=typeof window&&(this.trackAppOpen(),this.setupVisibilityTracking(),this.setupUnloadTracking())}teardown(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[]}trackAppOpen(){this.hasTrackedAppOpen||(this.track("app_open",{referrer:document.referrer||"direct"}),this.hasTrackedAppOpen=!0)}setupVisibilityTracking(){const e=()=>{"hidden"===document.visibilityState?this.track("app_close",{visibility_state:"hidden"}):"visible"===document.visibilityState&&this.track("app_open",{visibility_state:"visible"})};document.addEventListener("visibilitychange",e),this.unsubscribers.push(()=>{document.removeEventListener("visibilitychange",e)})}setupUnloadTracking(){const e=()=>{this.track("app_close",{reason:"unload"})};window.addEventListener("pagehide",e),this.unsubscribers.push(()=>{window.removeEventListener("pagehide",e)}),window.addEventListener("beforeunload",e),this.unsubscribers.push(()=>{window.removeEventListener("beforeunload",e)})}}class T extends w{constructor(e,t){super(e,t,2),this.unsubscribers=[],this.lastPath="",this.inputValues=new Map}setup(){"undefined"!=typeof window&&(this.trackScreenView(),this.setupHistoryTracking(),this.setupClickTracking(),this.setupFormTracking(),this.setupInputTracking(),this.setupClipboardTracking(),this.setupSelectionTracking(),this.setupErrorTracking())}teardown(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[]}trackScreenView(){const e="undefined"==typeof window?"":window.location.pathname;e!==this.lastPath&&(this.lastPath=e,this.track("screen_view",{path:e,url:"undefined"==typeof window?"":window.location.href,title:"undefined"==typeof document?"":document.title||"",referrer:document.referrer||"direct"}))}setupHistoryTracking(){const e=history.pushState,t=history.replaceState,s=()=>{this.trackScreenView()};history.pushState=function(...t){e.apply(history,t),s()},history.replaceState=function(...e){t.apply(history,e),s()},window.addEventListener("popstate",s),this.unsubscribers.push(()=>{history.pushState=e,history.replaceState=t,window.removeEventListener("popstate",s)})}setupClickTracking(){const e=e=>{const t=e.target;if(!t)return;const s=t.closest('button, [role="button"], a');if(s){if("a"===s.tagName.toLowerCase()){const e=s,t=e.href,i=!!t&&this.isExternalLink(t);this.track("link_click",{element:b(s),text:m(s),href:t||void 0,target:e.target||void 0,is_external:i,is_download:e.hasAttribute("download")})}else this.track("button_click",{element:b(s),text:m(s)})}};document.addEventListener("click",e,{capture:!0}),this.unsubscribers.push(()=>{document.removeEventListener("click",e,{capture:!0})})}isExternalLink(e){try{return new URL(e,window.location.href).origin!==window.location.origin}catch{return!1}}setupFormTracking(){const e=e=>{const t=e.target;t&&this.track("form_submit",{form_id:t.id||void 0,form_name:t.name||void 0,form_action:t.action||void 0,form_method:t.method||void 0})};document.addEventListener("submit",e,{capture:!0}),this.unsubscribers.push(()=>{document.removeEventListener("submit",e,{capture:!0})})}setupInputTracking(){const e=g(e=>{const t=e.target;if(!t)return;const s=t.tagName.toLowerCase();if(["input","textarea","select"].includes(s)){const e=t;this.inputValues.set(t,e.value||""),this.track("input_focus",{element:b(e),input_type:e.type||s,input_name:e.name||void 0,input_id:e.id||void 0})}},1e3),t=e=>{const t=e.target;if(!t)return;const s=t.tagName.toLowerCase();if(["input","textarea","select"].includes(s)){const e=t,i=this.inputValues.get(t),n=e.value||"";void 0!==i&&i!==n&&this.track("input_change",{element:b(e),input_type:e.type||s,input_name:e.name||void 0,input_id:e.id||void 0,had_value:i.length>0,has_value:n.length>0}),this.inputValues.delete(t)}};document.addEventListener("focus",e,{capture:!0}),document.addEventListener("blur",t,{capture:!0}),this.unsubscribers.push(()=>{document.removeEventListener("focus",e,{capture:!0}),document.removeEventListener("blur",t,{capture:!0}),this.inputValues.clear()})}setupClipboardTracking(){const e=e=>{const t=window.getSelection(),s=t?.toString()||"";this.track("copy",{text_length:s.length,has_selection:s.length>0})},t=e=>{const t=window.getSelection(),s=t?.toString()||"";this.track("cut",{text_length:s.length,has_selection:s.length>0})},s=e=>{const t=e.clipboardData?.getData("text")||"",s=e.target;this.track("paste",{text_length:t.length,target_element:s?b(s):void 0})};document.addEventListener("copy",e),document.addEventListener("cut",t),document.addEventListener("paste",s),this.unsubscribers.push(()=>{document.removeEventListener("copy",e),document.removeEventListener("cut",t),document.removeEventListener("paste",s)})}setupSelectionTracking(){let e;const t=()=>{clearTimeout(e),e=setTimeout(()=>{const e=window.getSelection(),t=e?.toString()||"";t.length>0&&this.track("text_select",{text_length:t.length})},500)};document.addEventListener("selectionchange",t),this.unsubscribers.push(()=>{document.removeEventListener("selectionchange",t),clearTimeout(e)})}setupErrorTracking(){const e=e=>{this.track("js_error",{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno,stack:e.error?.stack})};window.addEventListener("error",e),this.unsubscribers.push(()=>{window.removeEventListener("error",e)});const t=e=>{this.track("unhandled_rejection",{reason:String(e.reason),promise:String(e.promise)})};window.addEventListener("unhandledrejection",t),this.unsubscribers.push(()=>{window.removeEventListener("unhandledrejection",t)})}}class E extends w{constructor(e,t){super(e,t,3),this.unsubscribers=[],this.observers=[],this.clickTracker=new Map,this.maxScrollDepth=0,this.trackedMedia=new WeakSet}setup(){"undefined"!=typeof window&&(this.setupScrollTracking(),this.setupVisibilityTracking(),this.setupRageClickTracking(),this.setupLongTaskTracking(),this.setupWebVitals(),this.setupNetworkTracking(),this.setupOrientationTracking(),this.setupMediaTracking(),this.setupTelegramTracking())}teardown(){this.unsubscribers.forEach(e=>e()),this.unsubscribers=[],this.observers.forEach(e=>e.disconnect()),this.observers=[],this.clickTracker.clear()}getScrollDepth(){const e=window.innerHeight,t=document.documentElement.scrollHeight,s=window.pageYOffset||document.documentElement.scrollTop;if(t<=e)return 100;const i=s/(t-e)*100;return Math.min(Math.round(i),100)}setupScrollTracking(){const e=g(()=>{const e=this.getScrollDepth();if(e>this.maxScrollDepth){this.maxScrollDepth=e;const t=[25,50,75,100].find(t=>e>=t&&this.maxScrollDepth-e<t);t&&this.track("scroll_depth",{depth:t,max_depth:this.maxScrollDepth})}},500);window.addEventListener("scroll",e,{passive:!0}),this.unsubscribers.push(()=>{window.removeEventListener("scroll",e)})}setupVisibilityTracking(){if(!("IntersectionObserver"in window))return;const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){const s=t.target,i=s.getAttribute("data-track-visible");i&&(this.track("element_visible",{element:i,intersection_ratio:t.intersectionRatio}),e.unobserve(s))}})},{threshold:.5});document.querySelectorAll("[data-track-visible]").forEach(t=>{e.observe(t)}),this.observers.push(e);const t=new MutationObserver(t=>{t.forEach(t=>{t.addedNodes.forEach(t=>{t instanceof Element&&(t.hasAttribute("data-track-visible")&&e.observe(t),t.querySelectorAll("[data-track-visible]").forEach(t=>{e.observe(t)}))})})});t.observe(document.body,{childList:!0,subtree:!0}),this.unsubscribers.push(()=>{t.disconnect()})}setupRageClickTracking(){const e=e=>{const t=e.target;if(!t)return;const s=this.clickTracker.get(t);if(s)s.count++,clearTimeout(s.timer),s.count>=5?(this.track("rage_click",{element:t.tagName.toLowerCase(),click_count:s.count}),this.clickTracker.delete(t)):s.timer=setTimeout(()=>{this.clickTracker.delete(t)},2e3);else{const e=setTimeout(()=>{this.clickTracker.delete(t)},2e3);this.clickTracker.set(t,{count:1,timer:e})}};document.addEventListener("click",e),this.unsubscribers.push(()=>{document.removeEventListener("click",e)})}setupLongTaskTracking(){if("PerformanceObserver"in window)try{const e=new PerformanceObserver(e=>{for(const t of e.getEntries())t.duration>50&&this.track("long_task",{duration:Math.round(t.duration),start_time:Math.round(t.startTime)})});e.observe({entryTypes:["longtask"]}),this.observers.push(e)}catch(e){this.log("Long task tracking not supported")}}setupWebVitals(){if(!("PerformanceObserver"in window))return;try{const e=new PerformanceObserver(e=>{const t=e.getEntries(),s=t[t.length-1];this.track("web_vital_lcp",{value:Math.round(s.renderTime||s.loadTime),element:s.element?.tagName.toLowerCase()})});e.observe({entryTypes:["largest-contentful-paint"]}),this.observers.push(e)}catch(e){this.log("LCP tracking not supported")}try{const e=new PerformanceObserver(e=>{e.getEntries().forEach(e=>{this.track("web_vital_fid",{value:Math.round(e.processingStart-e.startTime),event_type:e.name})})});e.observe({entryTypes:["first-input"]}),this.observers.push(e)}catch(e){this.log("FID tracking not supported")}let e=0;try{const t=new PerformanceObserver(t=>{t.getEntries().forEach(t=>{t.hadRecentInput||(e+=t.value)})});t.observe({entryTypes:["layout-shift"]}),this.observers.push(t);const s=()=>{e>0&&this.track("web_vital_cls",{value:Math.round(1e3*e)/1e3})};window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&s()}),this.unsubscribers.push(()=>{s()})}catch(e){this.log("CLS tracking not supported")}}setupNetworkTracking(){const e=()=>{this.track("network_status",{status:"online",effective_type:navigator.connection?.effectiveType,downlink:navigator.connection?.downlink,rtt:navigator.connection?.rtt})},t=()=>{this.track("network_status",{status:"offline"})};window.addEventListener("online",e),window.addEventListener("offline",t),this.unsubscribers.push(()=>{window.removeEventListener("online",e),window.removeEventListener("offline",t)});const s=navigator.connection;if(s){const e=()=>{this.track("network_change",{effective_type:s.effectiveType,downlink:s.downlink,rtt:s.rtt,save_data:s.saveData})};s.addEventListener("change",e),this.unsubscribers.push(()=>{s.removeEventListener("change",e)})}}setupOrientationTracking(){const e=()=>{const e=screen.orientation?.type||(window.innerWidth>window.innerHeight?"landscape":"portrait");this.track("orientation_change",{orientation:e,angle:screen.orientation?.angle,width:window.innerWidth,height:window.innerHeight})};screen.orientation?(screen.orientation.addEventListener("change",e),this.unsubscribers.push(()=>{screen.orientation.removeEventListener("change",e)})):(window.addEventListener("orientationchange",e),this.unsubscribers.push(()=>{window.removeEventListener("orientationchange",e)}))}setupMediaTracking(){const e=e=>{const t=e.target;if(!t||this.trackedMedia.has(t))return;const s=t.tagName.toLowerCase(),i=e.type,n={media_type:s,src:t.currentSrc||t.src,duration:isFinite(t.duration)?Math.round(t.duration):void 0,current_time:Math.round(t.currentTime),muted:t.muted,volume:Math.round(100*t.volume)};"play"===i?this.track("media_play",n):"pause"===i?this.track("media_pause",{...n,percent_played:t.duration?Math.round(t.currentTime/t.duration*100):0}):"ended"===i?this.track("media_ended",{...n,completed:!0}):"error"===i&&this.track("media_error",{media_type:s,src:t.currentSrc||t.src,error:t.error?.message||"unknown"})},t=t=>{this.trackedMedia.has(t)||(this.trackedMedia.add(t),t.addEventListener("play",e),t.addEventListener("pause",e),t.addEventListener("ended",e),t.addEventListener("error",e))};document.querySelectorAll("video, audio").forEach(e=>{t(e)});const s=new MutationObserver(e=>{e.forEach(e=>{e.addedNodes.forEach(e=>{e instanceof HTMLMediaElement&&t(e),e instanceof Element&&e.querySelectorAll("video, audio").forEach(e=>{t(e)})})})});s.observe(document.body,{childList:!0,subtree:!0}),this.observers.push(s)}setupTelegramTracking(){const e=window.Telegram?.WebApp,t=(e,t)=>{this.track(`telegram_${e}`,t||{})},s=d("themeChanged",()=>{t("theme_changed",{color_scheme:e?.colorScheme,theme_params:e?.themeParams})});this.unsubscribers.push(s);const i=d("viewportChanged",s=>{t("viewport_changed",{is_state_stable:s?.isStateStable,is_expanded:e?.isExpanded,viewport_height:e?.viewportHeight,viewport_stable_height:e?.viewportStableHeight})});this.unsubscribers.push(i);const n=d("safeAreaChanged",()=>{t("safe_area_changed",{safe_area:e?.safeAreaInset})});this.unsubscribers.push(n);const r=d("contentSafeAreaChanged",()=>{t("content_safe_area_changed",{content_safe_area:e?.contentSafeAreaInset})});this.unsubscribers.push(r);const o=d("backButtonClicked",()=>{t("back_button_clicked",{})});this.unsubscribers.push(o);const c=d("mainButtonClicked",()=>{t("main_button_clicked",{button_text:e?.MainButton?.text})});this.unsubscribers.push(c);const a=d("invoiceClosed",e=>{t("invoice_closed",{url:e?.url,status:e?.status})});this.unsubscribers.push(a);const u=d("popupClosed",e=>{t("popup_closed",{button_id:e?.button_id})});this.unsubscribers.push(u);const h=d("qrTextReceived",e=>{t("qr_text_received",{data:e?.data})});this.unsubscribers.push(h);const l=d("scanQrPopupClosed",()=>{t("scan_qr_popup_closed",{})});this.unsubscribers.push(l);const p=d("clipboardTextReceived",e=>{t("clipboard_text_received",{data:e?.data})});this.unsubscribers.push(p);const g=d("writeAccessRequested",e=>{t("write_access_requested",{status:e?.status})});this.unsubscribers.push(g);const f=d("fileDownloadRequested",e=>{t("file_download_requested",{status:e?.status})});this.unsubscribers.push(f);const b=d("customMethodInvoked",e=>{t("custom_method_invoked",{req_id:e?.req_id,result:e?.result,error:e?.error})});this.unsubscribers.push(b);const m=d("fullscreenChanged",e=>{t("fullscreen_changed",{is_fullscreen:e?.isFullscreen})});this.unsubscribers.push(m);const v=d("fullscreenFailed",e=>{t("fullscreen_failed",{error:e?.error})});this.unsubscribers.push(v);const _=d("homeScreenAdded",()=>{t("home_screen_added",{})});this.unsubscribers.push(_);const k=d("homeScreenChecked",e=>{t("home_screen_checked",{status:e?.status})});this.unsubscribers.push(k);const w=d("preparedMessageSent",()=>{t("prepared_message_sent",{})});this.unsubscribers.push(w);const y=d("preparedMessageFailed",e=>{t("prepared_message_failed",{error:e?.error})});this.unsubscribers.push(y);const T=d("emojiStatusSet",()=>{t("emoji_status_set",{})});this.unsubscribers.push(T);const E=d("emojiStatusFailed",e=>{t("emoji_status_failed",{error:e?.error})});this.unsubscribers.push(E);const L=d("emojiStatusAccessRequested",e=>{t("emoji_status_access_requested",{status:e?.status})});this.unsubscribers.push(L);const S=d("settingsButtonClicked",()=>{t("settings_button_clicked",{})});this.unsubscribers.push(S);const x=d("secondaryButtonClicked",()=>{t("secondary_button_clicked",{})});this.unsubscribers.push(x);const q=d("shareMessageSent",()=>{t("share_message_sent",{})});this.unsubscribers.push(q);const A=d("shareMessageFailed",e=>{t("share_message_failed",{error:e?.error})});this.unsubscribers.push(A);const D=d("locationManagerUpdated",()=>{const s=e?.LocationManager;t("location_manager_updated",{is_inited:s?.isInited,is_location_available:s?.isLocationAvailable,is_access_requested:s?.isAccessRequested,is_access_granted:s?.isAccessGranted})});this.unsubscribers.push(D);const I=d("locationRequested",e=>{t("location_requested",{available:!1!==e?.available,latitude:e?.latitude,longitude:e?.longitude,altitude:e?.altitude,course:e?.course,speed:e?.speed,horizontal_accuracy:e?.horizontal_accuracy,vertical_accuracy:e?.vertical_accuracy,course_accuracy:e?.course_accuracy,speed_accuracy:e?.speed_accuracy})});this.unsubscribers.push(I);const P=d("accelerometerStarted",()=>{t("accelerometer_started",{})});this.unsubscribers.push(P);const C=d("accelerometerStopped",()=>{t("accelerometer_stopped",{})});this.unsubscribers.push(C);const M=d("accelerometerChanged",()=>{const s=e?.Accelerometer;t("accelerometer_changed",{x:s?.x,y:s?.y,z:s?.z})});this.unsubscribers.push(M);const O=d("accelerometerFailed",e=>{t("accelerometer_failed",{error:e?.error})});this.unsubscribers.push(O);const z=d("deviceOrientationStarted",()=>{t("device_orientation_started",{})});this.unsubscribers.push(z);const R=d("deviceOrientationStopped",()=>{t("device_orientation_stopped",{})});this.unsubscribers.push(R);const j=d("deviceOrientationChanged",()=>{const s=e?.DeviceOrientation;t("device_orientation_changed",{absolute:s?.absolute,alpha:s?.alpha,beta:s?.beta,gamma:s?.gamma})});this.unsubscribers.push(j);const F=d("deviceOrientationFailed",e=>{t("device_orientation_failed",{error:e?.error})});this.unsubscribers.push(F);const N=d("gyroscopeStarted",()=>{t("gyroscope_started",{})});this.unsubscribers.push(N);const U=d("gyroscopeStopped",()=>{t("gyroscope_stopped",{})});this.unsubscribers.push(U);const B=d("gyroscopeChanged",()=>{const s=e?.Gyroscope;t("gyroscope_changed",{x:s?.x,y:s?.y,z:s?.z})});this.unsubscribers.push(B);const $=d("gyroscopeFailed",e=>{t("gyroscope_failed",{error:e?.error})});this.unsubscribers.push($);const V=d("contactRequested",e=>{t("contact_requested",{status:e?.status})});this.unsubscribers.push(V);const H=d("activated",()=>{t("activated",{})});this.unsubscribers.push(H);const W=d("deactivated",()=>{t("deactivated",{})});this.unsubscribers.push(W);const G=d("biometricManagerUpdated",()=>{const s=e?.BiometricManager;t("biometric_manager_updated",{is_inited:s?.isInited,is_biometric_available:s?.isBiometricAvailable,biometric_type:s?.biometricType,is_access_requested:s?.isAccessRequested,is_access_granted:s?.isAccessGranted,is_biometric_token_saved:s?.isBiometricTokenSaved,device_id:s?.deviceId})});this.unsubscribers.push(G);const Q=d("biometricAuthRequested",e=>{t("biometric_auth_requested",{is_authenticated:e?.isAuthenticated,biometric_token:e?.biometricToken})});this.unsubscribers.push(Q);const K=d("biometricTokenUpdated",e=>{t("biometric_token_updated",{is_updated:e?.isUpdated})});this.unsubscribers.push(K),this.patchWebAppMethods(e,t)}patchWebAppMethods(e,t){if(e&&!e.openLink?._dashgramPatched){if(e.openLink&&"function"==typeof e.openLink){const s=e.openLink.bind(e),i=(e,i)=>(t("open_link",{url:e,options:i}),s(e,i));i._dashgramPatched=!0,e.openLink=i}if(e.openTelegramLink&&"function"==typeof e.openTelegramLink){const s=e.openTelegramLink.bind(e),i=e=>(t("open_telegram_link",{url:e}),s(e));i._dashgramPatched=!0,e.openTelegramLink=i}if(e.switchInlineQuery&&"function"==typeof e.switchInlineQuery){const s=e.switchInlineQuery.bind(e),i=(e,i)=>(t("switch_inline_query",{query:e,choose_chat_types:i}),s(e,i));i._dashgramPatched=!0,e.switchInlineQuery=i}if(e.shareToStory&&"function"==typeof e.shareToStory){const s=e.shareToStory.bind(e),i=(e,i)=>(t("share_story",{media_url:e,params:i}),s(e,i));i._dashgramPatched=!0,e.shareToStory=i}if(e.close&&"function"==typeof e.close){const s=e.close.bind(e),i=e=>(t("webapp_close",{return_back:e?.return_back}),s(e));i._dashgramPatched=!0,e.close=i}if(e.exitFullscreen&&"function"==typeof e.exitFullscreen){const s=e.exitFullscreen.bind(e),i=()=>(t("webapp_exit_fullscreen",{}),s());i._dashgramPatched=!0,e.exitFullscreen=i}if(e.openInvoice&&"function"==typeof e.openInvoice){const s=e.openInvoice.bind(e),i=(e,i)=>(t("open_invoice",{slug:e}),s(e,i));i._dashgramPatched=!0,e.openInvoice=i}if(e.requestAccess&&"function"==typeof e.requestAccess){const s=e.requestAccess.bind(e),i=(e,i)=>(t("request_access",{access_type:e}),s(e,i));i._dashgramPatched=!0,e.requestAccess=i}if(e.requestContact&&"function"==typeof e.requestContact){const s=e.requestContact.bind(e),i=e=>(t("request_contact",{}),s(e));i._dashgramPatched=!0,e.requestContact=i}if(e.requestPhone&&"function"==typeof e.requestPhone){const s=e.requestPhone.bind(e),i=e=>(t("request_phone",{}),s(e));i._dashgramPatched=!0,e.requestPhone=i}if(e.requestLocation&&"function"==typeof e.requestLocation){const s=e.requestLocation.bind(e),i=e=>(t("request_location",{}),s(e));i._dashgramPatched=!0,e.requestLocation=i}if(e.checkLocation&&"function"==typeof e.checkLocation){const s=e.checkLocation.bind(e),i=e=>(t("check_location",{}),s(e));i._dashgramPatched=!0,e.checkLocation=i}}}}const L=new class{constructor(){this.config=null,this.context=null,this.transport=null,this.batchProcessor=null,this.trackers=[],this.isInitialized=!1}init(e){if(this.isInitialized)e.debug&&console.warn("Dashgram: Already initialized");else if("undefined"!=typeof window&&"undefined"!=typeof document)try{this.config=new o(e),"undefined"!=typeof window&&(window.__DASHGRAM_DEBUG__=this.config.isDebug()),this.context=new p,this.transport=new v(this.config),this.batchProcessor=new k(this.config,this.transport),this.setupTrackers(),this.batchProcessor.start(),this.isInitialized=!0,this.log("Initialized successfully",{projectId:this.config.get("projectId"),trackLevel:this.config.getTrackLevel()})}catch(e){throw console.error("Dashgram: Initialization failed",e),e}else e.debug&&console.warn("Dashgram: Not running in browser environment")}setupTrackers(){if(!this.config)return;const e=(e,t)=>{this.trackAuto(e,t)},t=new y(this.config,e);this.trackers.push(t),t.start();const s=new T(this.config,e);this.trackers.push(s),s.start();const i=new E(this.config,e);this.trackers.push(i),i.start()}track(e,t={}){this.ensureInitialized();const s=this.buildEvent(e,t,"manual");this.batchProcessor.addEvent(s),this.log("Tracked event",{event:e,properties:t})}trackAuto(e,t={}){if(!this.isInitialized)return;const s=this.buildEvent(e,t,"auto");this.batchProcessor.addEvent(s),this.log("Auto-tracked event",{event:e,properties:t})}buildEvent(e,t,s){return this.ensureInitialized(),{eventId:"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)}),type:e,initData:a(),properties:Object.keys(t).length>0?t:void 0,telemetry:this.context.getTelemetry(),source:s,level:this.config.getTrackLevel(),timestamp:Date.now()}}setTrackLevel(e){this.ensureInitialized();const t=this.config.getTrackLevel();this.config.setTrackLevel(e),this.trackers.forEach(e=>{e.stop(),e.start()}),this.log("Track level changed",{from:t,to:e})}async flush(){this.ensureInitialized(),await this.batchProcessor.flushAsync(),this.log("Flushed all events")}shutdown(){this.isInitialized&&(this.trackers.forEach(e=>e.stop()),this.trackers=[],this.batchProcessor.flush(),this.batchProcessor.stop(),this.isInitialized=!1,this.log("Shutdown complete"))}ensureInitialized(){if(!this.isInitialized)throw new Error("Dashgram: SDK not initialized. Call init() first.")}log(...e){this.config?.isDebug()&&console.log("[Dashgram SDK]",...e)}};e.DashgramAPIError=s,e.DashgramConfigurationError=n,e.DashgramError=t,e.DashgramMini=L,e.NetworkError=i,e.default=L,Object.defineProperty(e,"__esModule",{value:!0})});
|
|
2
|
+
//# sourceMappingURL=dashgram.min.js.map
|