lumely-next 0.1.3 → 0.1.4

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
@@ -10,15 +10,16 @@ npm install lumely-next
10
10
 
11
11
  ## Quick Start
12
12
 
13
+ Just wrap your app with `LumelyProvider` and add your API key:
14
+
13
15
  ```tsx
14
- // pages/_app.tsx or app/layout.tsx
16
+ // pages/_app.tsx
15
17
  import { LumelyProvider } from 'lumely-next';
16
18
 
17
19
  export default function App({ Component, pageProps }) {
18
20
  return (
19
21
  <LumelyProvider
20
22
  apiKey={process.env.NEXT_PUBLIC_LUMELY_API_KEY ?? ''}
21
- environment={process.env.NODE_ENV === 'production' ? 'production' : 'development'}
22
23
  >
23
24
  <Component {...pageProps} />
24
25
  </LumelyProvider>
@@ -26,7 +27,17 @@ export default function App({ Component, pageProps }) {
26
27
  }
27
28
  ```
28
29
 
29
- That's it. Lumely will automatically catch errors and display a user-friendly overlay.
30
+ That's it! Lumely will automatically:
31
+ - Catch errors and display a user-friendly overlay
32
+ - Send error data to Lumely's hosted backend
33
+ - Generate AI-powered explanations and fix suggestions
34
+ - Store errors in your Lumely dashboard
35
+
36
+ ## Get Your API Key
37
+
38
+ 1. Sign up at [lumely.vercel.app](https://lumely.vercel.app)
39
+ 2. Create a project
40
+ 3. Copy your API key from the project settings
30
41
 
31
42
  ## Features
32
43
 
@@ -34,29 +45,41 @@ That's it. Lumely will automatically catch errors and display a user-friendly ov
34
45
  - **User Feedback** - Collect context about what users were doing
35
46
  - **Modern Glassmorphism UI** - Beautiful overlay with Poppins font
36
47
  - **Fast Response** - User message appears in ~2s, detailed analysis runs in background
37
- - **Secure** - API keys stay on your server
38
- - **Next.js Optimized** - Uses next/font for optimal font loading
48
+ - **Zero Config** - Works out of the box with Lumely's hosted backend
39
49
 
40
50
  ## Props
41
51
 
42
- | Prop | Type | Required | Description |
43
- |------|------|----------|-------------|
44
- | `apiKey` | `string` | Yes | Your Lumely API key |
45
- | `environment` | `'development' \| 'production'` | No | Environment name |
46
- | `userId` | `string` | No | Current user's ID |
47
- | `sessionId` | `string` | No | Session ID (auto-generated if not provided) |
48
- | `onError` | `(report) => void` | No | Callback when error is caught |
52
+ | Prop | Type | Required | Default | Description |
53
+ |------|------|----------|---------|-------------|
54
+ | `apiKey` | string | Yes | - | Your Lumely API key |
55
+ | `environment` | 'development' \| 'production' | No | 'production' | Current environment |
56
+ | `userId` | string | No | - | Optional user identifier |
57
+
58
+ ## Manual Error Reporting
59
+
60
+ Report caught errors that don't crash the app:
49
61
 
50
- ## API Routes
62
+ ```tsx
63
+ import { useLumelyReport } from 'lumely-next';
64
+
65
+ function MyComponent() {
66
+ const { reportError } = useLumelyReport();
67
+
68
+ const handleClick = async () => {
69
+ try {
70
+ await fetch('/api/action');
71
+ } catch (error) {
72
+ reportError(error, { action: 'button_click' });
73
+ }
74
+ };
51
75
 
52
- This package expects API routes at `/api/lumely/`.
53
- 1. Create a `pages/api/lumely/report-error.ts` file.
54
- 2. Create a `pages/api/lumely/update-feedback.ts` file.
55
- 3. Use the `apiEndpoint="/api/lumely"` prop in your Provider.
76
+ return <button onClick={handleClick}>Action</button>;
77
+ }
78
+ ```
56
79
 
57
80
  ## Documentation
58
81
 
59
- Visit [lumely.vercel.app](https://lumely.vercel.app) for full documentation.
82
+ Visit [lumely.vercel.app/docs](https://lumely.vercel.app/docs) for full documentation.
60
83
 
61
84
  ## License
62
85
 
package/dist/index.d.mts CHANGED
@@ -3,6 +3,7 @@ import React, { Component, ErrorInfo, ReactNode } from 'react';
3
3
 
4
4
  interface LumelyConfig {
5
5
  apiKey: string;
6
+ apiEndpoint?: string;
6
7
  environment?: 'development' | 'production';
7
8
  userId?: string;
8
9
  sessionId?: string;
@@ -15,6 +16,7 @@ interface LumelyErrorContext {
15
16
  sessionId?: string;
16
17
  userFeedback?: string;
17
18
  timestamp: string;
19
+ additionalContext?: string;
18
20
  }
19
21
  interface LumelyErrorReport {
20
22
  errorMessage: string;
@@ -36,12 +38,14 @@ interface LumelyAPIResponse {
36
38
  interface LumelyProviderProps {
37
39
  children: React.ReactNode;
38
40
  apiKey: string;
41
+ /** API endpoint for error reporting. Defaults to Lumely's hosted backend. */
42
+ apiEndpoint?: string;
39
43
  environment?: 'development' | 'production';
40
44
  userId?: string;
41
45
  sessionId?: string;
42
46
  onError?: LumelyConfig['onError'];
43
47
  }
44
- declare const LumelyProvider: ({ children, apiKey, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
48
+ declare const LumelyProvider: ({ children, apiKey, apiEndpoint, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
45
49
 
46
50
  interface Props {
47
51
  children: React.ReactNode;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import React, { Component, ErrorInfo, ReactNode } from 'react';
3
3
 
4
4
  interface LumelyConfig {
5
5
  apiKey: string;
6
+ apiEndpoint?: string;
6
7
  environment?: 'development' | 'production';
7
8
  userId?: string;
8
9
  sessionId?: string;
@@ -15,6 +16,7 @@ interface LumelyErrorContext {
15
16
  sessionId?: string;
16
17
  userFeedback?: string;
17
18
  timestamp: string;
19
+ additionalContext?: string;
18
20
  }
19
21
  interface LumelyErrorReport {
20
22
  errorMessage: string;
@@ -36,12 +38,14 @@ interface LumelyAPIResponse {
36
38
  interface LumelyProviderProps {
37
39
  children: React.ReactNode;
38
40
  apiKey: string;
41
+ /** API endpoint for error reporting. Defaults to Lumely's hosted backend. */
42
+ apiEndpoint?: string;
39
43
  environment?: 'development' | 'production';
40
44
  userId?: string;
41
45
  sessionId?: string;
42
46
  onError?: LumelyConfig['onError'];
43
47
  }
44
- declare const LumelyProvider: ({ children, apiKey, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
48
+ declare const LumelyProvider: ({ children, apiKey, apiEndpoint, environment, userId, sessionId, onError, }: LumelyProviderProps) => react_jsx_runtime.JSX.Element;
45
49
 
46
50
  interface Props {
47
51
  children: React.ReactNode;
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- 'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var k=react.createContext(null),m=()=>react.useContext(k),v=({children:n})=>{let[e,o]=react.useState({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null}),r=react.useCallback((d,a,p)=>{o({isVisible:true,error:d,isLoading:!a,aiResponse:a||null,errorId:p||null});},[]),i=react.useCallback(()=>{o({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null});},[]),u=react.useCallback(d=>{o(a=>({...a,isLoading:d}));},[]),l=react.useCallback((d,a)=>{o(p=>({...p,aiResponse:d,errorId:a||p.errorId,isLoading:false}));},[]);return jsxRuntime.jsx(k.Provider,{value:{state:e,showOverlay:r,hideOverlay:i,setLoading:u,setAiResponse:l},children:n})};var R=react.createContext(null),T=()=>{if(typeof window=="undefined")return "server";let n=sessionStorage.getItem("lumely_session_id");if(n)return n;let e=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",e),e},D=()=>{let n=react.useContext(R);if(!n)throw new Error("useLumelyContext must be used within a LumelyProvider");return n},W=()=>{let n=react.useContext(R);return n?{reportError:n.reportError}:(typeof window!="undefined"&&process.env.NODE_ENV==="development"&&console.warn("[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh."),{reportError:async()=>{console.warn("[Lumely] Cannot report error: LumelyProvider not found");}})},I=({children:n,config:e})=>{let o=react.useMemo(()=>e.sessionId||T(),[e.sessionId]),r=m(),i=react.useCallback(async(l,d)=>{var p;let a={errorMessage:l.message,errorStack:l.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:e.userId,sessionId:o,timestamp:new Date().toISOString(),...d&&{additionalContext:JSON.stringify(d)}}};r==null||r.showOverlay(l);try{let y=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":e.apiKey},body:JSON.stringify(a)});if(y.ok){let b=await y.json();r==null||r.setAiResponse(b.ai,b.errorId);}else console.error("[Lumely] Failed to report error:",y.statusText),r==null||r.setLoading(!1);(p=e.onError)==null||p.call(e,a);}catch(y){console.error("[Lumely] Error reporting failed:",y),r==null||r.setLoading(false);}},[e,o,r]);react.useEffect(()=>{if(typeof window=="undefined")return;let l=a=>{let p=a.reason instanceof Error?a.reason:new Error(String(a.reason));i(p,{type:"unhandledRejection"});},d=a=>{let p=a.error instanceof Error?a.error:new Error(a.message);i(p,{type:"globalError",filename:a.filename,lineno:a.lineno,colno:a.colno});};return window.addEventListener("unhandledrejection",l),window.addEventListener("error",d),()=>{window.removeEventListener("unhandledrejection",l),window.removeEventListener("error",d);}},[i]);let u=react.useMemo(()=>({...e,sessionId:o,environment:e.environment||"production",reportError:i}),[e,o,i]);return jsxRuntime.jsx(R.Provider,{value:u,children:n})};var V=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let n=document.createElement("style");n.id="lumely-next-styles",n.textContent=`
1
+ 'use strict';var N=require('react'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var N__default=/*#__PURE__*/_interopDefault(N);var m="https://lumely.vercel.app/api/lumely";var k=N.createContext(null),f=()=>N.useContext(k),I=({children:d})=>{let[s,e]=N.useState({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null}),r=N.useCallback((a,n,p)=>{e({isVisible:true,error:a,isLoading:!n,aiResponse:n||null,errorId:p||null});},[]),i=N.useCallback(()=>{e({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null});},[]),u=N.useCallback(a=>{e(n=>({...n,isLoading:a}));},[]),t=N.useCallback((a,n)=>{e(p=>({...p,aiResponse:a,errorId:n||p.errorId,isLoading:false}));},[]);return jsxRuntime.jsx(k.Provider,{value:{state:s,showOverlay:r,hideOverlay:i,setLoading:u,setAiResponse:t},children:d})};var E=N.createContext(null),j=()=>typeof window=="undefined"?null:sessionStorage.getItem("lumely_session_id"),M=()=>`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,W=()=>{let d=N.useContext(E);if(!d)throw new Error("useLumelyContext must be used within a LumelyProvider");return d},z=()=>{let d=N.useContext(E);return d?{reportError:d.reportError}:(typeof window!="undefined"&&process.env.NODE_ENV==="development"&&console.warn("[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh."),{reportError:async()=>{console.warn("[Lumely] Cannot report error: LumelyProvider not found");}})},C=({children:d,config:s})=>{let[e]=N__default.default.useState(()=>s.sessionId?s.sessionId:j()||M());N.useEffect(()=>{typeof window!="undefined"&&!s.sessionId&&e!=="server"&&(sessionStorage.getItem("lumely_session_id")||sessionStorage.setItem("lumely_session_id",e));},[e,s.sessionId]);let r=f(),i=N.useCallback(async(t,a)=>{var p,x;let n={errorMessage:t.message,errorStack:t.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:s.userId,sessionId:e,timestamp:new Date().toISOString(),...a&&{additionalContext:JSON.stringify(a)}}};r==null||r.showOverlay(t);try{let g=(p=s.apiEndpoint)!=null?p:m,y=await fetch(`${g}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(n)});if(y.ok){let R=await y.json();r==null||r.setAiResponse(R.ai,R.errorId);}else console.error("[Lumely] Failed to report error:",y.statusText),r==null||r.setLoading(!1);(x=s.onError)==null||x.call(s,n);}catch(g){console.error("[Lumely] Error reporting failed:",g),r==null||r.setLoading(false);}},[s,e,r]);N.useEffect(()=>{if(typeof window=="undefined")return;let t=n=>{let p=n.reason instanceof Error?n.reason:new Error(String(n.reason));i(p,{type:"unhandledRejection"});},a=n=>{let p=n.error instanceof Error?n.error:new Error(n.message);i(p,{type:"globalError",filename:n.filename,lineno:n.lineno,colno:n.colno});};return window.addEventListener("unhandledrejection",t),window.addEventListener("error",a),()=>{window.removeEventListener("unhandledrejection",t),window.removeEventListener("error",a);}},[i]);let u=N.useMemo(()=>({...s,sessionId:e,environment:s.environment||"production",reportError:i}),[s,e,i]);return jsxRuntime.jsx(E.Provider,{value:u,children:d})};var G=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let d=document.createElement("style");d.id="lumely-next-styles",d.textContent=`
2
2
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
3
3
  @keyframes lumely-spin {
4
4
  from { transform: rotate(0deg); }
5
5
  to { transform: rotate(360deg); }
6
6
  }
7
- `,document.head.appendChild(n);},K=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),M=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsxRuntime.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),G=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsxRuntime.jsx("polyline",{points:"12 19 5 12 12 5"})]});var s={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:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",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",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},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",transition:"border-color 0.2s"},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",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},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"},primaryButton:{background:"#7c3aed",color:"white"}},f=({aiResponse:n,isLoading:e,feedbackSubmitted:o=false,onSubmitFeedback:r,onRetry:i,onDismiss:u,onGoBack:l})=>{let[d,a]=react.useState(""),[p,y]=react.useState(false);react.useEffect(()=>{V();},[]);let b=L=>{L.preventDefault(),d.trim()&&!p&&(y(true),r(d));};return jsxRuntime.jsx("div",{style:s.overlay,children:jsxRuntime.jsxs("div",{style:s.card,children:[jsxRuntime.jsx("button",{style:s.closeButton,onClick:u,children:jsxRuntime.jsx(K,{})}),jsxRuntime.jsxs("div",{style:s.content,children:[jsxRuntime.jsxs("div",{style:s.header,children:[jsxRuntime.jsx("div",{style:s.logo,children:"L"}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("h3",{style:s.title,children:"Something went wrong"}),jsxRuntime.jsx("p",{style:s.subtitle,children:"We're looking into it"})]})]}),e?jsxRuntime.jsxs("div",{style:s.loading,children:[jsxRuntime.jsx("div",{style:s.spinner}),jsxRuntime.jsx("span",{children:"Analyzing the issue..."})]}):n?jsxRuntime.jsx("div",{style:s.messageBox,children:jsxRuntime.jsx("p",{style:s.message,children:n.userMessage})}):jsxRuntime.jsx("div",{style:s.messageBox,children:jsxRuntime.jsx("p",{style:s.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!o&&!p?jsxRuntime.jsxs("form",{style:s.form,onSubmit:b,children:[jsxRuntime.jsx("label",{style:s.label,children:"What were you trying to do?"}),jsxRuntime.jsxs("div",{style:s.inputWrapper,children:[jsxRuntime.jsx("input",{type:"text",value:d,onChange:L=>a(L.target.value),placeholder:"e.g., I was trying to save my changes...",style:s.input}),jsxRuntime.jsx("button",{type:"submit",disabled:!d.trim(),style:{...s.submitButton,opacity:d.trim()?1:.3},children:jsxRuntime.jsx(M,{})})]})]}):jsxRuntime.jsx("div",{style:s.successBox,children:jsxRuntime.jsx("p",{style:s.successText,children:"Thank you! Your feedback helps us improve."})}),jsxRuntime.jsx("div",{style:s.buttons,children:jsxRuntime.jsxs("button",{style:{...s.button,...s.primaryButton},onClick:l,children:[jsxRuntime.jsx(G,{}),"Go Back"]})})]})]})})};var g=class extends react.Component{constructor(o){super(o);this.isReporting=false;this.handleSubmitFeedback=async o=>{let{errorId:r}=this.state,{config:i}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify({errorId:r,feedback:o})}),this.setState({feedbackSubmitted:!0});}catch(u){console.error("Lumely: Failed to submit feedback",u),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=()=>{this.handleDismiss(),typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(o){return {hasError:true,error:o}}componentDidCatch(o,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(o,r));}async reportError(o,r){let{config:i}=this.props,u={errorMessage:o.message,errorStack:o.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:i.userId,sessionId:i.sessionId,timestamp:new Date().toISOString()}};try{let l=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify(u)});if(l.ok){let d=await l.json();this.setState({aiResponse:d.ai,errorId:d.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(l){console.error("Lumely: Failed to report error",l),this.setState({isLoading:false});}i.onError&&i.onError(u);}render(){let{hasError:o,aiResponse:r,isLoading:i,feedbackSubmitted:u}=this.state,{children:l}=this.props;return o?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[l,jsxRuntime.jsx(f,{aiResponse:r||void 0,isLoading:i,feedbackSubmitted:u,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):l}};var Y=({apiKey:n})=>{let e=m();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async i=>{if(e.state.errorId)try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":n},body:JSON.stringify({errorId:e.state.errorId,userFeedback:i})});}catch(u){console.error("[Lumely] Failed to submit feedback:",u);}},r=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsxRuntime.jsx(f,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:r})},$=({children:n,apiKey:e,environment:o="production",userId:r,sessionId:i,onError:u})=>{let l={apiKey:e,environment:o,userId:r,sessionId:i,onError:u};return jsxRuntime.jsx(v,{children:jsxRuntime.jsxs(I,{config:l,children:[jsxRuntime.jsx(g,{config:l,children:n}),jsxRuntime.jsx(Y,{apiKey:e})]})})};exports.LumelyErrorBoundary=g;exports.LumelyErrorOverlay=f;exports.LumelyOverlayProvider=v;exports.LumelyProvider=$;exports.useLumelyContext=D;exports.useLumelyOverlay=m;exports.useLumelyReport=W;//# sourceMappingURL=index.js.map
7
+ `,document.head.appendChild(d);},U=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),Y=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsxRuntime.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),$=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsxRuntime.jsx("polyline",{points:"12 19 5 12 12 5"})]});var l={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:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",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",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},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",transition:"border-color 0.2s"},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",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},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"},primaryButton:{background:"#7c3aed",color:"white"}},b=({aiResponse:d,isLoading:s,feedbackSubmitted:e=false,onSubmitFeedback:r,onRetry:i,onDismiss:u,onGoBack:t})=>{let[a,n]=N.useState(""),[p,x]=N.useState(false);N.useEffect(()=>{G();},[]);let g=y=>{y.preventDefault(),a.trim()&&!p&&(x(true),r(a));};return jsxRuntime.jsx("div",{style:l.overlay,children:jsxRuntime.jsxs("div",{style:l.card,children:[jsxRuntime.jsx("button",{style:l.closeButton,onClick:u,children:jsxRuntime.jsx(U,{})}),jsxRuntime.jsxs("div",{style:l.content,children:[jsxRuntime.jsxs("div",{style:l.header,children:[jsxRuntime.jsx("div",{style:l.logo,children:"L"}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("h3",{style:l.title,children:"Something went wrong"}),jsxRuntime.jsx("p",{style:l.subtitle,children:"We're looking into it"})]})]}),s?jsxRuntime.jsxs("div",{style:l.loading,children:[jsxRuntime.jsx("div",{style:l.spinner}),jsxRuntime.jsx("span",{children:"Analyzing the issue..."})]}):d?jsxRuntime.jsx("div",{style:l.messageBox,children:jsxRuntime.jsx("p",{style:l.message,children:d.userMessage})}):jsxRuntime.jsx("div",{style:l.messageBox,children:jsxRuntime.jsx("p",{style:l.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!e&&!p?jsxRuntime.jsxs("form",{style:l.form,onSubmit:g,children:[jsxRuntime.jsx("label",{style:l.label,children:"What were you trying to do?"}),jsxRuntime.jsxs("div",{style:l.inputWrapper,children:[jsxRuntime.jsx("input",{type:"text",value:a,onChange:y=>n(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:l.input}),jsxRuntime.jsx("button",{type:"submit",disabled:!a.trim(),style:{...l.submitButton,opacity:a.trim()?1:.3},children:jsxRuntime.jsx(Y,{})})]})]}):jsxRuntime.jsx("div",{style:l.successBox,children:jsxRuntime.jsx("p",{style:l.successText,children:"Thank you! Your feedback helps us improve."})}),jsxRuntime.jsx("div",{style:l.buttons,children:jsxRuntime.jsxs("button",{style:{...l.button,...l.primaryButton},onClick:t,children:[jsxRuntime.jsx($,{}),"Go Back"]})})]})]})})};var h=class extends N.Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{var u;let{errorId:r}=this.state,{config:i}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{let t=(u=i.apiEndpoint)!=null?u:m;await fetch(`${t}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify({errorId:r,feedback:e})}),this.setState({feedbackSubmitted:!0});}catch(t){console.error("Lumely: Failed to submit feedback",t),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=()=>{this.handleDismiss(),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,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(e,r));}async reportError(e,r){var t;let{config:i}=this.props,u={errorMessage:e.message,errorStack:e.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:i.userId,sessionId:i.sessionId,timestamp:new Date().toISOString()}};try{let a=(t=i.apiEndpoint)!=null?t:m,n=await fetch(`${a}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify(u)});if(n.ok){let p=await n.json();this.setState({aiResponse:p.ai,errorId:p.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(a){console.error("Lumely: Failed to report error",a),this.setState({isLoading:false});}i.onError&&i.onError(u);}render(){let{hasError:e,aiResponse:r,isLoading:i,feedbackSubmitted:u}=this.state,{children:t}=this.props;return e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[t,jsxRuntime.jsx(b,{aiResponse:r||void 0,isLoading:i,feedbackSubmitted:u,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):t}};var Q=({apiEndpoint:d,apiKey:s})=>{let e=f();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let r=async u=>{if(e.state.errorId)try{await fetch(`${d}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s},body:JSON.stringify({errorId:e.state.errorId,userFeedback:u})});}catch(t){console.error("[Lumely] Failed to submit feedback:",t);}},i=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsxRuntime.jsx(b,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:r,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:i})},Z=({children:d,apiKey:s,apiEndpoint:e=m,environment:r="production",userId:i,sessionId:u,onError:t})=>{let a={apiKey:s,apiEndpoint:e,environment:r,userId:i,sessionId:u,onError:t};return jsxRuntime.jsx(I,{children:jsxRuntime.jsxs(C,{config:a,children:[jsxRuntime.jsx(h,{config:a,children:d}),jsxRuntime.jsx(Q,{apiEndpoint:e,apiKey:s})]})})};exports.LumelyErrorBoundary=h;exports.LumelyErrorOverlay=b;exports.LumelyOverlayProvider=I;exports.LumelyProvider=Z;exports.useLumelyContext=W;exports.useLumelyOverlay=f;exports.useLumelyReport=z;//# sourceMappingURL=index.js.map
8
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","errorId","hideOverlay","setLoading","loading","prev","setAiResponse","response","jsx","LumelyContext","generateSessionId","stored","newId","useLumelyContext","context","useLumelyReport","LumelyContextProvider","config","sessionId","useMemo","overlay","reportError","additionalContext","_a","report","data","e","useEffect","handleUnhandledRejection","event","handleGlobalError","value","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","err","errorInfo","hasError","Fragment","ManualErrorOverlay","apiKey","handleSubmitFeedback","handleGoBack","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Shared error state for overlay\r\ninterface LumelyOverlayState {\r\n isVisible: boolean;\r\n error: Error | null;\r\n isLoading: boolean;\r\n aiResponse: LumelyAIResponse | null;\r\n errorId: string | null;\r\n}\r\n\r\ninterface LumelyOverlayContextValue {\r\n state: LumelyOverlayState;\r\n showOverlay: (error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => void;\r\n hideOverlay: () => void;\r\n setLoading: (loading: boolean) => void;\r\n setAiResponse: (response: LumelyAIResponse | null, errorId?: string | null) => void;\r\n}\r\n\r\nconst LumelyOverlayContext = createContext<LumelyOverlayContextValue | null>(null);\r\n\r\nexport const useLumelyOverlay = () => {\r\n return useContext(LumelyOverlayContext);\r\n};\r\n\r\ninterface LumelyOverlayProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport const LumelyOverlayProvider = ({ children }: LumelyOverlayProviderProps) => {\r\n const [state, setState] = useState<LumelyOverlayState>({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n\r\n const showOverlay = useCallback((error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState({\r\n isVisible: true,\r\n error,\r\n isLoading: !aiResponse,\r\n aiResponse: aiResponse || null,\r\n errorId: errorId || null,\r\n });\r\n }, []);\r\n\r\n const hideOverlay = useCallback(() => {\r\n setState({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n }, []);\r\n\r\n const setLoading = useCallback((loading: boolean) => {\r\n setState(prev => ({ ...prev, isLoading: loading }));\r\n }, []);\r\n\r\n const setAiResponse = useCallback((response: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState(prev => ({\r\n ...prev,\r\n aiResponse: response,\r\n errorId: errorId || prev.errorId,\r\n isLoading: false\r\n }));\r\n }, []);\r\n\r\n return (\r\n <LumelyOverlayContext.Provider value={{ state, showOverlay, hideOverlay, setLoading, setAiResponse }}>\r\n {children}\r\n </LumelyOverlayContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\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 useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * The error overlay will be shown to the user.\r\n * \r\n * Usage:\r\n * ```tsx\r\n * const { reportError } = useLumelyReport();\r\n * \r\n * try {\r\n * await fetchData();\r\n * } catch (error) {\r\n * reportError(error, { action: 'fetching user data' });\r\n * }\r\n * ```\r\n */\r\nexport const useLumelyReport = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n // Return a no-op function instead of throwing to prevent crashes during SSR or Fast Refresh\r\n if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {\r\n console.warn('[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh.');\r\n }\r\n return {\r\n reportError: async () => {\r\n console.warn('[Lumely] Cannot report error: LumelyProvider not found');\r\n }\r\n };\r\n }\r\n return { reportError: context.reportError };\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 sessionId = useMemo(() => config.sessionId || generateSessionId(), [config.sessionId]);\r\n const overlay = useLumelyOverlay();\r\n\r\n // Manual error reporting function - now shows overlay\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n // Show overlay immediately with loading state\r\n overlay?.showOverlay(error);\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n // Update overlay with AI response\r\n overlay?.setAiResponse(data.ai, data.errorId);\r\n } else {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n overlay?.setLoading(false);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n overlay?.setLoading(false);\r\n }\r\n }, [config, sessionId, overlay]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n\r\n","'use client';\r\n\r\nimport 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-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-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\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\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: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\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 transition: 'border-color 0.2s',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\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 {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\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 {/* AI Message */}\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 ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\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={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\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 {/* Action Button */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\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; // Prevent duplicate reports\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 // Prevent duplicate reports\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 } = 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 try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\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 { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\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 // Dismiss the overlay first\r\n this.handleDismiss();\r\n // Then navigate back\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","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: 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// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiKey }: { apiKey: string }) => {\r\n const overlay = useLumelyOverlay();\r\n\r\n if (!overlay?.state.isVisible || !overlay.state.error) {\r\n return null;\r\n }\r\n\r\n const handleSubmitFeedback = async (feedback: string) => {\r\n if (!overlay.state.errorId) return;\r\n\r\n try {\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': apiKey,\r\n },\r\n body: JSON.stringify({\r\n errorId: overlay.state.errorId,\r\n userFeedback: feedback,\r\n }),\r\n });\r\n } catch (e) {\r\n console.error('[Lumely] Failed to submit feedback:', e);\r\n }\r\n };\r\n\r\n const handleGoBack = () => {\r\n overlay.hideOverlay();\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n return (\r\n <LumelyErrorOverlay\r\n aiResponse={overlay.state.aiResponse || undefined}\r\n isLoading={overlay.state.isLoading}\r\n feedbackSubmitted={false}\r\n onSubmitFeedback={handleSubmitFeedback}\r\n onRetry={overlay.hideOverlay}\r\n onDismiss={overlay.hideOverlay}\r\n onGoBack={handleGoBack}\r\n />\r\n );\r\n};\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\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 environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiKey={apiKey} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
1
+ {"version":3,"sources":["../types.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","errorId","hideOverlay","setLoading","loading","prev","setAiResponse","response","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumelyContext","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","overlay","reportError","additionalContext","_a","_b","report","apiEndpoint","data","e","handleUnhandledRejection","event","handleGlobalError","value","useMemo","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","err","errorInfo","hasError","Fragment","ManualErrorOverlay","apiKey","handleSubmitFeedback","handleGoBack","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.js","sourcesContent":["// Default API endpoint - points to Lumely's hosted backend\r\nexport const LUMELY_API_ENDPOINT = 'https://lumely.vercel.app/api/lumely';\r\n\r\nexport interface LumelyConfig {\r\n apiKey: string;\r\n apiEndpoint?: string; // Defaults to LUMELY_API_ENDPOINT\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: (error: LumelyErrorReport) => void;\r\n}\r\n\r\nexport interface LumelyErrorContext {\r\n url: string;\r\n userAgent: string;\r\n userId?: string;\r\n sessionId?: string;\r\n userFeedback?: string;\r\n timestamp: string;\r\n additionalContext?: string;\r\n}\r\n\r\nexport interface LumelyErrorReport {\r\n errorMessage: string;\r\n errorStack?: string;\r\n componentStack?: string;\r\n context: LumelyErrorContext;\r\n}\r\n\r\nexport interface LumelyAIResponse {\r\n userMessage: string;\r\n summary: string;\r\n suggestedFix: string;\r\n}\r\n\r\nexport interface LumelyAPIResponse {\r\n success: boolean;\r\n ai: LumelyAIResponse;\r\n errorId: string;\r\n}\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Shared error state for overlay\r\ninterface LumelyOverlayState {\r\n isVisible: boolean;\r\n error: Error | null;\r\n isLoading: boolean;\r\n aiResponse: LumelyAIResponse | null;\r\n errorId: string | null;\r\n}\r\n\r\ninterface LumelyOverlayContextValue {\r\n state: LumelyOverlayState;\r\n showOverlay: (error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => void;\r\n hideOverlay: () => void;\r\n setLoading: (loading: boolean) => void;\r\n setAiResponse: (response: LumelyAIResponse | null, errorId?: string | null) => void;\r\n}\r\n\r\nconst LumelyOverlayContext = createContext<LumelyOverlayContextValue | null>(null);\r\n\r\nexport const useLumelyOverlay = () => {\r\n return useContext(LumelyOverlayContext);\r\n};\r\n\r\ninterface LumelyOverlayProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport const LumelyOverlayProvider = ({ children }: LumelyOverlayProviderProps) => {\r\n const [state, setState] = useState<LumelyOverlayState>({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n\r\n const showOverlay = useCallback((error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState({\r\n isVisible: true,\r\n error,\r\n isLoading: !aiResponse,\r\n aiResponse: aiResponse || null,\r\n errorId: errorId || null,\r\n });\r\n }, []);\r\n\r\n const hideOverlay = useCallback(() => {\r\n setState({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n }, []);\r\n\r\n const setLoading = useCallback((loading: boolean) => {\r\n setState(prev => ({ ...prev, isLoading: loading }));\r\n }, []);\r\n\r\n const setAiResponse = useCallback((response: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState(prev => ({\r\n ...prev,\r\n aiResponse: response,\r\n errorId: errorId || prev.errorId,\r\n isLoading: false\r\n }));\r\n }, []);\r\n\r\n return (\r\n <LumelyOverlayContext.Provider value={{ state, showOverlay, hideOverlay, setLoading, setAiResponse }}>\r\n {children}\r\n </LumelyOverlayContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Pure functions for session ID\r\nconst getStoredSessionId = () => {\r\n if (typeof window === 'undefined') return null;\r\n return sessionStorage.getItem('lumely_session_id');\r\n};\r\n\r\nconst createSessionId = () => {\r\n return `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * The error overlay will be shown to the user.\r\n * \r\n * Usage:\r\n * ```tsx\r\n * const { reportError } = useLumelyReport();\r\n * \r\n * try {\r\n * await fetchData();\r\n * } catch (error) {\r\n * reportError(error, { action: 'fetching user data' });\r\n * }\r\n * ```\r\n */\r\nexport const useLumelyReport = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n // Return a no-op function instead of throwing to prevent crashes during SSR or Fast Refresh\r\n if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {\r\n console.warn('[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh.');\r\n }\r\n return {\r\n reportError: async () => {\r\n console.warn('[Lumely] Cannot report error: LumelyProvider not found');\r\n }\r\n };\r\n }\r\n return { reportError: context.reportError };\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 [sessionId] = React.useState(() => {\r\n if (config.sessionId) return config.sessionId;\r\n return getStoredSessionId() || createSessionId();\r\n });\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined' && !config.sessionId && sessionId !== 'server') {\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (!stored) {\r\n sessionStorage.setItem('lumely_session_id', sessionId);\r\n }\r\n }\r\n }, [sessionId, config.sessionId]);\r\n\r\n const overlay = useLumelyOverlay();\r\n\r\n // Manual error reporting function - now shows overlay\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n // Show overlay immediately with loading state\r\n overlay?.showOverlay(error);\r\n\r\n try {\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n const response = await fetch(`${apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n // Update overlay with AI response\r\n overlay?.setAiResponse(data.ai, data.errorId);\r\n } else {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n overlay?.setLoading(false);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n overlay?.setLoading(false);\r\n }\r\n }, [config, sessionId, overlay]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n\r\n","'use client';\r\n\r\nimport 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-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-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\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\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: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\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 transition: 'border-color 0.2s',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\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 {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\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 {/* AI Message */}\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 ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\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={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\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 {/* Action Button */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\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; // Prevent duplicate reports\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 // Prevent duplicate reports\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 } = 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 try {\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n const response = await fetch(`${apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\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 { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n await fetch(`${apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\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 // Dismiss the overlay first\r\n this.handleDismiss();\r\n // Then navigate back\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","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n /** API endpoint for error reporting. Defaults to Lumely's hosted backend. */\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// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, apiKey }: { apiEndpoint: string; apiKey: string }) => {\r\n const overlay = useLumelyOverlay();\r\n\r\n if (!overlay?.state.isVisible || !overlay.state.error) {\r\n return null;\r\n }\r\n\r\n const handleSubmitFeedback = async (feedback: string) => {\r\n if (!overlay.state.errorId) return;\r\n\r\n try {\r\n await fetch(`${apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': apiKey,\r\n },\r\n body: JSON.stringify({\r\n errorId: overlay.state.errorId,\r\n userFeedback: feedback,\r\n }),\r\n });\r\n } catch (e) {\r\n console.error('[Lumely] Failed to submit feedback:', e);\r\n }\r\n };\r\n\r\n const handleGoBack = () => {\r\n overlay.hideOverlay();\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n return (\r\n <LumelyErrorOverlay\r\n aiResponse={overlay.state.aiResponse || undefined}\r\n isLoading={overlay.state.isLoading}\r\n feedbackSubmitted={false}\r\n onSubmitFeedback={handleSubmitFeedback}\r\n onRetry={overlay.hideOverlay}\r\n onDismiss={overlay.hideOverlay}\r\n onGoBack={handleGoBack}\r\n />\r\n );\r\n};\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\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 return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} apiKey={apiKey} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n\r\n"]}
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import {createContext,useContext,useState,useCallback,useEffect,Component,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var k=createContext(null),m=()=>useContext(k),v=({children:n})=>{let[e,o]=useState({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null}),r=useCallback((d,a,p)=>{o({isVisible:true,error:d,isLoading:!a,aiResponse:a||null,errorId:p||null});},[]),i=useCallback(()=>{o({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null});},[]),u=useCallback(d=>{o(a=>({...a,isLoading:d}));},[]),l=useCallback((d,a)=>{o(p=>({...p,aiResponse:d,errorId:a||p.errorId,isLoading:false}));},[]);return jsx(k.Provider,{value:{state:e,showOverlay:r,hideOverlay:i,setLoading:u,setAiResponse:l},children:n})};var R=createContext(null),T=()=>{if(typeof window=="undefined")return "server";let n=sessionStorage.getItem("lumely_session_id");if(n)return n;let e=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",e),e},D=()=>{let n=useContext(R);if(!n)throw new Error("useLumelyContext must be used within a LumelyProvider");return n},W=()=>{let n=useContext(R);return n?{reportError:n.reportError}:(typeof window!="undefined"&&process.env.NODE_ENV==="development"&&console.warn("[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh."),{reportError:async()=>{console.warn("[Lumely] Cannot report error: LumelyProvider not found");}})},I=({children:n,config:e})=>{let o=useMemo(()=>e.sessionId||T(),[e.sessionId]),r=m(),i=useCallback(async(l,d)=>{var p;let a={errorMessage:l.message,errorStack:l.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:e.userId,sessionId:o,timestamp:new Date().toISOString(),...d&&{additionalContext:JSON.stringify(d)}}};r==null||r.showOverlay(l);try{let y=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":e.apiKey},body:JSON.stringify(a)});if(y.ok){let b=await y.json();r==null||r.setAiResponse(b.ai,b.errorId);}else console.error("[Lumely] Failed to report error:",y.statusText),r==null||r.setLoading(!1);(p=e.onError)==null||p.call(e,a);}catch(y){console.error("[Lumely] Error reporting failed:",y),r==null||r.setLoading(false);}},[e,o,r]);useEffect(()=>{if(typeof window=="undefined")return;let l=a=>{let p=a.reason instanceof Error?a.reason:new Error(String(a.reason));i(p,{type:"unhandledRejection"});},d=a=>{let p=a.error instanceof Error?a.error:new Error(a.message);i(p,{type:"globalError",filename:a.filename,lineno:a.lineno,colno:a.colno});};return window.addEventListener("unhandledrejection",l),window.addEventListener("error",d),()=>{window.removeEventListener("unhandledrejection",l),window.removeEventListener("error",d);}},[i]);let u=useMemo(()=>({...e,sessionId:o,environment:e.environment||"production",reportError:i}),[e,o,i]);return jsx(R.Provider,{value:u,children:n})};var V=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let n=document.createElement("style");n.id="lumely-next-styles",n.textContent=`
1
+ import N,{createContext,useContext,useState,useCallback,useEffect,Component,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var m="https://lumely.vercel.app/api/lumely";var k=createContext(null),f=()=>useContext(k),I=({children:d})=>{let[s,e]=useState({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null}),r=useCallback((a,n,p)=>{e({isVisible:true,error:a,isLoading:!n,aiResponse:n||null,errorId:p||null});},[]),i=useCallback(()=>{e({isVisible:false,error:null,isLoading:false,aiResponse:null,errorId:null});},[]),u=useCallback(a=>{e(n=>({...n,isLoading:a}));},[]),t=useCallback((a,n)=>{e(p=>({...p,aiResponse:a,errorId:n||p.errorId,isLoading:false}));},[]);return jsx(k.Provider,{value:{state:s,showOverlay:r,hideOverlay:i,setLoading:u,setAiResponse:t},children:d})};var E=createContext(null),j=()=>typeof window=="undefined"?null:sessionStorage.getItem("lumely_session_id"),M=()=>`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`,W=()=>{let d=useContext(E);if(!d)throw new Error("useLumelyContext must be used within a LumelyProvider");return d},z=()=>{let d=useContext(E);return d?{reportError:d.reportError}:(typeof window!="undefined"&&process.env.NODE_ENV==="development"&&console.warn("[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh."),{reportError:async()=>{console.warn("[Lumely] Cannot report error: LumelyProvider not found");}})},C=({children:d,config:s})=>{let[e]=N.useState(()=>s.sessionId?s.sessionId:j()||M());useEffect(()=>{typeof window!="undefined"&&!s.sessionId&&e!=="server"&&(sessionStorage.getItem("lumely_session_id")||sessionStorage.setItem("lumely_session_id",e));},[e,s.sessionId]);let r=f(),i=useCallback(async(t,a)=>{var p,x;let n={errorMessage:t.message,errorStack:t.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:s.userId,sessionId:e,timestamp:new Date().toISOString(),...a&&{additionalContext:JSON.stringify(a)}}};r==null||r.showOverlay(t);try{let g=(p=s.apiEndpoint)!=null?p:m,y=await fetch(`${g}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(n)});if(y.ok){let R=await y.json();r==null||r.setAiResponse(R.ai,R.errorId);}else console.error("[Lumely] Failed to report error:",y.statusText),r==null||r.setLoading(!1);(x=s.onError)==null||x.call(s,n);}catch(g){console.error("[Lumely] Error reporting failed:",g),r==null||r.setLoading(false);}},[s,e,r]);useEffect(()=>{if(typeof window=="undefined")return;let t=n=>{let p=n.reason instanceof Error?n.reason:new Error(String(n.reason));i(p,{type:"unhandledRejection"});},a=n=>{let p=n.error instanceof Error?n.error:new Error(n.message);i(p,{type:"globalError",filename:n.filename,lineno:n.lineno,colno:n.colno});};return window.addEventListener("unhandledrejection",t),window.addEventListener("error",a),()=>{window.removeEventListener("unhandledrejection",t),window.removeEventListener("error",a);}},[i]);let u=useMemo(()=>({...s,sessionId:e,environment:s.environment||"production",reportError:i}),[s,e,i]);return jsx(E.Provider,{value:u,children:d})};var G=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let d=document.createElement("style");d.id="lumely-next-styles",d.textContent=`
2
2
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
3
3
  @keyframes lumely-spin {
4
4
  from { transform: rotate(0deg); }
5
5
  to { transform: rotate(360deg); }
6
6
  }
7
- `,document.head.appendChild(n);},K=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),M=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),G=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsx("polyline",{points:"12 19 5 12 12 5"})]});var s={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:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",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",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},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",transition:"border-color 0.2s"},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",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},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"},primaryButton:{background:"#7c3aed",color:"white"}},f=({aiResponse:n,isLoading:e,feedbackSubmitted:o=false,onSubmitFeedback:r,onRetry:i,onDismiss:u,onGoBack:l})=>{let[d,a]=useState(""),[p,y]=useState(false);useEffect(()=>{V();},[]);let b=L=>{L.preventDefault(),d.trim()&&!p&&(y(true),r(d));};return jsx("div",{style:s.overlay,children:jsxs("div",{style:s.card,children:[jsx("button",{style:s.closeButton,onClick:u,children:jsx(K,{})}),jsxs("div",{style:s.content,children:[jsxs("div",{style:s.header,children:[jsx("div",{style:s.logo,children:"L"}),jsxs("div",{children:[jsx("h3",{style:s.title,children:"Something went wrong"}),jsx("p",{style:s.subtitle,children:"We're looking into it"})]})]}),e?jsxs("div",{style:s.loading,children:[jsx("div",{style:s.spinner}),jsx("span",{children:"Analyzing the issue..."})]}):n?jsx("div",{style:s.messageBox,children:jsx("p",{style:s.message,children:n.userMessage})}):jsx("div",{style:s.messageBox,children:jsx("p",{style:s.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!o&&!p?jsxs("form",{style:s.form,onSubmit:b,children:[jsx("label",{style:s.label,children:"What were you trying to do?"}),jsxs("div",{style:s.inputWrapper,children:[jsx("input",{type:"text",value:d,onChange:L=>a(L.target.value),placeholder:"e.g., I was trying to save my changes...",style:s.input}),jsx("button",{type:"submit",disabled:!d.trim(),style:{...s.submitButton,opacity:d.trim()?1:.3},children:jsx(M,{})})]})]}):jsx("div",{style:s.successBox,children:jsx("p",{style:s.successText,children:"Thank you! Your feedback helps us improve."})}),jsx("div",{style:s.buttons,children:jsxs("button",{style:{...s.button,...s.primaryButton},onClick:l,children:[jsx(G,{}),"Go Back"]})})]})]})})};var g=class extends Component{constructor(o){super(o);this.isReporting=false;this.handleSubmitFeedback=async o=>{let{errorId:r}=this.state,{config:i}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify({errorId:r,feedback:o})}),this.setState({feedbackSubmitted:!0});}catch(u){console.error("Lumely: Failed to submit feedback",u),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=()=>{this.handleDismiss(),typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(o){return {hasError:true,error:o}}componentDidCatch(o,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(o,r));}async reportError(o,r){let{config:i}=this.props,u={errorMessage:o.message,errorStack:o.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:i.userId,sessionId:i.sessionId,timestamp:new Date().toISOString()}};try{let l=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify(u)});if(l.ok){let d=await l.json();this.setState({aiResponse:d.ai,errorId:d.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(l){console.error("Lumely: Failed to report error",l),this.setState({isLoading:false});}i.onError&&i.onError(u);}render(){let{hasError:o,aiResponse:r,isLoading:i,feedbackSubmitted:u}=this.state,{children:l}=this.props;return o?jsxs(Fragment,{children:[l,jsx(f,{aiResponse:r||void 0,isLoading:i,feedbackSubmitted:u,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):l}};var Y=({apiKey:n})=>{let e=m();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async i=>{if(e.state.errorId)try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":n},body:JSON.stringify({errorId:e.state.errorId,userFeedback:i})});}catch(u){console.error("[Lumely] Failed to submit feedback:",u);}},r=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsx(f,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:r})},$=({children:n,apiKey:e,environment:o="production",userId:r,sessionId:i,onError:u})=>{let l={apiKey:e,environment:o,userId:r,sessionId:i,onError:u};return jsx(v,{children:jsxs(I,{config:l,children:[jsx(g,{config:l,children:n}),jsx(Y,{apiKey:e})]})})};export{g as LumelyErrorBoundary,f as LumelyErrorOverlay,v as LumelyOverlayProvider,$ as LumelyProvider,D as useLumelyContext,m as useLumelyOverlay,W as useLumelyReport};//# sourceMappingURL=index.mjs.map
7
+ `,document.head.appendChild(d);},U=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),Y=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),$=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsx("polyline",{points:"12 19 5 12 12 5"})]});var l={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:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",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",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},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",transition:"border-color 0.2s"},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",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},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"},primaryButton:{background:"#7c3aed",color:"white"}},b=({aiResponse:d,isLoading:s,feedbackSubmitted:e=false,onSubmitFeedback:r,onRetry:i,onDismiss:u,onGoBack:t})=>{let[a,n]=useState(""),[p,x]=useState(false);useEffect(()=>{G();},[]);let g=y=>{y.preventDefault(),a.trim()&&!p&&(x(true),r(a));};return jsx("div",{style:l.overlay,children:jsxs("div",{style:l.card,children:[jsx("button",{style:l.closeButton,onClick:u,children:jsx(U,{})}),jsxs("div",{style:l.content,children:[jsxs("div",{style:l.header,children:[jsx("div",{style:l.logo,children:"L"}),jsxs("div",{children:[jsx("h3",{style:l.title,children:"Something went wrong"}),jsx("p",{style:l.subtitle,children:"We're looking into it"})]})]}),s?jsxs("div",{style:l.loading,children:[jsx("div",{style:l.spinner}),jsx("span",{children:"Analyzing the issue..."})]}):d?jsx("div",{style:l.messageBox,children:jsx("p",{style:l.message,children:d.userMessage})}):jsx("div",{style:l.messageBox,children:jsx("p",{style:l.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!e&&!p?jsxs("form",{style:l.form,onSubmit:g,children:[jsx("label",{style:l.label,children:"What were you trying to do?"}),jsxs("div",{style:l.inputWrapper,children:[jsx("input",{type:"text",value:a,onChange:y=>n(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:l.input}),jsx("button",{type:"submit",disabled:!a.trim(),style:{...l.submitButton,opacity:a.trim()?1:.3},children:jsx(Y,{})})]})]}):jsx("div",{style:l.successBox,children:jsx("p",{style:l.successText,children:"Thank you! Your feedback helps us improve."})}),jsx("div",{style:l.buttons,children:jsxs("button",{style:{...l.button,...l.primaryButton},onClick:t,children:[jsx($,{}),"Go Back"]})})]})]})})};var h=class extends Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{var u;let{errorId:r}=this.state,{config:i}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{let t=(u=i.apiEndpoint)!=null?u:m;await fetch(`${t}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify({errorId:r,feedback:e})}),this.setState({feedbackSubmitted:!0});}catch(t){console.error("Lumely: Failed to submit feedback",t),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=()=>{this.handleDismiss(),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,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(e,r));}async reportError(e,r){var t;let{config:i}=this.props,u={errorMessage:e.message,errorStack:e.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:i.userId,sessionId:i.sessionId,timestamp:new Date().toISOString()}};try{let a=(t=i.apiEndpoint)!=null?t:m,n=await fetch(`${a}/report-error`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":i.apiKey},body:JSON.stringify(u)});if(n.ok){let p=await n.json();this.setState({aiResponse:p.ai,errorId:p.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(a){console.error("Lumely: Failed to report error",a),this.setState({isLoading:false});}i.onError&&i.onError(u);}render(){let{hasError:e,aiResponse:r,isLoading:i,feedbackSubmitted:u}=this.state,{children:t}=this.props;return e?jsxs(Fragment,{children:[t,jsx(b,{aiResponse:r||void 0,isLoading:i,feedbackSubmitted:u,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):t}};var Q=({apiEndpoint:d,apiKey:s})=>{let e=f();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let r=async u=>{if(e.state.errorId)try{await fetch(`${d}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s},body:JSON.stringify({errorId:e.state.errorId,userFeedback:u})});}catch(t){console.error("[Lumely] Failed to submit feedback:",t);}},i=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsx(b,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:r,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:i})},Z=({children:d,apiKey:s,apiEndpoint:e=m,environment:r="production",userId:i,sessionId:u,onError:t})=>{let a={apiKey:s,apiEndpoint:e,environment:r,userId:i,sessionId:u,onError:t};return jsx(I,{children:jsxs(C,{config:a,children:[jsx(h,{config:a,children:d}),jsx(Q,{apiEndpoint:e,apiKey:s})]})})};export{h as LumelyErrorBoundary,b as LumelyErrorOverlay,I as LumelyOverlayProvider,Z as LumelyProvider,W as useLumelyContext,f as useLumelyOverlay,z as useLumelyReport};//# sourceMappingURL=index.mjs.map
8
8
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","errorId","hideOverlay","setLoading","loading","prev","setAiResponse","response","jsx","LumelyContext","generateSessionId","stored","newId","useLumelyContext","context","useLumelyReport","LumelyContextProvider","config","sessionId","useMemo","overlay","reportError","additionalContext","_a","report","data","e","useEffect","handleUnhandledRejection","event","handleGlobalError","value","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","err","errorInfo","hasError","Fragment","ManualErrorOverlay","apiKey","handleSubmitFeedback","handleGoBack","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Shared error state for overlay\r\ninterface LumelyOverlayState {\r\n isVisible: boolean;\r\n error: Error | null;\r\n isLoading: boolean;\r\n aiResponse: LumelyAIResponse | null;\r\n errorId: string | null;\r\n}\r\n\r\ninterface LumelyOverlayContextValue {\r\n state: LumelyOverlayState;\r\n showOverlay: (error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => void;\r\n hideOverlay: () => void;\r\n setLoading: (loading: boolean) => void;\r\n setAiResponse: (response: LumelyAIResponse | null, errorId?: string | null) => void;\r\n}\r\n\r\nconst LumelyOverlayContext = createContext<LumelyOverlayContextValue | null>(null);\r\n\r\nexport const useLumelyOverlay = () => {\r\n return useContext(LumelyOverlayContext);\r\n};\r\n\r\ninterface LumelyOverlayProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport const LumelyOverlayProvider = ({ children }: LumelyOverlayProviderProps) => {\r\n const [state, setState] = useState<LumelyOverlayState>({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n\r\n const showOverlay = useCallback((error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState({\r\n isVisible: true,\r\n error,\r\n isLoading: !aiResponse,\r\n aiResponse: aiResponse || null,\r\n errorId: errorId || null,\r\n });\r\n }, []);\r\n\r\n const hideOverlay = useCallback(() => {\r\n setState({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n }, []);\r\n\r\n const setLoading = useCallback((loading: boolean) => {\r\n setState(prev => ({ ...prev, isLoading: loading }));\r\n }, []);\r\n\r\n const setAiResponse = useCallback((response: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState(prev => ({\r\n ...prev,\r\n aiResponse: response,\r\n errorId: errorId || prev.errorId,\r\n isLoading: false\r\n }));\r\n }, []);\r\n\r\n return (\r\n <LumelyOverlayContext.Provider value={{ state, showOverlay, hideOverlay, setLoading, setAiResponse }}>\r\n {children}\r\n </LumelyOverlayContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\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 useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * The error overlay will be shown to the user.\r\n * \r\n * Usage:\r\n * ```tsx\r\n * const { reportError } = useLumelyReport();\r\n * \r\n * try {\r\n * await fetchData();\r\n * } catch (error) {\r\n * reportError(error, { action: 'fetching user data' });\r\n * }\r\n * ```\r\n */\r\nexport const useLumelyReport = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n // Return a no-op function instead of throwing to prevent crashes during SSR or Fast Refresh\r\n if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {\r\n console.warn('[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh.');\r\n }\r\n return {\r\n reportError: async () => {\r\n console.warn('[Lumely] Cannot report error: LumelyProvider not found');\r\n }\r\n };\r\n }\r\n return { reportError: context.reportError };\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 sessionId = useMemo(() => config.sessionId || generateSessionId(), [config.sessionId]);\r\n const overlay = useLumelyOverlay();\r\n\r\n // Manual error reporting function - now shows overlay\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n // Show overlay immediately with loading state\r\n overlay?.showOverlay(error);\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n // Update overlay with AI response\r\n overlay?.setAiResponse(data.ai, data.errorId);\r\n } else {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n overlay?.setLoading(false);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n overlay?.setLoading(false);\r\n }\r\n }, [config, sessionId, overlay]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n\r\n","'use client';\r\n\r\nimport 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-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-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\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\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: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\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 transition: 'border-color 0.2s',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\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 {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\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 {/* AI Message */}\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 ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\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={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\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 {/* Action Button */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\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; // Prevent duplicate reports\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 // Prevent duplicate reports\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 } = 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 try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\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 { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\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 // Dismiss the overlay first\r\n this.handleDismiss();\r\n // Then navigate back\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","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: 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// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiKey }: { apiKey: string }) => {\r\n const overlay = useLumelyOverlay();\r\n\r\n if (!overlay?.state.isVisible || !overlay.state.error) {\r\n return null;\r\n }\r\n\r\n const handleSubmitFeedback = async (feedback: string) => {\r\n if (!overlay.state.errorId) return;\r\n\r\n try {\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': apiKey,\r\n },\r\n body: JSON.stringify({\r\n errorId: overlay.state.errorId,\r\n userFeedback: feedback,\r\n }),\r\n });\r\n } catch (e) {\r\n console.error('[Lumely] Failed to submit feedback:', e);\r\n }\r\n };\r\n\r\n const handleGoBack = () => {\r\n overlay.hideOverlay();\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n return (\r\n <LumelyErrorOverlay\r\n aiResponse={overlay.state.aiResponse || undefined}\r\n isLoading={overlay.state.isLoading}\r\n feedbackSubmitted={false}\r\n onSubmitFeedback={handleSubmitFeedback}\r\n onRetry={overlay.hideOverlay}\r\n onDismiss={overlay.hideOverlay}\r\n onGoBack={handleGoBack}\r\n />\r\n );\r\n};\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\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 environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiKey={apiKey} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
1
+ {"version":3,"sources":["../types.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","errorId","hideOverlay","setLoading","loading","prev","setAiResponse","response","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumelyContext","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","overlay","reportError","additionalContext","_a","_b","report","apiEndpoint","data","e","handleUnhandledRejection","event","handleGlobalError","value","useMemo","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","err","errorInfo","hasError","Fragment","ManualErrorOverlay","apiKey","handleSubmitFeedback","handleGoBack","LumelyProvider","environment","userId","onError"],"mappings":"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","file":"index.mjs","sourcesContent":["// Default API endpoint - points to Lumely's hosted backend\r\nexport const LUMELY_API_ENDPOINT = 'https://lumely.vercel.app/api/lumely';\r\n\r\nexport interface LumelyConfig {\r\n apiKey: string;\r\n apiEndpoint?: string; // Defaults to LUMELY_API_ENDPOINT\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: (error: LumelyErrorReport) => void;\r\n}\r\n\r\nexport interface LumelyErrorContext {\r\n url: string;\r\n userAgent: string;\r\n userId?: string;\r\n sessionId?: string;\r\n userFeedback?: string;\r\n timestamp: string;\r\n additionalContext?: string;\r\n}\r\n\r\nexport interface LumelyErrorReport {\r\n errorMessage: string;\r\n errorStack?: string;\r\n componentStack?: string;\r\n context: LumelyErrorContext;\r\n}\r\n\r\nexport interface LumelyAIResponse {\r\n userMessage: string;\r\n summary: string;\r\n suggestedFix: string;\r\n}\r\n\r\nexport interface LumelyAPIResponse {\r\n success: boolean;\r\n ai: LumelyAIResponse;\r\n errorId: string;\r\n}\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Shared error state for overlay\r\ninterface LumelyOverlayState {\r\n isVisible: boolean;\r\n error: Error | null;\r\n isLoading: boolean;\r\n aiResponse: LumelyAIResponse | null;\r\n errorId: string | null;\r\n}\r\n\r\ninterface LumelyOverlayContextValue {\r\n state: LumelyOverlayState;\r\n showOverlay: (error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => void;\r\n hideOverlay: () => void;\r\n setLoading: (loading: boolean) => void;\r\n setAiResponse: (response: LumelyAIResponse | null, errorId?: string | null) => void;\r\n}\r\n\r\nconst LumelyOverlayContext = createContext<LumelyOverlayContextValue | null>(null);\r\n\r\nexport const useLumelyOverlay = () => {\r\n return useContext(LumelyOverlayContext);\r\n};\r\n\r\ninterface LumelyOverlayProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport const LumelyOverlayProvider = ({ children }: LumelyOverlayProviderProps) => {\r\n const [state, setState] = useState<LumelyOverlayState>({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n\r\n const showOverlay = useCallback((error: Error, aiResponse?: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState({\r\n isVisible: true,\r\n error,\r\n isLoading: !aiResponse,\r\n aiResponse: aiResponse || null,\r\n errorId: errorId || null,\r\n });\r\n }, []);\r\n\r\n const hideOverlay = useCallback(() => {\r\n setState({\r\n isVisible: false,\r\n error: null,\r\n isLoading: false,\r\n aiResponse: null,\r\n errorId: null,\r\n });\r\n }, []);\r\n\r\n const setLoading = useCallback((loading: boolean) => {\r\n setState(prev => ({ ...prev, isLoading: loading }));\r\n }, []);\r\n\r\n const setAiResponse = useCallback((response: LumelyAIResponse | null, errorId?: string | null) => {\r\n setState(prev => ({\r\n ...prev,\r\n aiResponse: response,\r\n errorId: errorId || prev.errorId,\r\n isLoading: false\r\n }));\r\n }, []);\r\n\r\n return (\r\n <LumelyOverlayContext.Provider value={{ state, showOverlay, hideOverlay, setLoading, setAiResponse }}>\r\n {children}\r\n </LumelyOverlayContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Pure functions for session ID\r\nconst getStoredSessionId = () => {\r\n if (typeof window === 'undefined') return null;\r\n return sessionStorage.getItem('lumely_session_id');\r\n};\r\n\r\nconst createSessionId = () => {\r\n return `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * The error overlay will be shown to the user.\r\n * \r\n * Usage:\r\n * ```tsx\r\n * const { reportError } = useLumelyReport();\r\n * \r\n * try {\r\n * await fetchData();\r\n * } catch (error) {\r\n * reportError(error, { action: 'fetching user data' });\r\n * }\r\n * ```\r\n */\r\nexport const useLumelyReport = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n // Return a no-op function instead of throwing to prevent crashes during SSR or Fast Refresh\r\n if (typeof window !== 'undefined' && process.env.NODE_ENV === 'development') {\r\n console.warn('[Lumely] useLumelyReport called outside of LumelyProvider. This is expected during Fast Refresh.');\r\n }\r\n return {\r\n reportError: async () => {\r\n console.warn('[Lumely] Cannot report error: LumelyProvider not found');\r\n }\r\n };\r\n }\r\n return { reportError: context.reportError };\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 [sessionId] = React.useState(() => {\r\n if (config.sessionId) return config.sessionId;\r\n return getStoredSessionId() || createSessionId();\r\n });\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined' && !config.sessionId && sessionId !== 'server') {\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (!stored) {\r\n sessionStorage.setItem('lumely_session_id', sessionId);\r\n }\r\n }\r\n }, [sessionId, config.sessionId]);\r\n\r\n const overlay = useLumelyOverlay();\r\n\r\n // Manual error reporting function - now shows overlay\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n // Show overlay immediately with loading state\r\n overlay?.showOverlay(error);\r\n\r\n try {\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n const response = await fetch(`${apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n // Update overlay with AI response\r\n overlay?.setAiResponse(data.ai, data.errorId);\r\n } else {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n overlay?.setLoading(false);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n overlay?.setLoading(false);\r\n }\r\n }, [config, sessionId, overlay]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n\r\n","'use client';\r\n\r\nimport 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-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-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\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\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: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\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 transition: 'border-color 0.2s',\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 display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\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 {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\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 {/* AI Message */}\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 ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\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={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\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 {/* Action Button */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\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; // Prevent duplicate reports\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 // Prevent duplicate reports\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 } = 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 try {\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n const response = await fetch(`${apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\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 { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n const apiEndpoint = config.apiEndpoint ?? LUMELY_API_ENDPOINT;\r\n await fetch(`${apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\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 // Dismiss the overlay first\r\n this.handleDismiss();\r\n // Then navigate back\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","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n /** API endpoint for error reporting. Defaults to Lumely's hosted backend. */\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// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, apiKey }: { apiEndpoint: string; apiKey: string }) => {\r\n const overlay = useLumelyOverlay();\r\n\r\n if (!overlay?.state.isVisible || !overlay.state.error) {\r\n return null;\r\n }\r\n\r\n const handleSubmitFeedback = async (feedback: string) => {\r\n if (!overlay.state.errorId) return;\r\n\r\n try {\r\n await fetch(`${apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': apiKey,\r\n },\r\n body: JSON.stringify({\r\n errorId: overlay.state.errorId,\r\n userFeedback: feedback,\r\n }),\r\n });\r\n } catch (e) {\r\n console.error('[Lumely] Failed to submit feedback:', e);\r\n }\r\n };\r\n\r\n const handleGoBack = () => {\r\n overlay.hideOverlay();\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n return (\r\n <LumelyErrorOverlay\r\n aiResponse={overlay.state.aiResponse || undefined}\r\n isLoading={overlay.state.isLoading}\r\n feedbackSubmitted={false}\r\n onSubmitFeedback={handleSubmitFeedback}\r\n onRetry={overlay.hideOverlay}\r\n onDismiss={overlay.hideOverlay}\r\n onGoBack={handleGoBack}\r\n />\r\n );\r\n};\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\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 return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} apiKey={apiKey} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumely-next",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "AI-powered error handling for Next.js applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",