@yuanze_dev/tracker 0.4.0 → 0.5.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/dist/tracker.d.ts +5 -0
- package/dist/tracker.js +33 -6
- package/package.json +1 -1
package/dist/tracker.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type TrackerOptions = {
|
|
|
10
10
|
flushMs?: number;
|
|
11
11
|
autocapture?: boolean;
|
|
12
12
|
sender?: Sender;
|
|
13
|
+
maxQueueSize?: number;
|
|
13
14
|
};
|
|
14
15
|
export declare class Tracker {
|
|
15
16
|
private queue;
|
|
@@ -23,6 +24,9 @@ export declare class Tracker {
|
|
|
23
24
|
readonly appVersion?: string;
|
|
24
25
|
readonly maxBatch: number;
|
|
25
26
|
readonly flushMs: number;
|
|
27
|
+
readonly maxQueueSize: number;
|
|
28
|
+
private flushing;
|
|
29
|
+
private retryCount;
|
|
26
30
|
constructor(opts: TrackerOptions);
|
|
27
31
|
private anonId;
|
|
28
32
|
register(props: Record<string, unknown>): void;
|
|
@@ -32,6 +36,7 @@ export declare class Tracker {
|
|
|
32
36
|
track<K extends EventName>(name: K, properties?: EventProps<K>): void;
|
|
33
37
|
trackUnsafe(name: string, properties?: Record<string, unknown>): void;
|
|
34
38
|
private enqueue;
|
|
39
|
+
private trim;
|
|
35
40
|
private schedule;
|
|
36
41
|
flush(unloading?: boolean): Promise<void>;
|
|
37
42
|
}
|
package/dist/tracker.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const MAX_BATCH_SIZE = 50;
|
|
2
|
+
const MAX_BACKOFF_MS = 30_000;
|
|
1
3
|
function uuid() {
|
|
2
4
|
return globalThis.crypto.randomUUID();
|
|
3
5
|
}
|
|
@@ -13,6 +15,9 @@ export class Tracker {
|
|
|
13
15
|
appVersion;
|
|
14
16
|
maxBatch;
|
|
15
17
|
flushMs;
|
|
18
|
+
maxQueueSize;
|
|
19
|
+
flushing = false;
|
|
20
|
+
retryCount = 0;
|
|
16
21
|
constructor(opts) {
|
|
17
22
|
this.endpoint = opts.endpoint;
|
|
18
23
|
this.writeKey = opts.writeKey;
|
|
@@ -20,6 +25,7 @@ export class Tracker {
|
|
|
20
25
|
this.appVersion = opts.appVersion;
|
|
21
26
|
this.maxBatch = opts.maxBatch ?? 5;
|
|
22
27
|
this.flushMs = opts.flushMs ?? 5000;
|
|
28
|
+
this.maxQueueSize = opts.maxQueueSize ?? 500;
|
|
23
29
|
this.send = opts.sender ?? defaultFetchSender;
|
|
24
30
|
this.distinctId = opts.distinctId || this.anonId();
|
|
25
31
|
if (typeof document !== "undefined") {
|
|
@@ -80,34 +86,55 @@ export class Tracker {
|
|
|
80
86
|
clientTime: new Date().toISOString(),
|
|
81
87
|
properties: { ...this.superProps, ...properties },
|
|
82
88
|
});
|
|
89
|
+
this.trim();
|
|
83
90
|
if (this.queue.length >= this.maxBatch)
|
|
84
91
|
this.flush();
|
|
85
92
|
else
|
|
86
93
|
this.schedule();
|
|
87
94
|
}
|
|
88
|
-
|
|
95
|
+
trim() {
|
|
96
|
+
const overflow = this.queue.length - this.maxQueueSize;
|
|
97
|
+
if (overflow > 0) {
|
|
98
|
+
this.queue.splice(0, overflow);
|
|
99
|
+
console.warn(`[tracker] 队列超过 ${this.maxQueueSize} 条,丢弃最旧的 ${overflow} 条`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
schedule(delayMs = this.flushMs) {
|
|
89
103
|
if (this.timer)
|
|
90
104
|
return;
|
|
91
|
-
this.timer = setTimeout(() => this.flush(),
|
|
105
|
+
this.timer = setTimeout(() => this.flush(), delayMs);
|
|
92
106
|
}
|
|
93
107
|
async flush(unloading = false) {
|
|
94
108
|
if (this.timer) {
|
|
95
109
|
clearTimeout(this.timer);
|
|
96
110
|
this.timer = null;
|
|
97
111
|
}
|
|
98
|
-
if (this.queue.length === 0)
|
|
112
|
+
if (this.queue.length === 0 || (this.flushing && !unloading))
|
|
99
113
|
return;
|
|
100
|
-
|
|
114
|
+
this.flushing = true;
|
|
115
|
+
const batch = this.queue.splice(0, Math.min(MAX_BATCH_SIZE, this.queue.length));
|
|
101
116
|
const body = JSON.stringify({ events: batch });
|
|
102
117
|
const headers = { "Content-Type": "application/json", "x-write-key": this.writeKey };
|
|
103
118
|
try {
|
|
104
119
|
await this.send(this.endpoint, body, headers, unloading);
|
|
120
|
+
this.retryCount = 0;
|
|
105
121
|
}
|
|
106
122
|
catch (err) {
|
|
107
|
-
if (err?.retryable !== false)
|
|
123
|
+
if (err?.retryable !== false) {
|
|
108
124
|
this.queue.unshift(...batch);
|
|
109
|
-
|
|
125
|
+
this.trim();
|
|
126
|
+
this.retryCount += 1;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
110
129
|
console.warn("[tracker] 丢弃一批(不可重试):", err?.status);
|
|
130
|
+
this.retryCount = 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
this.flushing = false;
|
|
135
|
+
}
|
|
136
|
+
if (this.queue.length > 0 && !unloading) {
|
|
137
|
+
this.schedule(Math.min(this.flushMs * 2 ** this.retryCount, MAX_BACKOFF_MS));
|
|
111
138
|
}
|
|
112
139
|
}
|
|
113
140
|
}
|