lumely-react 0.1.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 ADDED
@@ -0,0 +1,59 @@
1
+ # @lumely/react
2
+
3
+ AI-powered error handling for React applications. Automatically catches errors, explains them to users in plain language, and provides developers with AI-generated fix suggestions.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @lumely/react
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```tsx
14
+ import { LumelyProvider } from '@lumely/react';
15
+
16
+ function App() {
17
+ return (
18
+ <LumelyProvider
19
+ apiKey="your-lumely-api-key"
20
+ apiEndpoint="https://api.lumely.com/api/lumely"
21
+ >
22
+ <YourApp />
23
+ </LumelyProvider>
24
+ );
25
+ }
26
+ ```
27
+
28
+ That's it! Lumely will automatically catch errors and display a user-friendly overlay.
29
+
30
+ ## Features
31
+
32
+ - **🤖 AI-Powered Explanations** - Errors are explained in plain language
33
+ - **📝 User Feedback** - Collect context about what users were doing
34
+ - **🎨 Beautiful Glassmorphism UI** - Modern, customizable overlay
35
+ - **⚡ Fast** - User message appears in ~2s, detailed analysis runs in background
36
+ - **🔒 Secure** - API keys stay on your server
37
+
38
+ ## Props
39
+
40
+ | Prop | Type | Required | Description |
41
+ |------|------|----------|-------------|
42
+ | `apiKey` | `string` | ✅ | Your Lumely API key |
43
+ | `apiEndpoint` | `string` | ✅ | URL to your Lumely API |
44
+ | `environment` | `'development' \| 'production'` | ❌ | Environment name |
45
+ | `userId` | `string` | ❌ | Current user's ID |
46
+ | `sessionId` | `string` | ❌ | Session ID (auto-generated if not provided) |
47
+ | `onError` | `(report) => void` | ❌ | Callback when error is caught |
48
+
49
+ ## How It Works
50
+
51
+ 1. **Error Caught** → React Error Boundary catches the crash
52
+ 2. **Reported** → Error details sent to your Lumely API
53
+ 3. **AI Analysis** → Gemini analyzes and generates user-friendly message
54
+ 4. **Overlay Shown** → User sees explanation + can provide feedback
55
+ 5. **Saved** → Everything stored in your database
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,119 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React, { Component, ErrorInfo } from 'react';
3
+
4
+ interface LumelyConfig {
5
+ apiKey: string;
6
+ apiEndpoint: string;
7
+ environment?: 'development' | 'production';
8
+ userId?: string;
9
+ sessionId?: string;
10
+ onError?: (error: LumelyErrorReport) => void;
11
+ }
12
+ interface LumelyErrorContext {
13
+ url: string;
14
+ userAgent: string;
15
+ userId?: string;
16
+ sessionId?: string;
17
+ userFeedback?: string;
18
+ timestamp: string;
19
+ }
20
+ interface LumelyErrorReport {
21
+ errorMessage: string;
22
+ errorStack?: string;
23
+ componentStack?: string;
24
+ context: LumelyErrorContext;
25
+ }
26
+ interface LumelyAIResponse {
27
+ userMessage: string;
28
+ summary: string;
29
+ suggestedFix: string;
30
+ }
31
+ interface LumelyAPIResponse {
32
+ success: boolean;
33
+ ai: LumelyAIResponse;
34
+ errorId: string;
35
+ }
36
+
37
+ interface LumelyProviderProps {
38
+ children: React.ReactNode;
39
+ apiKey: string;
40
+ apiEndpoint: string;
41
+ environment?: 'development' | 'production';
42
+ userId?: string;
43
+ sessionId?: string;
44
+ onError?: LumelyConfig['onError'];
45
+ }
46
+ /**
47
+ * LumelyProvider for Plain React (Vite, CRA, etc.)
48
+ *
49
+ * Usage:
50
+ * ```tsx
51
+ * import { LumelyProvider } from './components/lumely-react';
52
+ *
53
+ * function App() {
54
+ * return (
55
+ * <LumelyProvider
56
+ * apiKey="your-api-key"
57
+ * apiEndpoint="https://your-api.com/api/lumely"
58
+ * >
59
+ * <YourApp />
60
+ * </LumelyProvider>
61
+ * );
62
+ * }
63
+ * ```
64
+ */
65
+ declare const LumelyProvider: ({ children, apiKey, apiEndpoint, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
66
+
67
+ declare class LumelyClient {
68
+ private apiKey;
69
+ private apiEndpoint;
70
+ constructor(apiKey: string, apiEndpoint: string);
71
+ reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse>;
72
+ updateFeedback(errorId: string, feedback: string): Promise<boolean>;
73
+ }
74
+
75
+ interface Props {
76
+ children: React.ReactNode;
77
+ config: LumelyConfig;
78
+ client: LumelyClient;
79
+ }
80
+ interface State {
81
+ hasError: boolean;
82
+ error: Error | null;
83
+ errorInfo: ErrorInfo | null;
84
+ aiResponse: LumelyAIResponse | null;
85
+ isLoading: boolean;
86
+ errorId: string | null;
87
+ feedbackSubmitted: boolean;
88
+ }
89
+ declare class LumelyErrorBoundary extends Component<Props, State> {
90
+ private isReporting;
91
+ constructor(props: Props);
92
+ static getDerivedStateFromError(error: Error): Partial<State>;
93
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
94
+ private reportError;
95
+ private handleSubmitFeedback;
96
+ private handleRetry;
97
+ private handleDismiss;
98
+ private handleGoBack;
99
+ render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
100
+ }
101
+
102
+ interface LumelyErrorOverlayProps {
103
+ aiResponse?: LumelyAIResponse;
104
+ isLoading: boolean;
105
+ feedbackSubmitted?: boolean;
106
+ onSubmitFeedback: (feedback: string) => void;
107
+ onRetry: () => void;
108
+ onDismiss: () => void;
109
+ onGoBack: () => void;
110
+ }
111
+ declare const LumelyErrorOverlay: ({ aiResponse, isLoading, feedbackSubmitted, onSubmitFeedback, onRetry, onDismiss, onGoBack, }: LumelyErrorOverlayProps) => react_jsx_runtime.JSX.Element;
112
+
113
+ interface LumelyContextValue extends LumelyConfig {
114
+ client: LumelyClient;
115
+ sessionId: string;
116
+ }
117
+ declare const useLumely: () => LumelyContextValue;
118
+
119
+ export { type LumelyAIResponse, type LumelyAPIResponse, LumelyClient, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumely };
@@ -0,0 +1,119 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React, { Component, ErrorInfo } from 'react';
3
+
4
+ interface LumelyConfig {
5
+ apiKey: string;
6
+ apiEndpoint: string;
7
+ environment?: 'development' | 'production';
8
+ userId?: string;
9
+ sessionId?: string;
10
+ onError?: (error: LumelyErrorReport) => void;
11
+ }
12
+ interface LumelyErrorContext {
13
+ url: string;
14
+ userAgent: string;
15
+ userId?: string;
16
+ sessionId?: string;
17
+ userFeedback?: string;
18
+ timestamp: string;
19
+ }
20
+ interface LumelyErrorReport {
21
+ errorMessage: string;
22
+ errorStack?: string;
23
+ componentStack?: string;
24
+ context: LumelyErrorContext;
25
+ }
26
+ interface LumelyAIResponse {
27
+ userMessage: string;
28
+ summary: string;
29
+ suggestedFix: string;
30
+ }
31
+ interface LumelyAPIResponse {
32
+ success: boolean;
33
+ ai: LumelyAIResponse;
34
+ errorId: string;
35
+ }
36
+
37
+ interface LumelyProviderProps {
38
+ children: React.ReactNode;
39
+ apiKey: string;
40
+ apiEndpoint: string;
41
+ environment?: 'development' | 'production';
42
+ userId?: string;
43
+ sessionId?: string;
44
+ onError?: LumelyConfig['onError'];
45
+ }
46
+ /**
47
+ * LumelyProvider for Plain React (Vite, CRA, etc.)
48
+ *
49
+ * Usage:
50
+ * ```tsx
51
+ * import { LumelyProvider } from './components/lumely-react';
52
+ *
53
+ * function App() {
54
+ * return (
55
+ * <LumelyProvider
56
+ * apiKey="your-api-key"
57
+ * apiEndpoint="https://your-api.com/api/lumely"
58
+ * >
59
+ * <YourApp />
60
+ * </LumelyProvider>
61
+ * );
62
+ * }
63
+ * ```
64
+ */
65
+ declare const LumelyProvider: ({ children, apiKey, apiEndpoint, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
66
+
67
+ declare class LumelyClient {
68
+ private apiKey;
69
+ private apiEndpoint;
70
+ constructor(apiKey: string, apiEndpoint: string);
71
+ reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse>;
72
+ updateFeedback(errorId: string, feedback: string): Promise<boolean>;
73
+ }
74
+
75
+ interface Props {
76
+ children: React.ReactNode;
77
+ config: LumelyConfig;
78
+ client: LumelyClient;
79
+ }
80
+ interface State {
81
+ hasError: boolean;
82
+ error: Error | null;
83
+ errorInfo: ErrorInfo | null;
84
+ aiResponse: LumelyAIResponse | null;
85
+ isLoading: boolean;
86
+ errorId: string | null;
87
+ feedbackSubmitted: boolean;
88
+ }
89
+ declare class LumelyErrorBoundary extends Component<Props, State> {
90
+ private isReporting;
91
+ constructor(props: Props);
92
+ static getDerivedStateFromError(error: Error): Partial<State>;
93
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
94
+ private reportError;
95
+ private handleSubmitFeedback;
96
+ private handleRetry;
97
+ private handleDismiss;
98
+ private handleGoBack;
99
+ render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
100
+ }
101
+
102
+ interface LumelyErrorOverlayProps {
103
+ aiResponse?: LumelyAIResponse;
104
+ isLoading: boolean;
105
+ feedbackSubmitted?: boolean;
106
+ onSubmitFeedback: (feedback: string) => void;
107
+ onRetry: () => void;
108
+ onDismiss: () => void;
109
+ onGoBack: () => void;
110
+ }
111
+ declare const LumelyErrorOverlay: ({ aiResponse, isLoading, feedbackSubmitted, onSubmitFeedback, onRetry, onDismiss, onGoBack, }: LumelyErrorOverlayProps) => react_jsx_runtime.JSX.Element;
112
+
113
+ interface LumelyContextValue extends LumelyConfig {
114
+ client: LumelyClient;
115
+ sessionId: string;
116
+ }
117
+ declare const useLumely: () => LumelyContextValue;
118
+
119
+ export { type LumelyAIResponse, type LumelyAPIResponse, LumelyClient, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumely };
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ 'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var u=class{constructor(r,e){this.apiKey=r,this.apiEndpoint=e;}async reportError(r){try{let e=await fetch(`${this.apiEndpoint}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":this.apiKey},body:JSON.stringify(r)});if(e.ok)return await e.json();throw new Error("Failed to report error")}catch(e){return console.error("Lumely: Failed to report error",e),{success:false,ai:{userMessage:"Something went wrong. We're looking into it.",summary:"",suggestedFix:""},errorId:"client-error"}}}async updateFeedback(r,e){try{return (await fetch(`${this.apiEndpoint}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":this.apiKey},body:JSON.stringify({errorId:r,feedback:e})})).ok}catch(n){return console.error("Lumely: Failed to update feedback",n),false}}};var b=react.createContext(null),I=()=>{if(typeof window=="undefined")return "server";let o=sessionStorage.getItem("lumely_session_id");if(o)return o;let r=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",r),r},w=()=>{let o=react.useContext(b);if(!o)throw new Error("useLumely must be used within a LumelyProvider");return o},x=({children:o,config:r})=>{let e=react.useMemo(()=>{let n=r.sessionId||I(),s=new u(r.apiKey,r.apiEndpoint);return {...r,sessionId:n,environment:r.environment||"production",client:s}},[r]);return jsxRuntime.jsx(b.Provider,{value:e,children:o})};var B=()=>{if(typeof document=="undefined"||document.getElementById("lumely-react-styles"))return;let o=document.createElement("style");o.id="lumely-react-styles",o.textContent=`
2
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
3
+ @keyframes lumely-spin {
4
+ from { transform: rotate(0deg); }
5
+ to { transform: rotate(360deg); }
6
+ }
7
+ `,document.head.appendChild(o);},t={overlay:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",padding:"16px",backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(8px)",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"},card:{position:"relative",width:"100%",maxWidth:"400px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.2)",borderRadius:"16px",overflow:"hidden"},closeButton:{position:"absolute",top:"12px",right:"12px",padding:"6px",color:"rgba(255, 255, 255, 0.6)",background:"transparent",border:"none",borderRadius:"8px",cursor:"pointer",fontSize:"18px"},content:{padding:"24px"},header:{display:"flex",alignItems:"center",gap:"12px",marginBottom:"16px"},logo:{width:"40px",height:"40px",borderRadius:"12px",background:"linear-gradient(135deg, #7c3aed, #8b5cf6)",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontWeight:700,fontSize:"18px"},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0},subtitle:{color:"rgba(255, 255, 255, 0.5)",fontSize:"12px",margin:0},messageBox:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"16px",marginBottom:"16px"},message:{color:"rgba(255, 255, 255, 0.9)",fontSize:"14px",lineHeight:1.6,margin:0},loading:{display:"flex",alignItems:"center",gap:"8px",color:"rgba(255, 255, 255, 0.7)",fontSize:"14px",padding:"16px 0"},spinner:{width:"16px",height:"16px",border:"2px solid rgba(255, 255, 255, 0.3)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},form:{marginBottom:"16px"},label:{display:"block",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",marginBottom:"8px"},inputWrapper:{position:"relative"},input:{width:"100%",background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"12px 48px 12px 16px",color:"white",fontSize:"14px",outline:"none",boxSizing:"border-box"},submitButton:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",padding:"8px",color:"rgba(255, 255, 255, 0.4)",background:"transparent",border:"none",cursor:"pointer",fontSize:"16px"},successBox:{background:"rgba(34, 197, 94, 0.1)",border:"1px solid rgba(34, 197, 94, 0.2)",borderRadius:"12px",padding:"12px",marginBottom:"16px"},successText:{color:"#4ade80",fontSize:"12px",textAlign:"center",margin:0},buttons:{display:"flex",gap:"8px"},button:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"8px",padding:"10px 16px",borderRadius:"12px",fontSize:"14px",fontWeight:500,cursor:"pointer",border:"none",transition:"all 0.2s"},secondaryButton:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.8)"},primaryButton:{background:"#7c3aed",color:"white"}},g=({aiResponse:o,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:n,onRetry:s,onDismiss:p,onGoBack:l})=>{let[a,m]=react.useState(""),[f,L]=react.useState(false);react.useEffect(()=>{B();},[]);let S=y=>{y.preventDefault(),a.trim()&&!f&&(L(true),n(a));};return jsxRuntime.jsx("div",{style:t.overlay,children:jsxRuntime.jsxs("div",{style:t.card,children:[jsxRuntime.jsx("button",{style:t.closeButton,onClick:p,children:"\u2715"}),jsxRuntime.jsxs("div",{style:t.content,children:[jsxRuntime.jsxs("div",{style:t.header,children:[jsxRuntime.jsx("div",{style:t.logo,children:"L"}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("h3",{style:t.title,children:"Something went wrong"}),jsxRuntime.jsx("p",{style:t.subtitle,children:"We're looking into it"})]})]}),r?jsxRuntime.jsxs("div",{style:t.loading,children:[jsxRuntime.jsx("div",{style:t.spinner}),jsxRuntime.jsx("span",{children:"Analyzing the issue..."})]}):jsxRuntime.jsx("div",{style:t.messageBox,children:jsxRuntime.jsx("p",{style:t.message,children:(o==null?void 0:o.userMessage)||"We encountered an unexpected issue. Our team has been notified."})}),!e&&!f?jsxRuntime.jsxs("form",{style:t.form,onSubmit:S,children:[jsxRuntime.jsx("label",{style:t.label,children:"What were you trying to do?"}),jsxRuntime.jsxs("div",{style:t.inputWrapper,children:[jsxRuntime.jsx("input",{type:"text",value:a,onChange:y=>m(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:t.input}),jsxRuntime.jsx("button",{type:"submit",disabled:!a.trim(),style:{...t.submitButton,opacity:a.trim()?1:.3},children:"\u27A4"})]})]}):jsxRuntime.jsx("div",{style:t.successBox,children:jsxRuntime.jsx("p",{style:t.successText,children:"Thank you! Your feedback helps us improve."})}),jsxRuntime.jsxs("div",{style:t.buttons,children:[jsxRuntime.jsx("button",{style:{...t.button,...t.secondaryButton},onClick:l,children:"\u2190 Go Back"}),jsxRuntime.jsx("button",{style:{...t.button,...t.primaryButton},onClick:s,children:"\u21BB Try Again"})]})]})]})})};var c=class extends react.Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:n}=this.state,{client:s}=this.props;if(!n||n==="client-error"){this.setState({feedbackSubmitted:true});return}await s.updateFeedback(n,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,n){this.isReporting||(this.isReporting=true,this.setState({errorInfo:n,isLoading:true}),this.reportError(e,n));}async reportError(e,n){let{config:s,client:p}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:n.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:s.userId,sessionId:s.sessionId,timestamp:new Date().toISOString()}},a=await p.reportError(l);this.setState({aiResponse:a.ai,errorId:a.errorId,isLoading:false}),s.onError&&s.onError(l);}render(){let{hasError:e,aiResponse:n,isLoading:s,feedbackSubmitted:p}=this.state,{children:l}=this.props;return e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[l,jsxRuntime.jsx(g,{aiResponse:n||void 0,isLoading:s,feedbackSubmitted:p,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):l}};var W=({children:o,apiKey:r,apiEndpoint:e,environment:n="production",userId:s,sessionId:p,onError:l})=>{let a={apiKey:r,apiEndpoint:e,environment:n,userId:s,sessionId:p,onError:l},m=new u(r,e);return jsxRuntime.jsx(x,{config:a,children:jsxRuntime.jsx(c,{config:a,client:m,children:o})})};exports.LumelyClient=u;exports.LumelyErrorBoundary=c;exports.LumelyErrorOverlay=g;exports.LumelyProvider=W;exports.useLumely=w;//# sourceMappingURL=index.js.map
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../LumelyClient.ts","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyClient","apiKey","apiEndpoint","report","response","err","errorId","feedback","LumelyContext","createContext","generateSessionId","stored","newId","useLumely","context","useContext","LumelyContextProvider","children","config","value","useMemo","sessionId","client","jsx","injectStyles","style","styles","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","useState","isSubmitting","setIsSubmitting","useEffect","handleSubmit","e","jsxs","LumelyErrorBoundary","Component","props","error","errorInfo","hasError","Fragment","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.js","sourcesContent":["import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","import React, { createContext, useContext, useMemo } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\r\n sessionId: string;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\ninterface LumelyContextProviderProps {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\nexport const LumelyContextProvider = ({ children, config }: LumelyContextProviderProps) => {\r\n const value = useMemo(() => {\r\n const sessionId = config.sessionId || generateSessionId();\r\n const client = new LumelyClient(config.apiKey, config.apiEndpoint);\r\n\r\n return {\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n };\r\n }, [config]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\nconst styles: Record<string, React.CSSProperties> = {\r\n overlay: {\r\n position: 'fixed',\r\n inset: 0,\r\n zIndex: 9999,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '16px',\r\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\r\n backdropFilter: 'blur(8px)',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n },\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n maxWidth: '400px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.2)',\r\n borderRadius: '16px',\r\n overflow: 'hidden',\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '12px',\r\n right: '12px',\r\n padding: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n fontSize: '18px',\r\n },\r\n content: {\r\n padding: '24px',\r\n },\r\n header: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '16px',\r\n },\r\n logo: {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '12px',\r\n background: 'linear-gradient(135deg, #7c3aed, #8b5cf6)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'white',\r\n fontWeight: 700,\r\n fontSize: '18px',\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n },\r\n subtitle: {\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n fontSize: '12px',\r\n margin: 0,\r\n },\r\n messageBox: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '16px',\r\n marginBottom: '16px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.9)',\r\n fontSize: '14px',\r\n lineHeight: 1.6,\r\n margin: 0,\r\n },\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n color: 'rgba(255, 255, 255, 0.7)',\r\n fontSize: '14px',\r\n padding: '16px 0',\r\n },\r\n spinner: {\r\n width: '16px',\r\n height: '16px',\r\n border: '2px solid rgba(255, 255, 255, 0.3)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n form: {\r\n marginBottom: '16px',\r\n },\r\n label: {\r\n display: 'block',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n marginBottom: '8px',\r\n },\r\n inputWrapper: {\r\n position: 'relative',\r\n },\r\n input: {\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '12px 48px 12px 16px',\r\n color: 'white',\r\n fontSize: '14px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n },\r\n submitButton: {\r\n position: 'absolute',\r\n right: '8px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n padding: '8px',\r\n color: 'rgba(255, 255, 255, 0.4)',\r\n background: 'transparent',\r\n border: 'none',\r\n cursor: 'pointer',\r\n fontSize: '16px',\r\n },\r\n successBox: {\r\n background: 'rgba(34, 197, 94, 0.1)',\r\n border: '1px solid rgba(34, 197, 94, 0.2)',\r\n borderRadius: '12px',\r\n padding: '12px',\r\n marginBottom: '16px',\r\n },\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n margin: 0,\r\n },\r\n buttons: {\r\n display: 'flex',\r\n gap: '8px',\r\n },\r\n button: {\r\n flex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '8px',\r\n padding: '10px 16px',\r\n borderRadius: '12px',\r\n fontSize: '14px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s',\r\n },\r\n secondaryButton: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n color: 'rgba(255, 255, 255, 0.8)',\r\n },\r\n primaryButton: {\r\n background: '#7c3aed',\r\n color: 'white',\r\n },\r\n};\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n useEffect(() => {\r\n injectStyles();\r\n }, []);\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div style={styles.overlay}>\r\n <div style={styles.card}>\r\n <button style={styles.closeButton} onClick={onDismiss}>✕</button>\r\n\r\n <div style={styles.content}>\r\n <div style={styles.header}>\r\n <div style={styles.logo}>L</div>\r\n <div>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n <p style={styles.subtitle}>We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n {aiResponse?.userMessage || \"We encountered an unexpected issue. Our team has been notified.\"}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form style={styles.form} onSubmit={handleSubmit}>\r\n <label style={styles.label}>What were you trying to do?</label>\r\n <div style={styles.inputWrapper}>\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n style={styles.input}\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n style={{ ...styles.submitButton, opacity: feedback.trim() ? 1 : 0.3 }}\r\n >\r\n ➤\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div style={styles.successBox}>\r\n <p style={styles.successText}>Thank you! Your feedback helps us improve.</p>\r\n </div>\r\n )}\r\n\r\n <div style={styles.buttons}>\r\n <button style={{ ...styles.button, ...styles.secondaryButton }} onClick={onGoBack}>\r\n ← Go Back\r\n </button>\r\n <button style={{ ...styles.button, ...styles.primaryButton }} onClick={onRetry}>\r\n ↻ Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n apiEndpoint: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,8 @@
1
+ import {createContext,useContext,useState,useEffect,Component,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var u=class{constructor(r,e){this.apiKey=r,this.apiEndpoint=e;}async reportError(r){try{let e=await fetch(`${this.apiEndpoint}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":this.apiKey},body:JSON.stringify(r)});if(e.ok)return await e.json();throw new Error("Failed to report error")}catch(e){return console.error("Lumely: Failed to report error",e),{success:false,ai:{userMessage:"Something went wrong. We're looking into it.",summary:"",suggestedFix:""},errorId:"client-error"}}}async updateFeedback(r,e){try{return (await fetch(`${this.apiEndpoint}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":this.apiKey},body:JSON.stringify({errorId:r,feedback:e})})).ok}catch(n){return console.error("Lumely: Failed to update feedback",n),false}}};var b=createContext(null),I=()=>{if(typeof window=="undefined")return "server";let o=sessionStorage.getItem("lumely_session_id");if(o)return o;let r=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",r),r},w=()=>{let o=useContext(b);if(!o)throw new Error("useLumely must be used within a LumelyProvider");return o},x=({children:o,config:r})=>{let e=useMemo(()=>{let n=r.sessionId||I(),s=new u(r.apiKey,r.apiEndpoint);return {...r,sessionId:n,environment:r.environment||"production",client:s}},[r]);return jsx(b.Provider,{value:e,children:o})};var B=()=>{if(typeof document=="undefined"||document.getElementById("lumely-react-styles"))return;let o=document.createElement("style");o.id="lumely-react-styles",o.textContent=`
2
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
3
+ @keyframes lumely-spin {
4
+ from { transform: rotate(0deg); }
5
+ to { transform: rotate(360deg); }
6
+ }
7
+ `,document.head.appendChild(o);},t={overlay:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",padding:"16px",backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(8px)",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"},card:{position:"relative",width:"100%",maxWidth:"400px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.2)",borderRadius:"16px",overflow:"hidden"},closeButton:{position:"absolute",top:"12px",right:"12px",padding:"6px",color:"rgba(255, 255, 255, 0.6)",background:"transparent",border:"none",borderRadius:"8px",cursor:"pointer",fontSize:"18px"},content:{padding:"24px"},header:{display:"flex",alignItems:"center",gap:"12px",marginBottom:"16px"},logo:{width:"40px",height:"40px",borderRadius:"12px",background:"linear-gradient(135deg, #7c3aed, #8b5cf6)",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontWeight:700,fontSize:"18px"},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0},subtitle:{color:"rgba(255, 255, 255, 0.5)",fontSize:"12px",margin:0},messageBox:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"16px",marginBottom:"16px"},message:{color:"rgba(255, 255, 255, 0.9)",fontSize:"14px",lineHeight:1.6,margin:0},loading:{display:"flex",alignItems:"center",gap:"8px",color:"rgba(255, 255, 255, 0.7)",fontSize:"14px",padding:"16px 0"},spinner:{width:"16px",height:"16px",border:"2px solid rgba(255, 255, 255, 0.3)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},form:{marginBottom:"16px"},label:{display:"block",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",marginBottom:"8px"},inputWrapper:{position:"relative"},input:{width:"100%",background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"12px 48px 12px 16px",color:"white",fontSize:"14px",outline:"none",boxSizing:"border-box"},submitButton:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",padding:"8px",color:"rgba(255, 255, 255, 0.4)",background:"transparent",border:"none",cursor:"pointer",fontSize:"16px"},successBox:{background:"rgba(34, 197, 94, 0.1)",border:"1px solid rgba(34, 197, 94, 0.2)",borderRadius:"12px",padding:"12px",marginBottom:"16px"},successText:{color:"#4ade80",fontSize:"12px",textAlign:"center",margin:0},buttons:{display:"flex",gap:"8px"},button:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"8px",padding:"10px 16px",borderRadius:"12px",fontSize:"14px",fontWeight:500,cursor:"pointer",border:"none",transition:"all 0.2s"},secondaryButton:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.8)"},primaryButton:{background:"#7c3aed",color:"white"}},g=({aiResponse:o,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:n,onRetry:s,onDismiss:p,onGoBack:l})=>{let[a,m]=useState(""),[f,L]=useState(false);useEffect(()=>{B();},[]);let S=y=>{y.preventDefault(),a.trim()&&!f&&(L(true),n(a));};return jsx("div",{style:t.overlay,children:jsxs("div",{style:t.card,children:[jsx("button",{style:t.closeButton,onClick:p,children:"\u2715"}),jsxs("div",{style:t.content,children:[jsxs("div",{style:t.header,children:[jsx("div",{style:t.logo,children:"L"}),jsxs("div",{children:[jsx("h3",{style:t.title,children:"Something went wrong"}),jsx("p",{style:t.subtitle,children:"We're looking into it"})]})]}),r?jsxs("div",{style:t.loading,children:[jsx("div",{style:t.spinner}),jsx("span",{children:"Analyzing the issue..."})]}):jsx("div",{style:t.messageBox,children:jsx("p",{style:t.message,children:(o==null?void 0:o.userMessage)||"We encountered an unexpected issue. Our team has been notified."})}),!e&&!f?jsxs("form",{style:t.form,onSubmit:S,children:[jsx("label",{style:t.label,children:"What were you trying to do?"}),jsxs("div",{style:t.inputWrapper,children:[jsx("input",{type:"text",value:a,onChange:y=>m(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:t.input}),jsx("button",{type:"submit",disabled:!a.trim(),style:{...t.submitButton,opacity:a.trim()?1:.3},children:"\u27A4"})]})]}):jsx("div",{style:t.successBox,children:jsx("p",{style:t.successText,children:"Thank you! Your feedback helps us improve."})}),jsxs("div",{style:t.buttons,children:[jsx("button",{style:{...t.button,...t.secondaryButton},onClick:l,children:"\u2190 Go Back"}),jsx("button",{style:{...t.button,...t.primaryButton},onClick:s,children:"\u21BB Try Again"})]})]})]})})};var c=class extends Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:n}=this.state,{client:s}=this.props;if(!n||n==="client-error"){this.setState({feedbackSubmitted:true});return}await s.updateFeedback(n,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,n){this.isReporting||(this.isReporting=true,this.setState({errorInfo:n,isLoading:true}),this.reportError(e,n));}async reportError(e,n){let{config:s,client:p}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:n.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:s.userId,sessionId:s.sessionId,timestamp:new Date().toISOString()}},a=await p.reportError(l);this.setState({aiResponse:a.ai,errorId:a.errorId,isLoading:false}),s.onError&&s.onError(l);}render(){let{hasError:e,aiResponse:n,isLoading:s,feedbackSubmitted:p}=this.state,{children:l}=this.props;return e?jsxs(Fragment,{children:[l,jsx(g,{aiResponse:n||void 0,isLoading:s,feedbackSubmitted:p,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):l}};var W=({children:o,apiKey:r,apiEndpoint:e,environment:n="production",userId:s,sessionId:p,onError:l})=>{let a={apiKey:r,apiEndpoint:e,environment:n,userId:s,sessionId:p,onError:l},m=new u(r,e);return jsx(x,{config:a,children:jsx(c,{config:a,client:m,children:o})})};export{u as LumelyClient,c as LumelyErrorBoundary,g as LumelyErrorOverlay,W as LumelyProvider,w as useLumely};//# sourceMappingURL=index.mjs.map
8
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../LumelyClient.ts","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyClient","apiKey","apiEndpoint","report","response","err","errorId","feedback","LumelyContext","createContext","generateSessionId","stored","newId","useLumely","context","useContext","LumelyContextProvider","children","config","value","useMemo","sessionId","client","jsx","injectStyles","style","styles","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","useState","isSubmitting","setIsSubmitting","useEffect","handleSubmit","e","jsxs","LumelyErrorBoundary","Component","props","error","errorInfo","hasError","Fragment","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n return await response.json();\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","import React, { createContext, useContext, useMemo } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\r\n sessionId: string;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\ninterface LumelyContextProviderProps {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\nexport const LumelyContextProvider = ({ children, config }: LumelyContextProviderProps) => {\r\n const value = useMemo(() => {\r\n const sessionId = config.sessionId || generateSessionId();\r\n const client = new LumelyClient(config.apiKey, config.apiEndpoint);\r\n\r\n return {\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n };\r\n }, [config]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\nconst styles: Record<string, React.CSSProperties> = {\r\n overlay: {\r\n position: 'fixed',\r\n inset: 0,\r\n zIndex: 9999,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '16px',\r\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\r\n backdropFilter: 'blur(8px)',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n },\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n maxWidth: '400px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.2)',\r\n borderRadius: '16px',\r\n overflow: 'hidden',\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '12px',\r\n right: '12px',\r\n padding: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n fontSize: '18px',\r\n },\r\n content: {\r\n padding: '24px',\r\n },\r\n header: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '16px',\r\n },\r\n logo: {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '12px',\r\n background: 'linear-gradient(135deg, #7c3aed, #8b5cf6)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'white',\r\n fontWeight: 700,\r\n fontSize: '18px',\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n },\r\n subtitle: {\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n fontSize: '12px',\r\n margin: 0,\r\n },\r\n messageBox: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '16px',\r\n marginBottom: '16px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.9)',\r\n fontSize: '14px',\r\n lineHeight: 1.6,\r\n margin: 0,\r\n },\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n color: 'rgba(255, 255, 255, 0.7)',\r\n fontSize: '14px',\r\n padding: '16px 0',\r\n },\r\n spinner: {\r\n width: '16px',\r\n height: '16px',\r\n border: '2px solid rgba(255, 255, 255, 0.3)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n form: {\r\n marginBottom: '16px',\r\n },\r\n label: {\r\n display: 'block',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n marginBottom: '8px',\r\n },\r\n inputWrapper: {\r\n position: 'relative',\r\n },\r\n input: {\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '12px 48px 12px 16px',\r\n color: 'white',\r\n fontSize: '14px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n },\r\n submitButton: {\r\n position: 'absolute',\r\n right: '8px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n padding: '8px',\r\n color: 'rgba(255, 255, 255, 0.4)',\r\n background: 'transparent',\r\n border: 'none',\r\n cursor: 'pointer',\r\n fontSize: '16px',\r\n },\r\n successBox: {\r\n background: 'rgba(34, 197, 94, 0.1)',\r\n border: '1px solid rgba(34, 197, 94, 0.2)',\r\n borderRadius: '12px',\r\n padding: '12px',\r\n marginBottom: '16px',\r\n },\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n margin: 0,\r\n },\r\n buttons: {\r\n display: 'flex',\r\n gap: '8px',\r\n },\r\n button: {\r\n flex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '8px',\r\n padding: '10px 16px',\r\n borderRadius: '12px',\r\n fontSize: '14px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s',\r\n },\r\n secondaryButton: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n color: 'rgba(255, 255, 255, 0.8)',\r\n },\r\n primaryButton: {\r\n background: '#7c3aed',\r\n color: 'white',\r\n },\r\n};\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n useEffect(() => {\r\n injectStyles();\r\n }, []);\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div style={styles.overlay}>\r\n <div style={styles.card}>\r\n <button style={styles.closeButton} onClick={onDismiss}>✕</button>\r\n\r\n <div style={styles.content}>\r\n <div style={styles.header}>\r\n <div style={styles.logo}>L</div>\r\n <div>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n <p style={styles.subtitle}>We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n {aiResponse?.userMessage || \"We encountered an unexpected issue. Our team has been notified.\"}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form style={styles.form} onSubmit={handleSubmit}>\r\n <label style={styles.label}>What were you trying to do?</label>\r\n <div style={styles.inputWrapper}>\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n style={styles.input}\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n style={{ ...styles.submitButton, opacity: feedback.trim() ? 1 : 0.3 }}\r\n >\r\n ➤\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div style={styles.successBox}>\r\n <p style={styles.successText}>Thank you! Your feedback helps us improve.</p>\r\n </div>\r\n )}\r\n\r\n <div style={styles.buttons}>\r\n <button style={{ ...styles.button, ...styles.secondaryButton }} onClick={onGoBack}>\r\n ← Go Back\r\n </button>\r\n <button style={{ ...styles.button, ...styles.primaryButton }} onClick={onRetry}>\r\n ↻ Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n apiEndpoint: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "lumely-react",
3
+ "version": "0.1.0",
4
+ "description": "AI-powered error handling for React applications",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "peerDependencies": {
24
+ "react": ">=17.0.0",
25
+ "react-dom": ">=17.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/react": "^18.0.0",
29
+ "@types/react-dom": "^18.0.0",
30
+ "react": "^18.0.0",
31
+ "react-dom": "^18.0.0",
32
+ "tsup": "^8.0.0",
33
+ "typescript": "^5.0.0"
34
+ },
35
+ "keywords": [
36
+ "lumely",
37
+ "react",
38
+ "error-handling",
39
+ "error-boundary",
40
+ "ai",
41
+ "error-reporting",
42
+ "crash-reporting"
43
+ ],
44
+ "author": "Lumely",
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/lumely/lumely-react"
49
+ },
50
+ "homepage": "https://lumely.com",
51
+ "bugs": {
52
+ "url": "https://github.com/lumely/lumely-react/issues"
53
+ }
54
+ }