@fz-firefly/react 0.0.0-stage → 0.2.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.
package/README.md CHANGED
@@ -1,3 +1,121 @@
1
- # Temporary Holding Version
1
+ # @fz-firefly/react
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 萤火虫 SDK 的 React Web 一键接入包。安装后只需要调用一次 `initFirefly`,内部会创建客户端并安装浏览器全局错误钩子;再给根组件包一层 `FireflyErrorBoundary` 即可捕获 React 渲染期异常。
4
+
5
+ `@fz-firefly/web`、`@fz-firefly/core`、`@fz-firefly/react-plugin` 都是内部依赖,不需要单独安装。
6
+
7
+ ## 安装
8
+
9
+ ```bash
10
+ pnpm add @fz-firefly/react
11
+ ```
12
+
13
+ ## React 18 / 19
14
+
15
+ ```tsx
16
+ // main.tsx
17
+ import { createRoot } from 'react-dom/client'
18
+ import { FireflyErrorBoundary, initFirefly } from '@fz-firefly/react'
19
+ import App from './App'
20
+
21
+ const firefly = initFirefly({
22
+ dsn: import.meta.env.VITE_FIREFLY_DSN,
23
+ endpoint: import.meta.env.VITE_FIREFLY_ENDPOINT,
24
+ environment: import.meta.env.PROD ? 'production' : 'development',
25
+ release: import.meta.env.VITE_APP_RELEASE,
26
+ })
27
+
28
+ createRoot(document.getElementById('root')!).render(
29
+ <FireflyErrorBoundary client={firefly.client}>
30
+ <App />
31
+ </FireflyErrorBoundary>,
32
+ )
33
+ ```
34
+
35
+ `FireflyErrorBoundary` 只捕获子树里的渲染错误、生命周期错误和构造函数错误。事件处理器、`setTimeout` 里的异常仍会冒到 `window`,由 `@fz-firefly/web` 的全局钩子捕获。
36
+
37
+ ## 自定义兜底 UI
38
+
39
+ ```tsx
40
+ <FireflyErrorBoundary
41
+ client={firefly.client}
42
+ fallback={(error, reset) => (
43
+ <div>
44
+ <p>页面出错了:{error.message}</p>
45
+ <button onClick={reset}>重试</button>
46
+ </div>
47
+ )}
48
+ >
49
+ <App />
50
+ </FireflyErrorBoundary>
51
+ ```
52
+
53
+ ## React 19 根级错误回调
54
+
55
+ React 19 的 `createRoot` 支持 `onUncaughtError` / `onCaughtError` / `onRecoverableError`。把 `createFireflyErrorHandlers` 展开进去,可以覆盖错误边界之外的异常:
56
+
57
+ ```tsx
58
+ import { createRoot } from 'react-dom/client'
59
+ import {
60
+ FireflyErrorBoundary,
61
+ createFireflyErrorHandlers,
62
+ initFirefly,
63
+ } from '@fz-firefly/react'
64
+
65
+ const firefly = initFirefly({ ... })
66
+
67
+ createRoot(document.getElementById('root')!, {
68
+ ...createFireflyErrorHandlers(firefly.client),
69
+ }).render(
70
+ <FireflyErrorBoundary client={firefly.client}>
71
+ <App />
72
+ </FireflyErrorBoundary>,
73
+ )
74
+ ```
75
+
76
+ `FireflyErrorBoundary` 已经上报过的错误会自动跳过,不会因为 `onCaughtError` 重复计数。如果业务自己的错误边界也会上报,可以传 `{ reportCaught: false }`。
77
+
78
+ ## 手动上报
79
+
80
+ 初始化返回值里始终有 `client`:
81
+
82
+ ```tsx
83
+ firefly.client.captureException(error, {
84
+ tags: { module: 'checkout' },
85
+ })
86
+ ```
87
+
88
+ 组件里也可以先用 `FireflyProvider` 注入,再用 `useFirefly()`:
89
+
90
+ ```tsx
91
+ import { FireflyProvider, useFirefly } from '@fz-firefly/react'
92
+
93
+ createRoot(root).render(
94
+ <FireflyProvider client={firefly.client}>
95
+ <FireflyErrorBoundary client={firefly.client}>
96
+ <App />
97
+ </FireflyErrorBoundary>
98
+ </FireflyProvider>,
99
+ )
100
+
101
+ function PayButton() {
102
+ const client = useFirefly()
103
+
104
+ return (
105
+ <button
106
+ onClick={() => {
107
+ client.track('pay_click', { channel: 'wechat' })
108
+ }}
109
+ >
110
+ 支付
111
+ </button>
112
+ )
113
+ }
114
+ ```
115
+
116
+ ## 行为
117
+
118
+ - 创建 client,并安装浏览器全局错误、资源错误和 `pagehide` 钩子。
119
+ - 不传 `dist` 时默认使用 `h5`。
120
+ - 保留业务已有的 React 错误边界:`FireflyErrorBoundary` 只负责上报和兜底,不会吞掉其他边界的处理。
121
+ - `initFirefly` 返回 `dispose()`,SPA 卸载或 HMR 时调用以移除全局钩子并停止定时器。
package/dist/index.cjs ADDED
@@ -0,0 +1,118 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _fz_firefly_web = require("@fz-firefly/web");
3
+ let _fz_firefly_react_plugin = require("@fz-firefly/react-plugin");
4
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/typeof.js
5
+ function _typeof(o) {
6
+ "@babel/helpers - typeof";
7
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
8
+ return typeof o;
9
+ } : function(o) {
10
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
11
+ }, _typeof(o);
12
+ }
13
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/toPrimitive.js
14
+ function toPrimitive(t, r) {
15
+ if ("object" != _typeof(t) || !t) return t;
16
+ var e = t[Symbol.toPrimitive];
17
+ if (void 0 !== e) {
18
+ var i = e.call(t, r || "default");
19
+ if ("object" != _typeof(i)) return i;
20
+ throw new TypeError("@@toPrimitive must return a primitive value.");
21
+ }
22
+ return ("string" === r ? String : Number)(t);
23
+ }
24
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/toPropertyKey.js
25
+ function toPropertyKey(t) {
26
+ var i = toPrimitive(t, "string");
27
+ return "symbol" == _typeof(i) ? i : i + "";
28
+ }
29
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/defineProperty.js
30
+ function _defineProperty(e, r, t) {
31
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
32
+ value: t,
33
+ enumerable: !0,
34
+ configurable: !0,
35
+ writable: !0
36
+ }) : e[r] = t, e;
37
+ }
38
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/objectSpread2.js
39
+ function ownKeys(e, r) {
40
+ var t = Object.keys(e);
41
+ if (Object.getOwnPropertySymbols) {
42
+ var o = Object.getOwnPropertySymbols(e);
43
+ r && (o = o.filter(function(r) {
44
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
45
+ })), t.push.apply(t, o);
46
+ }
47
+ return t;
48
+ }
49
+ function _objectSpread2(e) {
50
+ for (var r = 1; r < arguments.length; r++) {
51
+ var t = null != arguments[r] ? arguments[r] : {};
52
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
53
+ _defineProperty(e, r, t[r]);
54
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
55
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
56
+ });
57
+ }
58
+ return e;
59
+ }
60
+ // src/index.ts
61
+ /**
62
+ * 初始化 React Web 项目。
63
+ *
64
+ * 内部完成三件事:
65
+ * - 创建 client;
66
+ * - 安装浏览器全局错误、资源错误和 pagehide 钩子;
67
+ * - 默认把 dist 设为 h5。
68
+ *
69
+ * React 组件渲染错误需要再用 FireflyErrorBoundary 包住根组件;
70
+ * React 19 还可以把 createFireflyErrorHandlers 传给 createRoot。
71
+ *
72
+ * ```tsx
73
+ * const firefly = initFirefly({ dsn, endpoint, environment })
74
+ *
75
+ * createRoot(root).render(
76
+ * <FireflyErrorBoundary client={firefly.client}>
77
+ * <App />
78
+ * </FireflyErrorBoundary>,
79
+ * )
80
+ * ```
81
+ */
82
+ function initFirefly(options) {
83
+ var _options$dist;
84
+ return (0, _fz_firefly_web.initFirefly)(_objectSpread2(_objectSpread2({}, options), {}, { dist: (_options$dist = options.dist) !== null && _options$dist !== void 0 ? _options$dist : "h5" }));
85
+ }
86
+ Object.defineProperty(exports, "FireflyErrorBoundary", {
87
+ enumerable: true,
88
+ get: function() {
89
+ return _fz_firefly_react_plugin.FireflyErrorBoundary;
90
+ }
91
+ });
92
+ Object.defineProperty(exports, "FireflyProvider", {
93
+ enumerable: true,
94
+ get: function() {
95
+ return _fz_firefly_react_plugin.FireflyProvider;
96
+ }
97
+ });
98
+ Object.defineProperty(exports, "createFireflyErrorHandlers", {
99
+ enumerable: true,
100
+ get: function() {
101
+ return _fz_firefly_react_plugin.createFireflyErrorHandlers;
102
+ }
103
+ });
104
+ exports.initFirefly = initFirefly;
105
+ Object.defineProperty(exports, "toError", {
106
+ enumerable: true,
107
+ get: function() {
108
+ return _fz_firefly_react_plugin.toError;
109
+ }
110
+ });
111
+ Object.defineProperty(exports, "useFirefly", {
112
+ enumerable: true,
113
+ get: function() {
114
+ return _fz_firefly_react_plugin.useFirefly;
115
+ }
116
+ });
117
+
118
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,29 @@
1
+ import { FireflyHandle, InitOptions as InitOptions$1 } from "@fz-firefly/web";
2
+ import { FireflyErrorBoundary, FireflyErrorBoundaryProps, FireflyErrorBoundaryState, FireflyErrorHandlerOptions, FireflyErrorInfo, FireflyProvider, FireflyProviderProps, FireflyRootErrorHandlers, createFireflyErrorHandlers, toError, useFirefly } from "@fz-firefly/react-plugin";
3
+ import { CaptureContext, FireflyClient, FireflyOptions, FireflyStorage, FireflyTransport, PlatformContext, ResolvedOptions, Tags } from "@fz-firefly/core";
4
+ /** React Web 项目的初始化参数,与 @fz-firefly/web 一致。 */
5
+ export type InitOptions = InitOptions$1;
6
+ /**
7
+ * 初始化 React Web 项目。
8
+ *
9
+ * 内部完成三件事:
10
+ * - 创建 client;
11
+ * - 安装浏览器全局错误、资源错误和 pagehide 钩子;
12
+ * - 默认把 dist 设为 h5。
13
+ *
14
+ * React 组件渲染错误需要再用 FireflyErrorBoundary 包住根组件;
15
+ * React 19 还可以把 createFireflyErrorHandlers 传给 createRoot。
16
+ *
17
+ * ```tsx
18
+ * const firefly = initFirefly({ dsn, endpoint, environment })
19
+ *
20
+ * createRoot(root).render(
21
+ * <FireflyErrorBoundary client={firefly.client}>
22
+ * <App />
23
+ * </FireflyErrorBoundary>,
24
+ * )
25
+ * ```
26
+ */
27
+ export declare function initFirefly(options: InitOptions): FireflyHandle;
28
+ export { type CaptureContext, type FireflyClient, FireflyErrorBoundary, type FireflyErrorBoundaryProps, type FireflyErrorBoundaryState, type FireflyErrorHandlerOptions, type FireflyErrorInfo, type FireflyHandle, type FireflyOptions, FireflyProvider, type FireflyProviderProps, type FireflyRootErrorHandlers, type FireflyStorage, type FireflyTransport, type PlatformContext, type ResolvedOptions, type Tags, createFireflyErrorHandlers, toError, useFirefly };
29
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,29 @@
1
+ import { FireflyHandle, InitOptions as InitOptions$1 } from "@fz-firefly/web";
2
+ import { FireflyErrorBoundary, FireflyErrorBoundaryProps, FireflyErrorBoundaryState, FireflyErrorHandlerOptions, FireflyErrorInfo, FireflyProvider, FireflyProviderProps, FireflyRootErrorHandlers, createFireflyErrorHandlers, toError, useFirefly } from "@fz-firefly/react-plugin";
3
+ import { CaptureContext, FireflyClient, FireflyOptions, FireflyStorage, FireflyTransport, PlatformContext, ResolvedOptions, Tags } from "@fz-firefly/core";
4
+ /** React Web 项目的初始化参数,与 @fz-firefly/web 一致。 */
5
+ export type InitOptions = InitOptions$1;
6
+ /**
7
+ * 初始化 React Web 项目。
8
+ *
9
+ * 内部完成三件事:
10
+ * - 创建 client;
11
+ * - 安装浏览器全局错误、资源错误和 pagehide 钩子;
12
+ * - 默认把 dist 设为 h5。
13
+ *
14
+ * React 组件渲染错误需要再用 FireflyErrorBoundary 包住根组件;
15
+ * React 19 还可以把 createFireflyErrorHandlers 传给 createRoot。
16
+ *
17
+ * ```tsx
18
+ * const firefly = initFirefly({ dsn, endpoint, environment })
19
+ *
20
+ * createRoot(root).render(
21
+ * <FireflyErrorBoundary client={firefly.client}>
22
+ * <App />
23
+ * </FireflyErrorBoundary>,
24
+ * )
25
+ * ```
26
+ */
27
+ export declare function initFirefly(options: InitOptions): FireflyHandle;
28
+ export { type CaptureContext, type FireflyClient, FireflyErrorBoundary, type FireflyErrorBoundaryProps, type FireflyErrorBoundaryState, type FireflyErrorHandlerOptions, type FireflyErrorInfo, type FireflyHandle, type FireflyOptions, FireflyProvider, type FireflyProviderProps, type FireflyRootErrorHandlers, type FireflyStorage, type FireflyTransport, type PlatformContext, type ResolvedOptions, type Tags, createFireflyErrorHandlers, toError, useFirefly };
29
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,87 @@
1
+ import { initFirefly as initFirefly$1 } from "@fz-firefly/web";
2
+ import { FireflyErrorBoundary, FireflyProvider, createFireflyErrorHandlers, toError, useFirefly } from "@fz-firefly/react-plugin";
3
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/typeof.js
4
+ function _typeof(o) {
5
+ "@babel/helpers - typeof";
6
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
7
+ return typeof o;
8
+ } : function(o) {
9
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
10
+ }, _typeof(o);
11
+ }
12
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/toPrimitive.js
13
+ function toPrimitive(t, r) {
14
+ if ("object" != _typeof(t) || !t) return t;
15
+ var e = t[Symbol.toPrimitive];
16
+ if (void 0 !== e) {
17
+ var i = e.call(t, r || "default");
18
+ if ("object" != _typeof(i)) return i;
19
+ throw new TypeError("@@toPrimitive must return a primitive value.");
20
+ }
21
+ return ("string" === r ? String : Number)(t);
22
+ }
23
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/toPropertyKey.js
24
+ function toPropertyKey(t) {
25
+ var i = toPrimitive(t, "string");
26
+ return "symbol" == _typeof(i) ? i : i + "";
27
+ }
28
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/defineProperty.js
29
+ function _defineProperty(e, r, t) {
30
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
31
+ value: t,
32
+ enumerable: !0,
33
+ configurable: !0,
34
+ writable: !0
35
+ }) : e[r] = t, e;
36
+ }
37
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/objectSpread2.js
38
+ function ownKeys(e, r) {
39
+ var t = Object.keys(e);
40
+ if (Object.getOwnPropertySymbols) {
41
+ var o = Object.getOwnPropertySymbols(e);
42
+ r && (o = o.filter(function(r) {
43
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
44
+ })), t.push.apply(t, o);
45
+ }
46
+ return t;
47
+ }
48
+ function _objectSpread2(e) {
49
+ for (var r = 1; r < arguments.length; r++) {
50
+ var t = null != arguments[r] ? arguments[r] : {};
51
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
52
+ _defineProperty(e, r, t[r]);
53
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
54
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
55
+ });
56
+ }
57
+ return e;
58
+ }
59
+ // src/index.ts
60
+ /**
61
+ * 初始化 React Web 项目。
62
+ *
63
+ * 内部完成三件事:
64
+ * - 创建 client;
65
+ * - 安装浏览器全局错误、资源错误和 pagehide 钩子;
66
+ * - 默认把 dist 设为 h5。
67
+ *
68
+ * React 组件渲染错误需要再用 FireflyErrorBoundary 包住根组件;
69
+ * React 19 还可以把 createFireflyErrorHandlers 传给 createRoot。
70
+ *
71
+ * ```tsx
72
+ * const firefly = initFirefly({ dsn, endpoint, environment })
73
+ *
74
+ * createRoot(root).render(
75
+ * <FireflyErrorBoundary client={firefly.client}>
76
+ * <App />
77
+ * </FireflyErrorBoundary>,
78
+ * )
79
+ * ```
80
+ */
81
+ function initFirefly(options) {
82
+ var _options$dist;
83
+ return initFirefly$1(_objectSpread2(_objectSpread2({}, options), {}, { dist: (_options$dist = options.dist) !== null && _options$dist !== void 0 ? _options$dist : "h5" }));
84
+ }
85
+ export { FireflyErrorBoundary, FireflyProvider, createFireflyErrorHandlers, initFirefly, toError, useFirefly };
86
+
87
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@fz-firefly/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "萤火虫 SDK 的 React 一键接入包:Web 初始化、错误边界和 React 19 根级错误回调。",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "!dist/**/*.map"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "@fz-firefly/core": "0.2.0",
26
+ "@fz-firefly/react-plugin": "0.2.0",
27
+ "@fz-firefly/web": "0.2.0"
28
+ },
29
+ "devDependencies": {
30
+ "tsdown": "0.23.2",
31
+ "typescript": "^5.6.0",
32
+ "vitest": "^5.0.5"
33
+ },
34
+ "peerDependencies": {
35
+ "react": ">=16.8.0"
36
+ },
37
+ "scripts": {
38
+ "build": "tsdown",
39
+ "test": "vitest run",
40
+ "typecheck": "tsc --noEmit"
41
+ }
6
42
  }