@sensorswave/electron-sdk
v1.0.0
Published
Sensors Wave Electron analytics SDK — main + renderer dual entry
Readme
Sensors Wave Electron SDK
English | 简体中文
Sensors Wave Electron SDK 是面向 Electron 应用的桌面端数据埋点上报库, 覆盖主进程与渲染进程:事件采集、用户身份管理、用户属性、批量上报、AB 测试与合规(opt-out)能力。
如果你是第一次接触 Sensors Wave,欢迎访问 sensorswave.com 了解产品并创建账号。
完整的可运行示例见 demo/ 目录。
SDK 使用
SDK 提供三个入口,分别对应 Electron 的三个运行环境:
| 入口 | 导入路径 | 运行环境 |
| -------- | ----------------------------------------- | ------------------------ |
| Main | @sensorswave/electron-sdk(或 /main) | Electron 主进程 |
| Preload | @sensorswave/electron-sdk/preload | Preload 脚本 |
| Renderer | @sensorswave/electron-sdk/renderer | 渲染进程(页面/webview) |
1. 安装
yarn add @sensorswave/electron-sdk要求 electron >= 20(peerDependency)。支持 Windows、macOS 与 Linux。
2. 主进程初始化
import sensorswave from '@sensorswave/electron-sdk/main';
sensorswave.init('your-source-token', {
apiHost: 'https://your-api-host.com',
autoCapture: true,
enableClickTrack: true,
debug: false
});主进程的 init 是同步的 —— 调用后立即返回 SDK 实例。可以在主进程入口文件顶部、app.whenReady() 之前调用。
公共属性(静态值或动态函数)在主进程注册:
// 动态属性必须在此注册:渲染进程经 IPC 注册的属性会被序列化,
// 函数值无法透传到主进程。
sensorswave.registerCommonProperties({
app_version: '1.0.0',
current_time: () => Date.now() // 每次发事件都会重新求值
});3. 接入 Preload 脚本
preload 脚本会安装桥接层,在 window.sensorswave 上暴露受限 API(不暴露 ipcRenderer 本身):
// preload.js
import { setupPreload } from '@sensorswave/electron-sdk/preload';
setupPreload(); // 暴露 window.sensorswave要求开启 contextIsolation: true(Electron 推荐默认)。
4. 渲染进程初始化
import sensorswave from '@sensorswave/electron-sdk/renderer';
await sensorswave.init();渲染端 init 是异步的:初始化时经 IPC 拉取一次主进程配置,保证插件开关(autoCapture、enableClickTrack、opt-out 状态)与主进程的单一配置源保持同步。所有写操作(trackEvent、profileSet 等)均经 IPC 转发到主进程。
5. 上报自定义事件
sensorswave.trackEvent('ButtonClick', {
button_name: 'submit',
page: 'home'
});配置项
| 配置项 | 类型 | 默认值 | 说明 |
| ----------------- | ------- | ----------------- | ---------------------------------------------------------------------------------------------- |
| sourceToken | string | (必填) | 项目唯一标识,用于上报鉴权 |
| apiHost | string | (必填) | 数据接收服务器地址 |
| debug | boolean | false | 是否开启调试日志 |
| autoCapture | boolean | true | 是否自动采集预置事件(应用生命周期、页面浏览/离开) |
| enableClickTrack | boolean | false | 是否开启元素点击自动采集($AppClick) |
| batchSend | boolean | false | 是否批量发送事件(每批最多 10 条、每 5 秒批量发送一次);关闭时每条事件立即发送 |
| enableAB | boolean | false | 是否启用 AB 测试 |
| abRefreshInterval | number | 600000(10 分钟) | AB 数据刷新间隔(毫秒),最小 30000 |
| anonId | string | '' | 接入方传入的匿名 ID。设置后覆盖 SDK 生成的匿名 ID 并持久化在本地,后续启动即使不再传入也会复用 |
| optOutCapturing | boolean | false | 合规:禁用全部采集(opt-out)。为 true 时 SDK 不采集、不上报任何数据 |
| persistOptOut | boolean | false | 合规:将 opt-out 决策持久化到本地,跨应用重启保留 |
API 方法
除特别说明外,以下方法均为主进程 SDK 的方法。渲染进程 SDK 暴露相同的写方法(经 IPC 转发),差异见渲染进程 API。
事件上报
trackEvent
手动上报自定义事件并携带属性。
参数:
eventName(string, 必填):事件名properties(Object, 可选):随事件附带的其他属性
示例:
sensorswave.trackEvent('ButtonClick', {
button_name: 'submit',
page: 'home',
category: 'user_action'
});track
完整控制事件结构的高级上报方法,允许手动指定事件的各字段。未传(或传空)的字段由 SDK 兜底:time 默认取当前时间,trace_id 默认生成 UUID v4,anon_id / login_id 默认取本地存储的身份。
参数:
eventData(Object, 必填):事件对象,结构如下:event(string, 必填):事件名properties(Record<string, any>, 可选):事件属性time(number, 可选):事件时间戳(毫秒);缺省取当前时间trace_id(string, 可选):唯一追踪 ID;缺省生成 UUID v4anon_id(string, 可选):匿名用户 ID;缺省取本地存储的匿名 IDlogin_id(string, 可选):登录用户 ID;缺省取本地存储的登录 IDuser_properties(Object, 可选):随本事件附带的用户属性subject_properties(Record<string, any>, 可选):主体属性,原样透传
示例:
sensorswave.track({
event: 'PurchaseCompleted',
properties: {
product_id: '12345',
amount: 99.99,
currency: 'USD'
},
time: Date.now(),
trace_id: 'unique-trace-id-12345',
anon_id: 'anonymous-user-id',
login_id: 'user_12345',
user_properties: {
plan: 'premium',
signup_date: '2024-01-01'
}
});flush
手动触发一次队列批量发送。batchSend 关闭时为 no-op。
示例:
sensorswave.flush();用户身份
identify
设置当前用户的登录 ID,并发送 $Identify 事件将匿名行为与登录用户关联。
参数:
loginId(string, 必填):用户唯一标识(如邮箱、用户 ID、用户名)
示例:
sensorswave.identify('user_12345');setLoginId
仅设置登录 ID,不发送关联事件。适用于恢复已知登录态(如应用启动时),且不需要再次上报关联事件的场景。
示例:
sensorswave.setLoginId('user_12345');getAnonId
获取当前匿名 ID。默认由 SDK 自动生成并持久化在用户数据目录;若初始化时通过 anonId 配置传入,则返回该值。
返回: string
示例:
const anonId = sensorswave.getAnonId();
console.log('匿名 ID:', anonId);getLoginId
获取当前登录用户的登录 ID。未登录时返回空字符串。
返回: string
示例:
const loginId = sensorswave.getLoginId();
console.log('当前登录 ID:', loginId);用户属性
profileSet
覆盖设置用户属性。同名属性已存在时会被覆盖。
示例:
sensorswave.profileSet({
name: 'John Doe',
age: 30,
plan: 'premium'
});profileSetOnce
仅首次设置用户属性。已有值的属性不会被覆盖。
示例:
sensorswave.profileSetOnce({
signup_date: '2024-01-15',
initial_referrer: 'google'
});profileIncrement
对数值型用户属性累加指定数值。仅支持数值属性,非数值会被忽略。
示例:
sensorswave.profileIncrement({
login_count: 1,
points_earned: 100
});profileAppend
向列表型用户属性追加值,不去重。
示例:
sensorswave.profileAppend({
categories_viewed: ['electronics', 'mobile_phones']
});profileUnion
向列表型用户属性追加值并去重(避免重复值)。
示例:
sensorswave.profileUnion({
interests: ['technology', 'gaming']
});profileUnset
将指定用户属性置空(等效删除)。
参数:
propertyNames(string | string[], 必填):要置空的属性名(单个或数组)
示例:
sensorswave.profileUnset(['old_plan', 'expired_flag']);profileDelete
删除当前用户的全部用户属性数据。要求此前已设置登录 ID(identify 或 setLoginId)。此操作不可撤销。
示例:
sensorswave.profileDelete();公共属性
registerCommonProperties
注册静态或动态公共属性,之后每条事件都会携带。适用于附加全局上下文:应用版本、环境、用户维度的数据等。
参数:
properties(Record<string, string | number | boolean | Function>, 必填):要注册的属性- 静态属性:普通值
- 动态属性:返回值的函数(每次发事件时求值)
示例:
sensorswave.registerCommonProperties({
// 静态属性
app_version: '1.0.0',
environment: 'production',
// 动态属性(每次发事件时求值)
current_time: () => Date.now(),
user_session_id: () => getSessionId()
});动态属性必须在主进程注册。渲染进程注册的属性经 IPC 序列化后函数值会丢失 —— 渲染端只能注册静态值。
clearCommonProperties
删除已注册的指定公共属性。
参数:
propertyNames(string[], 可选):要删除的属性名数组;不传则清空全部
示例:
sensorswave.clearCommonProperties(['app_version', 'user_session_id']);AB 测试 / 功能开关
需要在 init 配置中开启 enableAB: true。以下方法均返回 Promise,求值在主进程完成。
checkFeatureGate
查询某功能开关(feature flag)对当前用户是否开启。AB 未启用或已禁用采集时返回 false。
返回: Promise<boolean>
示例:
const isEnabled = await sensorswave.checkFeatureGate('new_checkout_flow');
if (isEnabled) {
showNewCheckout();
}getExperiment
获取当前用户的实验变体数据。
返回: Promise<Object> —— 找不到 key 或 AB 未启用时返回空对象 {}。
示例:
const experiment = await sensorswave.getExperiment('homepage_layout');
if (Object.keys(experiment).length > 0) {
applyLayout(experiment.layout_type);
}getFeatureConfig
获取当前用户的功能远程配置。服务端返回 JSON 字符串,SDK 自动解析。
返回: Promise<Object> —— 找不到 key 或 AB 未启用时返回空对象 {}。
示例:
const config = await sensorswave.getFeatureConfig('ui_config');
if (config) {
const { theme, layout, features } = config;
updateUI(theme, layout, features);
}合规(opt-out 采集开关)
optOutCapturing
禁用全部采集。事件、属性操作、AB 求值全部变为 no-op;批量队列暂停(不删除);所有渲染进程会收到通知并停止 DOM 自动采集。init 前后均可调用。
示例:
sensorswave.optOutCapturing();optInCapturing
重新开启采集。若 init 时处于禁用状态(装配被跳过),此处会补跑装配(包括被延迟的 UTM $UserSet,如有)。
示例:
sensorswave.optInCapturing();hasOptedOutCapturing
查询当前是否已禁用采集。
返回: boolean
示例:
if (sensorswave.hasOptedOutCapturing()) {
console.log('采集已禁用');
}在 init 配置中设置
persistOptOut: true,可将 opt-out 决策持久化到本地、跨应用重启保留。
destroy
销毁 SDK:停止定时器、释放 IPC 监听并重置为未初始化状态。主要用于测试或完整重新初始化的场景。已持久化的 opt-out 决策会被保留。
示例:
sensorswave.destroy();渲染进程 API
渲染进程 SDK(@sensorswave/electron-sdk/renderer)提供与主进程一致的写方法(trackEvent、identify、setLoginId、profile*、registerCommonProperties —— 仅静态值、clearCommonProperties、flush、optOutCapturing、optInCapturing)。差异如下:
| 方法 | 渲染端行为 |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| init(options?) | 异步。经 IPC 拉取主进程配置以同步插件开关;options 可在本地覆盖 autoCapture / enableClickTrack / optOutCapturing |
| getAnonId() / getLoginId() | 异步(Promise<string>)。经 IPC 从主进程取值,本地缓存,身份变更时自动刷新 |
| hasOptedOutCapturing() | 异步(Promise<boolean>) |
| checkFeatureGate / getExperiment / getFeatureConfig | 签名相同,求值在主进程完成 |
示例:
import sensorswave from '@sensorswave/electron-sdk/renderer';
await sensorswave.init();
const anonId = await sensorswave.getAnonId();
sensorswave.trackEvent('PageRendered', { page: 'home' });预置事件
autoCapture 开启时,SDK 自动采集以下事件:
| 事件 | 触发时机 |
| --------------- | --------------------------------------------------------------------------------------------------------------------- |
| $AppInstall | 本机首次启动被检测到时(取不到真实安装时间时,兜底使用首次启动时间) |
| $AppStart | 应用 ready 时 |
| $AppEnd | 应用退出前(携带会话时长 $event_duration) |
| $AppPageView | 渲染进程页面展示时(含 history / hash 路由切换) |
| $AppPageLeave | 离开渲染进程页面时(携带页面停留时长) |
| $AppClick | 元素被点击时 —— 仅 enableClickTrack 为 true 时采集;仅采集带 data-track 属性(或 id)的元素,同一元素有节流去重 |
SDK 自身发送的系统事件:$Identify(登录绑定)、$UserSet(属性操作、UTM 归因)、$FeatureImpress / $ExpImpress(AB 曝光)。
自定义事件通过 trackEvent() 或 track() 上报。
预置属性
每条事件都会携带以下预置属性(在主进程采集):
| 属性 | 说明 |
| ---------------------------------------- | ------------------------------------------------- |
| $lib / $lib_version | SDK 类型(electron)与版本 |
| $os / $os_version | 操作系统与版本 |
| $app_id / $app_name / $app_version | 应用标识(取不到时从可执行文件/应用名推导)与版本 |
| $language | 系统语言 |
| $timezone_offset | 时区偏移(秒) |
| $screen_width / $screen_height | 主屏幕尺寸 |
| $device_id | 稳定的设备标识 |
| $brand / $manufacturer | 硬件厂商信息(桌面端通常为空) |
| $network_type / $wifi | 网络连接类型 |
数据存储与上报
- 身份(
anon_id、login_id)、opt-out 决策(可选持久化)与批量队列持久化在 ElectronuserData目录下。 - 立即发送模式(
batchSend: false,默认):每条事件立即发送。 - 批量模式(
batchSend: true):事件先写入磁盘队列,每 5 秒或每 10 条批量发送一次,失败时指数退避重试。队列上限 200 条;超过 7 天的数据会被丢弃。 - opt-out 期间产生的事件不会入队,也不会补发。
