lumely-next 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/index.d.mts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,10 @@ That's it. Lumely will automatically catch errors and display a user-friendly ov
|
|
|
49
49
|
|
|
50
50
|
## API Routes
|
|
51
51
|
|
|
52
|
-
This package expects API routes at `/api/lumely/`.
|
|
52
|
+
This package expects API routes at `/api/lumely/`.
|
|
53
|
+
1. Create a `pages/api/lumely/report-error.ts` file.
|
|
54
|
+
2. Create a `pages/api/lumely/update-feedback.ts` file.
|
|
55
|
+
3. Use the `apiEndpoint="/api/lumely"` prop in your Provider.
|
|
53
56
|
|
|
54
57
|
## Documentation
|
|
55
58
|
|
package/dist/index.d.mts
CHANGED
|
@@ -82,7 +82,25 @@ declare const LumelyErrorOverlay: ({ aiResponse, isLoading, feedbackSubmitted, o
|
|
|
82
82
|
|
|
83
83
|
interface LumelyContextValue extends LumelyConfig {
|
|
84
84
|
sessionId: string;
|
|
85
|
+
reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;
|
|
85
86
|
}
|
|
86
87
|
declare const useLumelyContext: () => LumelyContextValue;
|
|
88
|
+
/**
|
|
89
|
+
* Hook for manually reporting errors that aren't caught by the Error Boundary.
|
|
90
|
+
*
|
|
91
|
+
* Usage:
|
|
92
|
+
* ```tsx
|
|
93
|
+
* const { reportError } = useLumelyReport();
|
|
94
|
+
*
|
|
95
|
+
* try {
|
|
96
|
+
* await fetchData();
|
|
97
|
+
* } catch (error) {
|
|
98
|
+
* reportError(error, { action: 'fetching user data' });
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare const useLumelyReport: () => {
|
|
103
|
+
reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;
|
|
104
|
+
};
|
|
87
105
|
|
|
88
|
-
export { type LumelyAIResponse, type LumelyAPIResponse, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumelyContext };
|
|
106
|
+
export { type LumelyAIResponse, type LumelyAPIResponse, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumelyContext, useLumelyReport };
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,25 @@ declare const LumelyErrorOverlay: ({ aiResponse, isLoading, feedbackSubmitted, o
|
|
|
82
82
|
|
|
83
83
|
interface LumelyContextValue extends LumelyConfig {
|
|
84
84
|
sessionId: string;
|
|
85
|
+
reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;
|
|
85
86
|
}
|
|
86
87
|
declare const useLumelyContext: () => LumelyContextValue;
|
|
88
|
+
/**
|
|
89
|
+
* Hook for manually reporting errors that aren't caught by the Error Boundary.
|
|
90
|
+
*
|
|
91
|
+
* Usage:
|
|
92
|
+
* ```tsx
|
|
93
|
+
* const { reportError } = useLumelyReport();
|
|
94
|
+
*
|
|
95
|
+
* try {
|
|
96
|
+
* await fetchData();
|
|
97
|
+
* } catch (error) {
|
|
98
|
+
* reportError(error, { action: 'fetching user data' });
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare const useLumelyReport: () => {
|
|
103
|
+
reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;
|
|
104
|
+
};
|
|
87
105
|
|
|
88
|
-
export { type LumelyAIResponse, type LumelyAPIResponse, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumelyContext };
|
|
106
|
+
export { type LumelyAIResponse, type LumelyAPIResponse, type LumelyConfig, LumelyErrorBoundary, type LumelyErrorContext, LumelyErrorOverlay, type LumelyErrorReport, LumelyProvider, useLumelyContext, useLumelyReport };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime')
|
|
1
|
+
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var g=react.createContext(null),I=()=>{if(typeof window=="undefined")return "server";let i=sessionStorage.getItem("lumely_session_id");if(i)return i;let s=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",s),s},C=()=>{let i=react.useContext(g);if(!i)throw new Error("useLumelyContext must be used within a LumelyProvider");return i},P=()=>{let i=react.useContext(g);if(!i)throw new Error("useLumelyReport must be used within a LumelyProvider");return {reportError:i.reportError}},x=({children:i,config:s})=>{let o=react.useMemo(()=>s.sessionId||I(),[s.sessionId]),n=react.useCallback(async(l,a)=>{var u;let t={errorMessage:l.message,errorStack:l.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:s.userId,sessionId:o,timestamp:new Date().toISOString(),...a&&{additionalContext:JSON.stringify(a)}}};try{let c=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(t)});c.ok||console.error("[Lumely] Failed to report error:",c.statusText),(u=s.onError)==null||u.call(s,t);}catch(c){console.error("[Lumely] Error reporting failed:",c);}},[s,o]);react.useEffect(()=>{if(typeof window=="undefined")return;let l=t=>{let u=t.reason instanceof Error?t.reason:new Error(String(t.reason));n(u,{type:"unhandledRejection"});},a=t=>{let u=t.error instanceof Error?t.error:new Error(t.message);n(u,{type:"globalError",filename:t.filename,lineno:t.lineno,colno:t.colno});};return window.addEventListener("unhandledrejection",l),window.addEventListener("error",a),()=>{window.removeEventListener("unhandledrejection",l),window.removeEventListener("error",a);}},[n]);let d=react.useMemo(()=>({...s,sessionId:o,environment:s.environment||"production",reportError:n}),[s,o,n]);return jsxRuntime.jsx(g.Provider,{value:d,children:i})};var j=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let i=document.createElement("style");i.id="lumely-next-styles",i.textContent=`
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
|
|
3
|
+
@keyframes lumely-spin {
|
|
4
|
+
from { transform: rotate(0deg); }
|
|
5
|
+
to { transform: rotate(360deg); }
|
|
6
|
+
}
|
|
7
|
+
`,document.head.appendChild(i);},O=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsxRuntime.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),F=()=>jsxRuntime.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsxRuntime.jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),W=()=>jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsxRuntime.jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsxRuntime.jsx("polyline",{points:"12 19 5 12 12 5"})]}),z=()=>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("polyline",{points:"23 4 23 10 17 10"}),jsxRuntime.jsx("polyline",{points:"1 20 1 14 7 14"}),jsxRuntime.jsx("path",{d:"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"})]}),r={overlay:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",padding:"16px",backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(8px)",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"},card:{position:"relative",width:"100%",maxWidth:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",border:"1px solid rgba(255, 255, 255, 0.2)",borderRadius:"16px",overflow:"hidden"},closeButton:{position:"absolute",top:"12px",right:"12px",padding:"6px",color:"rgba(255, 255, 255, 0.6)",background:"transparent",border:"none",borderRadius:"8px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},content:{padding:"24px"},header:{display:"flex",alignItems:"center",gap:"12px",marginBottom:"16px"},logo:{width:"40px",height:"40px",borderRadius:"12px",background:"linear-gradient(135deg, #7c3aed, #8b5cf6)",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontWeight:700,fontSize:"18px"},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0},subtitle:{color:"rgba(255, 255, 255, 0.5)",fontSize:"12px",margin:0},messageBox:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"16px",marginBottom:"16px"},message:{color:"rgba(255, 255, 255, 0.9)",fontSize:"14px",lineHeight:1.6,margin:0},loading:{display:"flex",alignItems:"center",gap:"8px",color:"rgba(255, 255, 255, 0.7)",fontSize:"14px",padding:"16px 0"},spinner:{width:"16px",height:"16px",border:"2px solid rgba(255, 255, 255, 0.3)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},form:{marginBottom:"16px"},label:{display:"block",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",marginBottom:"8px"},inputWrapper:{position:"relative"},input:{width:"100%",background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"12px 48px 12px 16px",color:"white",fontSize:"14px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},submitButton:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",padding:"8px",color:"rgba(255, 255, 255, 0.4)",background:"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},successBox:{background:"rgba(34, 197, 94, 0.1)",border:"1px solid rgba(34, 197, 94, 0.2)",borderRadius:"12px",padding:"12px",marginBottom:"16px"},successText:{color:"#4ade80",fontSize:"12px",textAlign:"center",margin:0},buttons:{display:"flex",gap:"8px"},button:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"8px",padding:"10px 16px",borderRadius:"12px",fontSize:"14px",fontWeight:500,cursor:"pointer",border:"none",transition:"all 0.2s"},secondaryButton:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.8)"},primaryButton:{background:"#7c3aed",color:"white"}},f=({aiResponse:i,isLoading:s,feedbackSubmitted:o=false,onSubmitFeedback:n,onRetry:d,onDismiss:l,onGoBack:a})=>{let[t,u]=react.useState(""),[c,k]=react.useState(false);react.useEffect(()=>{j();},[]);let S=y=>{y.preventDefault(),t.trim()&&!c&&(k(true),n(t));};return jsxRuntime.jsx("div",{style:r.overlay,children:jsxRuntime.jsxs("div",{style:r.card,children:[jsxRuntime.jsx("button",{style:r.closeButton,onClick:l,children:jsxRuntime.jsx(O,{})}),jsxRuntime.jsxs("div",{style:r.content,children:[jsxRuntime.jsxs("div",{style:r.header,children:[jsxRuntime.jsx("div",{style:r.logo,children:"L"}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("h3",{style:r.title,children:"Something went wrong"}),jsxRuntime.jsx("p",{style:r.subtitle,children:"We're looking into it"})]})]}),s?jsxRuntime.jsxs("div",{style:r.loading,children:[jsxRuntime.jsx("div",{style:r.spinner}),jsxRuntime.jsx("span",{children:"Analyzing the issue..."})]}):i?jsxRuntime.jsx("div",{style:r.messageBox,children:jsxRuntime.jsx("p",{style:r.message,children:i.userMessage})}):jsxRuntime.jsx("div",{style:r.messageBox,children:jsxRuntime.jsx("p",{style:r.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!o&&!c?jsxRuntime.jsxs("form",{style:r.form,onSubmit:S,children:[jsxRuntime.jsx("label",{style:r.label,children:"What were you trying to do?"}),jsxRuntime.jsxs("div",{style:r.inputWrapper,children:[jsxRuntime.jsx("input",{type:"text",value:t,onChange:y=>u(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:r.input}),jsxRuntime.jsx("button",{type:"submit",disabled:!t.trim(),style:{...r.submitButton,opacity:t.trim()?1:.3},children:jsxRuntime.jsx(F,{})})]})]}):jsxRuntime.jsx("div",{style:r.successBox,children:jsxRuntime.jsx("p",{style:r.successText,children:"Thank you! Your feedback helps us improve."})}),jsxRuntime.jsxs("div",{style:r.buttons,children:[jsxRuntime.jsxs("button",{style:{...r.button,...r.secondaryButton},onClick:a,children:[jsxRuntime.jsx(W,{}),"Go Back"]}),jsxRuntime.jsxs("button",{style:{...r.button,...r.primaryButton},onClick:d,children:[jsxRuntime.jsx(z,{}),"Try Again"]})]})]})]})})};var m=class extends react.Component{constructor(o){super(o);this.isReporting=false;this.handleSubmitFeedback=async o=>{let{errorId:n}=this.state,{config:d}=this.props;if(!n||n==="no-db"||n==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":d.apiKey},body:JSON.stringify({errorId:n,feedback:o})}),this.setState({feedbackSubmitted:!0});}catch(l){console.error("Lumely: Failed to submit feedback",l),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(o){return {hasError:true,error:o}}componentDidCatch(o,n){this.isReporting||(this.isReporting=true,this.setState({errorInfo:n,isLoading:true}),this.reportError(o,n));}async reportError(o,n){let{config:d}=this.props,l={errorMessage:o.message,errorStack:o.stack,componentStack:n.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:d.userId,sessionId:d.sessionId,timestamp:new Date().toISOString()}};try{let a=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":d.apiKey},body:JSON.stringify(l)});if(a.ok){let t=await a.json();this.setState({aiResponse:t.ai,errorId:t.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(a){console.error("Lumely: Failed to report error",a),this.setState({isLoading:false});}d.onError&&d.onError(l);}render(){let{hasError:o,aiResponse:n,isLoading:d,feedbackSubmitted:l}=this.state,{children:a}=this.props;return o?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[a,jsxRuntime.jsx(f,{aiResponse:n||void 0,isLoading:d,feedbackSubmitted:l,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):a}};var N=({children:i,apiKey:s,environment:o="production",userId:n,sessionId:d,onError:l})=>{let a={apiKey:s,environment:o,userId:n,sessionId:d,onError:l};return jsxRuntime.jsx(x,{config:a,children:jsxRuntime.jsx(m,{config:a,children:i})})};exports.LumelyErrorBoundary=m;exports.LumelyErrorOverlay=f;exports.LumelyProvider=N;exports.useLumelyContext=C;exports.useLumelyReport=P;//# sourceMappingURL=index.js.map
|
|
2
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyContext","createContext","generateSessionId","stored","newId","useLumelyContext","context","useContext","LumelyContextProvider","children","config","value","useMemo","jsx","poppins","Poppins","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","useState","isSubmitting","setIsSubmitting","handleSubmit","e","jsxs","LumelyErrorBoundary","Component","props","errorId","err","error","errorInfo","report","response","data","hasError","Fragment","LumelyProvider","apiKey","environment","userId","sessionId","onError"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useMemo } from 'react';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\ninterface LumelyContextProviderProps {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\nexport const LumelyContextProvider = ({ children, config }: LumelyContextProviderProps) => {\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId: config.sessionId || generateSessionId(),\r\n environment: config.environment || 'production',\r\n }), [config]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { Poppins } from 'next/font/google';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\nconst poppins = Poppins({\r\n subsets: ['latin'],\r\n weight: ['400', '500', '600', '700'],\r\n variable: '--font-poppins'\r\n});\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div className={`${poppins.className} fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`}>\r\n {/* Glassmorphism Card */}\r\n <div className=\"relative w-full max-w-md bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl overflow-hidden\">\r\n {/* Close Button */}\r\n <button\r\n onClick={onDismiss}\r\n className=\"absolute top-3 right-3 p-1.5 text-white/60 hover:text-white hover:bg-white/10 rounded-lg transition-colors\"\r\n >\r\n ✕\r\n </button>\r\n\r\n {/* Content */}\r\n <div className=\"p-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-lg\">L</span>\r\n </div>\r\n <div>\r\n <h3 className=\"text-white font-semibold text-sm\">Something went wrong</h3>\r\n <p className=\"text-white/50 text-xs\">We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {/* AI Message */}\r\n {isLoading ? (\r\n <div className=\"flex items-center gap-2 text-white/70 text-sm py-4\">\r\n <div className=\"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : aiResponse ? (\r\n <div className=\"bg-white/5 border border-white/10 rounded-xl p-4 mb-4\">\r\n <p className=\"text-white/90 text-sm leading-relaxed\">\r\n {aiResponse.userMessage}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-white/5 border border-white/10 rounded-xl p-4 mb-4\">\r\n <p className=\"text-white/90 text-sm leading-relaxed\">\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* User Feedback Input */}\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form onSubmit={handleSubmit} className=\"mb-4\">\r\n <label className=\"block text-white/60 text-xs mb-2\">\r\n What were you trying to do?\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n className=\"w-full bg-white/5 border border-white/10 rounded-xl py-3 px-4 pr-12 text-white text-sm placeholder:text-white/30 focus:outline-none focus:border-primary-500/50 transition-colors\"\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-2 text-white/40 hover:text-primary-400 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n ➤\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div className=\"bg-green-500/10 border border-green-500/20 rounded-xl p-3 mb-4\">\r\n <p className=\"text-green-400 text-xs text-center\">\r\n Thank you! Your feedback helps us improve.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={onGoBack}\r\n className=\"flex-1 flex items-center justify-center gap-2 py-2.5 px-4 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-white/80 text-sm font-medium transition-colors\"\r\n >\r\n ← Go Back\r\n </button>\r\n <button\r\n onClick={onRetry}\r\n className=\"flex-1 flex items-center justify-center gap-2 py-2.5 px-4 bg-primary-600 hover:bg-primary-500 rounded-xl text-white text-sm font-medium transition-colors\"\r\n >\r\n ↻ Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false; // Prevent duplicate reports\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n // Prevent duplicate reports\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyContext","createContext","generateSessionId","stored","newId","useLumelyContext","context","useContext","useLumelyReport","LumelyContextProvider","children","config","sessionId","useMemo","reportError","useCallback","error","additionalContext","_a","report","response","e","useEffect","handleUnhandledRejection","event","handleGlobalError","value","jsx","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","RefreshCwIcon","styles","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","useState","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","errorId","err","errorInfo","data","hasError","Fragment","LumelyProvider","apiKey","environment","userId","onError"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * \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 = useMemo(() => config.sessionId || generateSessionId(), [config.sessionId]);\r\n\r\n // Manual error reporting function\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (!response.ok) {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n }\r\n }, [config, sessionId]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\r\n);\r\n\r\nconst styles: Record<string, React.CSSProperties> = {\r\n overlay: {\r\n position: 'fixed',\r\n inset: 0,\r\n zIndex: 9999,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '16px',\r\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\r\n backdropFilter: 'blur(8px)',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n },\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n maxWidth: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\r\n border: '1px solid rgba(255, 255, 255, 0.2)',\r\n borderRadius: '16px',\r\n overflow: 'hidden',\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '12px',\r\n right: '12px',\r\n padding: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\r\n },\r\n content: {\r\n padding: '24px',\r\n },\r\n header: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '16px',\r\n },\r\n logo: {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '12px',\r\n background: 'linear-gradient(135deg, #7c3aed, #8b5cf6)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'white',\r\n fontWeight: 700,\r\n fontSize: '18px',\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n },\r\n subtitle: {\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n fontSize: '12px',\r\n margin: 0,\r\n },\r\n messageBox: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '16px',\r\n marginBottom: '16px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.9)',\r\n fontSize: '14px',\r\n lineHeight: 1.6,\r\n margin: 0,\r\n },\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n color: 'rgba(255, 255, 255, 0.7)',\r\n fontSize: '14px',\r\n padding: '16px 0',\r\n },\r\n spinner: {\r\n width: '16px',\r\n height: '16px',\r\n border: '2px solid rgba(255, 255, 255, 0.3)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n form: {\r\n marginBottom: '16px',\r\n },\r\n label: {\r\n display: 'block',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n marginBottom: '8px',\r\n },\r\n inputWrapper: {\r\n position: 'relative',\r\n },\r\n input: {\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '12px 48px 12px 16px',\r\n color: 'white',\r\n fontSize: '14px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n submitButton: {\r\n position: 'absolute',\r\n right: '8px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n padding: '8px',\r\n color: 'rgba(255, 255, 255, 0.4)',\r\n background: 'transparent',\r\n border: 'none',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\r\n },\r\n successBox: {\r\n background: 'rgba(34, 197, 94, 0.1)',\r\n border: '1px solid rgba(34, 197, 94, 0.2)',\r\n borderRadius: '12px',\r\n padding: '12px',\r\n marginBottom: '16px',\r\n },\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n margin: 0,\r\n },\r\n buttons: {\r\n display: 'flex',\r\n gap: '8px',\r\n },\r\n button: {\r\n flex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '8px',\r\n padding: '10px 16px',\r\n borderRadius: '12px',\r\n fontSize: '14px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s',\r\n },\r\n secondaryButton: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n color: 'rgba(255, 255, 255, 0.8)',\r\n },\r\n primaryButton: {\r\n background: '#7c3aed',\r\n color: 'white',\r\n },\r\n};\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n useEffect(() => {\r\n injectStyles();\r\n }, []);\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div style={styles.overlay}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\r\n <div style={styles.header}>\r\n <div style={styles.logo}>L</div>\r\n <div>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n <p style={styles.subtitle}>We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {/* AI Message */}\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form style={styles.form} onSubmit={handleSubmit}>\r\n <label style={styles.label}>What were you trying to do?</label>\r\n <div style={styles.inputWrapper}>\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n style={styles.input}\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n style={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div style={styles.successBox}>\r\n <p style={styles.successText}>Thank you! Your feedback helps us improve.</p>\r\n </div>\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.secondaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onRetry}\r\n >\r\n <RefreshCwIcon />\r\n Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false; // Prevent duplicate reports\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n // Prevent duplicate reports\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import {createContext,useContext,useState,Component,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';
|
|
1
|
+
import {createContext,useContext,useState,useEffect,Component,useMemo,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var g=createContext(null),I=()=>{if(typeof window=="undefined")return "server";let i=sessionStorage.getItem("lumely_session_id");if(i)return i;let s=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",s),s},C=()=>{let i=useContext(g);if(!i)throw new Error("useLumelyContext must be used within a LumelyProvider");return i},P=()=>{let i=useContext(g);if(!i)throw new Error("useLumelyReport must be used within a LumelyProvider");return {reportError:i.reportError}},x=({children:i,config:s})=>{let o=useMemo(()=>s.sessionId||I(),[s.sessionId]),n=useCallback(async(l,a)=>{var u;let t={errorMessage:l.message,errorStack:l.stack,context:{url:typeof window!="undefined"?window.location.href:"server",userAgent:typeof navigator!="undefined"?navigator.userAgent:"server",userId:s.userId,sessionId:o,timestamp:new Date().toISOString(),...a&&{additionalContext:JSON.stringify(a)}}};try{let c=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(t)});c.ok||console.error("[Lumely] Failed to report error:",c.statusText),(u=s.onError)==null||u.call(s,t);}catch(c){console.error("[Lumely] Error reporting failed:",c);}},[s,o]);useEffect(()=>{if(typeof window=="undefined")return;let l=t=>{let u=t.reason instanceof Error?t.reason:new Error(String(t.reason));n(u,{type:"unhandledRejection"});},a=t=>{let u=t.error instanceof Error?t.error:new Error(t.message);n(u,{type:"globalError",filename:t.filename,lineno:t.lineno,colno:t.colno});};return window.addEventListener("unhandledrejection",l),window.addEventListener("error",a),()=>{window.removeEventListener("unhandledrejection",l),window.removeEventListener("error",a);}},[n]);let d=useMemo(()=>({...s,sessionId:o,environment:s.environment||"production",reportError:n}),[s,o,n]);return jsx(g.Provider,{value:d,children:i})};var j=()=>{if(typeof document=="undefined"||document.getElementById("lumely-next-styles"))return;let i=document.createElement("style");i.id="lumely-next-styles",i.textContent=`
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
|
|
3
|
+
@keyframes lumely-spin {
|
|
4
|
+
from { transform: rotate(0deg); }
|
|
5
|
+
to { transform: rotate(360deg); }
|
|
6
|
+
}
|
|
7
|
+
`,document.head.appendChild(i);},O=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),F=()=>jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"22",y1:"2",x2:"11",y2:"13"}),jsx("polygon",{points:"22 2 15 22 11 13 2 9 22 2"})]}),W=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("line",{x1:"19",y1:"12",x2:"5",y2:"12"}),jsx("polyline",{points:"12 19 5 12 12 5"})]}),z=()=>jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[jsx("polyline",{points:"23 4 23 10 17 10"}),jsx("polyline",{points:"1 20 1 14 7 14"}),jsx("path",{d:"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"})]}),r={overlay:{position:"fixed",inset:0,zIndex:9999,display:"flex",alignItems:"center",justifyContent:"center",padding:"16px",backgroundColor:"rgba(0, 0, 0, 0.4)",backdropFilter:"blur(8px)",fontFamily:"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif"},card:{position:"relative",width:"100%",maxWidth:"448px",background:"rgba(255, 255, 255, 0.1)",backdropFilter:"blur(24px)",border:"1px solid rgba(255, 255, 255, 0.2)",borderRadius:"16px",overflow:"hidden"},closeButton:{position:"absolute",top:"12px",right:"12px",padding:"6px",color:"rgba(255, 255, 255, 0.6)",background:"transparent",border:"none",borderRadius:"8px",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s"},content:{padding:"24px"},header:{display:"flex",alignItems:"center",gap:"12px",marginBottom:"16px"},logo:{width:"40px",height:"40px",borderRadius:"12px",background:"linear-gradient(135deg, #7c3aed, #8b5cf6)",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontWeight:700,fontSize:"18px"},title:{color:"white",fontWeight:600,fontSize:"14px",margin:0},subtitle:{color:"rgba(255, 255, 255, 0.5)",fontSize:"12px",margin:0},messageBox:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"16px",marginBottom:"16px"},message:{color:"rgba(255, 255, 255, 0.9)",fontSize:"14px",lineHeight:1.6,margin:0},loading:{display:"flex",alignItems:"center",gap:"8px",color:"rgba(255, 255, 255, 0.7)",fontSize:"14px",padding:"16px 0"},spinner:{width:"16px",height:"16px",border:"2px solid rgba(255, 255, 255, 0.3)",borderTopColor:"white",borderRadius:"50%",animation:"lumely-spin 1s linear infinite"},form:{marginBottom:"16px"},label:{display:"block",color:"rgba(255, 255, 255, 0.6)",fontSize:"12px",marginBottom:"8px"},inputWrapper:{position:"relative"},input:{width:"100%",background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",borderRadius:"12px",padding:"12px 48px 12px 16px",color:"white",fontSize:"14px",outline:"none",boxSizing:"border-box",transition:"border-color 0.2s"},submitButton:{position:"absolute",right:"8px",top:"50%",transform:"translateY(-50%)",padding:"8px",color:"rgba(255, 255, 255, 0.4)",background:"transparent",border:"none",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"color 0.2s"},successBox:{background:"rgba(34, 197, 94, 0.1)",border:"1px solid rgba(34, 197, 94, 0.2)",borderRadius:"12px",padding:"12px",marginBottom:"16px"},successText:{color:"#4ade80",fontSize:"12px",textAlign:"center",margin:0},buttons:{display:"flex",gap:"8px"},button:{flex:1,display:"flex",alignItems:"center",justifyContent:"center",gap:"8px",padding:"10px 16px",borderRadius:"12px",fontSize:"14px",fontWeight:500,cursor:"pointer",border:"none",transition:"all 0.2s"},secondaryButton:{background:"rgba(255, 255, 255, 0.05)",border:"1px solid rgba(255, 255, 255, 0.1)",color:"rgba(255, 255, 255, 0.8)"},primaryButton:{background:"#7c3aed",color:"white"}},f=({aiResponse:i,isLoading:s,feedbackSubmitted:o=false,onSubmitFeedback:n,onRetry:d,onDismiss:l,onGoBack:a})=>{let[t,u]=useState(""),[c,k]=useState(false);useEffect(()=>{j();},[]);let S=y=>{y.preventDefault(),t.trim()&&!c&&(k(true),n(t));};return jsx("div",{style:r.overlay,children:jsxs("div",{style:r.card,children:[jsx("button",{style:r.closeButton,onClick:l,children:jsx(O,{})}),jsxs("div",{style:r.content,children:[jsxs("div",{style:r.header,children:[jsx("div",{style:r.logo,children:"L"}),jsxs("div",{children:[jsx("h3",{style:r.title,children:"Something went wrong"}),jsx("p",{style:r.subtitle,children:"We're looking into it"})]})]}),s?jsxs("div",{style:r.loading,children:[jsx("div",{style:r.spinner}),jsx("span",{children:"Analyzing the issue..."})]}):i?jsx("div",{style:r.messageBox,children:jsx("p",{style:r.message,children:i.userMessage})}):jsx("div",{style:r.messageBox,children:jsx("p",{style:r.message,children:"We encountered an unexpected issue. Our team has been notified."})}),!o&&!c?jsxs("form",{style:r.form,onSubmit:S,children:[jsx("label",{style:r.label,children:"What were you trying to do?"}),jsxs("div",{style:r.inputWrapper,children:[jsx("input",{type:"text",value:t,onChange:y=>u(y.target.value),placeholder:"e.g., I was trying to save my changes...",style:r.input}),jsx("button",{type:"submit",disabled:!t.trim(),style:{...r.submitButton,opacity:t.trim()?1:.3},children:jsx(F,{})})]})]}):jsx("div",{style:r.successBox,children:jsx("p",{style:r.successText,children:"Thank you! Your feedback helps us improve."})}),jsxs("div",{style:r.buttons,children:[jsxs("button",{style:{...r.button,...r.secondaryButton},onClick:a,children:[jsx(W,{}),"Go Back"]}),jsxs("button",{style:{...r.button,...r.primaryButton},onClick:d,children:[jsx(z,{}),"Try Again"]})]})]})]})})};var m=class extends Component{constructor(o){super(o);this.isReporting=false;this.handleSubmitFeedback=async o=>{let{errorId:n}=this.state,{config:d}=this.props;if(!n||n==="no-db"||n==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":d.apiKey},body:JSON.stringify({errorId:n,feedback:o})}),this.setState({feedbackSubmitted:!0});}catch(l){console.error("Lumely: Failed to submit feedback",l),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(o){return {hasError:true,error:o}}componentDidCatch(o,n){this.isReporting||(this.isReporting=true,this.setState({errorInfo:n,isLoading:true}),this.reportError(o,n));}async reportError(o,n){let{config:d}=this.props,l={errorMessage:o.message,errorStack:o.stack,componentStack:n.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:d.userId,sessionId:d.sessionId,timestamp:new Date().toISOString()}};try{let a=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":d.apiKey},body:JSON.stringify(l)});if(a.ok){let t=await a.json();this.setState({aiResponse:t.ai,errorId:t.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(a){console.error("Lumely: Failed to report error",a),this.setState({isLoading:false});}d.onError&&d.onError(l);}render(){let{hasError:o,aiResponse:n,isLoading:d,feedbackSubmitted:l}=this.state,{children:a}=this.props;return o?jsxs(Fragment,{children:[a,jsx(f,{aiResponse:n||void 0,isLoading:d,feedbackSubmitted:l,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):a}};var N=({children:i,apiKey:s,environment:o="production",userId:n,sessionId:d,onError:l})=>{let a={apiKey:s,environment:o,userId:n,sessionId:d,onError:l};return jsx(x,{config:a,children:jsx(m,{config:a,children:i})})};export{m as LumelyErrorBoundary,f as LumelyErrorOverlay,N as LumelyProvider,C as useLumelyContext,P as useLumelyReport};//# sourceMappingURL=index.mjs.map
|
|
2
8
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyContext","createContext","generateSessionId","stored","newId","useLumelyContext","context","useContext","LumelyContextProvider","children","config","value","useMemo","jsx","poppins","Poppins","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","useState","isSubmitting","setIsSubmitting","handleSubmit","e","jsxs","LumelyErrorBoundary","Component","props","errorId","err","error","errorInfo","report","response","data","hasError","Fragment","LumelyProvider","apiKey","environment","userId","sessionId","onError"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useMemo } from 'react';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\ninterface LumelyContextProviderProps {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\nexport const LumelyContextProvider = ({ children, config }: LumelyContextProviderProps) => {\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId: config.sessionId || generateSessionId(),\r\n environment: config.environment || 'production',\r\n }), [config]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { useState } from 'react';\r\nimport { Poppins } from 'next/font/google';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\nconst poppins = Poppins({\r\n subsets: ['latin'],\r\n weight: ['400', '500', '600', '700'],\r\n variable: '--font-poppins'\r\n});\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div className={`${poppins.className} fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`}>\r\n {/* Glassmorphism Card */}\r\n <div className=\"relative w-full max-w-md bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl overflow-hidden\">\r\n {/* Close Button */}\r\n <button\r\n onClick={onDismiss}\r\n className=\"absolute top-3 right-3 p-1.5 text-white/60 hover:text-white hover:bg-white/10 rounded-lg transition-colors\"\r\n >\r\n ✕\r\n </button>\r\n\r\n {/* Content */}\r\n <div className=\"p-6\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-3 mb-4\">\r\n <div className=\"w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-lg\">L</span>\r\n </div>\r\n <div>\r\n <h3 className=\"text-white font-semibold text-sm\">Something went wrong</h3>\r\n <p className=\"text-white/50 text-xs\">We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {/* AI Message */}\r\n {isLoading ? (\r\n <div className=\"flex items-center gap-2 text-white/70 text-sm py-4\">\r\n <div className=\"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : aiResponse ? (\r\n <div className=\"bg-white/5 border border-white/10 rounded-xl p-4 mb-4\">\r\n <p className=\"text-white/90 text-sm leading-relaxed\">\r\n {aiResponse.userMessage}\r\n </p>\r\n </div>\r\n ) : (\r\n <div className=\"bg-white/5 border border-white/10 rounded-xl p-4 mb-4\">\r\n <p className=\"text-white/90 text-sm leading-relaxed\">\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* User Feedback Input */}\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form onSubmit={handleSubmit} className=\"mb-4\">\r\n <label className=\"block text-white/60 text-xs mb-2\">\r\n What were you trying to do?\r\n </label>\r\n <div className=\"relative\">\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n className=\"w-full bg-white/5 border border-white/10 rounded-xl py-3 px-4 pr-12 text-white text-sm placeholder:text-white/30 focus:outline-none focus:border-primary-500/50 transition-colors\"\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-2 text-white/40 hover:text-primary-400 disabled:opacity-30 disabled:cursor-not-allowed transition-colors\"\r\n >\r\n ➤\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div className=\"bg-green-500/10 border border-green-500/20 rounded-xl p-3 mb-4\">\r\n <p className=\"text-green-400 text-xs text-center\">\r\n Thank you! Your feedback helps us improve.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={onGoBack}\r\n className=\"flex-1 flex items-center justify-center gap-2 py-2.5 px-4 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-white/80 text-sm font-medium transition-colors\"\r\n >\r\n ← Go Back\r\n </button>\r\n <button\r\n onClick={onRetry}\r\n className=\"flex-1 flex items-center justify-center gap-2 py-2.5 px-4 bg-primary-600 hover:bg-primary-500 rounded-xl text-white text-sm font-medium transition-colors\"\r\n >\r\n ↻ Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false; // Prevent duplicate reports\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n // Prevent duplicate reports\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../LumelyContext.tsx","../LumelyErrorOverlay.tsx","../LumelyErrorBoundary.tsx","../LumelyProvider.tsx"],"names":["LumelyContext","createContext","generateSessionId","stored","newId","useLumelyContext","context","useContext","useLumelyReport","LumelyContextProvider","children","config","sessionId","useMemo","reportError","useCallback","error","additionalContext","_a","report","response","e","useEffect","handleUnhandledRejection","event","handleGlobalError","value","jsx","injectStyles","style","XIcon","jsxs","SendIcon","ArrowLeftIcon","RefreshCwIcon","styles","LumelyErrorOverlay","aiResponse","isLoading","feedbackSubmitted","onSubmitFeedback","onRetry","onDismiss","onGoBack","feedback","setFeedback","useState","isSubmitting","setIsSubmitting","handleSubmit","LumelyErrorBoundary","Component","props","errorId","err","errorInfo","data","hasError","Fragment","LumelyProvider","apiKey","environment","userId","onError"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\r\n\r\nimport React, { createContext, useContext, useMemo, useCallback, useEffect } from 'react';\r\nimport type { LumelyConfig, LumelyErrorReport } from './types';\r\n\r\ninterface LumelyContextValue extends LumelyConfig {\r\n sessionId: string;\r\n reportError: (error: Error, additionalContext?: Record<string, unknown>) => Promise<void>;\r\n}\r\n\r\nconst LumelyContext = createContext<LumelyContextValue | null>(null);\r\n\r\n// Generate a unique session ID\r\nconst generateSessionId = () => {\r\n if (typeof window === 'undefined') return 'server';\r\n const stored = sessionStorage.getItem('lumely_session_id');\r\n if (stored) return stored;\r\n const newId = `sess_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\r\n sessionStorage.setItem('lumely_session_id', newId);\r\n return newId;\r\n};\r\n\r\nexport const useLumelyContext = () => {\r\n const context = useContext(LumelyContext);\r\n if (!context) {\r\n throw new Error('useLumelyContext must be used within a LumelyProvider');\r\n }\r\n return context;\r\n};\r\n\r\n/**\r\n * Hook for manually reporting errors that aren't caught by the Error Boundary.\r\n * \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 = useMemo(() => config.sessionId || generateSessionId(), [config.sessionId]);\r\n\r\n // Manual error reporting function\r\n const reportError = useCallback(async (error: Error, additionalContext?: Record<string, unknown>) => {\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'server',\r\n userId: config.userId,\r\n sessionId: sessionId,\r\n timestamp: new Date().toISOString(),\r\n ...(additionalContext && { additionalContext: JSON.stringify(additionalContext) }),\r\n }\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (!response.ok) {\r\n console.error('[Lumely] Failed to report error:', response.statusText);\r\n }\r\n\r\n // Call user's onError callback if provided\r\n config.onError?.(report);\r\n } catch (e) {\r\n console.error('[Lumely] Error reporting failed:', e);\r\n }\r\n }, [config, sessionId]);\r\n\r\n // Setup global error handlers for uncaught errors\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n // Catch unhandled promise rejections\r\n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\r\n const error = event.reason instanceof Error\r\n ? event.reason\r\n : new Error(String(event.reason));\r\n reportError(error, { type: 'unhandledRejection' });\r\n };\r\n\r\n // Catch global errors (non-React)\r\n const handleGlobalError = (event: ErrorEvent) => {\r\n const error = event.error instanceof Error\r\n ? event.error\r\n : new Error(event.message);\r\n reportError(error, {\r\n type: 'globalError',\r\n filename: event.filename,\r\n lineno: event.lineno,\r\n colno: event.colno\r\n });\r\n };\r\n\r\n window.addEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.addEventListener('error', handleGlobalError);\r\n\r\n return () => {\r\n window.removeEventListener('unhandledrejection', handleUnhandledRejection);\r\n window.removeEventListener('error', handleGlobalError);\r\n };\r\n }, [reportError]);\r\n\r\n const value = useMemo(() => ({\r\n ...config,\r\n sessionId,\r\n environment: config.environment || 'production',\r\n reportError,\r\n }), [config, sessionId, reportError]);\r\n\r\n return (\r\n <LumelyContext.Provider value={value}>\r\n {children}\r\n </LumelyContext.Provider>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { useState, useEffect } from 'react';\r\nimport type { LumelyAIResponse } from './types';\r\n\r\n// Inject Poppins font and keyframes\r\nconst injectStyles = () => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById('lumely-next-styles')) return;\r\n\r\n const style = document.createElement('style');\r\n style.id = 'lumely-next-styles';\r\n style.textContent = `\r\n @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');\r\n @keyframes lumely-spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n};\r\n\r\n// SVG Icons as components (replacing lucide-react)\r\nconst XIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\r\n </svg>\r\n);\r\n\r\nconst ArrowLeftIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line>\r\n <polyline points=\"12 19 5 12 12 5\"></polyline>\r\n </svg>\r\n);\r\n\r\nconst RefreshCwIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\"></polyline>\r\n <polyline points=\"1 20 1 14 7 14\"></polyline>\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>\r\n </svg>\r\n);\r\n\r\nconst styles: Record<string, React.CSSProperties> = {\r\n overlay: {\r\n position: 'fixed',\r\n inset: 0,\r\n zIndex: 9999,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '16px',\r\n backgroundColor: 'rgba(0, 0, 0, 0.4)',\r\n backdropFilter: 'blur(8px)',\r\n fontFamily: \"'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\r\n },\r\n card: {\r\n position: 'relative',\r\n width: '100%',\r\n maxWidth: '448px',\r\n background: 'rgba(255, 255, 255, 0.1)',\r\n backdropFilter: 'blur(24px)',\r\n border: '1px solid rgba(255, 255, 255, 0.2)',\r\n borderRadius: '16px',\r\n overflow: 'hidden',\r\n },\r\n closeButton: {\r\n position: 'absolute',\r\n top: '12px',\r\n right: '12px',\r\n padding: '6px',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n background: 'transparent',\r\n border: 'none',\r\n borderRadius: '8px',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'all 0.2s',\r\n },\r\n content: {\r\n padding: '24px',\r\n },\r\n header: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n marginBottom: '16px',\r\n },\r\n logo: {\r\n width: '40px',\r\n height: '40px',\r\n borderRadius: '12px',\r\n background: 'linear-gradient(135deg, #7c3aed, #8b5cf6)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'white',\r\n fontWeight: 700,\r\n fontSize: '18px',\r\n },\r\n title: {\r\n color: 'white',\r\n fontWeight: 600,\r\n fontSize: '14px',\r\n margin: 0,\r\n },\r\n subtitle: {\r\n color: 'rgba(255, 255, 255, 0.5)',\r\n fontSize: '12px',\r\n margin: 0,\r\n },\r\n messageBox: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '16px',\r\n marginBottom: '16px',\r\n },\r\n message: {\r\n color: 'rgba(255, 255, 255, 0.9)',\r\n fontSize: '14px',\r\n lineHeight: 1.6,\r\n margin: 0,\r\n },\r\n loading: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n color: 'rgba(255, 255, 255, 0.7)',\r\n fontSize: '14px',\r\n padding: '16px 0',\r\n },\r\n spinner: {\r\n width: '16px',\r\n height: '16px',\r\n border: '2px solid rgba(255, 255, 255, 0.3)',\r\n borderTopColor: 'white',\r\n borderRadius: '50%',\r\n animation: 'lumely-spin 1s linear infinite',\r\n },\r\n form: {\r\n marginBottom: '16px',\r\n },\r\n label: {\r\n display: 'block',\r\n color: 'rgba(255, 255, 255, 0.6)',\r\n fontSize: '12px',\r\n marginBottom: '8px',\r\n },\r\n inputWrapper: {\r\n position: 'relative',\r\n },\r\n input: {\r\n width: '100%',\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n borderRadius: '12px',\r\n padding: '12px 48px 12px 16px',\r\n color: 'white',\r\n fontSize: '14px',\r\n outline: 'none',\r\n boxSizing: 'border-box',\r\n transition: 'border-color 0.2s',\r\n },\r\n submitButton: {\r\n position: 'absolute',\r\n right: '8px',\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n padding: '8px',\r\n color: 'rgba(255, 255, 255, 0.4)',\r\n background: 'transparent',\r\n border: 'none',\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'color 0.2s',\r\n },\r\n successBox: {\r\n background: 'rgba(34, 197, 94, 0.1)',\r\n border: '1px solid rgba(34, 197, 94, 0.2)',\r\n borderRadius: '12px',\r\n padding: '12px',\r\n marginBottom: '16px',\r\n },\r\n successText: {\r\n color: '#4ade80',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n margin: 0,\r\n },\r\n buttons: {\r\n display: 'flex',\r\n gap: '8px',\r\n },\r\n button: {\r\n flex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n gap: '8px',\r\n padding: '10px 16px',\r\n borderRadius: '12px',\r\n fontSize: '14px',\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n border: 'none',\r\n transition: 'all 0.2s',\r\n },\r\n secondaryButton: {\r\n background: 'rgba(255, 255, 255, 0.05)',\r\n border: '1px solid rgba(255, 255, 255, 0.1)',\r\n color: 'rgba(255, 255, 255, 0.8)',\r\n },\r\n primaryButton: {\r\n background: '#7c3aed',\r\n color: 'white',\r\n },\r\n};\r\n\r\ninterface LumelyErrorOverlayProps {\r\n aiResponse?: LumelyAIResponse;\r\n isLoading: boolean;\r\n feedbackSubmitted?: boolean;\r\n onSubmitFeedback: (feedback: string) => void;\r\n onRetry: () => void;\r\n onDismiss: () => void;\r\n onGoBack: () => void;\r\n}\r\n\r\nexport const LumelyErrorOverlay = ({\r\n aiResponse,\r\n isLoading,\r\n feedbackSubmitted = false,\r\n onSubmitFeedback,\r\n onRetry,\r\n onDismiss,\r\n onGoBack,\r\n}: LumelyErrorOverlayProps) => {\r\n const [feedback, setFeedback] = useState('');\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n\r\n useEffect(() => {\r\n injectStyles();\r\n }, []);\r\n\r\n const handleSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (feedback.trim() && !isSubmitting) {\r\n setIsSubmitting(true);\r\n onSubmitFeedback(feedback);\r\n }\r\n };\r\n\r\n return (\r\n <div style={styles.overlay}>\r\n <div style={styles.card}>\r\n {/* Close Button */}\r\n <button style={styles.closeButton} onClick={onDismiss}>\r\n <XIcon />\r\n </button>\r\n\r\n <div style={styles.content}>\r\n {/* Header */}\r\n <div style={styles.header}>\r\n <div style={styles.logo}>L</div>\r\n <div>\r\n <h3 style={styles.title}>Something went wrong</h3>\r\n <p style={styles.subtitle}>We're looking into it</p>\r\n </div>\r\n </div>\r\n\r\n {/* AI Message */}\r\n {isLoading ? (\r\n <div style={styles.loading}>\r\n <div style={styles.spinner} />\r\n <span>Analyzing the issue...</span>\r\n </div>\r\n ) : aiResponse ? (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>{aiResponse.userMessage}</p>\r\n </div>\r\n ) : (\r\n <div style={styles.messageBox}>\r\n <p style={styles.message}>\r\n We encountered an unexpected issue. Our team has been notified.\r\n </p>\r\n </div>\r\n )}\r\n\r\n {/* Feedback Input */}\r\n {!feedbackSubmitted && !isSubmitting ? (\r\n <form style={styles.form} onSubmit={handleSubmit}>\r\n <label style={styles.label}>What were you trying to do?</label>\r\n <div style={styles.inputWrapper}>\r\n <input\r\n type=\"text\"\r\n value={feedback}\r\n onChange={(e) => setFeedback(e.target.value)}\r\n placeholder=\"e.g., I was trying to save my changes...\"\r\n style={styles.input}\r\n />\r\n <button\r\n type=\"submit\"\r\n disabled={!feedback.trim()}\r\n style={{\r\n ...styles.submitButton,\r\n opacity: feedback.trim() ? 1 : 0.3,\r\n }}\r\n >\r\n <SendIcon />\r\n </button>\r\n </div>\r\n </form>\r\n ) : (\r\n <div style={styles.successBox}>\r\n <p style={styles.successText}>Thank you! Your feedback helps us improve.</p>\r\n </div>\r\n )}\r\n\r\n {/* Action Buttons */}\r\n <div style={styles.buttons}>\r\n <button\r\n style={{ ...styles.button, ...styles.secondaryButton }}\r\n onClick={onGoBack}\r\n >\r\n <ArrowLeftIcon />\r\n Go Back\r\n </button>\r\n <button\r\n style={{ ...styles.button, ...styles.primaryButton }}\r\n onClick={onRetry}\r\n >\r\n <RefreshCwIcon />\r\n Try Again\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","'use client';\r\n\r\nimport React, { Component, ErrorInfo } from 'react';\r\nimport { LumelyErrorOverlay } from './LumelyErrorOverlay';\r\nimport type { LumelyConfig, LumelyErrorReport, LumelyAIResponse, LumelyAPIResponse } from './types';\r\n\r\ninterface Props {\r\n children: React.ReactNode;\r\n config: LumelyConfig;\r\n}\r\n\r\ninterface State {\r\n hasError: boolean;\r\n error: Error | null;\r\n errorInfo: ErrorInfo | null;\r\n aiResponse: LumelyAIResponse | null;\r\n isLoading: boolean;\r\n errorId: string | null;\r\n feedbackSubmitted: boolean;\r\n}\r\n\r\nexport class LumelyErrorBoundary extends Component<Props, State> {\r\n private isReporting = false; // Prevent duplicate reports\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n this.state = {\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): Partial<State> {\r\n return { hasError: true, error };\r\n }\r\n\r\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\r\n // Prevent duplicate reports\r\n if (this.isReporting) return;\r\n\r\n this.isReporting = true;\r\n this.setState({ errorInfo, isLoading: true });\r\n this.reportError(error, errorInfo);\r\n }\r\n\r\n private async reportError(error: Error, errorInfo: ErrorInfo) {\r\n const { config } = this.props;\r\n\r\n const report: LumelyErrorReport = {\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n componentStack: errorInfo.componentStack || undefined,\r\n context: {\r\n url: typeof window !== 'undefined' ? window.location.href : '',\r\n userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : '',\r\n userId: config.userId,\r\n sessionId: config.sessionId,\r\n timestamp: new Date().toISOString(),\r\n },\r\n };\r\n\r\n try {\r\n const response = await fetch('/api/lumely/report-error', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify(report),\r\n });\r\n\r\n if (response.ok) {\r\n const data: LumelyAPIResponse = await response.json();\r\n this.setState({\r\n aiResponse: data.ai,\r\n errorId: data.errorId,\r\n isLoading: false,\r\n });\r\n } else {\r\n this.setState({ isLoading: false });\r\n }\r\n } catch (err) {\r\n console.error('Lumely: Failed to report error', err);\r\n this.setState({ isLoading: false });\r\n }\r\n\r\n // Call optional callback\r\n if (config.onError) {\r\n config.onError(report);\r\n }\r\n }\r\n\r\n private handleSubmitFeedback = async (feedback: string) => {\r\n const { errorId } = this.state;\r\n const { config } = this.props;\r\n\r\n if (!errorId || errorId === 'no-db' || errorId === 'db-error') {\r\n // Can't update if no valid error ID\r\n this.setState({ feedbackSubmitted: true });\r\n return;\r\n }\r\n\r\n try {\r\n // Update existing error record with feedback\r\n await fetch('/api/lumely/update-feedback', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Lumely-Key': config.apiKey,\r\n },\r\n body: JSON.stringify({ errorId, feedback }),\r\n });\r\n\r\n this.setState({ feedbackSubmitted: true });\r\n } catch (err) {\r\n console.error('Lumely: Failed to submit feedback', err);\r\n this.setState({ feedbackSubmitted: true });\r\n }\r\n };\r\n\r\n private handleRetry = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleDismiss = () => {\r\n this.isReporting = false;\r\n this.setState({\r\n hasError: false,\r\n error: null,\r\n errorInfo: null,\r\n aiResponse: null,\r\n isLoading: false,\r\n errorId: null,\r\n feedbackSubmitted: false,\r\n });\r\n };\r\n\r\n private handleGoBack = () => {\r\n if (typeof window !== 'undefined') {\r\n window.history.back();\r\n }\r\n };\r\n\r\n render() {\r\n const { hasError, aiResponse, isLoading, feedbackSubmitted } = this.state;\r\n const { children } = this.props;\r\n\r\n if (hasError) {\r\n return (\r\n <>\r\n {children}\r\n <LumelyErrorOverlay\r\n aiResponse={aiResponse || undefined}\r\n isLoading={isLoading}\r\n feedbackSubmitted={feedbackSubmitted}\r\n onSubmitFeedback={this.handleSubmitFeedback}\r\n onRetry={this.handleRetry}\r\n onDismiss={this.handleDismiss}\r\n onGoBack={this.handleGoBack}\r\n />\r\n </>\r\n );\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","'use client';\r\n\r\nimport React from 'react';\r\nimport { LumelyContextProvider } from './LumelyContext';\r\nimport { LumelyErrorBoundary } from './LumelyErrorBoundary';\r\nimport type { LumelyConfig } from './types';\r\n\r\ninterface LumelyProviderProps {\r\n children: React.ReactNode;\r\n apiKey: string;\r\n environment?: 'development' | 'production';\r\n userId?: string;\r\n sessionId?: string;\r\n onError?: LumelyConfig['onError'];\r\n}\r\n\r\nexport const LumelyProvider = ({\r\n children,\r\n apiKey,\r\n environment = 'production',\r\n userId,\r\n sessionId,\r\n onError,\r\n}: LumelyProviderProps) => {\r\n const config: LumelyConfig = {\r\n apiKey,\r\n environment,\r\n userId,\r\n sessionId,\r\n onError,\r\n };\r\n\r\n return (\r\n <LumelyContextProvider config={config}>\r\n <LumelyErrorBoundary config={config}>\r\n {children}\r\n </LumelyErrorBoundary>\r\n </LumelyContextProvider>\r\n );\r\n};\r\n"]}
|