feat(sdk): 页面浏览/有效停留/事件入口,打包≤15KB
- events.ts:page_view/page_stay(有效停留=可见+30s 内有活动), close 双触发(hidden+pagehide)靠 activeMs 清零不重发 - index.ts:IIFE 入口,队列重放前先替换 g.ctk=dispatch; 首触归因——__ctk_ctx 除设备环境外带 referrer_domain/utm/path - transport.ts:stringify 抛错(track 宿主可控对象)按已换出 批次事件数计 dropped(Task 14 审查加固) - demo 双页互跳;gzip 2209B ≤ 15360B;测试 35→44 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -7,8 +7,8 @@ export type TransportConfig = Required<CtkConfig>;
|
||||
// 批量传输:满 batchSize 或 flushMs 到期即发;4xx(除 429)不重试;
|
||||
// 指数退避 + 抖动重试;重试耗尽按本批事件数计 dropped;queueMax 溢出丢最旧。
|
||||
// 红线:任何异常不得冒泡到宿主页(定时器/事件回调内的异常无人捕获)。
|
||||
// 审查留档:events 目前均为 SDK 自产可序列化对象;若未来引入受控外的 events
|
||||
// 来源,需处理 stringify 抛错时已换出批次的计数(当前静默丢弃不计 dropped)。
|
||||
// 审查留档(Task 14 结论):index.ts 的 track 分支已引入宿主可控对象——
|
||||
// stringify 抛错(如循环引用)时已换出的批次按事件数计 dropped。
|
||||
export class Transport {
|
||||
private q: object[] = [];
|
||||
private timer: ReturnType<typeof setTimeout> | null = null;
|
||||
@@ -33,9 +33,11 @@ export class Transport {
|
||||
this.timer = null;
|
||||
}
|
||||
if (!this.q.length) return;
|
||||
let n = 0;
|
||||
try {
|
||||
const events = this.q;
|
||||
this.q = [];
|
||||
n = events.length; // 换出后先记数:stringify 抛错时本批已丢,须计 dropped
|
||||
const body = JSON.stringify({
|
||||
batch_id: uuid(),
|
||||
site_id: this.cfg.siteId,
|
||||
@@ -55,7 +57,9 @@ export class Transport {
|
||||
}
|
||||
this.send(body, events.length);
|
||||
} catch {
|
||||
// 定时器/事件回调内的任何异常不得冒泡到宿主页
|
||||
// 定时器/事件回调内的任何异常不得冒泡到宿主页;
|
||||
// stringify 抛错时批次已换出(宿主可控对象),按事件数计丢弃
|
||||
this.dropped += n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user