# @brunyee-studio/onus-sdk 中文文档

规范地址：https://npmcn.com/package/%40brunyee-studio/onus-sdk/

版本：3\.1\.1
npm 元数据更新时间：2026-11-06T14:43:11.520Z
中文译文更新时间：2026-11-08T16:58:13.429Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40brunyee-studio/onus-sdk
原文对照：https://npmcn.com/package/%40brunyee-studio/onus-sdk/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：377 kB，70 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：rrweb ^2\.0\.0，@vercel/otel ^2\.1\.4，winston-transport ^4\.9\.0，@opentelemetry/api ^1\.9\.0，@opentelemetry/core ^2\.12\.0，@opentelemetry/api-logs ^0\.223\.0，@opentelemetry/sdk-logs ^0\.223\.0，pino-abstract-transport ^3\.0\.0，@opentelemetry/resources ^2\.12\.0，@opentelemetry/sdk-trace-base ^2\.12\.0，@opentelemetry/otlp-transformer ^0\.300\.0，@opentelemetry/context-async-hooks ^2\.12\.0
- 首次发布：2026-09-23T03:46:07.979Z
- 最新版本发布：2026-11-06T14:43:11.284Z
- 近 30 天下载量：2048（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：13（近 12 个月 13 个）

## 中文简介

Onus SDK官方:浏览器出错,会话回放,自定义事件,日志和网络分析,外加节点,皮诺,Winton和Next.js日志输出者(已存在的 Sentry SDKs工作不变;服务器日志的OTLP)

## 安装

```sh
npm install @brunyee-studio/onus-sdk
```

也可以使用：`pnpm add @brunyee-studio/onus-sdk`、`yarn add @brunyee-studio/onus-sdk`、`bun add @brunyee-studio/onus-sdk`

## README

# @brunyee-studio/onus-sdk (英语)

Onus 官方浏览器 SDK **错误、 会话重放、 自定义事件和网络分析** 它与Onus信封终点站交谈(`/api/{ingest_project_id}/envelope/`)并抓取API(`/api/{projectId}/analytics/batch/`) (中文(简体) ). 信封端点也接受一个已存在的Sentry SDK不变,分析师调用镜像 PostHog 的核心调用,因此一个已存在的PostHog 集成端口无需重写调用站点即可被取用.

## 安装

```bash
pnpm add @brunyee-studio/onus-sdk
```

分析包内的船只——独立 `@brunyee-studio/onus-analytics` 软件包已删除。 从 页:1 `@brunyee-studio/onus-sdk/analytics` 子路径( 见 [网络分析](https://npmcn.com/package/%40brunyee-studio/onus-sdk/#readme-web-analytics-brunyee-studioonus-sdkanalytics) 页:1.

```js
import { init, captureException, setReplayCaptureAllowed } from '@brunyee-studio/onus-sdk';

init({
  dsn: 'https://<public-key>@<ingest-host>/<numeric-project-id>',
  release: '1.0.0',
  environment: 'production',
  // Configure replay; recording waits for explicit host authorization:
  replays: { sampleRate: 1 },
});

// Only after the host has determined capture is authorized:
await setReplayCaptureAllowed(true);

try {
  risky();
} catch (e) {
  captureException(e);
}
```

DSN在设计上是公开的;滥用是通过利率限制和可选的每个键源允许列表处理服务器侧. 缺少或变形的 DSN 从未丢出: 每一个切入点(`init`,分析 `init`, (中文(简体) ), `startSessionReplay`, (中文(简体) ), `./node`, (中文(简体) ), `./next`, (中文(简体) ), `./pino`记录 a `console.warn`,禁用网络发送并保持应用程序运行,每个抓取,日志和分析呼叫都成为了禁用.

### 应用框标识( :`allowUrls` 编号 : `denyUrls`(中文(简体) )

默认, `captureException` 使用同样来源的应用中标记堆栈框架 高度:相对/空径和同源URL是应用程序代码,其他 绝对起源是第三方。 两个 `init` 选项缩小或扩展此选项:

```js
init({
  dsn,
  allowUrls: ['app.example.com', /\/static\/chunks/], // strings match by substring, RegExp by test
  denyUrls: ['/vendor/'], // always excludes, even when allowUrls matches
});
```

-   `allowUrls` (非空) 标记只匹配 app中的帧; `denyUrls` 永远 标记匹配框架退出应用,优先于 `allowUrls`。 。 。 .
-   空数组行为为“ 未设置 ” (返回到同一来源) heuristic);非阵列值被忽略.
-   适用于 `captureException` 仅限路径——有效载荷传递到 `captureEvent` 没有自动标记.

服务器散列上只有程序框分组出错, 所以跨源供应商 噪音不能分散组合。 捆绑 `webpack://` 框架(包括 `node_modules` 路径)默认情况下仍然在应用中被标记——使用 `denyUrls` 改为 把他们排除在外。 无应用框的堆叠倒回倒置所有框.

## 会话重放

二道所录. **自动启动( 建议)** - 通过一个 `replays` 块到 `init()`; 录音推迟到主机呼叫时进行 `setReplayCaptureAllowed(true)` 在其本身的法律/CMP决定之后。 SDK的内幕授权开始 每页会话都关闭,而且永远不会持续。 经批准, 默认情况下,每个会话记录和抽样都是选择下限的:

```js
init({
  dsn,
  replays: {
    sampleRate: 1, // fraction of sessions recorded (default 1 = all users)
    // sessionId: () => analytics.get_session_id(), // link playback to analytics sessions
  },
});
await setReplayCaptureAllowed(true); // Only after host authorization
// On withdrawal: stop without flushing unsent events, abort in-flight sends,
// and remove the replay id from future errors.
await setReplayCaptureAllowed(false);
// Re-grant re-runs the configured auto-start (including sampling) and, if
// selected, starts a fresh recording with a new replay id.
await setReplayCaptureAllowed(true);
```

事后发现的错误 `contexts.replay.replay_id` 自动 - 没有额外的接线。 一旦Onus接受第一首录音 就会开始连接 片段( 页面快照播放从开始), 因此错误从不指向 无法播放的重放; 在此之前捕获出的错误没有带重放 ID 。 补助金在开放时具有独家能力;退出后,提供新的补助金 重新运行最新 `init({ replays })` 配置, 而重新初始化 无 `replays` 删除已停放的自动启动. `enabled: false` (或省略 )选择完全退出.

**现有人工呼叫者的行为变化 :** 一个直接 `startSessionReplay()` 现在决定 `null` 直到主机明确调用 `setReplayCaptureAllowed(true)`。退出即刻停止记录,不 尾冲,取消飞行中的请求,并清除出错的qq重播链接. 重新赠与允许进行新的人工录音;它从未恢复撤回的录音.

### 隐私默认( 总是在)

捕捉默认是安全的隐私, 和面具发生 **运输前** (SDK在rrweb序列化任何内容之前和任何内容之前解决口罩) 片段离开页面 :

-   非密码字,类似文本的输入值通过强制口罩映射被遮蔽 (单位:千美元)`maskAllInputs`; 密码值为 **永远** 蒙上面纱,不能 解开面具.
-   普通 DOM 文本节点默认被遮蔽( Name`maskTextSelector: '*'`) (中文(简体) ).
-   `input[type="hidden"]`, (中文(简体) ), `input[type="radio"]`,以及 `input[type="checkbox"]` 要素是: **完全封锁** 默认: rrweb 隐藏路径跳过 这些类型(隐藏值和无线电/检查框) `value` 属性 ),并且其检查状态不会被重播.
-   标记了子树 `data-onus-private` 被完全封锁.
-   摄像头 横跨原生地的 Iframe 摄像头 内线影像不动.
-   已录制的页面 URL 省略了查询字符串,片段,以及证书.

**未洗过的:** 遮盖输入值, 普通 DOM 文本 节点和被封锁的子树 管理部 **属性** (例如要件) `title` 或 `href` 锁定的属性),图像 URL, **`<style>` 编号 : 样式表文本** (由rrweb序列化为: `_cssText`外边 `maskTextSelector` 隐藏路径)和非回放有效载荷被记录 逐字记录。 主机必须用 `data-onus-private` (或 `privacy.blockSelector`)并审查敏感路线和每个数据路径 之前允许在生产中重放.

### 每集成一次淘汰

通过一个打字 `privacy` 对象( 手工 `startSessionReplay` 或 `replays` 故意放松非密码口罩 以达到这个目的. `privacy` 旗子总能取胜 `recordOptions` 传球,还有 敌对 `recordOptions` 永远无法击败蒙面,启用画布/框架 抓取,替换SDK的 `emit`,或通过rrweb预包装事件 `packFn`编号 :`plugins` (被剥去的:在SDK发射前跑出并 能够绕过 Meta href sanitization. 空的、 空白的或 CSS 无效的 选择器返回到安全默认处, 而不是损坏掩码( rrweb) 2.1.1 无声记录在无效选择器上被揭发). `privacy.blockSelector` 实值 **添加剂**: 它 EXTENDS 内置块列表 —— 它永远无法删除 默认块( e)`data-onus-private`,隐藏,收音机,和复选框输入). 没有 `privacy: false` 方便开关. URL 最小化意味着敏感数据必须永远不要 活在路径中——主机也应屏蔽敏感的子树:

```js
import { init, setReplayCaptureAllowed } from '@brunyee-studio/onus-sdk';
import { startSessionReplay } from '@brunyee-studio/onus-sdk/replay';

// Strict default — everything masked (after authorization):
await setReplayCaptureAllowed(true);
await startSessionReplay({ dsn });

// Selective text opt-down — only mask text inside a known-sensitive area:
init({
  dsn,
  replays: {
    privacy: { maskTextSelector: '.sensitive-area' },
  },
});

// Extra blocked subtree — privacy.blockSelector ADDS to the built-in block
// list; [data-onus-private], input[type=hidden], input[type=radio] and
// input[type=checkbox] stay blocked:
init({
  dsn,
  replays: {
    privacy: {
      blockSelector: '.payment-form',
      ignoreSelector: '.skip-recording',
    },
  },
});
```

手动控制仍然通过单独的切入点工作 :

```js
import { setReplayCaptureAllowed } from '@brunyee-studio/onus-sdk';
import { startSessionReplay, stopSessionReplay } from '@brunyee-studio/onus-sdk/replay';

await setReplayCaptureAllowed(true); // Manual starts also require authorization.
const replayId = await startSessionReplay({ dsn, environment: 'production' });
// Errors carry contexts.replay.replay_id once the first segment is accepted.
```

`rrweb` 是一个 **可选同伴依赖** ——录音机捆绑只在录音实际开始时才懒散地装入,因此禁用回放的应用程序从不下载. 重放片段作为配对发布 `replay_event` + 键 `replay_recording` 封装物品(gzipt)与摄入路线和私人存储桶所期望的完全一致。 第一段(rrweb Meta + FullSnapshot)一拍即发;后段分批分送 `segmentIntervalMs` (违约5000)或 `maxEventsPerSegment` 事件(默认 100)。 片段发送重试网络错误,408,429和5xx至3次尝试并封顶回放;其他4xx回复则没有重试. 每个录相机在上传前被粘住( 在哪里) `CompressionStream` ),因此它是被压缩而存储的. 重播结束于 `idleTimeoutMs` 没有用户输入( 默认 5分钟) 或一次是 `maxReplayDurationMs` 长 (默认和最长为60分钟; 摄入会减少后段); 下一个用户输入会开始新的重放, 所以一个未注意的标签会停止记录 。 按球队保留赛设置的回放到期(默认为90天).

## 日志

结构化日志到 Onus 日志查看器为 `log` 信封项目。 打开 带有 `logs` 块; 没有一块, `logger` 电话什么也不做.

```ts
import { init, logger } from '@brunyee-studio/onus-sdk';

init({
  dsn: 'https://<key>@onus.example/<projectId>',
  release: 'web@1.4.2',
  logs: {
    minLevel: 'info', // default 'trace'
    captureConsole: ['warn', 'error'], // also send these console calls
    sessionId: () => analytics.get_session_id(),
  },
});

logger.info('checkout started', { cartItems: 3, tier: 'pro' });
logger.error(logger.fmt`payment ${orderId} failed after ${attempts} tries`);
```

-   **级别 :** `trace`, (中文(简体) ), `debug`, (中文(简体) ), `info`, (中文(简体) ), `warn`, (中文(简体) ), `error` 财务报告和审定财务报表 `fatal`。 。 。 .
-   **属性 :** 字符串、数字和布林,在线上输入。 其他值为JSON-字符串.
-   **`logger.fmt`数字 :** 保留信件模板及其参数为属性,因此类似行组在一起.
-   **自动上下文 :** 环境, 发布, SDK 名称和版本, 活动重放 id, `session.id`,以及没有查询字符串或碎片的页面 URL.
-   **交付 :**
    -   每封信封高达100个记录(和约512个KiB),默认每5个秒发送,或一批封装后立即发送.
    -   当页面被隐藏或卸下时,缓冲记录会随 `sendBeacon`。 。 。 .
-   **限制和失败:**
    -   最多保存了1 000份未发送的记录,最古老的记录首先被删除.
    -   A 类 `429` 暂停发送 `Retry-After`其他故障以指数方式回落到60秒.
    -   被丢弃的记录在客户报告中被计算并报告给Onus.
    -   伐木工从不扔.
-   **套装大小 :** 核心条目中的伐木船。 导入它永远不会在重放或分析码中拉出.

## 追踪`@brunyee-studio/onus-sdk/tracing`(中文(简体) )

浏览器跟踪: a `pageload` 根, a 键 `navigation` 根/ SPA 路由变化, 还有一个 `http.client` 儿童间距/ 每名 `fetch`编号 :`XMLHttpRequest`每一个根被发送 作为一体 `transaction` 信封项并显示在 Traces 页面上.

```ts
import { init } from '@brunyee-studio/onus-sdk';
import { startBrowserTracing } from '@brunyee-studio/onus-sdk/tracing';

init({ dsn: 'https://<key>@onus.example/<projectId>', environment: 'production' });
const tracing = startBrowserTracing({
  tracesSampleRate: 0.1, // default 1
  service: 'web', // default 'browser'
  tracePropagationTargets: ['https://api.example.com', /^https:\/\/[a-z]+\.example\.com\//],
});
// tracing?.stop() removes every patch.
```

-   **需求 `init()` 先说.** `startBrowserTracing` 返回时 `null` 当 SDK 没有有效的 DSN 或追踪已经启动时.
-   **根数 :** 根结束于其最后一次请求完成后 1 s ()`idleTimeoutMs`),最多为30 s后(`finalTimeoutMs`),在下一个导航上,或 `pagehide`。请求尚未打开,然后发出状态 `cancelled`开始于 `performance.timeOrigin`。 。 。 .
-   **导航 :** `history.pushState`编号 :`replaceState` 财务报告和审定财务报表 `popstate`; 只有路径名更改才开始新的根。 在更改 URL 之前获取下一页的路由器应该调用 `startNavigation(url)` 当导航开始时,这些请求(并且服务器横跨它们)会在新页面的跟踪中降落;随后的历史变化不会为同一路径启动第二个根. `startNavigation` 追踪未运行时是禁用.
-   **根与根之间的请求 :** 在没有根端时(在上个根结束之后)提出的请求会随着上个根端的采样决定而获得新的痕量标识,所以一个已结束的痕量永远不会继续增长.

Next.js App 路由器在下页的有效载荷之前获取 `pushState`,所以打电话 `startNavigation` 从 `instrumentation-client.ts`数字 :

```ts
// instrumentation-client.ts
import { startNavigation } from '@brunyee-studio/onus-sdk/tracing';

export function onRouterTransitionStart(url: string) {
  startNavigation(url);
}
```

-   **请求跨度 :** 名称 `METHOD /path`,与 `http.request.method`, (中文(简体) ), `url.full` (无查询或片段)和 `http.response.status_code`。状态 \\\\ 500 或网络错误为 `internal_error`对SDK自己摄入路线的要求永远无法追查.
-   **`traceparent` 传播 :** 默认情况下, 只有同源请求才能得到信头, 因此 CDNs 和第三方 永远不会看到你的跟踪 ID . `tracePropagationTargets` 替换默认 : RegExp 用绝对 URL 进行测试; 字符串为绝对 URL ()`https://api.example.com`)仅在该确切来源上与前缀相匹配;路径字符串(`/api/`)只匹配路径始于它的同源请求;任何其他字符串都是主机(`api.example.com`, (中文(简体) ), `localhost:3000`)与主机或其子域相匹配,从不象像 `api.example.com.evil.net`。字符串在 URL 的子字符串上永远不匹配,所以一个有路径的主机(`api.example.com/v1`)或协议相对字符串(`//cdn.example.com`)从不匹配任何东西:使用完整的URL(`https://api.example.com/v1`)或RegExp. `tracePropagationTargets: []` 完全关闭传播。 现有 `traceparent` 永远不会被覆盖.
-   **抽样:** 确定每个根一次。 未被采样的根没有发出任何信号,但仍会传播 `traceparent` 有旗帜 `00`,因此服务器可以尊重决定.
-   **关联性 :** 在追踪运行时, `logger` 记录带有活动 `trace_id` 并记录错误 `contexts.trace`。核心条目只保留一个微小的跟踪记录,而不是跟踪器。 每个回放片段列出自前一段以来开始或传播的痕迹为: `trace_ids`,所以重播的日志侧边栏也显示了你的后端对这些痕迹的行.
-   **套装大小 :** 其自己的子路径,没有OpenTeleometry依赖。 从未导入其下载的应用程序 .

## 节点( E)`@brunyee-studio/onus-sdk/node`(中文(简体) )

```sh
pnpm add @brunyee-studio/onus-sdk @opentelemetry/api @opentelemetry/api-logs @opentelemetry/core \
  @opentelemetry/otlp-transformer @opentelemetry/resources @opentelemetry/sdk-logs
```

```ts
import { init, logger, captureException, flush } from '@brunyee-studio/onus-sdk/node';

init({
  dsn: process.env.ONUS_DSN,
  service: 'api',
  environment: 'production',
  release: '1.4.0',
});
logger.info('order placed', { orderId });
captureException(err); // error event with contexts.trace from the active span
await flush(); // before a serverless function returns
```

-   日志从OTLP/JSON到 `/api/{projectId}/otlp/v1/logs`,分批(≤512个记录, 1 s),并被拆分到1个米B请求上限下。 DSN的钥匙一定有 **无允许来源列表**,因为服务器发送者没有源头.
    
-   `logLevel` (默认) `info`过滤器 `logger.*` 并控制台捕获. `captureConsole: ['warn', 'error']` 镜像那些控制台的方法.
    
-   记录带有活性的OpenTeleometry跨度.
    
-   **追踪** 是它的子道, `@brunyee-studio/onus-sdk/node/tracing`,所以只发送日志和错误的应用程序就不需要其两个额外的软件包. 添加 `@opentelemetry/sdk-trace-base @opentelemetry/context-async-hooks` 转到安装行并传递 `onusTracing` 改为 `init`数字 :
    
    ```ts
    import { init } from '@brunyee-studio/onus-sdk/node';
    import { onusTracing } from '@brunyee-studio/onus-sdk/node/tracing';
    
    init({
      dsn: process.env.ONUS_DSN,
      service: 'api',
      tracing: onusTracing({ tracesSampleRate: 0.1 }),
    });
    ```
    
    `init` 然后登记一个全局跟踪器提供者、一个Async上下文管理器和W3C `traceContext` 在OTLP/JSON至 `/api/{projectId}/otlp/v1/traces` (批量处理、gzip和后退作为日志) 无 `tracing` 没有注册的追踪器,请携带它`@opentelemetry/sdk-node`) (中文(简体) ). 抽样基于父方: 正在接收 `traceparent` 决定(所以浏览器的被抽取出微量保留在外),只有根跨度使用 `tracesSampleRate` (单位:千美元). `ignoreSpanPaths: /\/health/` 从未对名称或 `http.target`编号 :`url.path`编号 :`http.route`编号 :`next.route` 火柴。 比赛。 出口者自己的要求被查封,因此它们从未成为期限.
    
-   没有 HTTP 自动仪器的服务器加入呼叫者的追踪 `continueTrace(headers, name, fn)`数字 : `fn` 在活动中运行 `SERVER` 以请求为父的间距 `traceparent`,并记录了一次掷出.
    
    ```ts
    import { continueTrace } from '@brunyee-studio/onus-sdk/node';
    
    app.get('/orders', (req, res) =>
      continueTrace(req.headers, 'GET /orders', async () => res.json(await listOrders())),
    );
    ```
    
-   `init` 不替换已注册的全局OTel日志提供者: OTel API 保存了第一个并忽略了以后的注册, 所以 `logger` 记录将交给提供商而不是Onus(误捕不受影响)。 如果您的应用程序已经注册( 例如 ) . `@opentelemetry/sdk-node` 和日志处理器一起通过 `./pino` 运输,通过自己的供应商而不是全球供应商出口 `registerOnus` 从 `./next` 成为记录OTel的.
    
-   打开 `429`编号 :`503` 暂停 `Retry-After` 并减少批量,直到那时。 被拒绝的密钥或项目( E)`401`编号 :`403`编号 :`404`,例如带有允许来源列表的密钥)暂停转发10分钟。 没有东西扔进你的应用程序.
    

### 皮诺( pino) (`@brunyee-studio/onus-sdk/pino`(中文(简体) )

添加 `pino-abstract-transport` 到节点安装行.

```ts
const log = pino({
  transport: {
    targets: [
      { target: 'pino/file', options: { destination: 1 } }, // keep stdout
      {
        target: '@brunyee-studio/onus-sdk/pino',
        options: { dsn: process.env.ONUS_DSN, service: 'api' },
      },
    ],
  },
});
```

运输以皮诺的工人线为主,并自行出口. 皮诺拒绝自定义 `formatters.level` 合并 `transport.targets`,且运输同时接受数字级别和级别标签。 线条保留 `trace_id`编号 :`span_id` (例如来自 `@opentelemetry/instrumentation-pino`)作为记录的微量上下文.

若为 `./node` `init` (或 `./next` `registerOnus`) 已运行在进程, 使用 `createOnusPinoStream({ exclude? })` 作为 `pino.multistream` 取而代之的是目的地。 它通过提供商传播.

### 温斯顿( r)`@brunyee-studio/onus-sdk/winston`(中文(简体) )

添加 `winston-transport` 到节点安装行,并调用 `init` 从 `./node` 先说.

```ts
import { OnusWinstonTransport } from '@brunyee-studio/onus-sdk/winston';

const log = winston.createLogger({
  transports: [new winston.transports.Console(), new OnusWinstonTransport()],
});
```

npm 和 syslog 都将映射到OTel断层,元数据成为属性,记录带有活性跨度.

### 下册.js`@brunyee-studio/onus-sdk/next`(中文(简体) )

添加 `@vercel/otel` 到节点安装行,以及 `@opentelemetry/sdk-trace-base` 如果设置 `tracesSampleRate`。 。 。 .

```ts
// instrumentation.ts
import { registerOnus } from '@brunyee-studio/onus-sdk/next';

export const register = () =>
  registerOnus({ dsn: process.env.ONUS_DSN, service: 'web', environment: process.env.VERCEL_ENV });
export { onRequestError } from '@brunyee-studio/onus-sdk/next';
```

在节点运行时此登记簿 `@vercel/otel` (请求跨度)与 Onus 日志处理器(以及 `tracesSampleRate`,与 Onus 取样器和处理器并列 `@vercel/otel`属于自己的 `'auto'` 处理器),所以 `logger`, (中文(简体) ), `createOnusPinoStream` 财务报告和审定财务报表 `OnusWinstonTransport` 通过它输出。 一次 `registerOnus` 已经运行, `captureException` 财务报告和审定财务报表 `logger` 从 `./node` 来自应用程序中任何模块的工作(程序处理器、服务器动作、服务器组件);您不调用 `init`。 。 。 . `onRequestError` 抓取路径和活性跟踪的未处理错误。 在边缘运行时只登记了追踪,请求错误被写成 JSON 的一行 `trace_id`编号 :`span_id`。 。 。 .

## 运输语义

-   POST 信封装有 `X-Sentry-Auth` (单位:千美元)`sentry_key` =你的公用钥匙).
-   Gzips 身体通过 `CompressionStream` 当可用时;摄入路线会嗅出魔法字节并接受身份体.
-   荣誉 `429` + 键 `retry-after` 带有上限后退(按键率限制).
-   覆盖在服务器的盖子上 (gzip后有1个MiB在线上,10个MiB被充气) 被丢弃客户端.
-   `navigator.sendBeacon` 可在卸货时交货`?sentry_key=` 查询回落,因为信标不能设置信头).

## 抖树调试旗( D)

-   只导入您使用的内容; 回放记录器被隔离于 `@brunyee-studio/onus-sdk/replay`。 。 。 .
-   **已知限制 :** 不混合常见JS `require('@brunyee-studio/onus-sdk')` 无害环境管理的进口 `/replay` 一页的子路径 。 两座建筑可以 创建单独的模块实例, 带有单独的内存授权门 状态。 在SDK两个切入点使用一个模块系统直至 双相兼容性已经解决.
-   除错日志在编译时旗后被锁定 `__ONUS_DEBUG__`在生产捆绑机中剥去:

```js
// webpack
new webpack.DefinePlugin({ __ONUS_DEBUG__: false });
// esbuild / tsup
define: {
  __ONUS_DEBUG__: 'false';
}
```

## 浏览器支持

| 浏览器 | 最低 |
| --- | --- |
| 颜色 | 90 (韩语) |
| 边缘 | 90 (韩语) |
| 火花 | 90 (韩语) |
| 萨法里 | 15.4 国家 |
| iOS 萨法里 | 15.4 国家 |

要求数 `crypto.randomUUID` **或者说** `crypto.getRandomValues` (事件编号), `fetch`,可选择 `CompressionStream` (gzip) / (英语) `navigator.sendBeacon` (卸载快递). 更古老的浏览器轻而易举地降解:身份体而非gzip,取出而非信标.

**版本策略 :** 我们支持目前主要路线的修复.

## 出版

`@brunyee-studio/onus-sdk` 通过与下列相同的语义释放管道释放: `packages/cli`。仅限 `dist/` 财务报告和审定财务报表 `README.md` 现予公布(`files` 内 `package.json`) (中文(简体) ).

## 网络分析`@brunyee-studio/onus-sdk/analytics`(中文(简体) )

产品分析表面`init` 编号 : `capture` 编号 : `identify` 编号 : `alias` 编号 : `register` 编号 : `reset` 编号 : `get_distinct_id` 编号 : `get_session_id`)上取取取取取API. 核心调用匹配 已有的 PostHog 集成,所以调用站点端口无需重写 . 从自己的子路径导入它, 所以应用程序只需要错误跟踪, 永远不会下载 分析码 副路径仅为无害环境管理(`import` 条件,像 `./replay`页:1 软件包是 `sideEffects: false`,所以捆绑者放弃任何不导入的功能集.

```ts
import { init } from '@brunyee-studio/onus-sdk/analytics';

const onus = init({
  // Flat ingest DSN from your team's keys panel (public by design).
  dsn: 'https://<token>@<ingest-host>/<ingest-project-id>',
});

onus.capture('cta_click', { button: 'hero' });
```

或有明确部分:

```ts
init({ apiKey: '<token>', apiHost: 'https://app.onus.dev', projectId: 42 });
```

### API 密码

| 方法 | 行为 |
| --- | --- |
| `init(config)` | 解析 DSN, 恢复持续的身份, 电线页被冲出 . |
| `capture(name, props?)` | 队列自定义事件 . |
| `identify(id, $set?, $set_once?)` | 释放 `$identify`; 采用 id; 保留 anon id 用于服务器侧合并 . |
| `alias(id)` | 释放 `$create_alias` 连接当前不同的 id 到 `id`。 。 。 . |
| `register(props)` 编号 : `register_once(props, def?)` 编号 : `unregister(name)` | 每起事件都带有超强特性. |
| `reset()` | 新鲜的匿名 id + 会话; 清除超级属性 . |
| `get_distinct_id()` 编号 : `get_session_id()` | 读取当前 ids( 会话: uuidv7, 30- min 闲 / 24- h 最大) . |
| `flush()` | 等待运输冲出( 测试, SPA 在路由拆卸前) . |

### 行为说明

-   **会议** 是客户端uuidv7的ID,通过本地Storage在标签上共享, 闲作30分钟后旋转,或共计24小时.
-   **持久性** 偏好本地Storage, 当被封锁时会降解为内存 (Safari私人模式). Cookie 持久性被故意不支持于 v1 (同意地表+4KB预算).
-   **页数**: 缓冲事件 `sendBeacon` 打开 `pagehide`,带有 保存状态 `fetch` 倒计时.
-   **检索**: 瞬态失败( 5xx/ network) 用指数重试 在4次尝试后退后和下降; 4xx回复被确认,从未 再审——服务器的费率限制决定是权威的.
-   **限制费率**:客户端标志桶(默认为10起事件/s,爆破为10x); 过度事件是在当地放弃的,而不是429起损害终点.
-   **数字**数字 : `capture` 当 `navigator.doNotTrack` 设置和 `respectDnt` 真实( 默认) .
-   **`before_send`** 在退出浏览器前接收每个事件; 返回 `null` 放弃它.
-   **自动抓取**数字 : `$pageview` + SPA 历史变化, `$pageleave`, (中文(简体) ), 财务报告和审定财务报表 `$autocapture` 点击/提交带有元素链并 `data-onus-capture-attribute-*` 财产通过.

## 常见问题

### @brunyee-studio/onus-sdk 是什么？

Onus SDK官方:浏览器出错,会话回放,自定义事件,日志和网络分析,外加节点,皮诺,Winton和Next\.js日志输出者\(已存在的 Sentry SDKs工作不变;服务器日志的OTLP\)

### 如何安装 @brunyee-studio/onus-sdk？

在项目目录运行 npm install @brunyee-studio/onus-sdk，或使用 pnpm add / yarn add / bun add。

### @brunyee-studio/onus-sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @brunyee-studio/onus-sdk 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @brunyee-studio/onus-sdk 可以商用吗？

@brunyee-studio/onus-sdk 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @brunyee-studio/onus-sdk 的下载量有多少？

根据 npm 官方下载统计，@brunyee-studio/onus-sdk 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,048 次，日均约 68 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @brunyee-studio/onus-sdk 还在维护吗？

最新版本 3\.1\.1 发布于 2026/11/06（2 天前）；至今共发布 13 个版本，其中过去 12 个月发布了 13 个；首次发布于 2026/09/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

