@ihyeon/browser-error-log-react 0.0.0-stage → 0.1.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hyeonse Im
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ko.md ADDED
@@ -0,0 +1,65 @@
1
+ # @ihyeon/browser-error-log-react
2
+
3
+ [English](https://github.com/hyeonse-swing/browser-error-log/blob/main/packages/react/README.md) | 한국어
4
+
5
+ Browser Error Log의 React Error Boundary입니다. 렌더링 오류와 React 컴포넌트 스택을 기존 브라우저 SDK 클라이언트에 전달하므로 앱의 다른 오류와 같은 수집기·정책을 사용합니다.
6
+
7
+ React peer 범위는 `>=18 <20`입니다. 이 선언이 모든 React 버전·프레임워크 검증을 뜻하지는 않습니다.
8
+
9
+ ## 설치
10
+
11
+ React 앱에서 브라우저 SDK와 어댑터를 설치합니다.
12
+
13
+ ```sh
14
+ npm install @ihyeon/browser-error-log @ihyeon/browser-error-log-react
15
+ ```
16
+
17
+ 앱에 React가 이미 설치되어 있어야 합니다. 어댑터는 React를 번들에 넣지 않습니다. 게시 패키지 대신 로컬 소스를 사용하려면 [SDK 가이드](https://github.com/hyeonse-swing/browser-error-log/blob/main/docs/ko/personal-sdk.md)에 따라 프로토콜·브라우저·React tarball을 함께 설치하세요.
18
+
19
+ ## 브라우저 진입점에서 사용
20
+
21
+ 앱 Origin을 허용해 저장소의 자체 호스팅 수집기를 시작합니다.
22
+
23
+ ```sh
24
+ MICRO_PROJECTS=my-web MICRO_ALLOWED_ORIGINS=http://localhost:5173 npm run micro
25
+ ```
26
+
27
+ 브라우저 코드에서 클라이언트를 한 번 초기화하고 보호할 UI를 감쌉니다.
28
+
29
+ ```tsx
30
+ import { init } from '@ihyeon/browser-error-log';
31
+ import { ErrorBoundary } from '@ihyeon/browser-error-log-react';
32
+
33
+ const errorLog = init({
34
+ project: 'my-web',
35
+ endpoint: 'http://127.0.0.1:4319/api/events',
36
+ environment: 'development',
37
+ release: 'my-release',
38
+ });
39
+
40
+ export function Root() {
41
+ return (
42
+ <ErrorBoundary
43
+ client={errorLog}
44
+ fallback={(_error, reset) => (
45
+ <section>
46
+ <p>This view could not be displayed.</p>
47
+ <button onClick={reset}>Try again</button>
48
+ </section>
49
+ )}
50
+ >
51
+ <App />
52
+ </ErrorBoundary>
53
+ );
54
+ }
55
+ ```
56
+
57
+ 위 `App`은 앱 컴포넌트입니다. fallback은 React 노드 또는 `Error`와 reset 콜백을 받는 함수입니다. `null`·`false`처럼 Error가 아닌 값도 fallback에서는 `Error`로 변환하며 원래 던진 값은 SDK에 그대로 전달합니다. reset은 Boundary의 오류 상태를 지우고 자식을 다시 렌더링하므로 원인 상태가 그대로라면 다시 실패할 수 있습니다. fallback이 없으면 실패한 Boundary는 아무것도 렌더링하지 않습니다.
58
+
59
+ SSR 프레임워크에서는 클라이언트 진입점을 사용하세요. 서버에서 SDK를 import할 수는 있지만 서버 오류를 수집하지 않습니다. 이 Boundary는 React가 `componentDidCatch`에 전달한 오류를 처리합니다. 앱에서 처리한 오류에는 `captureException`을 사용하고 전역 JavaScript·Promise·네트워크 오류에는 기본 SDK를 사용하세요. 네이티브 크래시나 서버 오류 처리기는 아닙니다.
60
+
61
+ 수집 기록은 `http://127.0.0.1:4319/`에서 확인할 수 있습니다. 외부 배포에는 자체 HTTPS 수집기와 [자체 호스팅 가이드](https://github.com/hyeonse-swing/browser-error-log/blob/main/docs/ko/micro-server.md)를 사용하세요. 뷰어 암호를 브라우저 코드에 넣지 마세요.
62
+
63
+ ## 호스팅과 비용
64
+
65
+ 인프라는 포함되지 않습니다. 호스팅, 서버, 데이터베이스, 스토리지, 대역폭, 도메인, 백업 및 제3자 서비스는 각 운영자가 선택하고 비용을 부담합니다. 요금은 해당 제공업체가 이 프로젝트 및 유지관리자와 독립적으로 청구합니다.
package/README.md CHANGED
@@ -1,3 +1,65 @@
1
- # Temporary Holding Version
1
+ # @ihyeon/browser-error-log-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
+ English | [한국어](https://github.com/hyeonse-swing/browser-error-log/blob/main/packages/react/README.ko.md)
4
+
5
+ A React Error Boundary for Browser Error Log. It forwards render errors and React component stacks to an existing browser SDK client, so React errors use the same collector and collection policies as the rest of your app.
6
+
7
+ The declared React peer range is `>=18 <20`; this range is not a claim of verification against every React version or framework.
8
+
9
+ ## Install
10
+
11
+ In a React app, install the browser SDK and adapter:
12
+
13
+ ```sh
14
+ npm install @ihyeon/browser-error-log @ihyeon/browser-error-log-react
15
+ ```
16
+
17
+ React must already be installed in your app. The adapter does not bundle React. For local source-checkout development, follow the [SDK guide](https://github.com/hyeonse-swing/browser-error-log/blob/main/docs/personal-sdk.md) to install protocol, browser, and React tarballs together.
18
+
19
+ ## Use in your browser entry point
20
+
21
+ Start the repository's self-hosted collector with your app origin allowed:
22
+
23
+ ```sh
24
+ MICRO_PROJECTS=my-web MICRO_ALLOWED_ORIGINS=http://localhost:5173 npm run micro
25
+ ```
26
+
27
+ Initialize a client once in browser code, then wrap the part of the UI you want to protect:
28
+
29
+ ```tsx
30
+ import { init } from '@ihyeon/browser-error-log';
31
+ import { ErrorBoundary } from '@ihyeon/browser-error-log-react';
32
+
33
+ const errorLog = init({
34
+ project: 'my-web',
35
+ endpoint: 'http://127.0.0.1:4319/api/events',
36
+ environment: 'development',
37
+ release: 'my-release',
38
+ });
39
+
40
+ export function Root() {
41
+ return (
42
+ <ErrorBoundary
43
+ client={errorLog}
44
+ fallback={(_error, reset) => (
45
+ <section>
46
+ <p>This view could not be displayed.</p>
47
+ <button onClick={reset}>Try again</button>
48
+ </section>
49
+ )}
50
+ >
51
+ <App />
52
+ </ErrorBoundary>
53
+ );
54
+ }
55
+ ```
56
+
57
+ `App` above is your application component. The fallback can be a React node or a function receiving an `Error` and a reset callback. Non-Error throws, including `null` and `false`, are normalized for the fallback; the original thrown value is still forwarded to the SDK. Reset clears the boundary's error state and retries rendering its children; fix the underlying state if rendering would fail again. With no fallback, a failed boundary renders nothing.
58
+
59
+ Use a client entry point in SSR frameworks. Importing the SDK on the server is safe but does not collect server errors. This boundary handles errors React passes to `componentDidCatch`; use `captureException` for handled errors and the base SDK for global JavaScript, promise, and network error capture. It is not native crash monitoring or a server-side error handler.
60
+
61
+ Open `http://127.0.0.1:4319/` to inspect collected events. For an externally accessible deployment, use your own HTTPS collector and the [self-hosting guide](https://github.com/hyeonse-swing/browser-error-log/blob/main/docs/micro-server.md). Never put the viewer password in browser code.
62
+
63
+ ## Hosting and costs
64
+
65
+ Infrastructure is not included. Hosting, servers, databases, storage, bandwidth, domains, backups, and third-party services are selected and paid for by each operator. Any charges are billed independently by their providers, not by this project or its maintainers.
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.create;var n=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var E=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var h=(r,e,t)=>e in r?n(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var y=(r,e)=>{for(var t in e)n(r,t,{get:e[t],enumerable:!0})},s=(r,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of u(e))!f.call(r,o)&&o!==t&&n(r,o,{get:()=>e[o],enumerable:!(a=d(e,o))||a.enumerable});return r};var R=(r,e,t)=>(t=r!=null?p(E(r)):{},s(e||!r||!r.__esModule?n(t,"default",{value:r,enumerable:!0}):t,r)),k=r=>s(n({},"__esModule",{value:!0}),r);var c=(r,e,t)=>h(r,typeof e!="symbol"?e+"":e,t);var w={};y(w,{ErrorBoundary:()=>i});module.exports=k(w);var l=R(require("react"),1);function m(r){try{return r instanceof Error?r:new Error(String(r))}catch{return new Error("Unknown render error")}}var i=class extends l.Component{constructor(){super(...arguments);c(this,"state",{error:null});c(this,"reset",()=>{this.setState({error:null})})}static getDerivedStateFromError(t){return{error:m(t)}}componentDidCatch(t,a){try{this.props.client.captureException(t,{type:"react",componentStack:a.componentStack??void 0})}catch{}}render(){let t=this.state.error;return t?typeof this.props.fallback=="function"?this.props.fallback(t,this.reset):this.props.fallback??null:this.props.children}};
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nimport type { BrowserErrorLogClient } from '@ihyeon/browser-error-log';\n\nexport interface ErrorBoundaryProps {\n client: BrowserErrorLogClient;\n children: React.ReactNode;\n fallback?: React.ReactNode | ((error: Error, reset: () => void) => React.ReactNode);\n}\n\ninterface ErrorBoundaryState { error: Error | null }\n\nfunction normalizeError(error: unknown): Error {\n try {\n return error instanceof Error ? error : new Error(String(error));\n } catch {\n return new Error('Unknown render error');\n }\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { error: normalizeError(error) };\n }\n\n componentDidCatch(error: unknown, info: React.ErrorInfo): void {\n try {\n this.props.client.captureException(error, {\n type: 'react',\n componentStack: info.componentStack ?? undefined,\n });\n } catch { /* a diagnostics hook must not replace the render error */ }\n }\n\n private readonly reset = (): void => { this.setState({ error: null }); };\n\n render(): React.ReactNode {\n const error = this.state.error;\n if (!error) return this.props.children;\n return typeof this.props.fallback === 'function'\n ? this.props.fallback(error, this.reset)\n : (this.props.fallback ?? null);\n }\n}\n"],
5
+ "mappings": "ksBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,mBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAuB,sBAWvB,SAASC,EAAeC,EAAuB,CAC7C,GAAI,CACF,OAAOA,aAAiB,MAAQA,EAAQ,IAAI,MAAM,OAAOA,CAAK,CAAC,CACjE,MAAQ,CACN,OAAO,IAAI,MAAM,sBAAsB,CACzC,CACF,CAEO,IAAMC,EAAN,cAAkC,WAAkD,CAApF,kCACLC,EAAA,aAA4B,CAAE,MAAO,IAAK,GAe1CA,EAAA,KAAiB,QAAQ,IAAY,CAAE,KAAK,SAAS,CAAE,MAAO,IAAK,CAAC,CAAG,GAbvE,OAAO,yBAAyBF,EAAoC,CAClE,MAAO,CAAE,MAAOD,EAAeC,CAAK,CAAE,CACxC,CAEA,kBAAkBA,EAAgBG,EAA6B,CAC7D,GAAI,CACF,KAAK,MAAM,OAAO,iBAAiBH,EAAO,CACxC,KAAM,QACN,eAAgBG,EAAK,gBAAkB,MACzC,CAAC,CACH,MAAQ,CAA6D,CACvE,CAIA,QAA0B,CACxB,IAAMH,EAAQ,KAAK,MAAM,MACzB,OAAKA,EACE,OAAO,KAAK,MAAM,UAAa,WAClC,KAAK,MAAM,SAASA,EAAO,KAAK,KAAK,EACpC,KAAK,MAAM,UAAY,KAHT,KAAK,MAAM,QAIhC,CACF",
6
+ "names": ["index_exports", "__export", "ErrorBoundary", "__toCommonJS", "React", "normalizeError", "error", "ErrorBoundary", "__publicField", "info"]
7
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import type { BrowserErrorLogClient } from '@ihyeon/browser-error-log';
3
+ export interface ErrorBoundaryProps {
4
+ client: BrowserErrorLogClient;
5
+ children: React.ReactNode;
6
+ fallback?: React.ReactNode | ((error: Error, reset: () => void) => React.ReactNode);
7
+ }
8
+ interface ErrorBoundaryState {
9
+ error: Error | null;
10
+ }
11
+ export declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
12
+ state: ErrorBoundaryState;
13
+ static getDerivedStateFromError(error: unknown): ErrorBoundaryState;
14
+ componentDidCatch(error: unknown, info: React.ErrorInfo): void;
15
+ private readonly reset;
16
+ render(): React.ReactNode;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../packages/react/src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CACrF;AAED,UAAU,kBAAkB;IAAG,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE;AAUpD,qBAAa,aAAc,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACxF,KAAK,EAAE,kBAAkB,CAAmB;IAE5C,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAElE;IAED,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAO7D;IAED,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmD;IAEzE,MAAM,IAAI,KAAK,CAAC,SAAS,CAMxB;CACF"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var i=Object.defineProperty;var s=(e,t,r)=>t in e?i(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var o=(e,t,r)=>s(e,typeof t!="symbol"?t+"":t,r);import*as a from"react";function l(e){try{return e instanceof Error?e:new Error(String(e))}catch{return new Error("Unknown render error")}}var n=class extends a.Component{constructor(){super(...arguments);o(this,"state",{error:null});o(this,"reset",()=>{this.setState({error:null})})}static getDerivedStateFromError(r){return{error:l(r)}}componentDidCatch(r,c){try{this.props.client.captureException(r,{type:"react",componentStack:c.componentStack??void 0})}catch{}}render(){let r=this.state.error;return r?typeof this.props.fallback=="function"?this.props.fallback(r,this.reset):this.props.fallback??null:this.props.children}};export{n as ErrorBoundary};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.tsx"],
4
+ "sourcesContent": ["import * as React from 'react';\nimport type { BrowserErrorLogClient } from '@ihyeon/browser-error-log';\n\nexport interface ErrorBoundaryProps {\n client: BrowserErrorLogClient;\n children: React.ReactNode;\n fallback?: React.ReactNode | ((error: Error, reset: () => void) => React.ReactNode);\n}\n\ninterface ErrorBoundaryState { error: Error | null }\n\nfunction normalizeError(error: unknown): Error {\n try {\n return error instanceof Error ? error : new Error(String(error));\n } catch {\n return new Error('Unknown render error');\n }\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n state: ErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { error: normalizeError(error) };\n }\n\n componentDidCatch(error: unknown, info: React.ErrorInfo): void {\n try {\n this.props.client.captureException(error, {\n type: 'react',\n componentStack: info.componentStack ?? undefined,\n });\n } catch { /* a diagnostics hook must not replace the render error */ }\n }\n\n private readonly reset = (): void => { this.setState({ error: null }); };\n\n render(): React.ReactNode {\n const error = this.state.error;\n if (!error) return this.props.children;\n return typeof this.props.fallback === 'function'\n ? this.props.fallback(error, this.reset)\n : (this.props.fallback ?? null);\n }\n}\n"],
5
+ "mappings": "oKAAA,UAAYA,MAAW,QAWvB,SAASC,EAAeC,EAAuB,CAC7C,GAAI,CACF,OAAOA,aAAiB,MAAQA,EAAQ,IAAI,MAAM,OAAOA,CAAK,CAAC,CACjE,MAAQ,CACN,OAAO,IAAI,MAAM,sBAAsB,CACzC,CACF,CAEO,IAAMC,EAAN,cAAkC,WAAkD,CAApF,kCACLC,EAAA,aAA4B,CAAE,MAAO,IAAK,GAe1CA,EAAA,KAAiB,QAAQ,IAAY,CAAE,KAAK,SAAS,CAAE,MAAO,IAAK,CAAC,CAAG,GAbvE,OAAO,yBAAyBF,EAAoC,CAClE,MAAO,CAAE,MAAOD,EAAeC,CAAK,CAAE,CACxC,CAEA,kBAAkBA,EAAgBG,EAA6B,CAC7D,GAAI,CACF,KAAK,MAAM,OAAO,iBAAiBH,EAAO,CACxC,KAAM,QACN,eAAgBG,EAAK,gBAAkB,MACzC,CAAC,CACH,MAAQ,CAA6D,CACvE,CAIA,QAA0B,CACxB,IAAMH,EAAQ,KAAK,MAAM,MACzB,OAAKA,EACE,OAAO,KAAK,MAAM,UAAa,WAClC,KAAK,MAAM,SAASA,EAAO,KAAK,KAAK,EACpC,KAAK,MAAM,UAAY,KAHT,KAAK,MAAM,QAIhC,CACF",
6
+ "names": ["React", "normalizeError", "error", "ErrorBoundary", "__publicField", "info"]
7
+ }
package/package.json CHANGED
@@ -1,6 +1,45 @@
1
1
  {
2
2
  "name": "@ihyeon/browser-error-log-react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.6",
4
+ "description": "A React Error Boundary adapter for the self-hosted Browser Error Log SDK.",
5
+ "keywords": [
6
+ "react",
7
+ "error-boundary",
8
+ "error-monitoring",
9
+ "self-hosted"
10
+ ],
11
+ "license": "MIT",
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "registry": "https://registry.npmjs.org/"
15
+ },
16
+ "type": "module",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.cjs"
22
+ }
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18 <20"
26
+ },
27
+ "dependencies": {
28
+ "@ihyeon/browser-error-log": "0.1.6"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "README.ko.md",
34
+ "LICENSE"
35
+ ],
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/hyeonse-swing/browser-error-log.git",
39
+ "directory": "packages/react"
40
+ },
41
+ "homepage": "https://github.com/hyeonse-swing/browser-error-log#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/hyeonse-swing/browser-error-log/issues"
44
+ }
45
+ }