@macroui/event-tracker 1.3.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +343 -0
  3. package/bin/event-tracker-suggest.mjs +141 -0
  4. package/bin/event-tracker.mjs +157 -0
  5. package/dist/event-tracker.cjs +3449 -0
  6. package/dist/event-tracker.js +3455 -0
  7. package/dist/event-tracker.min.js +1 -0
  8. package/dist/event-tracker.mjs +3402 -0
  9. package/dist/plugin/auto-track.cjs +201 -0
  10. package/dist/plugin/auto-track.mjs +199 -0
  11. package/dist/plugin/debug-sender.cjs +214 -0
  12. package/dist/plugin/debug-sender.mjs +211 -0
  13. package/dist/plugin/encrypt.cjs +284 -0
  14. package/dist/plugin/encrypt.mjs +275 -0
  15. package/dist/plugin/exposure.cjs +121 -0
  16. package/dist/plugin/exposure.mjs +119 -0
  17. package/dist/plugin/indexeddb-sender.cjs +94 -0
  18. package/dist/plugin/indexeddb-sender.mjs +92 -0
  19. package/dist/plugin/pageleave.cjs +74 -0
  20. package/dist/plugin/pageleave.mjs +72 -0
  21. package/dist/plugin/pageload.cjs +198 -0
  22. package/dist/plugin/pageload.mjs +196 -0
  23. package/dist/plugin/session-event.cjs +142 -0
  24. package/dist/plugin/session-event.mjs +140 -0
  25. package/dist/plugin/webview-bridge.cjs +111 -0
  26. package/dist/plugin/webview-bridge.mjs +109 -0
  27. package/dist/types/core/env.d.ts +10 -0
  28. package/dist/types/core/errors.d.ts +76 -0
  29. package/dist/types/core/failed-queue.d.ts +24 -0
  30. package/dist/types/core/identity-api.d.ts +6 -0
  31. package/dist/types/core/identity.d.ts +39 -0
  32. package/dist/types/core/instance-channel.d.ts +34 -0
  33. package/dist/types/core/lifecycle.d.ts +26 -0
  34. package/dist/types/core/logger.d.ts +13 -0
  35. package/dist/types/core/plugin.d.ts +60 -0
  36. package/dist/types/core/profile-api.d.ts +6 -0
  37. package/dist/types/core/profile-store.d.ts +23 -0
  38. package/dist/types/core/register-api.d.ts +22 -0
  39. package/dist/types/core/retry-policy.d.ts +33 -0
  40. package/dist/types/core/send-pipeline.d.ts +55 -0
  41. package/dist/types/core/signed-identity.d.ts +29 -0
  42. package/dist/types/core/stage.d.ts +48 -0
  43. package/dist/types/core/track-api.d.ts +6 -0
  44. package/dist/types/core/tracker.d.ts +130 -0
  45. package/dist/types/core/uuid.d.ts +4 -0
  46. package/dist/types/index.d.ts +40 -0
  47. package/dist/types/plugins/auto-track/index.d.ts +21 -0
  48. package/dist/types/plugins/debug-sender/index.d.ts +24 -0
  49. package/dist/types/plugins/encrypt/index.d.ts +56 -0
  50. package/dist/types/plugins/exposure/index.d.ts +18 -0
  51. package/dist/types/plugins/indexeddb-sender/index.d.ts +15 -0
  52. package/dist/types/plugins/pageleave/index.d.ts +12 -0
  53. package/dist/types/plugins/pageload/index.d.ts +14 -0
  54. package/dist/types/plugins/session-event/index.d.ts +14 -0
  55. package/dist/types/plugins/webview-bridge/index.d.ts +33 -0
  56. package/dist/types/presets/preset-properties.d.ts +25 -0
  57. package/dist/types/send/ajax-sender.d.ts +11 -0
  58. package/dist/types/send/batch-sender.d.ts +17 -0
  59. package/dist/types/send/beacon-sender.d.ts +10 -0
  60. package/dist/types/send/encode.d.ts +8 -0
  61. package/dist/types/send/image-sender.d.ts +10 -0
  62. package/dist/types/send/sender.d.ts +20 -0
  63. package/dist/types/storage/indexeddb-store.d.ts +14 -0
  64. package/dist/types/storage/store.d.ts +56 -0
  65. package/dist/types/types/common.d.ts +26 -0
  66. package/dist/types/types/config.d.ts +117 -0
  67. package/dist/types/types/constants.d.ts +110 -0
  68. package/dist/types/types/index.d.ts +25 -0
  69. package/dist/types/types.test-d.d.ts +5 -0
  70. package/dist/types.test-d.ts +103 -0
  71. package/package.json +218 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * 跨实例 channel
3
+ * - 用 BroadcastChannel 实现,浏览器跨 tab 通信
4
+ * - 降级到 localStorage(无 BroadcastChannel 时)
5
+ * - 主要用于:
6
+ * - 共享 disabled 状态
7
+ * - 共享 changeDistinctId
8
+ * - 共享 session_id
9
+ */
10
+ export interface ChannelMessage {
11
+ type: 'state' | 'distinct' | 'session' | 'custom';
12
+ source: string;
13
+ payload: unknown;
14
+ }
15
+ type Listener = (msg: ChannelMessage) => void;
16
+ export declare class InstanceChannel {
17
+ private bc;
18
+ private listeners;
19
+ private sourceId;
20
+ private localStorageKey;
21
+ private pollTimer;
22
+ constructor();
23
+ private initBroadcastChannel;
24
+ private initLocalStoragePolling;
25
+ /** 发送消息 */
26
+ post(type: ChannelMessage['type'], payload: unknown): void;
27
+ /** 监听消息,返回取消函数 */
28
+ on(fn: Listener): () => void;
29
+ /** 关闭 */
30
+ close(): void;
31
+ /** 实例 id(用于调试 / 验证) */
32
+ getSourceId(): string;
33
+ }
34
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 7 个生命周期钩子
3
+ * - sdkReady SDK 加载完成,init 之前
4
+ * - sdkInitPara init 处理参数时(合并前)
5
+ * - sdkAfterInitPara init 处理参数后
6
+ * - sdkInitAPI API 挂到 window 之前
7
+ * - sdkAfterInitAPI API 挂到 window 之后
8
+ * - changeDistinctId distinct 变化时
9
+ * - switch 配置切换(多实例)
10
+ */
11
+ export type HookName = 'sdkReady' | 'sdkInitPara' | 'sdkAfterInitPara' | 'sdkInitAPI' | 'sdkAfterInitAPI' | 'changeDistinctId' | 'switch';
12
+ export declare const ALL_HOOKS: readonly HookName[];
13
+ export type HookFn = (...args: unknown[]) => void | Promise<void>;
14
+ export declare class Lifecycle {
15
+ private hooks;
16
+ /** 注册钩子,返回取消函数 */
17
+ on(name: HookName, fn: HookFn): () => void;
18
+ /** 取消钩子 */
19
+ off(name: HookName, fn: HookFn): void;
20
+ /** 同步触发钩子(catch 内部错误,不向外抛) */
21
+ emit(name: HookName, ...args: unknown[]): void;
22
+ /** 移除全部钩子 */
23
+ clear(): void;
24
+ /** 调试用 */
25
+ inspect(): Record<HookName, number>;
26
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 简易 logger
3
+ */
4
+ import type { TrackerConfig } from '../types/index.js';
5
+ export declare class Logger {
6
+ private config;
7
+ constructor(config: Pick<TrackerConfig, 'debug' | 'show_log'>);
8
+ log(...args: unknown[]): void;
9
+ warn(...args: unknown[]): void;
10
+ error(...args: unknown[]): void;
11
+ private shouldLog;
12
+ private out;
13
+ }
@@ -0,0 +1,60 @@
1
+ import { StageChain, type StageInterceptor, type StageName } from './stage.js';
2
+ import { Lifecycle, type HookName, type HookFn } from './lifecycle.js';
3
+ import type { TrackerConfig } from '../types/index.js';
4
+ export interface InstallContext {
5
+ /** 当前配置(reference,mutate 会影响 SDK) */
6
+ config: TrackerConfig;
7
+ /** 钩子系统 */
8
+ registry: PluginRegistry;
9
+ /** 3 个 stage 注入点 */
10
+ stages: {
11
+ buildDataStage: StageChain<unknown>;
12
+ businessStage: StageChain<unknown>;
13
+ sendDataStage: StageChain<unknown>;
14
+ };
15
+ /** SDK 自身引用(提供 track / identify / use / quick 等 API) */
16
+ sdk: import('./tracker.js').EventTracker;
17
+ /** 给插件使用的命名空间(每个 plugin 可写入自己的子对象) */
18
+ kit: Record<string, unknown>;
19
+ /** 跨实例 channel */
20
+ channel: import('./instance-channel.js').InstanceChannel;
21
+ /** 持久化 store */
22
+ store: import('../storage/store.js').KVStore;
23
+ /** 卸载 */
24
+ uninstall: () => void;
25
+ }
26
+ export interface Plugin {
27
+ /** 唯一名(同名重复 install 会先卸载旧的) */
28
+ name: string;
29
+ install?(ctx: InstallContext): void;
30
+ uninstall?(ctx?: InstallContext): void;
31
+ }
32
+ export declare class PluginRegistry {
33
+ /** 3 个 stage */
34
+ readonly stages: {
35
+ buildDataStage: StageChain<unknown>;
36
+ businessStage: StageChain<unknown>;
37
+ sendDataStage: StageChain<unknown>;
38
+ };
39
+ /** 7 个生命周期钩子 */
40
+ readonly lifecycle: Lifecycle;
41
+ /** 已安装的 plugin 列表 */
42
+ private plugins;
43
+ /** commonWays:quick() 调用入口 */
44
+ readonly commonWays: Record<string, (...args: unknown[]) => unknown>;
45
+ /** hook 注册快捷方法(向后兼容 + 简化插件作者) */
46
+ on(name: HookName, fn: HookFn): () => void;
47
+ off(name: HookName, fn: HookFn): void;
48
+ emit(name: HookName, ...args: unknown[]): void;
49
+ /** stage 注册拦截器 */
50
+ intercept<T = unknown>(stage: StageName, spec: StageInterceptor<T>): void;
51
+ /** 兼容旧 API:invoke(name, ...args) = emit(name, ...args) */
52
+ invoke(name: HookName, ...args: unknown[]): void;
53
+ constructor();
54
+ /** 安装 plugin */
55
+ install(plugin: Plugin, ctx: Omit<InstallContext, 'registry' | 'stages'>): void;
56
+ /** 卸载 plugin */
57
+ uninstall(plugin: Plugin, ctx?: InstallContext): void;
58
+ /** 列出已安装 */
59
+ list(): string[];
60
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Profile API(v1.1.1)
3
+ */
4
+ import type { EventTracker } from '../core/tracker.js';
5
+ import type { SendPipeline } from './send-pipeline.js';
6
+ export declare function attachProfileApi(sdk: EventTracker, pipeline: SendPipeline): void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * ProfileStore:用户属性持久化
3
+ * - setOnce / append / increment / unset / delete
4
+ * - 落到 KVStore(cookie/localStorage/...)
5
+ * - SDK 启动时读入缓存
6
+ */
7
+ import type { KVStore } from '../storage/store.js';
8
+ import { uuidv4 } from './uuid.js';
9
+ export declare class ProfileStore {
10
+ private store;
11
+ private cache;
12
+ constructor(store: KVStore);
13
+ private persist;
14
+ get(key: string): unknown;
15
+ getAll(): Record<string, unknown>;
16
+ set(props: Record<string, unknown>): void;
17
+ setOnce(props: Record<string, unknown>): void;
18
+ append(props: Record<string, unknown>): void;
19
+ increment(props: Record<string, number>): void;
20
+ unset(key: string): void;
21
+ delete(): void;
22
+ }
23
+ export declare const _uuid: typeof uuidv4;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * 公共属性注册 API(v1.1.1)
3
+ */
4
+ import type { EventTracker } from '../core/tracker.js';
5
+ import type { PresetPropertyBuilder } from '../presets/preset-properties.js';
6
+ export interface RegisterApi {
7
+ /** 注册永久属性(每次事件附带) */
8
+ register(props: Record<string, unknown>): this;
9
+ /** 注册一次性属性(首次读取后清除) */
10
+ registerOnce(props: Record<string, unknown>): this;
11
+ /** 清空所有永久属性 */
12
+ clearAllRegister(): this;
13
+ /** 移除单个属性 */
14
+ unsetRegister(key: string): this;
15
+ /** 注册一次性属性(神策 registerPage 别名) */
16
+ registerPage(props: Record<string, unknown>): this;
17
+ /** 注册会话属性(每次会话唯一;等同 registerOnce) */
18
+ registerSession(props: Record<string, unknown>): this;
19
+ /** 注册会话一次性属性 */
20
+ registerSessionOnce(props: Record<string, unknown>): this;
21
+ }
22
+ export declare function attachRegisterApi(sdk: EventTracker, builder: PresetPropertyBuilder): void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 失败重试 + 退避
3
+ * - 包装单个 send 调用
4
+ * - 退避: 1s → 2s → 4s
5
+ * - 超过 max_retry_duration 放弃
6
+ * - 失败事件可写入失败队列(待用)
7
+ */
8
+ import type { TrackerConfig } from '../types/index.js';
9
+ import type { Logger } from './logger.js';
10
+ export interface RetryConfig {
11
+ max_retry_count: number;
12
+ max_retry_duration: number;
13
+ }
14
+ /** 重试执行结果 */
15
+ export interface RetryResult {
16
+ ok: boolean;
17
+ attempts: number;
18
+ finalErr: Error | null;
19
+ }
20
+ export declare class RetryPolicy {
21
+ private config;
22
+ private logger;
23
+ constructor(config: TrackerConfig, logger: Logger);
24
+ /** 计算本次重试要 sleep 多久(指数退避) */
25
+ private backoff;
26
+ /**
27
+ * 带重试执行 send 函数
28
+ * @param send 单次发送
29
+ * @param shouldRetry 判断失败是否重试
30
+ */
31
+ execute(send: () => Promise<void> | void, shouldRetry?: (err: Error | null) => boolean, onFailed?: (err: Error, attempt: number) => void): Promise<RetryResult>;
32
+ private sleep;
33
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * 发送管线(v1.1.1)
3
+ * - 集中管理 build / encrypt / send / failed-queue / batch flush
4
+ * - flush() / waitUntilIdle() 让上层能主动等待
5
+ */
6
+ import type { TrackerConfig, EventData, Callback } from '../types/index.js';
7
+ import type { PluginRegistry } from './plugin.js';
8
+ import type { IdentityManager } from './identity.js';
9
+ import type { PresetPropertyBuilder } from '../presets/preset-properties.js';
10
+ import type { RetryPolicy } from './retry-policy.js';
11
+ import type { FailedQueue } from './failed-queue.js';
12
+ import type { BatchSender } from '../send/batch-sender.js';
13
+ import type { Sender } from '../send/sender.js';
14
+ import { Logger } from './logger.js';
15
+ export declare class SendPipeline {
16
+ private config;
17
+ private registry;
18
+ private identity;
19
+ private presetProps;
20
+ private retryPolicy;
21
+ private failedQueue;
22
+ private logger;
23
+ private pending;
24
+ private senders;
25
+ private batchSender?;
26
+ private abortControllers;
27
+ constructor(config: TrackerConfig, registry: PluginRegistry, identity: IdentityManager, presetProps: PresetPropertyBuilder, retryPolicy: RetryPolicy, failedQueue: FailedQueue, logger: Logger);
28
+ setSenders(senders: Sender[]): void;
29
+ setBatchSender(b: BatchSender): void;
30
+ /** 构造事件对象 */
31
+ buildEvent(type: EventData['type'], opts?: {
32
+ event?: string;
33
+ properties?: Record<string, unknown>;
34
+ }): EventData;
35
+ /** 异步发送 */
36
+ send(data: EventData, callback?: Callback): void;
37
+ /** 加密后真正下发 */
38
+ private dispatchAfterEncrypt;
39
+ private pickSender;
40
+ private trackPending;
41
+ /**
42
+ * 强制 flush:
43
+ * - batch 模式:立即触发 batch sender 的 flush
44
+ * - failed queue:把残留队列重发
45
+ * - 所有 pending:等完成
46
+ */
47
+ flush(): Promise<void>;
48
+ /** 等待所有 in-flight 任务结束 */
49
+ waitUntilIdle(): Promise<void>;
50
+ /** Abort 所有挂起 / in-flight 任务 */
51
+ abortAll(reason?: string): void;
52
+ /** 给 sender 用:申请一个 AbortSignal,发送完成 / abort 时自动释放 */
53
+ takeAbortController(key: Symbol): AbortController;
54
+ releaseAbortController(key: Symbol): void;
55
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 签名 Identity(HMAC-SHA256)
3
+ * - 把 cookie / localStorage 中的 distinct_id / first_id 加密 + 签名
4
+ * - 防止用户篡改身份
5
+ * - 基于 Web Crypto API(jsdom + Node 18+)
6
+ */
7
+ /** 异步 HMAC-SHA256(推荐使用) */
8
+ export declare function hmacSignAsync(data: string, secret: string): Promise<string>;
9
+ /** 异步验证签名 */
10
+ export declare function hmacVerifyAsync(data: string, secret: string, signature: string): Promise<boolean>;
11
+ export interface SignedIdentity {
12
+ /** 同步签名 */
13
+ sign(value: string): string;
14
+ /** 异步签名(HMAC-SHA256) */
15
+ signAsync(value: string): Promise<string>;
16
+ /** 同步校验 */
17
+ verify(value: string, signed: string): boolean;
18
+ /** 异步校验 */
19
+ verifyAsync(value: string, signed: string): Promise<boolean>;
20
+ /** 给 KV 写入用的编码(`${value}|${sig}`) */
21
+ encode(value: string): string;
22
+ /** 从 KV 读取后还原(失败返回 null) */
23
+ decode(raw: string): string | null;
24
+ /** 异步版本 */
25
+ encodeAsync(value: string): Promise<string>;
26
+ decodeAsync(raw: string): Promise<string | null>;
27
+ }
28
+ /** 创建签名器 */
29
+ export declare function createSignedIdentity(secret: string): SignedIdentity;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 事件数据拦截 Stage
3
+ * - 3 个 Stage: buildDataStage / businessStage / sendDataStage
4
+ * - 按 priority 升序执行
5
+ * - cancellationToken 可中断后续
6
+ *
7
+ * 灵感来自神策 sa-sdk-javascript 内部实现
8
+ */
9
+ export type StageName = 'buildDataStage' | 'businessStage' | 'sendDataStage';
10
+ export interface StageContext<T> {
11
+ data: T;
12
+ /** 阶段元信息 */
13
+ meta: {
14
+ stage: StageName;
15
+ [key: string]: unknown;
16
+ };
17
+ /** 取消令牌:调 stop() 后后续 interceptor 跳过 */
18
+ cancellationToken: {
19
+ stop: () => void;
20
+ };
21
+ /** SDK 引用,供 interceptor 使用 */
22
+ owner?: unknown;
23
+ }
24
+ export interface StageInterceptor<T> {
25
+ /** 唯一名(同名注册会覆盖) */
26
+ name: string;
27
+ /** 数字越小越先执行,默认 100 */
28
+ priority?: number;
29
+ /** 拦截处理,返回新数据或直接改 ctx.data */
30
+ entry: (ctx: StageContext<T>) => T | void;
31
+ }
32
+ export declare class StageChain<T = unknown> {
33
+ private stage;
34
+ private list;
35
+ private stopped;
36
+ private stopFlag;
37
+ constructor(stage: StageName);
38
+ /** 注册一个拦截器(同名覆盖) */
39
+ register(spec: StageInterceptor<T>): void;
40
+ /** 移除一个拦截器 */
41
+ unregister(name: string): void;
42
+ /** 获取所有拦截器名(调试用) */
43
+ list2(): string[];
44
+ /** 重置 stage(含清除停止标志) */
45
+ reset(): void;
46
+ /** 主入口:顺序执行 */
47
+ run(input: T, owner?: unknown): T;
48
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Track API(v1.1.1)
3
+ */
4
+ import type { EventTracker } from '../core/tracker.js';
5
+ import type { SendPipeline } from './send-pipeline.js';
6
+ export declare function attachTrackApi(sdk: EventTracker, pipeline: SendPipeline): void;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * SDK 主类(v1.1.1)
3
+ *
4
+ * 通过 attachXxxApi 模块化挂载所有方法,主类只负责:
5
+ * - 初始化(init)
6
+ * - 装配管线(Pipeline)
7
+ * - 提供公共 getter / setter
8
+ * - 提供 flush / waitUntilIdle / abort / close
9
+ */
10
+ import { Logger } from './logger.js';
11
+ import { PluginRegistry, type Plugin } from './plugin.js';
12
+ import { InstanceChannel } from './instance-channel.js';
13
+ import { RetryPolicy } from './retry-policy.js';
14
+ import { FailedQueue } from './failed-queue.js';
15
+ import { SignedIdentity } from './signed-identity.js';
16
+ import { SendPipeline } from './send-pipeline.js';
17
+ import type { TrackerConfig, Callback, SendType, ServerURL } from '../types/index.js';
18
+ export declare class EventTracker {
19
+ readonly lib_name = "event-tracker";
20
+ readonly lib_version = "1.1.0";
21
+ readonly DEFAULT_SEND_TYPE: SendType;
22
+ private _config;
23
+ private _store;
24
+ private _identity;
25
+ private _presetProps;
26
+ private _logger;
27
+ private _registry;
28
+ private _senders;
29
+ private _batchSender?;
30
+ private _retryPolicy;
31
+ private _failedQueue;
32
+ private _channel;
33
+ private _pipeline;
34
+ private _signedIdentity?;
35
+ private _inited;
36
+ readonly instanceId: string;
37
+ constructor();
38
+ /**
39
+ * 初始化 SDK(只可调用一次;重复调用会被忽略)
40
+ * @param config 完整配置项;详见 TrackerConfig
41
+ * @throws InitError 当 server_url / app_id 缺失时
42
+ * @example
43
+ * ```ts
44
+ * sdk.init({
45
+ * app_id: 'demo',
46
+ * server_url: 'https://api.example.com/sa',
47
+ * send_type: 'beacon',
48
+ * debug: 1,
49
+ * });
50
+ * ```
51
+ */
52
+ init(config: TrackerConfig): void;
53
+ use(plugin: Plugin): this;
54
+ /** @internal */
55
+ __noop: () => void;
56
+ track(event: string, properties?: Record<string, unknown>, _callback?: Callback): void;
57
+ trackSignup(userId: string, properties?: Record<string, unknown>, _callback?: Callback): void;
58
+ trackLinkage(properties: Record<string, unknown>, _callback?: Callback): void;
59
+ trackLink(element: HTMLElement | string, properties?: Record<string, unknown>, _callback?: Callback): void;
60
+ trackLinks(elements: HTMLElement[] | NodeListOf<Element> | string, properties?: Record<string, unknown>, _callback?: Callback): void;
61
+ trackHeatMap(properties: Record<string, unknown>, _callback?: Callback): void;
62
+ trackWebClick(properties: Record<string, unknown>, _callback?: Callback): void;
63
+ trackWebStay(properties: Record<string, unknown>, _callback?: Callback): void;
64
+ identify(_distinctId: string, _isSave?: boolean): this;
65
+ login(_loginId: string): this;
66
+ logout(_resetAnonymousId?: string): this;
67
+ resetAnonymousIdentity(_newAnonymousId?: string): this;
68
+ alias(_newId: string, _originalId?: string): void;
69
+ getDistinctId(): string;
70
+ getAnonymousId(): string;
71
+ getFirstId(): string;
72
+ getLoginId(): string;
73
+ getOriginalId(): string;
74
+ register(_props: Record<string, unknown>): this;
75
+ registerOnce(_props: Record<string, unknown>): this;
76
+ clearAllRegister(): this;
77
+ unsetRegister(_key: string): this;
78
+ registerPage(_props: Record<string, unknown>): this;
79
+ registerSession(_props: Record<string, unknown>): this;
80
+ registerSessionOnce(_props: Record<string, unknown>): this;
81
+ setProfile(_props: Record<string, unknown>, _callback?: Callback): void;
82
+ setOnceProfile(_props: Record<string, unknown>, _callback?: Callback): void;
83
+ incrementProfile(_props: Record<string, number>, _callback?: Callback): void;
84
+ appendProfile(_props: Record<string, unknown>, _callback?: Callback): void;
85
+ unsetProfile(_prop: string, _callback?: Callback): void;
86
+ deleteProfile(_callback?: Callback): void;
87
+ /** 关闭 SDK(track noop) */
88
+ disable(): this;
89
+ /** 启用 SDK */
90
+ enable(): this;
91
+ /** 切换 server_url(多 sink / 灰度 / 主备切换)
92
+ * @param url 单个 URL 或 URL 数组
93
+ */
94
+ setServerURL(url: ServerURL): this;
95
+ switchServer(url: ServerURL): this;
96
+ /**
97
+ * 强制 flush batch sender + failed queue + 等待所有 in-flight 完成
98
+ */
99
+ flush(): Promise<void>;
100
+ /**
101
+ * 等待所有 in-flight 任务结束(发送、加密、queue 处理)
102
+ */
103
+ waitUntilIdle(): Promise<void>;
104
+ /** Abort 所有挂起任务 */
105
+ abort(reason?: string): void;
106
+ /** 完整关闭(batch stop + channel close) */
107
+ close(): void;
108
+ /** 工具 */
109
+ uuid(): string;
110
+ /** 预置属性(手动计算) */
111
+ getPresetProperties(): Record<string, unknown>;
112
+ /** 完整关闭:channel close + pipeline abort + batch stop */
113
+ shutdown(): void;
114
+ getConfig(): TrackerConfig;
115
+ getLogger(): Logger;
116
+ getRegistry(): PluginRegistry;
117
+ getRetryPolicy(): RetryPolicy;
118
+ getFailedQueue(): FailedQueue;
119
+ getChannel(): InstanceChannel;
120
+ getPipeline(): SendPipeline;
121
+ getSignedIdentity(): SignedIdentity | undefined;
122
+ isBrowser(): boolean;
123
+ isInitialized(): boolean;
124
+ }
125
+ /** 创建 / 切换实例 */
126
+ export declare function initPara(config: TrackerConfig): EventTracker;
127
+ /** 通过 client_id 取已有实例 */
128
+ export declare function registerAppid(instanceId: string): EventTracker | undefined;
129
+ /** 列出所有实例 */
130
+ export declare function listInstances(): EventTracker[];
@@ -0,0 +1,4 @@
1
+ /**
2
+ * UUID v4 生成(无依赖,使用 crypto.getRandomValues)
3
+ */
4
+ export declare function uuidv4(): string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * 主入口:构造一个默认 SDK 实例(兼容神策风格的全局对象)
3
+ *
4
+ * 暴露:
5
+ * - default export: 已经 attach 了所有 API 的全局单例
6
+ * - EventTracker: 类,可以多实例
7
+ * - named exports: 所有插件 / 工具
8
+ */
9
+ import { EventTracker } from './core/tracker.js';
10
+ import { PresetEvent, PresetProperty, LIB_NAME, LIB_VERSION } from './types/constants.js';
11
+ declare const tracker: EventTracker;
12
+ export default tracker;
13
+ export { tracker };
14
+ export { EventTracker };
15
+ export { initPara, registerAppid, listInstances } from './core/tracker.js';
16
+ export type { TrackerConfig, BaseConfig, SendConfig, StorageConfig, IdentityConfig, EncryptConfig, PresetConfig, DebugConfig, JsAppConfig, ClientConfig, DebugSenderConfig, EventData, SendType, StorageType, Callback, LogLevel, JSONValue, JSONObject, JSONArray, PropertyMap, ServerURL, StageName, HookName, } from './types/index.js';
17
+ export type { Plugin, InstallContext } from './core/plugin.js';
18
+ export type { StageInterceptor, StageContext, StageChain } from './core/stage.js';
19
+ export type { Lifecycle, HookFn } from './core/lifecycle.js';
20
+ export { SDKError, InitError, SendError, EncryptError, IdentityError, StorageError, PluginError, ConfigError, isSDKError, } from './core/errors.js';
21
+ export { createSignedIdentity, hmacSignAsync, hmacVerifyAsync, } from './core/signed-identity.js';
22
+ export type { SignedIdentity } from './core/signed-identity.js';
23
+ export { SendPipeline } from './core/send-pipeline.js';
24
+ export { PluginRegistry } from './core/plugin.js';
25
+ export { RetryPolicy } from './core/retry-policy.js';
26
+ export { FailedQueue } from './core/failed-queue.js';
27
+ export { InstanceChannel } from './core/instance-channel.js';
28
+ export { Logger } from './core/logger.js';
29
+ export { IdentityManager } from './core/identity.js';
30
+ export { PresetPropertyBuilder } from './presets/preset-properties.js';
31
+ export { PresetEvent, PresetProperty, LIB_NAME, LIB_VERSION };
32
+ export { autoTrack } from './plugins/auto-track/index.js';
33
+ export { pageLoad } from './plugins/pageload/index.js';
34
+ export { pageLeave } from './plugins/pageleave/index.js';
35
+ export { exposure } from './plugins/exposure/index.js';
36
+ export { sessionEvent } from './plugins/session-event/index.js';
37
+ export { debugSender } from './plugins/debug-sender/index.js';
38
+ export { indexedDBSender } from './plugins/indexeddb-sender/index.js';
39
+ export { webviewBridge } from './plugins/webview-bridge/index.js';
40
+ export { encryptor, xorEncryptor, defaultEncryptor, defaultDecryptor, aesGcmEncryptAsync, aesGcmDecryptAsync } from './plugins/encrypt/index.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * auto-track 插件
3
+ * - $pageview: 路由变化时自动 track
4
+ * - $WebClick: 监听 click,自动 track
5
+ * - $WebStay: 页面离开时上报停留时长
6
+ * - $scrolldepth: 25/50/75/100% 触发
7
+ */
8
+ import type { Plugin } from '../../core/plugin.js';
9
+ export interface AutoTrackOptions {
10
+ pageview?: boolean;
11
+ webclick?: boolean;
12
+ webstay?: boolean;
13
+ scrolldepth?: boolean;
14
+ /** webclick 元素选择器过滤,匹配才上报 */
15
+ webclickSelector?: string;
16
+ /** 上报时附带的元素属性(attribute 名单) */
17
+ webclickAttrs?: string[];
18
+ /** scroll 触发阈值(百分比数组) */
19
+ scrollThresholds?: number[];
20
+ }
21
+ export declare function autoTrack(opts?: AutoTrackOptions): Plugin;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Debug 发送器(独立 plugin)
3
+ * - 启用后走 GET 请求到 debug_mode_url(默认从 server_url 推导 ?debug)
4
+ * - 成功后 alert("debug数据发送成功" + data)
5
+ * - 失败时 alert("debug失败" + JSON.stringify(err))
6
+ * - 优先级最高(先于其它 senders 执行)
7
+ */
8
+ import { PresetProperty } from '../../types/constants.js';
9
+ import type { Plugin } from '../../core/plugin.js';
10
+ import type { EventData } from '../../types/index.js';
11
+ export interface DebugOptions {
12
+ /** 是否启用(默认从 config.debug_mode 取) */
13
+ enable?: boolean;
14
+ /** 调试接收端 URL(默认从 config.server_url 推导 ?debug) */
15
+ url?: string;
16
+ /** 调试上传标记(出现在 Dry-Run header) */
17
+ upload?: string;
18
+ /** 成功回调(默认 alert) */
19
+ onSuccess?: (event: EventData) => void;
20
+ /** 失败回调(默认 alert) */
21
+ onError?: (err: Error, event: EventData) => void;
22
+ }
23
+ export declare function debugSender(opts?: DebugOptions): Plugin;
24
+ export { PresetProperty };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * encrypt 插件(v1.1 增强版)
3
+ *
4
+ * 三个能力:
5
+ * 1. 加密 + 解密配对(神策风格)
6
+ * - config.encryptor / config.decoder
7
+ * - 加密函数接收 JSON 字符串返回字符串;解密函数反向
8
+ *
9
+ * 2. Web Crypto AES-GCM
10
+ * - aesGcmEncrypt / aesGcmDecrypt
11
+ * - 基于 Web Crypto API,256-bit key,输出 base64(iv||ciphertext)
12
+ *
13
+ * 3. 钩子:encryptEvent / decryptEvent
14
+ * - 用于在事件被发送前/接收后做二次处理(脱敏、补字段等)
15
+ *
16
+ * 用法示例:
17
+ * import { encryptor, aesGcmEncrypt, aesGcmDecrypt } from '@macroui/event-tracker/plugin/encrypt';
18
+ * const key = 'my-32-byte-secret-key-1234567890ab';
19
+ * sdk.use(encryptor({
20
+ * encrypt: aesGcmEncrypt(key),
21
+ * decrypt: aesGcmDecrypt(key),
22
+ * encryptEvent: (e) => scrubPII(e),
23
+ * decryptEvent: (e) => e,
24
+ * }));
25
+ */
26
+ import type { Plugin } from '../../core/plugin.js';
27
+ import type { EventData } from '../../types/index.js';
28
+ export type EncryptFn = (data: string) => string;
29
+ export type DecryptFn = (data: string) => string;
30
+ export type EventTransform = (event: EventData) => EventData | unknown;
31
+ export interface EncryptorOptions {
32
+ /** 加密:JSON 字符串 -> 字符串 */
33
+ encrypt: EncryptFn;
34
+ /** 解密:字符串 -> JSON 字符串(可选;多数场景 SDK 不下行) */
35
+ decrypt?: DecryptFn;
36
+ /** 事件级加密前钩子(脱敏、补字段) */
37
+ encryptEvent?: EventTransform;
38
+ /** 事件级解密后钩子(一般用于 debug 拉回来的事件) */
39
+ decryptEvent?: EventTransform;
40
+ }
41
+ declare function xorBase64(input: string, key: string): string;
42
+ export declare function defaultEncryptor(key: string): EncryptFn;
43
+ export declare function defaultDecryptor(key: string): DecryptFn;
44
+ export { xorBase64 };
45
+ /** AES-GCM 加密(同步 API 抛错;改用 Async 版本)
46
+ * @deprecated Web Crypto API 是异步的,同步签名不现实;
47
+ * 改用 aesGcmEncryptAsync + asyncSend helper,或预计算密文。
48
+ */
49
+ export declare function aesGcmEncrypt(_rawKey: string): EncryptFn;
50
+ /** AES-GCM 加密(异步版):返回 Promise<string> */
51
+ export declare function aesGcmEncryptAsync(rawKey: string): (data: string) => Promise<string>;
52
+ /** AES-GCM 解密(异步版) */
53
+ export declare function aesGcmDecryptAsync(rawKey: string): (data: string) => Promise<string>;
54
+ export declare function encryptor(opts: EncryptorOptions): Plugin;
55
+ /** 便捷工厂:XOR 配对 */
56
+ export declare function xorEncryptor(key: string): Plugin;