@baukit/analytics-core
为Baukit TypeScript应用提供中性,隐私第一产品分析. 包裹 定义端口和安全政策; PostHog 支持属于单独的网络和本地 适配软件包。 它没有运行时间依赖.
为什么是端口,不是提供者包装
产品代码应当拥有事件意义和编译时间形状而无需导入提供者SDK. 这个
核心接受产品事件联盟,应用同意和隐私控制,并发送中性命令
信封为 a Transport。一个提供者适配器只翻译那些已经解密的信封.
获取财产所需的命令是:
- 在事件许可列表中只保留密钥 .
- Scrub屏蔽了密钥和敏感的字符串模式.
- 标记必要的共同背景和身份.
- 将消毒的信封排入运输.
类型设置
import {
AnalyticsClient,
type AnalyticsEvent,
type EventAllowlist,
type Transport,
} from '@baukit/analytics-core';
type ProductEvent =
| {
name: 'onboarding_started';
properties: { source: 'organic' | 'invite' };
}
| {
name: 'onboarding_completed';
properties: { duration_seconds: number };
};
const allowlist = {
onboarding_started: ['source'],
onboarding_completed: ['duration_seconds'],
} as const satisfies EventAllowlist<ProductEvent>;
declare const transport: Transport<ProductEvent>; // for example, a PostHog adapter
const analytics = new AnalyticsClient<ProductEvent>({
context: {
schema_version: 1,
app: 'architecture-health',
app_version: '1.0.0',
platform: 'web',
environment: 'production',
locale: 'de-DE',
},
allowlist,
transport,
});
analytics.capture({
name: 'onboarding_started',
properties: { source: 'organic' },
});
AnalyticsClientOptions.context 因此构建客户端时不需要
schema_version, (中文(简体) ), app, (中文(简体) ), app_version, (中文(简体) ), platform, (中文(简体) ), environment,或 locale 不键入检查.
添加名称到 ProductEvent 还使匹配的许可列表条目成为必要。 运行时间输入可以
仍然含有多余的密钥(例如,在不安全的铸出后或跨越了JavaScript边界后),所以
许可列表在运输前将其删除.
事件名称是产品自主的公约:稳定、过去 snake_case,例如
onboarding_completed。以模板字数类型编码英文过去时态将拒绝有效
不规则的形式和产生虚假的信心。 相反,客户使用保守的发展
警告(snake case 加上过去紧张的休眠症);它永远不会改变运行时间的交付。 追踪计划
目的和所有权仍然是产品责任.
同意
同意开始于 unknown. 在表示同意时捕获、识别电话和别名
unknown 或者说 denied 立即投放,绝不缓冲后期选入.
analytics.setConsent('granted'); // persist opt-in, then analytics may run
analytics.capture({
name: 'onboarding_completed',
properties: { duration_seconds: 42 },
});
analytics.setConsent('denied'); // persist withdrawal and discard every unsent command
setConsent 这不是一个分析事件。 同意在施工期间同步读取,
在第一次捕捉之前. InMemoryAnalyticsStorage 无依赖性默认;
产品应注入小同步 AnalyticsStorage 由设备存储支持。 如果
平台的本地存储 API 在构建前是同步的,水合的同步缓存
客户 原生反应, HydratedAnalyticsStorage 从
@baukit/analytics-posthog-native/storage 是缓存;此软件包不发送一个。 存储失败无法保护隐私:无法读取的同意变为
unknown,而且分析方法不会因为持久性诊断失败而抛出.
撤离清除了尚未交给运输队的命令。 已经飞了一批了 无法回顾,这是一个运输边界,而不是隐藏缓冲.
身份
客户端创建并坚持匿名UUID globalThis.crypto.randomUUID()。运行时间
没有它,包括一些反应原生配置,必须注入加密安全
uuidFactory;故意没有 Math.random() 倒计时.
analytics.setConsent('granted');
const anonymousId = analytics.anonymousId;
analytics.identify(internalUserUuid, { plan: 'free' });
analytics.alias(anonymousId, internalUserUuid); // accepted once for this anonymous identity
analytics.reset(); // logout: clear known identity and alias guard, rotate anonymous UUID
只接受UUID形用户ID. 这无法证明哪个系统发布了UUID, 所以产品
必须通过内部用户 UUID , 而不是电子邮件、 名称或提供者主题 。 直接切换
拒绝已知用户之间; 调用 reset() 先说 异名的后卫一直坚持 并承认在
大部分别名是匿名身份的命令 包括客户重建 特质
使用与事件属性相同的被屏蔽的键和敏感值规则来擦除.
AnalyticsClient 存储同意状态、 匿名 UUID、 已知用户 UUID 以及其它名
storageKeyPrefix。 。 。 . analyticsStorageKeys(prefix) 返回这四个密钥, 因此是一个持续存储
适配器可以列出它所保存的.
捣乱
默认密钥块列表为 email, (中文(简体) ), name, (中文(简体) ), token, (中文(简体) ), password, (中文(简体) ), authorization, (中文(简体) ), cookie, (中文(简体) ),
phone,以及 address匹配是案件/分离者不敏感和故意保守,所以
键类 displayName 财务报告和审定财务报表 auth_token 已编辑。 产品可以通过
blockedKeys。电子邮件形状的字符串,JWT形状的字符串,以及长六进制/ Base64 类似字符串成为
"[redacted]"。嵌入式阵列和平面物体在不改变输入的情况下进行穿行.
短键需要精确匹配, 因为 ip 作为子字符串也会修改 zip_code 财务报告和审定财务报表
description。 。 。 . DEFAULT_EXACT_BLOCKED_KEYS 编辑 ip, (中文(简体) ), ip_address, (中文(简体) ), remote_addr, (中文(简体) ),
x_forwarded_for,以及 x_real_ip 只有当普通键等于其中之一时。 添加产品
键,例如 q,通过 exactBlockedKeys 打开 scrubProperties 或者说 AnalyticsClient。 。 。 .
scrubProperties(properties, { blockedKeys: ['notes'], exactBlockedKeys: ['q'] });
scrubErrorEvent 对崩溃报告适用同样的规则,例如在哨兵报告中 beforeSend。 。 。 .
还可以编辑其中的密钥 ERROR_EVENT_BLOCKED_KEYS (单位:千美元)headers, (中文(简体) ), data, (中文(简体) ), query_string, (中文(简体) ), body, (中文(简体) ),
vars, (中文(简体) ), geo,以及 env任何深度,包括请求的有效载荷、面包屑数据和堆栈
框变量。 字符串值在 ERROR_EVENT_PRESERVED_KEYS 保持原状, 所以事件,追踪
跨度 ID 幸存于长重击规则和堆栈框保存 filename, (中文(简体) ), abs_path, (中文(简体) ), function,以及
module。顶级 sdk 对象保留其密钥,所以SDK名称仍可读取. 其它 name
密钥,包括 OS 和设备名称,仍然被编辑.
Sentry.init({
dsn,
sendDefaultPii: false,
beforeSend: (event) => scrubErrorEvent(event, { blockedKeys: ['notes'] }),
});
洗涤器只是最后的防线. 事件属性必须保持有界限的元数据:永远 健康或食物价值,谈话或即时内容,免费文本,准确位置,证明, 或原始标识 URL.
缓冲和失败
接受命令输入带有这些默认的内存队列 :
- 最大100个等待命令;
- 20个命令或5秒后冲出;
- 最古老的等待命令掉到溢出处;
- 在最初的运输尝试之后进行两次复试,并有短暂的指数延迟;
- 重试后投放失败的批次 .
capture, (中文(简体) ), identify, (中文(简体) ), alias, (中文(简体) ), reset,以及 setConsent 是同步的,从不等待
供养. 大小触发的送出被安排在一个微任务中; 间隔送出使用 unref'd
运行时间支持的计时器 。 拒绝运输和同步运输的例外情况
内部被抓住,从不逃入用户之行. onTransportFailure 可用于
限制的诊断,甚至这种召回的例外都有限制.
flush() 是一个明确的最佳边界 总是解决的, 有用的测试和应用
寿命轮钩. dispose() 进行最佳冲洗并清除计时器。 队列不是
持续: 应用程序重新启动不会重现分析命令, 未知/ 否认的事件可以
后经同意后永远不会出现.
NoopTransport 安全丢弃命令. InMemoryTransport 保留可检查的信封
测试。 通过执行 PostHog 网络和 React 本地包插件 Transport<E> 翻译
中键 capture, (中文(简体) ), identify, (中文(简体) ), alias,以及 reset 信封变体;产品代码和隐私
政策保持不变.