lumely-react 0.1.13 → 0.1.14

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/dist/index.js CHANGED
@@ -14,5 +14,5 @@
14
14
  transform: translate(-50%, 0);
15
15
  }
16
16
  }
17
- `,document.head.appendChild(s);},J=()=>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:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),U=()=>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:"22",y1:"2",x2:"11",y2:"13"}),jsxRuntime.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),u={container:{position:"fixed",top:"16px",left:"50%",transform:"translateX(-50%)",zIndex:9999,width:"100%",maxWidth:"480px",padding:"0 16px",boxSizing:"border-box",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",animation:"lumely-slide-down 0.3s ease-out"},card:{position:"relative",width:"100%",background:"rgba(30, 30, 35, 0.95)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",overflow:"hidden"},content:{display:"flex",flexDirection:"column",alignItems:"stretch",gap:"16px",padding:"16px 20px"},textContent:{flex:1,minWidth:0},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0,marginBottom:"4px"},message:{color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",lineHeight:1.4,margin:0},formWrapper:{display:"flex",alignItems:"center",gap:"8px",flexShrink:0,width:"100%"},input:{flex:1,width:"100%",background:"rgba(255, 255, 255, 0.08)",border:"1px solid rgba(255, 255, 255, 0.12)",borderRadius:"8px",padding:"8px 12px",color:"white",fontSize:"12px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},sendButton:{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"8px 14px",borderRadius:"8px",fontSize:"12px",fontWeight:500,cursor:"pointer",border:"none",background:"#7c3aed",color:"white",transition:"all 0.2s",flexShrink:0},closeButton:{position:"absolute",top:"8px",right:"8px",padding:"4px",color:"rgba(255, 255, 255, 0.5)",background:"transparent",border:"none",borderRadius:"6px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},loading:{display:"flex",alignItems:"center",gap:"6px",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px"},spinner:{width:"12px",height:"12px",border:"2px solid rgba(255, 255, 255, 0.2)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},successText:{color:"#4ade80",fontSize:"12px",margin:0}},h=({aiResponse:s,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:o,onRetry:t,onDismiss:a,onGoBack:l})=>{let[n,d]=D.useState(""),[p,y]=D.useState(false);D.useEffect(()=>{j();},[]);let m=I=>{I.preventDefault(),n.trim()&&!p&&(y(true),o(n));},S=()=>r?"Analyzing the issue...":s!=null&&s.userMessage?s.userMessage:"An unexpected error occurred. Our team has been notified.";return jsxRuntime.jsx("div",{style:u.container,children:jsxRuntime.jsxs("div",{style:u.card,children:[jsxRuntime.jsx("button",{style:u.closeButton,onClick:a,"aria-label":"Close",children:jsxRuntime.jsx(J,{})}),jsxRuntime.jsxs("div",{style:u.content,children:[jsxRuntime.jsxs("div",{style:u.textContent,children:[jsxRuntime.jsx("h3",{style:u.title,children:"Something went wrong"}),r?jsxRuntime.jsxs("div",{style:u.loading,children:[jsxRuntime.jsx("div",{style:u.spinner}),jsxRuntime.jsx("span",{children:"Analyzing..."})]}):jsxRuntime.jsx("p",{style:u.message,title:S(),children:S()})]}),jsxRuntime.jsx("div",{style:u.formWrapper,children:!e&&!p?jsxRuntime.jsxs("form",{id:"lumely-feedback-form",onSubmit:m,style:{display:"flex",alignItems:"center",gap:"8px"},children:[jsxRuntime.jsx("input",{type:"text",value:n,onChange:I=>d(I.target.value),placeholder:"What were you doing?",style:u.input}),jsxRuntime.jsxs("button",{type:"submit",disabled:!n.trim(),style:{...u.sendButton,opacity:n.trim()?1:.5,cursor:n.trim()?"pointer":"not-allowed"},children:[jsxRuntime.jsx(U,{}),"Send"]})]}):jsxRuntime.jsx("p",{style:u.successText,children:"Thanks for the feedback, our team has been notified about the error."})})]})]})})};var L=class extends D.Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:o}=this.state,{client:t}=this.props;if(!o||o==="client-error"){this.setState({feedbackSubmitted:true});return}await t.updateFeedback(o,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,o){this.isReporting||(this.isReporting=true,this.setState({errorInfo:o,isLoading:true}),this.reportError(e,o));}async reportError(e,o){let{config:t,client:a}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:o.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:t.userId,sessionId:t.sessionId,timestamp:new Date().toISOString()}},n=await a.reportError(l);this.setState({aiResponse:n.ai,errorId:n.errorId,isLoading:false}),t.onError&&t.onError(l);}render(){let{hasError:e,aiResponse:o,isLoading:t,feedbackSubmitted:a}=this.state,{children:l}=this.props;return e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[l,jsxRuntime.jsx(h,{aiResponse:o||void 0,isLoading:t,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack,logo:this.props.logo})]}):l}};var Q=({apiEndpoint:s,logo:r})=>{let e=g();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async a=>{if(e.state.errorId)try{await fetch(`${s}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({errorId:e.state.errorId,userFeedback:a})});}catch(l){console.error("[Lumely] Failed to submit feedback:",l);}},t=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsxRuntime.jsx(h,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:t,logo:r})},Z=({children:s,apiKey:r,apiEndpoint:e=b,environment:o="production",userId:t,sessionId:a,onError:l,logo:n})=>{let d={apiKey:r,apiEndpoint:e,environment:o,userId:t,sessionId:a,onError:l},p=new f(r,e);return jsxRuntime.jsx(R,{children:jsxRuntime.jsxs(P,{config:d,children:[jsxRuntime.jsx(L,{config:d,client:p,logo:n,children:s}),jsxRuntime.jsx(Q,{apiEndpoint:e,logo:n})]})})};exports.LumelyClient=f;exports.LumelyErrorBoundary=L;exports.LumelyErrorOverlay=h;exports.LumelyOverlayProvider=R;exports.LumelyProvider=Z;exports.useLumely=V;exports.useLumelyOverlay=g;exports.useLumelyReport=W;//# sourceMappingURL=index.js.map
17
+ `,document.head.appendChild(s);},J=()=>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:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),U=()=>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:"22",y1:"2",x2:"11",y2:"13"}),jsxRuntime.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),u={container:{position:"fixed",top:"16px",left:"50%",transform:"translateX(-50%)",zIndex:9999,width:"100%",maxWidth:"480px",padding:"0 16px",boxSizing:"border-box",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",animation:"lumely-slide-down 0.3s ease-out"},card:{position:"relative",width:"100%",background:"rgba(30, 30, 35, 0.95)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",overflow:"hidden"},content:{display:"flex",flexDirection:"column",alignItems:"stretch",gap:"16px",padding:"16px 20px"},textContent:{flex:1,minWidth:0},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0,marginBottom:"4px"},message:{color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",lineHeight:1.4,margin:0},formWrapper:{display:"flex",alignItems:"center",gap:"8px",flexShrink:0,width:"100%"},input:{flex:1,minWidth:0,background:"rgba(255, 255, 255, 0.08)",border:"1px solid rgba(255, 255, 255, 0.12)",borderRadius:"8px",padding:"8px 12px",color:"white",fontSize:"12px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},sendButton:{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"8px 14px",borderRadius:"8px",fontSize:"12px",fontWeight:500,cursor:"pointer",border:"none",background:"#7c3aed",color:"white",transition:"all 0.2s",flexShrink:0},closeButton:{position:"absolute",top:"8px",right:"8px",padding:"4px",color:"rgba(255, 255, 255, 0.5)",background:"transparent",border:"none",borderRadius:"6px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},loading:{display:"flex",alignItems:"center",gap:"6px",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px"},spinner:{width:"12px",height:"12px",border:"2px solid rgba(255, 255, 255, 0.2)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},successText:{color:"#4ade80",fontSize:"12px",margin:0}},h=({aiResponse:s,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:o,onRetry:t,onDismiss:a,onGoBack:l})=>{let[n,d]=D.useState(""),[p,y]=D.useState(false);D.useEffect(()=>{j();},[]);let m=I=>{I.preventDefault(),n.trim()&&!p&&(y(true),o(n));},S=()=>r?"Analyzing the issue...":s!=null&&s.userMessage?s.userMessage:"An unexpected error occurred. Our team has been notified.";return jsxRuntime.jsx("div",{style:u.container,children:jsxRuntime.jsxs("div",{style:u.card,children:[jsxRuntime.jsx("button",{style:u.closeButton,onClick:a,"aria-label":"Close",children:jsxRuntime.jsx(J,{})}),jsxRuntime.jsxs("div",{style:u.content,children:[jsxRuntime.jsxs("div",{style:u.textContent,children:[jsxRuntime.jsx("h3",{style:u.title,children:"Something went wrong"}),r?jsxRuntime.jsxs("div",{style:u.loading,children:[jsxRuntime.jsx("div",{style:u.spinner}),jsxRuntime.jsx("span",{children:"Analyzing..."})]}):jsxRuntime.jsx("p",{style:u.message,title:S(),children:S()})]}),jsxRuntime.jsx("div",{style:u.formWrapper,children:!e&&!p?jsxRuntime.jsxs("form",{id:"lumely-feedback-form",onSubmit:m,style:{display:"flex",alignItems:"center",gap:"8px"},children:[jsxRuntime.jsx("input",{type:"text",value:n,onChange:I=>d(I.target.value),placeholder:"What were you doing?",style:u.input}),jsxRuntime.jsxs("button",{type:"submit",disabled:!n.trim(),style:{...u.sendButton,opacity:n.trim()?1:.5,cursor:n.trim()?"pointer":"not-allowed"},children:[jsxRuntime.jsx(U,{}),"Send"]})]}):jsxRuntime.jsx("p",{style:u.successText,children:"Thanks for the feedback, our team has been notified about the error."})})]})]})})};var L=class extends D.Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:o}=this.state,{client:t}=this.props;if(!o||o==="client-error"){this.setState({feedbackSubmitted:true});return}await t.updateFeedback(o,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,o){this.isReporting||(this.isReporting=true,this.setState({errorInfo:o,isLoading:true}),this.reportError(e,o));}async reportError(e,o){let{config:t,client:a}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:o.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:t.userId,sessionId:t.sessionId,timestamp:new Date().toISOString()}},n=await a.reportError(l);this.setState({aiResponse:n.ai,errorId:n.errorId,isLoading:false}),t.onError&&t.onError(l);}render(){let{hasError:e,aiResponse:o,isLoading:t,feedbackSubmitted:a}=this.state,{children:l}=this.props;return e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[l,jsxRuntime.jsx(h,{aiResponse:o||void 0,isLoading:t,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack,logo:this.props.logo})]}):l}};var Q=({apiEndpoint:s,logo:r})=>{let e=g();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async a=>{if(e.state.errorId)try{await fetch(`${s}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({errorId:e.state.errorId,userFeedback:a})});}catch(l){console.error("[Lumely] Failed to submit feedback:",l);}},t=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsxRuntime.jsx(h,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:t,logo:r})},Z=({children:s,apiKey:r,apiEndpoint:e=b,environment:o="production",userId:t,sessionId:a,onError:l,logo:n})=>{let d={apiKey:r,apiEndpoint:e,environment:o,userId:t,sessionId:a,onError:l},p=new f(r,e);return jsxRuntime.jsx(R,{children:jsxRuntime.jsxs(P,{config:d,children:[jsxRuntime.jsx(L,{config:d,client:p,logo:n,children:s}),jsxRuntime.jsx(Q,{apiEndpoint:e,logo:n})]})})};exports.LumelyClient=f;exports.LumelyErrorBoundary=L;exports.LumelyErrorOverlay=h;exports.LumelyOverlayProvider=R;exports.LumelyProvider=Z;exports.useLumely=V;exports.useLumelyOverlay=g;exports.useLumelyReport=W;//# sourceMappingURL=index.js.map
18
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../types.ts","../LumelyClient.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyClient","apiKey","apiEndpoint","report","response","data","err","errorId","feedback","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","prev","hideOverlay","setLoading","loading","setAiResponse","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumely","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","client","useMemo","overlay","reportError","additionalContext","_a","e","value","injectStyles","style","XIcon","jsxs","SendIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","getMessage","LumelyErrorBoundary","Component","props","errorInfo","hasError","Fragment","ManualErrorOverlay","logo","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-app.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","import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint?: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint || LUMELY_API_ENDPOINT;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n\r\n // Fire and forget enrichment for detailed AI analysis\r\n if (data.errorId && data.errorId !== 'no-db') {\r\n this.enrichError(data.errorId).catch(console.error);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async enrichError(errorId: string): Promise<void> {\r\n try {\r\n await fetch(`${this.apiEndpoint}/enrich-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId }),\r\n });\r\n } catch (err) {\r\n // We silent fail enrichment calls as they are background tasks\r\n console.error('[Lumely] Enrichment failed:', err);\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","'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 // IMPORTANT: If overlay is already showing, don't overwrite it\r\n // This ensures feedback goes to the correct error when multiple errors fire rapidly\r\n setState(prev => {\r\n if (prev.isVisible) {\r\n console.log('[Lumely] Overlay already visible, ignoring new error:', error.message);\r\n return prev; // Keep existing state, don't overwrite\r\n }\r\n return {\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\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","import React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\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\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 useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\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 throw new Error('useLumelyReport must be used within a LumelyProvider');\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 const client = useMemo(() => new LumelyClient(config.apiKey, config.apiEndpoint), [config.apiKey, config.apiEndpoint]);\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 // Skip if overlay is already showing (prevents duplicate reports)\r\n if (overlay?.state.isVisible) {\r\n console.log('[Lumely] Overlay already visible, skipping error report:', error.message);\r\n return;\r\n }\r\n\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 client.reportError(report);\r\n if (response && response.ai) {\r\n overlay?.setAiResponse(response.ai, response.errorId);\r\n } else {\r\n overlay?.setLoading(false);\r\n }\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 }, [client, config, sessionId, overlay]);\r\n\r\n // NOTE: Global error handlers removed to prevent duplicate reports.\r\n // The LumelyErrorBoundary handles React errors.\r\n // Use reportError() manually for non-React errors in try/catch blocks.\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n reportError,\r\n }), [config, sessionId, client, 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","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n @keyframes lumely-slide-down {\r\n from { \r\n opacity: 0;\r\n transform: translate(-50%, -20px);\r\n }\r\n to { \r\n opacity: 1;\r\n transform: translate(-50%, 0);\r\n }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components\r\nconst XIcon = () => (\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=\"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=\"14\" height=\"14\" 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 styles: Record<string, React.CSSProperties> = {\r\n // Toast container - positioned at top center, no backdrop\r\n container: {\r\n position: 'fixed',\r\n top: '16px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n zIndex: 9999,\r\n width: '100%',\r\n maxWidth: '480px',\r\n padding: '0 16px',\r\n boxSizing: 'border-box',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n animation: 'lumely-slide-down 0.3s ease-out',\r\n },\r\n // Glassmorphic card\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n background: 'rgba(30, 30, 35, 0.95)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n overflow: 'hidden',\r\n },\r\n // Main content with horizontal layout\r\n content: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'stretch',\r\n gap: '16px',\r\n padding: '16px 20px',\r\n },\r\n // Left side - text content\r\n textContent: {\r\n flex: 1,\r\n minWidth: 0,\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n marginBottom: '4px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n lineHeight: 1.4,\r\n margin: 0,\r\n },\r\n // Right side - feedback form\r\n formWrapper: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n flexShrink: 0,\r\n width: '100%',\r\n },\r\n input: {\r\n flex: 1,\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.08)',\r\n border: '1px solid rgba(255, 255, 255, 0.12)',\r\n borderRadius: '8px',\r\n padding: '8px 12px',\r\n color: 'white',\r\n fontSize: '12px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n sendButton: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '6px',\r\n padding: '8px 14px',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n background: '#7c3aed',\r\n color: 'white',\r\n transition: 'all 0.2s',\r\n flexShrink: 0,\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '8px',\r\n right: '8px',\r\n padding: '4px',\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '6px',\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 // Loading state\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n },\r\n spinner: {\r\n width: '12px',\r\n height: '12px',\r\n border: '2px solid rgba(255, 255, 255, 0.2)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n // Success state\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n margin: 0,\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 logo?: React.ReactNode;\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 // Get the display message\r\n const getMessage = () => {\r\n if (isLoading) return 'Analyzing the issue...';\r\n if (aiResponse?.userMessage) return aiResponse.userMessage;\r\n return 'An unexpected error occurred. Our team has been notified.';\r\n };\r\n\r\n return (\r\n <div style={styles.container}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button\r\n style={styles.closeButton}\r\n onClick={onDismiss}\r\n aria-label=\"Close\"\r\n >\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Left side - Text content */}\r\n <div style={styles.textContent}>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing...</span>\r\n </div>\r\n ) : (\r\n <p style={styles.message} title={getMessage()}>\r\n {getMessage()}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Right side - Feedback form or success message */}\r\n <div style={styles.formWrapper}>\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form\r\n id=\"lumely-feedback-form\"\r\n onSubmit={handleSubmit}\r\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\r\n >\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"What were you doing?\"\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.sendButton,\r\n opacity: feedback.trim() ? 1 : 0.5,\r\n cursor: feedback.trim() ? 'pointer' : 'not-allowed',\r\n }}\r\n >\r\n <SendIcon />\r\n Send\r\n </button>\r\n </form>\r\n ) : (\r\n <p style={styles.successText}>Thanks for the feedback, our team has been notified about the error.</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n logo?: React.ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n logo={this.props.logo}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\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 logo?: React.ReactNode;\r\n}\r\n\r\n// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, logo }: { apiEndpoint: string, logo?: React.ReactNode }) => {\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: { 'Content-Type': 'application/json' },\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 logo={logo}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n logo,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client} logo={logo}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} logo={logo} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
1
+ {"version":3,"sources":["../types.ts","../LumelyClient.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyClient","apiKey","apiEndpoint","report","response","data","err","errorId","feedback","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","prev","hideOverlay","setLoading","loading","setAiResponse","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumely","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","client","useMemo","overlay","reportError","additionalContext","_a","e","value","injectStyles","style","XIcon","jsxs","SendIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","getMessage","LumelyErrorBoundary","Component","props","errorInfo","hasError","Fragment","ManualErrorOverlay","logo","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-app.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","import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint?: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint || LUMELY_API_ENDPOINT;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n\r\n // Fire and forget enrichment for detailed AI analysis\r\n if (data.errorId && data.errorId !== 'no-db') {\r\n this.enrichError(data.errorId).catch(console.error);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async enrichError(errorId: string): Promise<void> {\r\n try {\r\n await fetch(`${this.apiEndpoint}/enrich-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId }),\r\n });\r\n } catch (err) {\r\n // We silent fail enrichment calls as they are background tasks\r\n console.error('[Lumely] Enrichment failed:', err);\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","'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 // IMPORTANT: If overlay is already showing, don't overwrite it\r\n // This ensures feedback goes to the correct error when multiple errors fire rapidly\r\n setState(prev => {\r\n if (prev.isVisible) {\r\n console.log('[Lumely] Overlay already visible, ignoring new error:', error.message);\r\n return prev; // Keep existing state, don't overwrite\r\n }\r\n return {\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\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","import React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\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\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 useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\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 throw new Error('useLumelyReport must be used within a LumelyProvider');\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 const client = useMemo(() => new LumelyClient(config.apiKey, config.apiEndpoint), [config.apiKey, config.apiEndpoint]);\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 // Skip if overlay is already showing (prevents duplicate reports)\r\n if (overlay?.state.isVisible) {\r\n console.log('[Lumely] Overlay already visible, skipping error report:', error.message);\r\n return;\r\n }\r\n\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 client.reportError(report);\r\n if (response && response.ai) {\r\n overlay?.setAiResponse(response.ai, response.errorId);\r\n } else {\r\n overlay?.setLoading(false);\r\n }\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 }, [client, config, sessionId, overlay]);\r\n\r\n // NOTE: Global error handlers removed to prevent duplicate reports.\r\n // The LumelyErrorBoundary handles React errors.\r\n // Use reportError() manually for non-React errors in try/catch blocks.\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n reportError,\r\n }), [config, sessionId, client, 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","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n @keyframes lumely-slide-down {\r\n from { \r\n opacity: 0;\r\n transform: translate(-50%, -20px);\r\n }\r\n to { \r\n opacity: 1;\r\n transform: translate(-50%, 0);\r\n }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components\r\nconst XIcon = () => (\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=\"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=\"14\" height=\"14\" 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 styles: Record<string, React.CSSProperties> = {\r\n // Toast container - positioned at top center, no backdrop\r\n container: {\r\n position: 'fixed',\r\n top: '16px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n zIndex: 9999,\r\n width: '100%',\r\n maxWidth: '480px',\r\n padding: '0 16px',\r\n boxSizing: 'border-box',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n animation: 'lumely-slide-down 0.3s ease-out',\r\n },\r\n // Glassmorphic card\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n background: 'rgba(30, 30, 35, 0.95)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n overflow: 'hidden',\r\n },\r\n // Main content with horizontal layout\r\n content: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'stretch',\r\n gap: '16px',\r\n padding: '16px 20px',\r\n },\r\n // Left side - text content\r\n textContent: {\r\n flex: 1,\r\n minWidth: 0,\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n marginBottom: '4px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n lineHeight: 1.4,\r\n margin: 0,\r\n },\r\n // Right side - feedback form\r\n formWrapper: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n flexShrink: 0,\r\n width: '100%',\r\n },\r\n input: {\r\n flex: 1,\r\n minWidth: 0,\r\n background: 'rgba(255, 255, 255, 0.08)',\r\n border: '1px solid rgba(255, 255, 255, 0.12)',\r\n borderRadius: '8px',\r\n padding: '8px 12px',\r\n color: 'white',\r\n fontSize: '12px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n sendButton: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '6px',\r\n padding: '8px 14px',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n background: '#7c3aed',\r\n color: 'white',\r\n transition: 'all 0.2s',\r\n flexShrink: 0,\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '8px',\r\n right: '8px',\r\n padding: '4px',\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '6px',\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 // Loading state\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n },\r\n spinner: {\r\n width: '12px',\r\n height: '12px',\r\n border: '2px solid rgba(255, 255, 255, 0.2)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n // Success state\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n margin: 0,\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 logo?: React.ReactNode;\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 // Get the display message\r\n const getMessage = () => {\r\n if (isLoading) return 'Analyzing the issue...';\r\n if (aiResponse?.userMessage) return aiResponse.userMessage;\r\n return 'An unexpected error occurred. Our team has been notified.';\r\n };\r\n\r\n return (\r\n <div style={styles.container}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button\r\n style={styles.closeButton}\r\n onClick={onDismiss}\r\n aria-label=\"Close\"\r\n >\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Left side - Text content */}\r\n <div style={styles.textContent}>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing...</span>\r\n </div>\r\n ) : (\r\n <p style={styles.message} title={getMessage()}>\r\n {getMessage()}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Right side - Feedback form or success message */}\r\n <div style={styles.formWrapper}>\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form\r\n id=\"lumely-feedback-form\"\r\n onSubmit={handleSubmit}\r\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\r\n >\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"What were you doing?\"\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.sendButton,\r\n opacity: feedback.trim() ? 1 : 0.5,\r\n cursor: feedback.trim() ? 'pointer' : 'not-allowed',\r\n }}\r\n >\r\n <SendIcon />\r\n Send\r\n </button>\r\n </form>\r\n ) : (\r\n <p style={styles.successText}>Thanks for the feedback, our team has been notified about the error.</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n logo?: React.ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n logo={this.props.logo}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\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 logo?: React.ReactNode;\r\n}\r\n\r\n// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, logo }: { apiEndpoint: string, logo?: React.ReactNode }) => {\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: { 'Content-Type': 'application/json' },\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 logo={logo}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n logo,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client} logo={logo}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} logo={logo} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
package/dist/index.mjs CHANGED
@@ -14,5 +14,5 @@ import D,{createContext,useContext,useState,useCallback,useEffect,Component,useM
14
14
  transform: translate(-50%, 0);
15
15
  }
16
16
  }
17
- `,document.head.appendChild(s);},J=()=>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:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),U=()=>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:"22",y1:"2",x2:"11",y2:"13"}),jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),u={container:{position:"fixed",top:"16px",left:"50%",transform:"translateX(-50%)",zIndex:9999,width:"100%",maxWidth:"480px",padding:"0 16px",boxSizing:"border-box",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",animation:"lumely-slide-down 0.3s ease-out"},card:{position:"relative",width:"100%",background:"rgba(30, 30, 35, 0.95)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",overflow:"hidden"},content:{display:"flex",flexDirection:"column",alignItems:"stretch",gap:"16px",padding:"16px 20px"},textContent:{flex:1,minWidth:0},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0,marginBottom:"4px"},message:{color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",lineHeight:1.4,margin:0},formWrapper:{display:"flex",alignItems:"center",gap:"8px",flexShrink:0,width:"100%"},input:{flex:1,width:"100%",background:"rgba(255, 255, 255, 0.08)",border:"1px solid rgba(255, 255, 255, 0.12)",borderRadius:"8px",padding:"8px 12px",color:"white",fontSize:"12px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},sendButton:{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"8px 14px",borderRadius:"8px",fontSize:"12px",fontWeight:500,cursor:"pointer",border:"none",background:"#7c3aed",color:"white",transition:"all 0.2s",flexShrink:0},closeButton:{position:"absolute",top:"8px",right:"8px",padding:"4px",color:"rgba(255, 255, 255, 0.5)",background:"transparent",border:"none",borderRadius:"6px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},loading:{display:"flex",alignItems:"center",gap:"6px",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px"},spinner:{width:"12px",height:"12px",border:"2px solid rgba(255, 255, 255, 0.2)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},successText:{color:"#4ade80",fontSize:"12px",margin:0}},h=({aiResponse:s,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:o,onRetry:t,onDismiss:a,onGoBack:l})=>{let[n,d]=useState(""),[p,y]=useState(false);useEffect(()=>{j();},[]);let m=I=>{I.preventDefault(),n.trim()&&!p&&(y(true),o(n));},S=()=>r?"Analyzing the issue...":s!=null&&s.userMessage?s.userMessage:"An unexpected error occurred. Our team has been notified.";return jsx("div",{style:u.container,children:jsxs("div",{style:u.card,children:[jsx("button",{style:u.closeButton,onClick:a,"aria-label":"Close",children:jsx(J,{})}),jsxs("div",{style:u.content,children:[jsxs("div",{style:u.textContent,children:[jsx("h3",{style:u.title,children:"Something went wrong"}),r?jsxs("div",{style:u.loading,children:[jsx("div",{style:u.spinner}),jsx("span",{children:"Analyzing..."})]}):jsx("p",{style:u.message,title:S(),children:S()})]}),jsx("div",{style:u.formWrapper,children:!e&&!p?jsxs("form",{id:"lumely-feedback-form",onSubmit:m,style:{display:"flex",alignItems:"center",gap:"8px"},children:[jsx("input",{type:"text",value:n,onChange:I=>d(I.target.value),placeholder:"What were you doing?",style:u.input}),jsxs("button",{type:"submit",disabled:!n.trim(),style:{...u.sendButton,opacity:n.trim()?1:.5,cursor:n.trim()?"pointer":"not-allowed"},children:[jsx(U,{}),"Send"]})]}):jsx("p",{style:u.successText,children:"Thanks for the feedback, our team has been notified about the error."})})]})]})})};var L=class extends Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:o}=this.state,{client:t}=this.props;if(!o||o==="client-error"){this.setState({feedbackSubmitted:true});return}await t.updateFeedback(o,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,o){this.isReporting||(this.isReporting=true,this.setState({errorInfo:o,isLoading:true}),this.reportError(e,o));}async reportError(e,o){let{config:t,client:a}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:o.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:t.userId,sessionId:t.sessionId,timestamp:new Date().toISOString()}},n=await a.reportError(l);this.setState({aiResponse:n.ai,errorId:n.errorId,isLoading:false}),t.onError&&t.onError(l);}render(){let{hasError:e,aiResponse:o,isLoading:t,feedbackSubmitted:a}=this.state,{children:l}=this.props;return e?jsxs(Fragment,{children:[l,jsx(h,{aiResponse:o||void 0,isLoading:t,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack,logo:this.props.logo})]}):l}};var Q=({apiEndpoint:s,logo:r})=>{let e=g();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async a=>{if(e.state.errorId)try{await fetch(`${s}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({errorId:e.state.errorId,userFeedback:a})});}catch(l){console.error("[Lumely] Failed to submit feedback:",l);}},t=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsx(h,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:t,logo:r})},Z=({children:s,apiKey:r,apiEndpoint:e=b,environment:o="production",userId:t,sessionId:a,onError:l,logo:n})=>{let d={apiKey:r,apiEndpoint:e,environment:o,userId:t,sessionId:a,onError:l},p=new f(r,e);return jsx(R,{children:jsxs(P,{config:d,children:[jsx(L,{config:d,client:p,logo:n,children:s}),jsx(Q,{apiEndpoint:e,logo:n})]})})};export{f as LumelyClient,L as LumelyErrorBoundary,h as LumelyErrorOverlay,R as LumelyOverlayProvider,Z as LumelyProvider,V as useLumely,g as useLumelyOverlay,W as useLumelyReport};//# sourceMappingURL=index.mjs.map
17
+ `,document.head.appendChild(s);},J=()=>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:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),U=()=>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:"22",y1:"2",x2:"11",y2:"13"}),jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),u={container:{position:"fixed",top:"16px",left:"50%",transform:"translateX(-50%)",zIndex:9999,width:"100%",maxWidth:"480px",padding:"0 16px",boxSizing:"border-box",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",animation:"lumely-slide-down 0.3s ease-out"},card:{position:"relative",width:"100%",background:"rgba(30, 30, 35, 0.95)",backdropFilter:"blur(20px)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",overflow:"hidden"},content:{display:"flex",flexDirection:"column",alignItems:"stretch",gap:"16px",padding:"16px 20px"},textContent:{flex:1,minWidth:0},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0,marginBottom:"4px"},message:{color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",lineHeight:1.4,margin:0},formWrapper:{display:"flex",alignItems:"center",gap:"8px",flexShrink:0,width:"100%"},input:{flex:1,minWidth:0,background:"rgba(255, 255, 255, 0.08)",border:"1px solid rgba(255, 255, 255, 0.12)",borderRadius:"8px",padding:"8px 12px",color:"white",fontSize:"12px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},sendButton:{display:"flex",alignItems:"center",justifyContent:"center",gap:"6px",padding:"8px 14px",borderRadius:"8px",fontSize:"12px",fontWeight:500,cursor:"pointer",border:"none",background:"#7c3aed",color:"white",transition:"all 0.2s",flexShrink:0},closeButton:{position:"absolute",top:"8px",right:"8px",padding:"4px",color:"rgba(255, 255, 255, 0.5)",background:"transparent",border:"none",borderRadius:"6px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},loading:{display:"flex",alignItems:"center",gap:"6px",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px"},spinner:{width:"12px",height:"12px",border:"2px solid rgba(255, 255, 255, 0.2)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},successText:{color:"#4ade80",fontSize:"12px",margin:0}},h=({aiResponse:s,isLoading:r,feedbackSubmitted:e=false,onSubmitFeedback:o,onRetry:t,onDismiss:a,onGoBack:l})=>{let[n,d]=useState(""),[p,y]=useState(false);useEffect(()=>{j();},[]);let m=I=>{I.preventDefault(),n.trim()&&!p&&(y(true),o(n));},S=()=>r?"Analyzing the issue...":s!=null&&s.userMessage?s.userMessage:"An unexpected error occurred. Our team has been notified.";return jsx("div",{style:u.container,children:jsxs("div",{style:u.card,children:[jsx("button",{style:u.closeButton,onClick:a,"aria-label":"Close",children:jsx(J,{})}),jsxs("div",{style:u.content,children:[jsxs("div",{style:u.textContent,children:[jsx("h3",{style:u.title,children:"Something went wrong"}),r?jsxs("div",{style:u.loading,children:[jsx("div",{style:u.spinner}),jsx("span",{children:"Analyzing..."})]}):jsx("p",{style:u.message,title:S(),children:S()})]}),jsx("div",{style:u.formWrapper,children:!e&&!p?jsxs("form",{id:"lumely-feedback-form",onSubmit:m,style:{display:"flex",alignItems:"center",gap:"8px"},children:[jsx("input",{type:"text",value:n,onChange:I=>d(I.target.value),placeholder:"What were you doing?",style:u.input}),jsxs("button",{type:"submit",disabled:!n.trim(),style:{...u.sendButton,opacity:n.trim()?1:.5,cursor:n.trim()?"pointer":"not-allowed"},children:[jsx(U,{}),"Send"]})]}):jsx("p",{style:u.successText,children:"Thanks for the feedback, our team has been notified about the error."})})]})]})})};var L=class extends Component{constructor(e){super(e);this.isReporting=false;this.handleSubmitFeedback=async e=>{let{errorId:o}=this.state,{client:t}=this.props;if(!o||o==="client-error"){this.setState({feedbackSubmitted:true});return}await t.updateFeedback(o,e),this.setState({feedbackSubmitted:true});};this.handleRetry=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleDismiss=()=>{this.isReporting=false,this.setState({hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false});};this.handleGoBack=()=>{typeof window!="undefined"&&window.history.back();};this.state={hasError:false,error:null,errorInfo:null,aiResponse:null,isLoading:false,errorId:null,feedbackSubmitted:false};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,o){this.isReporting||(this.isReporting=true,this.setState({errorInfo:o,isLoading:true}),this.reportError(e,o));}async reportError(e,o){let{config:t,client:a}=this.props,l={errorMessage:e.message,errorStack:e.stack,componentStack:o.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:t.userId,sessionId:t.sessionId,timestamp:new Date().toISOString()}},n=await a.reportError(l);this.setState({aiResponse:n.ai,errorId:n.errorId,isLoading:false}),t.onError&&t.onError(l);}render(){let{hasError:e,aiResponse:o,isLoading:t,feedbackSubmitted:a}=this.state,{children:l}=this.props;return e?jsxs(Fragment,{children:[l,jsx(h,{aiResponse:o||void 0,isLoading:t,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack,logo:this.props.logo})]}):l}};var Q=({apiEndpoint:s,logo:r})=>{let e=g();if(!(e!=null&&e.state.isVisible)||!e.state.error)return null;let o=async a=>{if(e.state.errorId)try{await fetch(`${s}/update-feedback`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({errorId:e.state.errorId,userFeedback:a})});}catch(l){console.error("[Lumely] Failed to submit feedback:",l);}},t=()=>{e.hideOverlay(),typeof window!="undefined"&&window.history.back();};return jsx(h,{aiResponse:e.state.aiResponse||void 0,isLoading:e.state.isLoading,feedbackSubmitted:false,onSubmitFeedback:o,onRetry:e.hideOverlay,onDismiss:e.hideOverlay,onGoBack:t,logo:r})},Z=({children:s,apiKey:r,apiEndpoint:e=b,environment:o="production",userId:t,sessionId:a,onError:l,logo:n})=>{let d={apiKey:r,apiEndpoint:e,environment:o,userId:t,sessionId:a,onError:l},p=new f(r,e);return jsx(R,{children:jsxs(P,{config:d,children:[jsx(L,{config:d,client:p,logo:n,children:s}),jsx(Q,{apiEndpoint:e,logo:n})]})})};export{f as LumelyClient,L as LumelyErrorBoundary,h as LumelyErrorOverlay,R as LumelyOverlayProvider,Z as LumelyProvider,V as useLumely,g as useLumelyOverlay,W as useLumelyReport};//# sourceMappingURL=index.mjs.map
18
18
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../types.ts","../LumelyClient.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyClient","apiKey","apiEndpoint","report","response","data","err","errorId","feedback","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","prev","hideOverlay","setLoading","loading","setAiResponse","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumely","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","client","useMemo","overlay","reportError","additionalContext","_a","e","value","injectStyles","style","XIcon","jsxs","SendIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","getMessage","LumelyErrorBoundary","Component","props","errorInfo","hasError","Fragment","ManualErrorOverlay","logo","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-app.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","import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint?: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint || LUMELY_API_ENDPOINT;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n\r\n // Fire and forget enrichment for detailed AI analysis\r\n if (data.errorId && data.errorId !== 'no-db') {\r\n this.enrichError(data.errorId).catch(console.error);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async enrichError(errorId: string): Promise<void> {\r\n try {\r\n await fetch(`${this.apiEndpoint}/enrich-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId }),\r\n });\r\n } catch (err) {\r\n // We silent fail enrichment calls as they are background tasks\r\n console.error('[Lumely] Enrichment failed:', err);\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","'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 // IMPORTANT: If overlay is already showing, don't overwrite it\r\n // This ensures feedback goes to the correct error when multiple errors fire rapidly\r\n setState(prev => {\r\n if (prev.isVisible) {\r\n console.log('[Lumely] Overlay already visible, ignoring new error:', error.message);\r\n return prev; // Keep existing state, don't overwrite\r\n }\r\n return {\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\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","import React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\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\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 useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\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 throw new Error('useLumelyReport must be used within a LumelyProvider');\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 const client = useMemo(() => new LumelyClient(config.apiKey, config.apiEndpoint), [config.apiKey, config.apiEndpoint]);\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 // Skip if overlay is already showing (prevents duplicate reports)\r\n if (overlay?.state.isVisible) {\r\n console.log('[Lumely] Overlay already visible, skipping error report:', error.message);\r\n return;\r\n }\r\n\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 client.reportError(report);\r\n if (response && response.ai) {\r\n overlay?.setAiResponse(response.ai, response.errorId);\r\n } else {\r\n overlay?.setLoading(false);\r\n }\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 }, [client, config, sessionId, overlay]);\r\n\r\n // NOTE: Global error handlers removed to prevent duplicate reports.\r\n // The LumelyErrorBoundary handles React errors.\r\n // Use reportError() manually for non-React errors in try/catch blocks.\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n reportError,\r\n }), [config, sessionId, client, 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","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n @keyframes lumely-slide-down {\r\n from { \r\n opacity: 0;\r\n transform: translate(-50%, -20px);\r\n }\r\n to { \r\n opacity: 1;\r\n transform: translate(-50%, 0);\r\n }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components\r\nconst XIcon = () => (\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=\"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=\"14\" height=\"14\" 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 styles: Record<string, React.CSSProperties> = {\r\n // Toast container - positioned at top center, no backdrop\r\n container: {\r\n position: 'fixed',\r\n top: '16px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n zIndex: 9999,\r\n width: '100%',\r\n maxWidth: '480px',\r\n padding: '0 16px',\r\n boxSizing: 'border-box',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n animation: 'lumely-slide-down 0.3s ease-out',\r\n },\r\n // Glassmorphic card\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n background: 'rgba(30, 30, 35, 0.95)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n overflow: 'hidden',\r\n },\r\n // Main content with horizontal layout\r\n content: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'stretch',\r\n gap: '16px',\r\n padding: '16px 20px',\r\n },\r\n // Left side - text content\r\n textContent: {\r\n flex: 1,\r\n minWidth: 0,\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n marginBottom: '4px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n lineHeight: 1.4,\r\n margin: 0,\r\n },\r\n // Right side - feedback form\r\n formWrapper: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n flexShrink: 0,\r\n width: '100%',\r\n },\r\n input: {\r\n flex: 1,\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.08)',\r\n border: '1px solid rgba(255, 255, 255, 0.12)',\r\n borderRadius: '8px',\r\n padding: '8px 12px',\r\n color: 'white',\r\n fontSize: '12px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n sendButton: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '6px',\r\n padding: '8px 14px',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n background: '#7c3aed',\r\n color: 'white',\r\n transition: 'all 0.2s',\r\n flexShrink: 0,\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '8px',\r\n right: '8px',\r\n padding: '4px',\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '6px',\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 // Loading state\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n },\r\n spinner: {\r\n width: '12px',\r\n height: '12px',\r\n border: '2px solid rgba(255, 255, 255, 0.2)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n // Success state\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n margin: 0,\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 logo?: React.ReactNode;\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 // Get the display message\r\n const getMessage = () => {\r\n if (isLoading) return 'Analyzing the issue...';\r\n if (aiResponse?.userMessage) return aiResponse.userMessage;\r\n return 'An unexpected error occurred. Our team has been notified.';\r\n };\r\n\r\n return (\r\n <div style={styles.container}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button\r\n style={styles.closeButton}\r\n onClick={onDismiss}\r\n aria-label=\"Close\"\r\n >\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Left side - Text content */}\r\n <div style={styles.textContent}>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing...</span>\r\n </div>\r\n ) : (\r\n <p style={styles.message} title={getMessage()}>\r\n {getMessage()}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Right side - Feedback form or success message */}\r\n <div style={styles.formWrapper}>\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form\r\n id=\"lumely-feedback-form\"\r\n onSubmit={handleSubmit}\r\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\r\n >\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"What were you doing?\"\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.sendButton,\r\n opacity: feedback.trim() ? 1 : 0.5,\r\n cursor: feedback.trim() ? 'pointer' : 'not-allowed',\r\n }}\r\n >\r\n <SendIcon />\r\n Send\r\n </button>\r\n </form>\r\n ) : (\r\n <p style={styles.successText}>Thanks for the feedback, our team has been notified about the error.</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n logo?: React.ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n logo={this.props.logo}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\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 logo?: React.ReactNode;\r\n}\r\n\r\n// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, logo }: { apiEndpoint: string, logo?: React.ReactNode }) => {\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: { 'Content-Type': 'application/json' },\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 logo={logo}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n logo,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client} logo={logo}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} logo={logo} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
1
+ {"version":3,"sources":["../types.ts","../LumelyClient.ts","../LumelyOverlayContext.tsx","../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LUMELY_API_ENDPOINT","LumelyClient","apiKey","apiEndpoint","report","response","data","err","errorId","feedback","LumelyOverlayContext","createContext","useLumelyOverlay","useContext","LumelyOverlayProvider","children","state","setState","useState","showOverlay","useCallback","error","aiResponse","prev","hideOverlay","setLoading","loading","setAiResponse","jsx","LumelyContext","getStoredSessionId","createSessionId","useLumely","context","useLumelyReport","LumelyContextProvider","config","sessionId","React","useEffect","client","useMemo","overlay","reportError","additionalContext","_a","e","value","injectStyles","style","XIcon","jsxs","SendIcon","styles","LumelyErrorOverlay","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","setFeedback","isSubmitting","setIsSubmitting","handleSubmit","getMessage","LumelyErrorBoundary","Component","props","errorInfo","hasError","Fragment","ManualErrorOverlay","logo","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-app.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","import type { LumelyErrorReport, LumelyAPIResponse } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\n\r\nexport class LumelyClient {\r\n private apiKey: string;\r\n private apiEndpoint: string;\r\n\r\n constructor(apiKey: string, apiEndpoint?: string) {\r\n this.apiKey = apiKey;\r\n this.apiEndpoint = apiEndpoint || LUMELY_API_ENDPOINT;\r\n }\r\n\r\n async reportError(report: LumelyErrorReport): Promise<LumelyAPIResponse> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/report-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n\r\n // Fire and forget enrichment for detailed AI analysis\r\n if (data.errorId && data.errorId !== 'no-db') {\r\n this.enrichError(data.errorId).catch(console.error);\r\n }\r\n\r\n return data;\r\n }\r\n\r\n throw new Error('Failed to report error');\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n return {\r\n success: false,\r\n ai: {\r\n userMessage: \"Something went wrong. We're looking into it.\",\r\n summary: '',\r\n suggestedFix: '',\r\n },\r\n errorId: 'client-error',\r\n };\r\n }\r\n }\r\n\r\n async enrichError(errorId: string): Promise<void> {\r\n try {\r\n await fetch(`${this.apiEndpoint}/enrich-error`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId }),\r\n });\r\n } catch (err) {\r\n // We silent fail enrichment calls as they are background tasks\r\n console.error('[Lumely] Enrichment failed:', err);\r\n }\r\n }\r\n\r\n async updateFeedback(errorId: string, feedback: string): Promise<boolean> {\r\n try {\r\n const response = await fetch(`${this.apiEndpoint}/update-feedback`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': this.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n return response.ok;\r\n } catch (err) {\r\n console.error('Lumely: Failed to update feedback', err);\r\n return false;\r\n }\r\n }\r\n}\r\n","'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 // IMPORTANT: If overlay is already showing, don't overwrite it\r\n // This ensures feedback goes to the correct error when multiple errors fire rapidly\r\n setState(prev => {\r\n if (prev.isVisible) {\r\n console.log('[Lumely] Overlay already visible, ignoring new error:', error.message);\r\n return prev; // Keep existing state, don't overwrite\r\n }\r\n return {\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\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","import React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\nimport { LUMELY_API_ENDPOINT } from './types';\r\nimport { useLumelyOverlay } from './LumelyOverlayContext';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n client: LumelyClient;\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\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 useLumely = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumely must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\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 throw new Error('useLumelyReport must be used within a LumelyProvider');\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 const client = useMemo(() => new LumelyClient(config.apiKey, config.apiEndpoint), [config.apiKey, config.apiEndpoint]);\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 // Skip if overlay is already showing (prevents duplicate reports)\r\n if (overlay?.state.isVisible) {\r\n console.log('[Lumely] Overlay already visible, skipping error report:', error.message);\r\n return;\r\n }\r\n\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 client.reportError(report);\r\n if (response && response.ai) {\r\n overlay?.setAiResponse(response.ai, response.errorId);\r\n } else {\r\n overlay?.setLoading(false);\r\n }\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 }, [client, config, sessionId, overlay]);\r\n\r\n // NOTE: Global error handlers removed to prevent duplicate reports.\r\n // The LumelyErrorBoundary handles React errors.\r\n // Use reportError() manually for non-React errors in try/catch blocks.\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n client,\r\n reportError,\r\n }), [config, sessionId, client, 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","import React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-react-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-react-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n @keyframes lumely-slide-down {\r\n from { \r\n opacity: 0;\r\n transform: translate(-50%, -20px);\r\n }\r\n to { \r\n opacity: 1;\r\n transform: translate(-50%, 0);\r\n }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components\r\nconst XIcon = () => (\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=\"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=\"14\" height=\"14\" 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 styles: Record<string, React.CSSProperties> = {\r\n // Toast container - positioned at top center, no backdrop\r\n container: {\r\n position: 'fixed',\r\n top: '16px',\r\n left: '50%',\r\n transform: 'translateX(-50%)',\r\n zIndex: 9999,\r\n width: '100%',\r\n maxWidth: '480px',\r\n padding: '0 16px',\r\n boxSizing: 'border-box',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n animation: 'lumely-slide-down 0.3s ease-out',\r\n },\r\n // Glassmorphic card\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n background: 'rgba(30, 30, 35, 0.95)',\r\n backdropFilter: 'blur(20px)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n overflow: 'hidden',\r\n },\r\n // Main content with horizontal layout\r\n content: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n alignItems: 'stretch',\r\n gap: '16px',\r\n padding: '16px 20px',\r\n },\r\n // Left side - text content\r\n textContent: {\r\n flex: 1,\r\n minWidth: 0,\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n marginBottom: '4px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n lineHeight: 1.4,\r\n margin: 0,\r\n },\r\n // Right side - feedback form\r\n formWrapper: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n flexShrink: 0,\r\n width: '100%',\r\n },\r\n input: {\r\n flex: 1,\r\n minWidth: 0,\r\n background: 'rgba(255, 255, 255, 0.08)',\r\n border: '1px solid rgba(255, 255, 255, 0.12)',\r\n borderRadius: '8px',\r\n padding: '8px 12px',\r\n color: 'white',\r\n fontSize: '12px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n sendButton: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '6px',\r\n padding: '8px 14px',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n background: '#7c3aed',\r\n color: 'white',\r\n transition: 'all 0.2s',\r\n flexShrink: 0,\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '8px',\r\n right: '8px',\r\n padding: '4px',\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '6px',\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 // Loading state\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n },\r\n spinner: {\r\n width: '12px',\r\n height: '12px',\r\n border: '2px solid rgba(255, 255, 255, 0.2)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n // Success state\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n margin: 0,\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 logo?: React.ReactNode;\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 // Get the display message\r\n const getMessage = () => {\r\n if (isLoading) return 'Analyzing the issue...';\r\n if (aiResponse?.userMessage) return aiResponse.userMessage;\r\n return 'An unexpected error occurred. Our team has been notified.';\r\n };\r\n\r\n return (\r\n <div style={styles.container}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button\r\n style={styles.closeButton}\r\n onClick={onDismiss}\r\n aria-label=\"Close\"\r\n >\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Left side - Text content */}\r\n <div style={styles.textContent}>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing...</span>\r\n </div>\r\n ) : (\r\n <p style={styles.message} title={getMessage()}>\r\n {getMessage()}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Right side - Feedback form or success message */}\r\n <div style={styles.formWrapper}>\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form\r\n id=\"lumely-feedback-form\"\r\n onSubmit={handleSubmit}\r\n style={{ display: 'flex', alignItems: 'center', gap: '8px' }}\r\n >\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"What were you doing?\"\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.sendButton,\r\n opacity: feedback.trim() ? 1 : 0.5,\r\n cursor: feedback.trim() ? 'pointer' : 'not-allowed',\r\n }}\r\n >\r\n <SendIcon />\r\n Send\r\n </button>\r\n </form>\r\n ) : (\r\n <p style={styles.successText}>Thanks for the feedback, our team has been notified about the error.</p>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n client: LumelyClient;\r\n logo?: React.ReactNode;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false;\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config, client } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n const response = await client.reportError(report);\r\n\r\n this.setState({\r\n aiResponse: response.ai,\r\n errorId: response.errorId,\r\n isLoading: false,\r\n });\r\n\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { client } = this.props;\r\n\r\n if (!errorId || errorId === 'client-error') {\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n await client.updateFeedback(errorId, feedback);\r\n this.setState({ feedbackSubmitted: true });\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n logo={this.props.logo}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport { LumelyOverlayProvider, useLumelyOverlay } from './LumelyOverlayContext';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport { LumelyClient } from './LumelyClient';\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 logo?: React.ReactNode;\r\n}\r\n\r\n// Component that renders the overlay for manually reported errors\r\nconst ManualErrorOverlay = ({ apiEndpoint, logo }: { apiEndpoint: string, logo?: React.ReactNode }) => {\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: { 'Content-Type': 'application/json' },\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 logo={logo}\r\n />\r\n );\r\n};\r\n\r\n/**\r\n * LumelyProvider for Plain React (Vite, CRA, etc.)\r\n * \r\n * Usage:\r\n * ```tsx\r\n * import { LumelyProvider } from './components/lumely-react';\r\n * \r\n * function App() {\r\n * return (\r\n * <LumelyProvider \r\n * apiKey=\"your-api-key\"\r\n * apiEndpoint=\"https://your-api.com/api/lumely\"\r\n * >\r\n * <YourApp />\r\n * </LumelyProvider>\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n apiEndpoint = LUMELY_API_ENDPOINT,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n logo,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n apiEndpoint,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n const client = new LumelyClient(apiKey, apiEndpoint);\r\n\r\n return (\r\n <LumelyOverlayProvider>\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config} client={client} logo={logo}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n <ManualErrorOverlay apiEndpoint={apiEndpoint} logo={logo} />\r\n </LumelyContextProvider>\r\n </LumelyOverlayProvider>\r\n );\r\n};\r\n\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumely-react",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "AI-powered error handling for React applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",