npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qfei-design/make-app-observability

v0.1.11

Published

Shared Make App error presentation and Trace ID display contracts.

Readme

@qfei-design/make-app-observability

Make App 统一错误展示与 Trace ID 呈现组件。它将错误卡片的布局、无障碍语义、复制反馈和 Trace ID 展示规则收敛到同一 npm 包,避免业务页面各自拼装 Toast 或 Alert。

包负责什么

  • 提供无 React 依赖的错误呈现模型:normalizeMakeAppErrorNotice。
  • 为所有真实请求失败展示格式正确的 Trace ID,包括 HTTP 非 2xx、网络异常和 HTTP 2xx 的业务码错误。
  • 提供与 Make App 设计一致的 MakeAppErrorNotice:错误图标、关闭按钮、Trace ID 区、复制和“已复制”状态。
  • 提供响应式、作用域限定的样式,不覆盖宿主全局 button、body 或弹层样式。
  • 在当前源码版本中统一管理全局 Toast 的生命周期:默认三秒关闭,支持 duration 秒数与 0 常驻;页面内提示保持常驻。

宿主负责什么

  • 在统一请求适配器中生成/保存 Trace ID,并把 HTTP 状态和错误类别转换为安全的用户文案。
  • 页面不得直接使用 message.error、Alert 或裸 fetch 来呈现 Make 业务请求错误;应统一交给应用的错误出口渲染本组件。
  • 在应用根节点或全局错误 Provider 中导入样式一次,并维护错误队列、业务重试和错误日志;包负责关闭计时,通过 onClose 通知宿主清理队列。
  • 继续确保 Service 返回 X-Log-ID、日志带 Trace ID,且不向浏览器暴露 token 或原始内部错误。

包不发起请求、不保存 Trace ID、不记录错误日志,也不自动探测宿主 UI 框架;这些运行时边界仍由 Make App 负责。

安装

pnpm add @qfei-design/make-app-observability

在 Make App UI 入口导入一次样式:

import "@qfei-design/make-app-observability/styles.css";

使用

import {
  MakeAppErrorNotice,
  MakeAppErrorNoticeViewport,
  type MakeAppErrorKind,
} from "@qfei-design/make-app-observability/react";

type Props = {
  kind: MakeAppErrorKind;
  status?: number;
  traceId?: string;
  visible: boolean;
  onClose: () => void;
};

export function GlobalMakeAppError(props: Props) {
  if (!props.visible) return null;

  return (
    <MakeAppErrorNoticeViewport>
      <MakeAppErrorNotice
        kind={props.kind}
        status={props.status}
        title="process/start 网络异常,请刷新后重试或更换网络后重试"
        traceId={props.traceId}
        onClose={props.onClose}
      />
    </MakeAppErrorNoticeViewport>
  );
}

MakeAppErrorNoticeViewport 在桌面和手机视口均将整个错误队列 portal 到 document.body,统一处理居中偏上、安全区、队列间距和超长内容滚动,避免单张卡片受宿主 transform containing block 影响或多张卡片相互覆盖。两端均水平居中;桌面队列默认从顶部 24px 开始向下排列,手机保持垂直居中偏上。 桌面采用顶部 Toast 定位,距顶部至少 24px 并避让安全区;手机队列中心相对可用视口中心向上偏移 clamp(24px, 5vh, 48px)。四边保留至少 12px 和安全区;长队列从安全区顶部开始并允许滚动。 宿主可通过容器的 --make-app-error-center-offset 调整手机向上偏移量(0px 为手机垂直居中),不需要额外的全屏定位 wrapper。 桌面卡片最大宽度 440px;桌面使用白底、红色左边线和紧凑标题/Trace ID 两行布局,右侧为关闭及复制图标。 手机(640px 及以下)沿用桌面的白底、灰色细边框、红色左边线、8px 圆角和普通等宽 Trace ID,仅增加底部双按钮:左侧「关闭」、右侧「复制」。手机卡片最大宽度 380px,两侧保留至少 12px 和安全区;按钮高度 32px,复制成功显示「已复制」与勾选。标题 14px,卡片留白略增,窄屏 Trace ID 自然换行。 viewport 内的卡片可带宿主 DOM wrapper,居中和卡片交互保持有效;首次服务端渲染和 hydration 保持一致,挂载后 portal 到 body。 宿主负责错误队列状态,并且一个全局错误出口只应渲染一个 viewport 容器;页面内嵌错误无需使用该容器。 viewport 默认使用 z-index: 2000;如果宿主的抽屉、预览或其他 overlay 层级更高,可通过 <MakeAppErrorNoticeViewport zIndex={2400}> 显式对齐宿主层级。portal 会脱离原宿主元素的 stacking context。

kind 必须明确传入:

  • http:存在合法 Trace ID 时显示。
  • network:存在合法 Trace ID 时显示,即使没有 HTTP 状态。
  • business:HTTP 2xx 的业务码异常同样显示合法 Trace ID,便于定位服务端校验失败。

包只消费宿主已经归一化的错误,不读取业务响应体,也不定义哪些业务 code 代表成功。 宿主请求层必须先判断 HTTP 状态,再在 HTTP 2xx 时继续判断业务 code:业务成功才返回数据, 非成功业务码应归类为 kind: "business",并优先提取公共非空字符串 msg,按接口兼容 message,连同 本次请求的 Trace ID 传入组件。不得因为 HTTP 状态为 200 就直接认定业务成功。HTTP 4xx/5xx 也保留有效公共原因; 不能按错误码或固定文案白名单覆盖具体原因和联系人,缺失公共原因时才兜底。禁止的是内部堆栈、凭据、原始 Error 和完整响应对象, 不是已确认的用户可见 msg。详细边界与宿主验收见 公共业务原因。

稳定入口和完整契约见 PUBLIC_API.md。

Toast 自动关闭(当前源码改动,尚未发布)

MakeAppErrorNoticeViewport 默认 duration={3},单位为秒。内部的全局错误卡片和权限 Toast 会在三秒后隐藏,并调用各自的 onClose 一次,供宿主清理对应队列项。 单条卡片的 duration 优先于 viewport;duration={0} 关闭自动计时,支持小数秒。 负数、NaN、Infinity 回退到有效的默认值。

<MakeAppErrorNoticeViewport duration={3}>
  <MakeAppErrorNotice kind="network" title="网络异常" onClose={removeError} />
  <MakeAppPermissionNotice variant="toast" duration={5} onClose={removePermissionToast} />
</MakeAppErrorNoticeViewport>

无 viewport 的错误卡片默认常驻,可显式指定 duration;权限 toast 即使独立渲染也默认三秒。 权限 inline/page 始终常驻并忽略 duration。手动关闭会取消计时器;卸载不会触发关闭回调。 包自身控制隐藏,即使未提供 onClose 也会按时关闭;宿主应提供回调清理队列,不再另建关闭计时器。 回调只用于清理提示,不能自动保存、删除或重试请求。

每次重新触发提示,都从该次触发重新计算完整显示时长。推荐给每个事件传 noticeKey(字符串或数字); 即使文案、Trace ID、关闭回调都相同,只要 noticeKey 改变就会重新显示并重新计时。React key 也可用于独立通知。

<MakeAppPermissionNotice noticeKey={eventId} variant="toast" onClose={removePermissionToast} />

兼容未传 noticeKey 的宿主:包把新的 onClose 函数引用视为重新触发信号,因此现有每次通知 更换关闭回调的接入方式无需改业务代码。若宿主每次普通重渲染也创建新的回调,计时同样会重置; 需要避免这种延长时,应使用显式 noticeKey。显式标识不变时,管理员加载或回调更新均不会重置计时。 如果相同文案、React key、noticeKey 与关闭回调都没有变化,包无法区分新事件与普通重渲染,宿主必须改变事件标识。 回调及计时信号只在 React 提交后更新,暂停或放弃的渲染不会影响当前提示。 需要长时间阅读或复制 Trace ID 时,宿主可以配置更长时长或 duration={0}。 以上默认行为仅存在于当前本地源码产物,接入前应核对实际安装包,不能根据相同的版本号推断。

权限拒绝提示(本分支新增,尚未发布)

新增 MakeAppPermissionNotice,在同一包内统一 Toast、表单/内容区、页面居中三种权限提示。 已发布的 0.1.8 不含此 API;接入前必须确认实际安装产物导出,版本由后续发布流程确定。 原 MakeAppErrorNotice、Trace ID 展示/复制与 viewport 默认行为保持不变。

import { MakeAppPermissionNotice, MakeAppErrorNoticeViewport } from "@qfei-design/make-app-observability/react";
import "@qfei-design/make-app-observability/styles.css";

// 内容区或表单内:放在原容器中,保留导航、标题和允许保留的输入。
<MakeAppPermissionNotice
  variant="inline"
  scope="resource"
  administrators={administrators}
  administratorStatus={administratorStatus}
  retryStatus={retryStatus}
  onRetry={refreshAccess}
/>

// 整个 App 无授权入口时,由宿主选择原入口的挂载位置与高度。
<MakeAppPermissionNotice variant="page" scope="app" administrators={administrators} onRetry={refreshAccess} />

// 全局 Toast 放到宿主已有的同一个错误出口,避免每个 Toast 创建 viewport。
<MakeAppErrorNoticeViewport>
  <MakeAppPermissionNotice variant="toast" operationName="导出" administrators={administrators} />
</MakeAppErrorNoticeViewport>

administrators 只接收当前 App 的直接授权人员 { userId, name, avatarUrl? },不传部门、Agent 或展开部门成员。Toast 显示姓名文字,inline/page 显示头像+姓名标签。空列表保留通用授权提示; 加载/查询失败不会展示旧联系人。姓名按文本渲染,头像允许 HTTPS 或安全站内绝对路径,加载失败用姓名首字。

宿主必须先确认是权限拒绝:401、未知403、租户不匹配和服务故障沿原错误出口处理,不能仅凭HTTP状态 使用此组件。包不请求管理员、不推断授权、不自动刷新或重试;包统一管理 Toast 关闭计时,宿主拥有队列状态。 onRetry 只由用户点击触发;retryStatus 支持 idle/checking/denied/error/restored,checking 禁用重复检查,denied 保留原授权引导而不追加重复提示, restored 只展示恢复结果,不重放导出/保存/删除。宿主刷新权限和授权后 Schema,再决定是否读取数据或允许用户重新操作。 只撤销记录读取权限时,由宿主清空旧行数据并把 inline 提示放在数据区,保留已授权表头和导航。

新增样式都同时限定在 .make-app-error-notice.make-app-error-notice--permission,不会改变原错误卡片。 可在新组件根节点通过 style/className 设置 --make-app-permission-primary、 --make-app-permission-primary-hover、--make-app-permission-text 和 --make-app-permission-muted。

本地视觉示例:先 pnpm build,再 pnpm dev,打开 /examples/permission-notice/。 示例通过公开包入口加载构建产物,用夹具演示三种样式、管理员和刷新状态,可与原错误卡片共同展示;不请求真实 IAM。