rusty-replay 1.0.10 β†’ 1.0.12

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.
Files changed (2) hide show
  1. package/README.md +161 -22
  2. package/package.json +20 -3
package/README.md CHANGED
@@ -1,26 +1,165 @@
1
+ # πŸ¦€ rusty-replay
2
+
3
+ μ›Ή ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ°œμƒν•œ 였λ₯˜λ₯Ό μˆ˜μ§‘ν•˜κ³ , 직전 μ‚¬μš©μž ν™œλ™μ„ λ¦¬ν”Œλ ˆμ΄ ν˜•νƒœλ‘œ ν•¨κ»˜ μ „μ†‘ν•˜λŠ” κ²½λŸ‰ 였λ₯˜ 좔적 λ„κ΅¬μž…λ‹ˆλ‹€.
4
+
5
+ `rrweb` 기반의 μ‚¬μš©μž 행동 λ¦¬ν”Œλ ˆμ΄ κΈ°λŠ₯κ³Ό `axios` μ—λŸ¬ μžλ™ μ „μ†‘κΉŒμ§€ μ§€μ›ν•©λ‹ˆλ‹€.
6
+
7
+ ## πŸ“¦ μ„€μΉ˜
8
+
9
+ ```bash
10
+ npm install rusty-replay
11
+ ```
12
+
13
+ ---
14
+
15
+ ## βš™οΈ μ΄ˆκΈ°ν™”
16
+
17
+ Next.jsμ—μ„œ `rusty-replay`λŠ” 일반적으둜 `app/providers.tsx` λ˜λŠ” `layout.tsx`μ—μ„œ μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.
18
+
19
+ ```ts
20
+ import { init } from 'rusty-replay';
21
+
22
+ init({
23
+ endpoint: 'https://your-api.com/batch-events',
24
+ apiKey: 'YOUR_PUBLIC_API_KEY',
25
+ flushIntervalMs: 10000, // 버퍼가 μ°° λ•ŒκΉŒμ§€ μ΅œλŒ€ λŒ€κΈ° μ‹œκ°„ (ms)
26
+ maxBufferSize: 2000000, // 전솑 μ „ μ΅œλŒ€ 버퍼 μ‚¬μ΄μ¦ˆ (bytes)
27
+ beforeErrorSec: 10, // μ—λŸ¬ λ°œμƒ μ „ λͺ‡ μ΄ˆκ°„μ˜ 이벀트λ₯Ό λ¦¬ν”Œλ ˆμ΄λ‘œ 남길지
28
+ });
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 🧠 κΈ€λ‘œλ²Œ μ—λŸ¬ μžλ™ 캑처
34
+
35
+ ```ts
36
+ import { setupGlobalErrorHandler } from 'rusty-replay';
37
+
38
+ setupGlobalErrorHandler();
39
+ ```
40
+
41
+ - `window.onerror`
42
+ - `window.onunhandledrejection`
43
+ 을 μžλ™ κ°μ§€ν•˜μ—¬ 였λ₯˜λ₯Ό μ„œλ²„λ‘œ μ „μ†‘ν•©λ‹ˆλ‹€.
44
+
45
+ ---
46
+
47
+ ## πŸ”§ Axios μ—λŸ¬ μžλ™ 전솑
48
+
49
+ ```ts
50
+ import axios from 'axios';
51
+ import { captureException, AdditionalInfo } from 'rusty-replay';
52
+
53
+ axios.interceptors.response.use(
54
+ (res) => res,
55
+ (error) => {
56
+ if (axios.isAxiosError(error)) {
57
+ const additionalInfo: Partial<AdditionalInfo> = {
58
+ pageUrl: window.location.href,
59
+ request: {
60
+ url: error.config?.url ?? '',
61
+ method: error.config?.method ?? '',
62
+ headers: error.config?.headers ?? {},
63
+ },
64
+ response: {
65
+ status: error.response?.status ?? 0,
66
+ statusText: error.response?.statusText ?? '',
67
+ data: {
68
+ message: error.response?.data?.message ?? '',
69
+ errorCode: error.response?.data?.errorCode ?? '',
70
+ },
71
+ },
72
+ };
73
+
74
+ captureException(
75
+ error instanceof Error ? error : new Error('API μš”μ²­ μ‹€νŒ¨'),
76
+ additionalInfo
77
+ );
78
+ }
79
+
80
+ return Promise.reject(error);
81
+ }
82
+ );
83
+ ```
84
+
85
+ ---
86
+
87
+ ## πŸ–₯️ React Error Boundary 톡합
88
+
1
89
  ```tsx
2
- // layout.tsx or RootLayout.tsx
3
- useEffect(() => {
4
- init({
5
- endpoint: 'http://localhost:8080/batch-errors', // endpoint
6
- apiKey: 'proj_c08cd1b02c9449c9a0d41f084ee92db9', // project id
7
- flushIntervalMs: 5000, // 5μ΄ˆλ§ˆλ‹€ ν•œλ²ˆμ”© 전솑
8
- maxBufferSize: 200, // 큐에 μ΅œλŒ€ 200κ±΄κΉŒμ§€
9
- beforeErrorSec: 30, // μ—λŸ¬ μ „ 30초 λ¦¬ν”Œλ ˆμ΄ 이벀트 포함
10
- });
11
- }, []);
12
-
13
- <button
14
- onClick={() => {
15
- captureException(new Error('μ˜λ„μ μœΌλ‘œ λ°œμƒμ‹œν‚¨ μˆ˜λ™ μ—λŸ¬'), {
16
- additionalInfo: {
17
- context: 'μˆ˜λ™ μ—λŸ¬ λ¦¬ν¬νŒ… ν…ŒμŠ€νŠΈ',
18
- button: 'μˆ˜λ™ μ—λŸ¬ λ²„νŠΌ',
19
- },
20
- });
90
+ import { ErrorBoundary } from 'react-error-boundary';
91
+ import { captureException } from 'rusty-replay';
92
+
93
+ <ErrorBoundaryFallbackComponent={() => <div>였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.</div>}
94
+ onError={(error, info) => {
95
+ captureException(error);
21
96
  }}
22
- className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
23
97
  >
24
- μˆ˜λ™ μ—λŸ¬ λ°œμƒ 및 리포트
25
- </button>;
98
+ <App />
99
+ </ErrorBoundary>
100
+
26
101
  ```
102
+
103
+ ---
104
+
105
+ ## πŸ” λ¦¬ν”Œλ ˆμ΄ μž¬μƒ (rrweb-player)
106
+
107
+ ```tsx
108
+ import { decompressFromBase64 } from 'rusty-replay';
109
+ import 'rrweb-player/dist/style.css';
110
+
111
+ const events = decompressFromBase64(error.replay);
112
+
113
+ new Player({
114
+ target: document.getElementById('player')!,
115
+ props: {
116
+ events,
117
+ width: 1000,
118
+ height: 600,
119
+ autoPlay: false,
120
+ showController: true,
121
+ skipInactive: true,
122
+ },
123
+ });
124
+ ```
125
+
126
+ ---
127
+
128
+ ## πŸ“‹ μ„œλ²„λ‘œ μ „μ†‘λ˜λŠ” 데이터 Payload
129
+
130
+ ```ts
131
+ {
132
+ message: 'Uncaught TypeError: ...',
133
+ stacktrace: 'TypeError: ...',
134
+ replay: 'compressedBase64Data',
135
+ environment: 'production',
136
+ browser: 'Chrome 123.0',
137
+ os: 'macOS 14',
138
+ userAgent: '...',
139
+ appVersion: '1.0.0',
140
+ apiKey: 'YOUR_API_KEY',
141
+ additionalInfo: {
142
+ request: {...},
143
+ response: {...},
144
+ pageUrl: 'https://your.site/path'
145
+ },
146
+ userId: 123
147
+ }
148
+
149
+ ```
150
+
151
+ ---
152
+
153
+ ## πŸ“Ž API μ°Έκ³ 
154
+
155
+ ### `init(options: InitOptions)`
156
+
157
+ μ˜΅μ…˜ μ„€λͺ…:
158
+
159
+ | μ˜΅μ…˜ | νƒ€μž… | μ„€λͺ… |
160
+ | ----------------- | ------ | -------------------------------------- |
161
+ | `endpoint` | string | μ—λŸ¬ μˆ˜μ§‘ μ„œλ²„μ˜ μ—”λ“œν¬μΈνŠΈ |
162
+ | `apiKey` | string | ν”„λ‘œμ νŠΈ μ‹λ³„μš© API Key |
163
+ | `flushIntervalMs` | number | μ—λŸ¬ 전솑 간격 (κΈ°λ³Έ: 10초) |
164
+ | `maxBufferSize` | number | μ΅œλŒ€ 전솑 버퍼 크기 |
165
+ | `beforeErrorSec` | number | λ¦¬ν”Œλ ˆμ΄ μˆ˜μ§‘ ꡬ간 (κΈ°λ³Έ: 10초 μ „κΉŒμ§€) |
package/package.json CHANGED
@@ -1,14 +1,31 @@
1
1
  {
2
2
  "name": "rusty-replay",
3
- "version": "1.0.10",
4
- "description": "",
3
+ "version": "1.0.12",
4
+ "description": "Lightweight error tracking and replay system for React apps using rrweb and Rust-powered backend integration.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
7
7
  "type": "module",
8
8
  "types": "dist/index.d.ts",
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "README.md"
11
12
  ],
13
+ "keywords": [
14
+ "rrweb",
15
+ "replay",
16
+ "error-tracking",
17
+ "frontend",
18
+ "typescript",
19
+ "react",
20
+ "cli",
21
+ "monitoring"
22
+ ],
23
+ "author": "Jaeha Lee <wogkdkrm112@gmail.com>",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/rusty-replay/replay"
28
+ },
12
29
  "scripts": {
13
30
  "build": "tsup",
14
31
  "prepublishOnly": "npm run build"