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 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/`. Set up the API by copying the route handlers from the Lumely documentation.
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'),google=require('next/font/google');var f=react.createContext(null),k=()=>{if(typeof window=="undefined")return "server";let o=sessionStorage.getItem("lumely_session_id");if(o)return o;let i=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",i),i},I=()=>{let o=react.useContext(f);if(!o)throw new Error("useLumelyContext must be used within a LumelyProvider");return o},y=({children:o,config:i})=>{let t=react.useMemo(()=>({...i,sessionId:i.sessionId||k(),environment:i.environment||"production"}),[i]);return jsxRuntime.jsx(f.Provider,{value:t,children:o})};var C=google.Poppins({subsets:["latin"],weight:["400","500","600","700"],variable:"--font-poppins"}),p=({aiResponse:o,isLoading:i,feedbackSubmitted:t=false,onSubmitFeedback:r,onRetry:s,onDismiss:a,onGoBack:n})=>{let[d,g]=react.useState(""),[c,x]=react.useState(false),v=async m=>{m.preventDefault(),d.trim()&&!c&&(x(true),r(d));};return jsxRuntime.jsx("div",{className:`${C.className} fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`,children:jsxRuntime.jsxs("div",{className:"relative w-full max-w-md bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl overflow-hidden",children:[jsxRuntime.jsx("button",{onClick:a,className:"absolute top-3 right-3 p-1.5 text-white/60 hover:text-white hover:bg-white/10 rounded-lg transition-colors",children:"\u2715"}),jsxRuntime.jsxs("div",{className:"p-6",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[jsxRuntime.jsx("div",{className:"w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center",children:jsxRuntime.jsx("span",{className:"text-white font-bold text-lg",children:"L"})}),jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("h3",{className:"text-white font-semibold text-sm",children:"Something went wrong"}),jsxRuntime.jsx("p",{className:"text-white/50 text-xs",children:"We're looking into it"})]})]}),i?jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-white/70 text-sm py-4",children:[jsxRuntime.jsx("div",{className:"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin"}),jsxRuntime.jsx("span",{children:"Analyzing the issue..."})]}):o?jsxRuntime.jsx("div",{className:"bg-white/5 border border-white/10 rounded-xl p-4 mb-4",children:jsxRuntime.jsx("p",{className:"text-white/90 text-sm leading-relaxed",children:o.userMessage})}):jsxRuntime.jsx("div",{className:"bg-white/5 border border-white/10 rounded-xl p-4 mb-4",children:jsxRuntime.jsx("p",{className:"text-white/90 text-sm leading-relaxed",children:"We encountered an unexpected issue. Our team has been notified."})}),!t&&!c?jsxRuntime.jsxs("form",{onSubmit:v,className:"mb-4",children:[jsxRuntime.jsx("label",{className:"block text-white/60 text-xs mb-2",children:"What were you trying to do?"}),jsxRuntime.jsxs("div",{className:"relative",children:[jsxRuntime.jsx("input",{type:"text",value:d,onChange:m=>g(m.target.value),placeholder:"e.g., I was trying to save my changes...",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"}),jsxRuntime.jsx("button",{type:"submit",disabled:!d.trim(),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",children:"\u27A4"})]})]}):jsxRuntime.jsx("div",{className:"bg-green-500/10 border border-green-500/20 rounded-xl p-3 mb-4",children:jsxRuntime.jsx("p",{className:"text-green-400 text-xs text-center",children:"Thank you! Your feedback helps us improve."})}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("button",{onClick: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",children:"\u2190 Go Back"}),jsxRuntime.jsx("button",{onClick:s,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",children:"\u21BB Try Again"})]})]})]})})};var u=class extends react.Component{constructor(t){super(t);this.isReporting=false;this.handleSubmitFeedback=async t=>{let{errorId:r}=this.state,{config:s}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify({errorId:r,feedback:t})}),this.setState({feedbackSubmitted:!0});}catch(a){console.error("Lumely: Failed to submit feedback",a),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(t){return {hasError:true,error:t}}componentDidCatch(t,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(t,r));}async reportError(t,r){let{config:s}=this.props,a={errorMessage:t.message,errorStack:t.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:s.userId,sessionId:s.sessionId,timestamp:new Date().toISOString()}};try{let n=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(a)});if(n.ok){let d=await n.json();this.setState({aiResponse:d.ai,errorId:d.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(n){console.error("Lumely: Failed to report error",n),this.setState({isLoading:false});}s.onError&&s.onError(a);}render(){let{hasError:t,aiResponse:r,isLoading:s,feedbackSubmitted:a}=this.state,{children:n}=this.props;return t?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[n,jsxRuntime.jsx(p,{aiResponse:r||void 0,isLoading:s,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):n}};var D=({children:o,apiKey:i,environment:t="production",userId:r,sessionId:s,onError:a})=>{let n={apiKey:i,environment:t,userId:r,sessionId:s,onError:a};return jsxRuntime.jsx(y,{config:n,children:jsxRuntime.jsx(u,{config:n,children:o})})};exports.LumelyErrorBoundary=u;exports.LumelyErrorOverlay=p;exports.LumelyProvider=D;exports.useLumelyContext=I;//# sourceMappingURL=index.js.map
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":"gFAUA,IAAMA,CAAAA,CAAgBC,oBAAyC,IAAI,CAAA,CAG7DC,CAAAA,CAAoB,IAAM,CAC5B,GAAI,OAAO,MAAA,EAAW,WAAA,CAAa,OAAO,QAAA,CAC1C,IAAMC,EAAS,cAAA,CAAe,OAAA,CAAQ,mBAAmB,CAAA,CACzD,GAAIA,CAAAA,CAAQ,OAAOA,CAAAA,CACnB,IAAMC,EAAQ,CAAA,KAAA,EAAQ,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAA,CAAU,EAAG,CAAC,CAAC,GAC9E,OAAA,cAAA,CAAe,OAAA,CAAQ,oBAAqBA,CAAK,CAAA,CAC1CA,CACX,CAAA,CAEaC,CAAAA,CAAmB,IAAM,CAClC,IAAMC,EAAUC,gBAAAA,CAAWP,CAAa,CAAA,CACxC,GAAI,CAACM,CAAAA,CACD,MAAM,IAAI,KAAA,CAAM,uDAAuD,CAAA,CAE3E,OAAOA,CACX,CAAA,CAgBaE,CAAAA,CAAkB,IAAM,CACjC,IAAMF,CAAAA,CAAUC,iBAAWP,CAAa,CAAA,CACxC,GAAI,CAACM,CAAAA,CACD,MAAM,IAAI,KAAA,CAAM,sDAAsD,CAAA,CAE1E,OAAO,CAAE,YAAaA,CAAAA,CAAQ,WAAY,CAC9C,CAAA,CAOaG,CAAAA,CAAwB,CAAC,CAAE,QAAA,CAAAC,EAAU,MAAA,CAAAC,CAAO,IAAkC,CACvF,IAAMC,EAAYC,aAAAA,CAAQ,IAAMF,EAAO,SAAA,EAAaT,CAAAA,EAAkB,CAAG,CAACS,CAAAA,CAAO,SAAS,CAAC,CAAA,CAGrFG,CAAAA,CAAcC,kBAAY,MAAOC,CAAAA,CAAcC,IAAgD,CA7DzG,IAAAC,CAAAA,CA8DQ,IAAMC,CAAAA,CAA4B,CAC9B,aAAcH,CAAAA,CAAM,OAAA,CACpB,WAAYA,CAAAA,CAAM,KAAA,CAClB,QAAS,CACL,GAAA,CAAK,OAAO,MAAA,EAAW,WAAA,CAAc,MAAA,CAAO,SAAS,IAAA,CAAO,QAAA,CAC5D,UAAW,OAAO,SAAA,EAAc,YAAc,SAAA,CAAU,SAAA,CAAY,SACpE,MAAA,CAAQL,CAAAA,CAAO,OACf,SAAA,CAAWC,CAAAA,CACX,UAAW,IAAI,IAAA,GAAO,WAAA,EAAY,CAClC,GAAIK,CAAAA,EAAqB,CAAE,iBAAA,CAAmB,KAAK,SAAA,CAAUA,CAAiB,CAAE,CACpF,CACJ,EAEA,GAAI,CACA,IAAMG,CAAAA,CAAW,MAAM,KAAA,CAAM,2BAA4B,CACrD,MAAA,CAAQ,OACR,OAAA,CAAS,CACL,eAAgB,kBAAA,CAChB,cAAA,CAAgBT,CAAAA,CAAO,MAC3B,CAAA,CACA,IAAA,CAAM,KAAK,SAAA,CAAUQ,CAAM,CAC/B,CAAC,CAAA,CAEIC,EAAS,EAAA,EACV,OAAA,CAAQ,MAAM,kCAAA,CAAoCA,CAAAA,CAAS,UAAU,CAAA,CAAA,CAIzEF,CAAAA,CAAAP,EAAO,OAAA,GAAP,IAAA,EAAAO,EAAA,IAAA,CAAAP,CAAAA,CAAiBQ,CAAAA,EACrB,CAAA,MAASE,CAAAA,CAAG,CACR,QAAQ,KAAA,CAAM,kCAAA,CAAoCA,CAAC,EACvD,CACJ,EAAG,CAACV,CAAAA,CAAQC,CAAS,CAAC,CAAA,CAGtBU,eAAAA,CAAU,IAAM,CACZ,GAAI,OAAO,MAAA,EAAW,WAAA,CAAa,OAGnC,IAAMC,CAAAA,CAA4BC,CAAAA,EAAiC,CAC/D,IAAMR,CAAAA,CAAQQ,EAAM,MAAA,YAAkB,KAAA,CAChCA,EAAM,MAAA,CACN,IAAI,MAAM,MAAA,CAAOA,CAAAA,CAAM,MAAM,CAAC,CAAA,CACpCV,EAAYE,CAAAA,CAAO,CAAE,KAAM,oBAAqB,CAAC,EACrD,CAAA,CAGMS,CAAAA,CAAqBD,CAAAA,EAAsB,CAC7C,IAAMR,CAAAA,CAAQQ,EAAM,KAAA,YAAiB,KAAA,CAC/BA,EAAM,KAAA,CACN,IAAI,MAAMA,CAAAA,CAAM,OAAO,CAAA,CAC7BV,CAAAA,CAAYE,CAAAA,CAAO,CACf,KAAM,aAAA,CACN,QAAA,CAAUQ,EAAM,QAAA,CAChB,MAAA,CAAQA,EAAM,MAAA,CACd,KAAA,CAAOA,CAAAA,CAAM,KACjB,CAAC,EACL,EAEA,OAAA,MAAA,CAAO,gBAAA,CAAiB,qBAAsBD,CAAwB,CAAA,CACtE,OAAO,gBAAA,CAAiB,OAAA,CAASE,CAAiB,CAAA,CAE3C,IAAM,CACT,MAAA,CAAO,mBAAA,CAAoB,qBAAsBF,CAAwB,CAAA,CACzE,OAAO,mBAAA,CAAoB,OAAA,CAASE,CAAiB,EACzD,CACJ,CAAA,CAAG,CAACX,CAAW,CAAC,EAEhB,IAAMY,CAAAA,CAAQb,cAAQ,KAAO,CACzB,GAAGF,CAAAA,CACH,SAAA,CAAAC,CAAAA,CACA,YAAaD,CAAAA,CAAO,WAAA,EAAe,aACnC,WAAA,CAAAG,CACJ,GAAI,CAACH,CAAAA,CAAQC,CAAAA,CAAWE,CAAW,CAAC,CAAA,CAEpC,OACIa,cAAAA,CAAC3B,CAAAA,CAAc,SAAd,CAAuB,KAAA,CAAO0B,EAC1B,QAAA,CAAAhB,CAAAA,CACL,CAER,ECxIA,IAAMkB,CAAAA,CAAe,IAAM,CAEvB,GADI,OAAO,QAAA,EAAa,WAAA,EACpB,QAAA,CAAS,cAAA,CAAe,oBAAoB,CAAA,CAAG,OAEnD,IAAMC,CAAAA,CAAQ,SAAS,aAAA,CAAc,OAAO,EAC5CA,CAAAA,CAAM,EAAA,CAAK,oBAAA,CACXA,CAAAA,CAAM,WAAA,CAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA,CAOpB,SAAS,IAAA,CAAK,WAAA,CAAYA,CAAK,EACnC,EAGMC,CAAAA,CAAQ,IACVC,eAAAA,CAAC,KAAA,CAAA,CAAI,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,YAAY,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,cAAA,CAAe,YAAY,GAAA,CAAI,aAAA,CAAc,OAAA,CAAQ,cAAA,CAAe,QACnI,QAAA,CAAA,CAAAJ,cAAAA,CAAC,MAAA,CAAA,CAAK,EAAA,CAAG,KAAK,EAAA,CAAG,GAAA,CAAI,EAAA,CAAG,GAAA,CAAI,GAAG,IAAA,CAAK,CAAA,CACpCA,cAAAA,CAAC,MAAA,CAAA,CAAK,GAAG,GAAA,CAAI,EAAA,CAAG,GAAA,CAAI,EAAA,CAAG,KAAK,EAAA,CAAG,IAAA,CAAK,CAAA,CAAA,CACxC,CAAA,CAGEK,EAAW,IACbD,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAM,KAAK,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,KAAK,MAAA,CAAO,MAAA,CAAO,cAAA,CAAe,WAAA,CAAY,IAAI,aAAA,CAAc,OAAA,CAAQ,cAAA,CAAe,OAAA,CACnI,UAAAJ,cAAAA,CAAC,MAAA,CAAA,CAAK,EAAA,CAAG,IAAA,CAAK,GAAG,GAAA,CAAI,EAAA,CAAG,IAAA,CAAK,EAAA,CAAG,KAAK,CAAA,CACrCA,cAAAA,CAAC,SAAA,CAAA,CAAQ,MAAA,CAAO,4BAA4B,CAAA,CAAA,CAChD,CAAA,CAGEM,CAAAA,CAAgB,IAClBF,gBAAC,KAAA,CAAA,CAAI,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,KAAK,OAAA,CAAQ,WAAA,CAAY,IAAA,CAAK,MAAA,CAAO,OAAO,cAAA,CAAe,WAAA,CAAY,GAAA,CAAI,aAAA,CAAc,QAAQ,cAAA,CAAe,OAAA,CACnI,QAAA,CAAA,CAAAJ,cAAAA,CAAC,QAAK,EAAA,CAAG,IAAA,CAAK,EAAA,CAAG,IAAA,CAAK,GAAG,GAAA,CAAI,EAAA,CAAG,IAAA,CAAK,CAAA,CACrCA,eAAC,UAAA,CAAA,CAAS,MAAA,CAAO,iBAAA,CAAkB,CAAA,CAAA,CACvC,EAGEO,CAAAA,CAAgB,IAClBH,eAAAA,CAAC,KAAA,CAAA,CAAI,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,YAAY,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,cAAA,CAAe,YAAY,GAAA,CAAI,aAAA,CAAc,OAAA,CAAQ,cAAA,CAAe,QACnI,QAAA,CAAA,CAAAJ,cAAAA,CAAC,UAAA,CAAA,CAAS,MAAA,CAAO,mBAAmB,CAAA,CACpCA,cAAAA,CAAC,UAAA,CAAA,CAAS,MAAA,CAAO,iBAAiB,CAAA,CAClCA,cAAAA,CAAC,MAAA,CAAA,CAAK,CAAA,CAAE,uEAAuE,CAAA,CAAA,CACnF,CAAA,CAGEQ,CAAAA,CAA8C,CAChD,QAAS,CACL,QAAA,CAAU,OAAA,CACV,KAAA,CAAO,EACP,MAAA,CAAQ,IAAA,CACR,OAAA,CAAS,MAAA,CACT,WAAY,QAAA,CACZ,cAAA,CAAgB,QAAA,CAChB,OAAA,CAAS,OACT,eAAA,CAAiB,oBAAA,CACjB,cAAA,CAAgB,WAAA,CAChB,WAAY,8EAChB,CAAA,CACA,IAAA,CAAM,CACF,SAAU,UAAA,CACV,KAAA,CAAO,MAAA,CACP,QAAA,CAAU,QACV,UAAA,CAAY,0BAAA,CACZ,cAAA,CAAgB,YAAA,CAChB,OAAQ,oCAAA,CACR,YAAA,CAAc,MAAA,CACd,QAAA,CAAU,QACd,CAAA,CACA,WAAA,CAAa,CACT,QAAA,CAAU,WACV,GAAA,CAAK,MAAA,CACL,KAAA,CAAO,MAAA,CACP,QAAS,KAAA,CACT,KAAA,CAAO,0BAAA,CACP,UAAA,CAAY,cACZ,MAAA,CAAQ,MAAA,CACR,YAAA,CAAc,KAAA,CACd,OAAQ,SAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,UAAA,CAAY,UAChB,EACA,OAAA,CAAS,CACL,OAAA,CAAS,MACb,EACA,MAAA,CAAQ,CACJ,OAAA,CAAS,MAAA,CACT,WAAY,QAAA,CACZ,GAAA,CAAK,MAAA,CACL,YAAA,CAAc,MAClB,CAAA,CACA,IAAA,CAAM,CACF,KAAA,CAAO,OACP,MAAA,CAAQ,MAAA,CACR,YAAA,CAAc,MAAA,CACd,WAAY,2CAAA,CACZ,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,KAAA,CAAO,OAAA,CACP,WAAY,GAAA,CACZ,QAAA,CAAU,MACd,CAAA,CACA,MAAO,CACH,KAAA,CAAO,OAAA,CACP,UAAA,CAAY,IACZ,QAAA,CAAU,MAAA,CACV,MAAA,CAAQ,CACZ,EACA,QAAA,CAAU,CACN,KAAA,CAAO,0BAAA,CACP,SAAU,MAAA,CACV,MAAA,CAAQ,CACZ,CAAA,CACA,WAAY,CACR,UAAA,CAAY,2BAAA,CACZ,MAAA,CAAQ,qCACR,YAAA,CAAc,MAAA,CACd,OAAA,CAAS,MAAA,CACT,aAAc,MAClB,CAAA,CACA,OAAA,CAAS,CACL,MAAO,0BAAA,CACP,QAAA,CAAU,OACV,UAAA,CAAY,GAAA,CACZ,OAAQ,CACZ,CAAA,CACA,OAAA,CAAS,CACL,QAAS,MAAA,CACT,UAAA,CAAY,QAAA,CACZ,GAAA,CAAK,MACL,KAAA,CAAO,0BAAA,CACP,QAAA,CAAU,MAAA,CACV,QAAS,QACb,CAAA,CACA,OAAA,CAAS,CACL,MAAO,MAAA,CACP,MAAA,CAAQ,MAAA,CACR,MAAA,CAAQ,qCACR,cAAA,CAAgB,OAAA,CAChB,YAAA,CAAc,KAAA,CACd,UAAW,gCACf,CAAA,CACA,IAAA,CAAM,CACF,aAAc,MAClB,CAAA,CACA,KAAA,CAAO,CACH,QAAS,OAAA,CACT,KAAA,CAAO,0BAAA,CACP,QAAA,CAAU,OACV,YAAA,CAAc,KAClB,CAAA,CACA,YAAA,CAAc,CACV,QAAA,CAAU,UACd,CAAA,CACA,KAAA,CAAO,CACH,KAAA,CAAO,MAAA,CACP,UAAA,CAAY,2BAAA,CACZ,OAAQ,oCAAA,CACR,YAAA,CAAc,MAAA,CACd,OAAA,CAAS,sBACT,KAAA,CAAO,OAAA,CACP,QAAA,CAAU,MAAA,CACV,QAAS,MAAA,CACT,SAAA,CAAW,YAAA,CACX,UAAA,CAAY,mBAChB,CAAA,CACA,YAAA,CAAc,CACV,QAAA,CAAU,WACV,KAAA,CAAO,KAAA,CACP,GAAA,CAAK,KAAA,CACL,UAAW,kBAAA,CACX,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,2BACP,UAAA,CAAY,aAAA,CACZ,MAAA,CAAQ,MAAA,CACR,OAAQ,SAAA,CACR,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,SACZ,cAAA,CAAgB,QAAA,CAChB,UAAA,CAAY,YAChB,EACA,UAAA,CAAY,CACR,UAAA,CAAY,wBAAA,CACZ,OAAQ,kCAAA,CACR,YAAA,CAAc,MAAA,CACd,OAAA,CAAS,OACT,YAAA,CAAc,MAClB,CAAA,CACA,WAAA,CAAa,CACT,KAAA,CAAO,SAAA,CACP,QAAA,CAAU,MAAA,CACV,UAAW,QAAA,CACX,MAAA,CAAQ,CACZ,CAAA,CACA,QAAS,CACL,OAAA,CAAS,MAAA,CACT,GAAA,CAAK,KACT,CAAA,CACA,MAAA,CAAQ,CACJ,IAAA,CAAM,EACN,OAAA,CAAS,MAAA,CACT,UAAA,CAAY,QAAA,CACZ,eAAgB,QAAA,CAChB,GAAA,CAAK,KAAA,CACL,OAAA,CAAS,YACT,YAAA,CAAc,MAAA,CACd,QAAA,CAAU,MAAA,CACV,WAAY,GAAA,CACZ,MAAA,CAAQ,SAAA,CACR,MAAA,CAAQ,OACR,UAAA,CAAY,UAChB,CAAA,CACA,eAAA,CAAiB,CACb,UAAA,CAAY,2BAAA,CACZ,MAAA,CAAQ,oCAAA,CACR,MAAO,0BACX,CAAA,CACA,aAAA,CAAe,CACX,WAAY,SAAA,CACZ,KAAA,CAAO,OACX,CACJ,EAYaC,CAAAA,CAAqB,CAAC,CAC/B,UAAA,CAAAC,EACA,SAAA,CAAAC,CAAAA,CACA,iBAAA,CAAAC,CAAAA,CAAoB,MACpB,gBAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,UAAAC,CAAAA,CACA,QAAA,CAAAC,CACJ,CAAA,GAA+B,CAC3B,GAAM,CAACC,CAAAA,CAAUC,CAAW,EAAIC,cAAAA,CAAS,EAAE,CAAA,CACrC,CAACC,EAAcC,CAAe,CAAA,CAAIF,cAAAA,CAAS,KAAK,EAEtDxB,eAAAA,CAAU,IAAM,CACZM,CAAAA,GACJ,CAAA,CAAG,EAAE,CAAA,CAEL,IAAMqB,CAAAA,CAAgB5B,CAAAA,EAAuB,CACzCA,CAAAA,CAAE,gBAAe,CACbuB,CAAAA,CAAS,IAAA,EAAK,EAAK,CAACG,CAAAA,GACpBC,CAAAA,CAAgB,IAAI,CAAA,CACpBR,EAAiBI,CAAQ,CAAA,EAEjC,CAAA,CAEA,OACIjB,eAAC,KAAA,CAAA,CAAI,KAAA,CAAOQ,CAAAA,CAAO,OAAA,CACf,SAAAJ,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAOI,CAAAA,CAAO,KAEf,QAAA,CAAA,CAAAR,cAAAA,CAAC,QAAA,CAAA,CAAO,KAAA,CAAOQ,EAAO,WAAA,CAAa,OAAA,CAASO,CAAAA,CACxC,QAAA,CAAAf,eAACG,CAAAA,CAAA,EAAM,CAAA,CACX,CAAA,CAEAC,gBAAC,KAAA,CAAA,CAAI,KAAA,CAAOI,CAAAA,CAAO,OAAA,CAEf,UAAAJ,eAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAOI,CAAAA,CAAO,OACf,QAAA,CAAA,CAAAR,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAOQ,EAAO,IAAA,CAAM,QAAA,CAAA,GAAA,CAAC,CAAA,CAC1BJ,eAAAA,CAAC,OACG,QAAA,CAAA,CAAAJ,cAAAA,CAAC,IAAA,CAAA,CAAG,KAAA,CAAOQ,EAAO,KAAA,CAAO,QAAA,CAAA,sBAAA,CAAoB,CAAA,CAC7CR,cAAAA,CAAC,KAAE,KAAA,CAAOQ,CAAAA,CAAO,QAAA,CAAU,QAAA,CAAA,uBAAA,CAAqB,GACpD,CAAA,CAAA,CACJ,CAAA,CAGCG,CAAAA,CACGP,eAAAA,CAAC,OAAI,KAAA,CAAOI,CAAAA,CAAO,OAAA,CACf,QAAA,CAAA,CAAAR,eAAC,KAAA,CAAA,CAAI,KAAA,CAAOQ,EAAO,OAAA,CAAS,CAAA,CAC5BR,eAAC,MAAA,CAAA,CAAK,QAAA,CAAA,wBAAA,CAAsB,CAAA,CAAA,CAChC,CAAA,CACAU,EACAV,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAOQ,CAAAA,CAAO,WACf,QAAA,CAAAR,cAAAA,CAAC,GAAA,CAAA,CAAE,KAAA,CAAOQ,EAAO,OAAA,CAAU,QAAA,CAAAE,CAAAA,CAAW,WAAA,CAAY,EACtD,CAAA,CAEAV,cAAAA,CAAC,KAAA,CAAA,CAAI,KAAA,CAAOQ,EAAO,UAAA,CACf,QAAA,CAAAR,cAAAA,CAAC,GAAA,CAAA,CAAE,MAAOQ,CAAAA,CAAO,OAAA,CAAS,QAAA,CAAA,iEAAA,CAE1B,CAAA,CACJ,EAIH,CAACI,CAAAA,EAAqB,CAACQ,CAAAA,CACpBhB,gBAAC,MAAA,CAAA,CAAK,KAAA,CAAOI,CAAAA,CAAO,IAAA,CAAM,SAAUc,CAAAA,CAChC,QAAA,CAAA,CAAAtB,cAAAA,CAAC,OAAA,CAAA,CAAM,MAAOQ,CAAAA,CAAO,KAAA,CAAO,QAAA,CAAA,6BAAA,CAA2B,CAAA,CACvDJ,gBAAC,KAAA,CAAA,CAAI,KAAA,CAAOI,CAAAA,CAAO,YAAA,CACf,UAAAR,cAAAA,CAAC,OAAA,CAAA,CACG,IAAA,CAAK,MAAA,CACL,MAAOiB,CAAAA,CACP,QAAA,CAAWvB,CAAAA,EAAMwB,CAAAA,CAAYxB,EAAE,MAAA,CAAO,KAAK,CAAA,CAC3C,WAAA,CAAY,2CACZ,KAAA,CAAOc,CAAAA,CAAO,KAAA,CAClB,CAAA,CACAR,eAAC,QAAA,CAAA,CACG,IAAA,CAAK,QAAA,CACL,QAAA,CAAU,CAACiB,CAAAA,CAAS,IAAA,EAAK,CACzB,KAAA,CAAO,CACH,GAAGT,CAAAA,CAAO,YAAA,CACV,OAAA,CAASS,EAAS,IAAA,EAAK,CAAI,CAAA,CAAI,EACnC,EAEA,QAAA,CAAAjB,cAAAA,CAACK,CAAAA,CAAA,EAAS,EACd,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,CAAA,CAEAL,cAAAA,CAAC,OAAI,KAAA,CAAOQ,CAAAA,CAAO,UAAA,CACf,QAAA,CAAAR,eAAC,GAAA,CAAA,CAAE,KAAA,CAAOQ,CAAAA,CAAO,WAAA,CAAa,sDAA0C,CAAA,CAC5E,CAAA,CAIJJ,eAAAA,CAAC,KAAA,CAAA,CAAI,MAAOI,CAAAA,CAAO,OAAA,CACf,QAAA,CAAA,CAAAJ,eAAAA,CAAC,UACG,KAAA,CAAO,CAAE,GAAGI,CAAAA,CAAO,OAAQ,GAAGA,CAAAA,CAAO,eAAgB,CAAA,CACrD,QAASQ,CAAAA,CAET,QAAA,CAAA,CAAAhB,cAAAA,CAACM,CAAAA,CAAA,EAAc,CAAA,CAAE,SAAA,CAAA,CAErB,CAAA,CACAF,eAAAA,CAAC,UACG,KAAA,CAAO,CAAE,GAAGI,CAAAA,CAAO,OAAQ,GAAGA,CAAAA,CAAO,aAAc,CAAA,CACnD,QAASM,CAAAA,CAET,QAAA,CAAA,CAAAd,cAAAA,CAACO,CAAAA,CAAA,EAAc,CAAA,CAAE,WAAA,CAAA,CAErB,CAAA,CAAA,CACJ,CAAA,CAAA,CACJ,GACJ,CAAA,CACJ,CAER,EC5UO,IAAMgB,CAAAA,CAAN,cAAkCC,eAAwB,CAG7D,WAAA,CAAYC,CAAAA,CAAc,CACtB,KAAA,CAAMA,CAAK,CAAA,CAHf,IAAA,CAAQ,WAAA,CAAc,KAAA,CA2EtB,KAAQ,oBAAA,CAAuB,MAAOR,CAAAA,EAAqB,CACvD,GAAM,CAAE,OAAA,CAAAS,CAAQ,CAAA,CAAI,KAAK,KAAA,CACnB,CAAE,MAAA,CAAA1C,CAAO,EAAI,IAAA,CAAK,KAAA,CAExB,GAAI,CAAC0C,GAAWA,CAAAA,GAAY,OAAA,EAAWA,CAAAA,GAAY,UAAA,CAAY,CAE3D,IAAA,CAAK,QAAA,CAAS,CAAE,iBAAA,CAAmB,IAAK,CAAC,CAAA,CACzC,MACJ,CAEA,GAAI,CAEA,MAAM,KAAA,CAAM,6BAAA,CAA+B,CACvC,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACL,eAAgB,kBAAA,CAChB,cAAA,CAAgB1C,CAAAA,CAAO,MAC3B,EACA,IAAA,CAAM,IAAA,CAAK,SAAA,CAAU,CAAE,QAAA0C,CAAAA,CAAS,QAAA,CAAAT,CAAS,CAAC,CAC9C,CAAC,CAAA,CAED,IAAA,CAAK,QAAA,CAAS,CAAE,iBAAA,CAAmB,CAAA,CAAK,CAAC,EAC7C,OAASU,CAAAA,CAAK,CACV,OAAA,CAAQ,KAAA,CAAM,oCAAqCA,CAAG,CAAA,CACtD,IAAA,CAAK,QAAA,CAAS,CAAE,iBAAA,CAAmB,IAAK,CAAC,EAC7C,CACJ,CAAA,CAEA,IAAA,CAAQ,WAAA,CAAc,IAAM,CACxB,IAAA,CAAK,WAAA,CAAc,KAAA,CACnB,IAAA,CAAK,SAAS,CACV,QAAA,CAAU,KAAA,CACV,KAAA,CAAO,KACP,SAAA,CAAW,IAAA,CACX,UAAA,CAAY,IAAA,CACZ,UAAW,KAAA,CACX,OAAA,CAAS,IAAA,CACT,iBAAA,CAAmB,KACvB,CAAC,EACL,CAAA,CAEA,IAAA,CAAQ,cAAgB,IAAM,CAC1B,IAAA,CAAK,WAAA,CAAc,MACnB,IAAA,CAAK,QAAA,CAAS,CACV,QAAA,CAAU,KAAA,CACV,MAAO,IAAA,CACP,SAAA,CAAW,IAAA,CACX,UAAA,CAAY,KACZ,SAAA,CAAW,KAAA,CACX,OAAA,CAAS,IAAA,CACT,kBAAmB,KACvB,CAAC,EACL,CAAA,CAEA,KAAQ,YAAA,CAAe,IAAM,CACrB,OAAO,QAAW,WAAA,EAClB,MAAA,CAAO,OAAA,CAAQ,IAAA,GAEvB,CAAA,CAjII,IAAA,CAAK,KAAA,CAAQ,CACT,SAAU,KAAA,CACV,KAAA,CAAO,IAAA,CACP,SAAA,CAAW,KACX,UAAA,CAAY,IAAA,CACZ,SAAA,CAAW,KAAA,CACX,QAAS,IAAA,CACT,iBAAA,CAAmB,KACvB,EACJ,CAEA,OAAO,wBAAA,CAAyBtC,CAAAA,CAA8B,CAC1D,OAAO,CAAE,QAAA,CAAU,IAAA,CAAM,KAAA,CAAAA,CAAM,CACnC,CAEA,iBAAA,CAAkBA,CAAAA,CAAcuC,EAAsB,CAE9C,IAAA,CAAK,WAAA,GAET,IAAA,CAAK,YAAc,IAAA,CACnB,IAAA,CAAK,QAAA,CAAS,CAAE,UAAAA,CAAAA,CAAW,SAAA,CAAW,IAAK,CAAC,EAC5C,IAAA,CAAK,WAAA,CAAYvC,CAAAA,CAAOuC,CAAS,GACrC,CAEA,MAAc,WAAA,CAAYvC,CAAAA,CAAcuC,EAAsB,CAC1D,GAAM,CAAE,MAAA,CAAA5C,CAAO,CAAA,CAAI,IAAA,CAAK,KAAA,CAElBQ,CAAAA,CAA4B,CAC9B,YAAA,CAAcH,CAAAA,CAAM,OAAA,CACpB,UAAA,CAAYA,EAAM,KAAA,CAClB,cAAA,CAAgBuC,CAAAA,CAAU,cAAA,EAAkB,OAC5C,OAAA,CAAS,CACL,GAAA,CAAK,OAAO,QAAW,WAAA,CAAc,MAAA,CAAO,QAAA,CAAS,IAAA,CAAO,GAC5D,SAAA,CAAW,OAAO,SAAA,EAAc,WAAA,CAAc,UAAU,SAAA,CAAY,EAAA,CACpE,MAAA,CAAQ5C,CAAAA,CAAO,OACf,SAAA,CAAWA,CAAAA,CAAO,SAAA,CAClB,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,WAAA,EAC1B,CACJ,CAAA,CAEA,GAAI,CACA,IAAMS,EAAW,MAAM,KAAA,CAAM,0BAAA,CAA4B,CACrD,OAAQ,MAAA,CACR,OAAA,CAAS,CACL,cAAA,CAAgB,mBAChB,cAAA,CAAgBT,CAAAA,CAAO,MAC3B,CAAA,CACA,KAAM,IAAA,CAAK,SAAA,CAAUQ,CAAM,CAC/B,CAAC,CAAA,CAED,GAAIC,CAAAA,CAAS,EAAA,CAAI,CACb,IAAMoC,CAAAA,CAA0B,MAAMpC,CAAAA,CAAS,MAAK,CACpD,IAAA,CAAK,QAAA,CAAS,CACV,WAAYoC,CAAAA,CAAK,EAAA,CACjB,OAAA,CAASA,CAAAA,CAAK,QACd,SAAA,CAAW,CAAA,CACf,CAAC,EACL,MACI,IAAA,CAAK,QAAA,CAAS,CAAE,SAAA,CAAW,EAAM,CAAC,EAE1C,CAAA,MAASF,CAAAA,CAAK,CACV,OAAA,CAAQ,KAAA,CAAM,gCAAA,CAAkCA,CAAG,EACnD,IAAA,CAAK,QAAA,CAAS,CAAE,SAAA,CAAW,KAAM,CAAC,EACtC,CAGI3C,CAAAA,CAAO,SACPA,CAAAA,CAAO,OAAA,CAAQQ,CAAM,EAE7B,CA8DA,MAAA,EAAS,CACL,GAAM,CAAE,SAAAsC,CAAAA,CAAU,UAAA,CAAApB,CAAAA,CAAY,SAAA,CAAAC,EAAW,iBAAA,CAAAC,CAAkB,CAAA,CAAI,IAAA,CAAK,MAC9D,CAAE,QAAA,CAAA7B,CAAS,CAAA,CAAI,KAAK,KAAA,CAE1B,OAAI+C,CAAAA,CAEI1B,eAAAA,CAAA2B,oBAAA,CACK,QAAA,CAAA,CAAAhD,CAAAA,CACDiB,cAAAA,CAACS,EAAA,CACG,UAAA,CAAYC,CAAAA,EAAc,MAAA,CAC1B,UAAWC,CAAAA,CACX,iBAAA,CAAmBC,CAAAA,CACnB,gBAAA,CAAkB,KAAK,oBAAA,CACvB,OAAA,CAAS,IAAA,CAAK,WAAA,CACd,UAAW,IAAA,CAAK,aAAA,CAChB,QAAA,CAAU,IAAA,CAAK,aACnB,CAAA,CAAA,CACJ,CAAA,CAID7B,CACX,CACJ,ECpKO,IAAMiD,EAAiB,CAAC,CAC3B,QAAA,CAAAjD,CAAAA,CACA,OAAAkD,CAAAA,CACA,WAAA,CAAAC,CAAAA,CAAc,YAAA,CACd,OAAAC,CAAAA,CACA,SAAA,CAAAlD,CAAAA,CACA,OAAA,CAAAmD,CACJ,CAAA,GAA2B,CACvB,IAAMpD,CAAAA,CAAuB,CACzB,MAAA,CAAAiD,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,OAAAC,CAAAA,CACA,SAAA,CAAAlD,CAAAA,CACA,OAAA,CAAAmD,CACJ,CAAA,CAEA,OACIpC,cAAAA,CAAClB,CAAAA,CAAA,CAAsB,MAAA,CAAQE,CAAAA,CAC3B,QAAA,CAAAgB,cAAAA,CAACuB,EAAA,CAAoB,MAAA,CAAQvC,EACxB,QAAA,CAAAD,CAAAA,CACL,EACJ,CAER","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';import {Poppins}from'next/font/google';var f=createContext(null),k=()=>{if(typeof window=="undefined")return "server";let o=sessionStorage.getItem("lumely_session_id");if(o)return o;let i=`sess_${Date.now()}_${Math.random().toString(36).substring(2,9)}`;return sessionStorage.setItem("lumely_session_id",i),i},I=()=>{let o=useContext(f);if(!o)throw new Error("useLumelyContext must be used within a LumelyProvider");return o},y=({children:o,config:i})=>{let t=useMemo(()=>({...i,sessionId:i.sessionId||k(),environment:i.environment||"production"}),[i]);return jsx(f.Provider,{value:t,children:o})};var C=Poppins({subsets:["latin"],weight:["400","500","600","700"],variable:"--font-poppins"}),p=({aiResponse:o,isLoading:i,feedbackSubmitted:t=false,onSubmitFeedback:r,onRetry:s,onDismiss:a,onGoBack:n})=>{let[d,g]=useState(""),[c,x]=useState(false),v=async m=>{m.preventDefault(),d.trim()&&!c&&(x(true),r(d));};return jsx("div",{className:`${C.className} fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm`,children:jsxs("div",{className:"relative w-full max-w-md bg-white/10 backdrop-blur-xl border border-white/20 rounded-2xl overflow-hidden",children:[jsx("button",{onClick:a,className:"absolute top-3 right-3 p-1.5 text-white/60 hover:text-white hover:bg-white/10 rounded-lg transition-colors",children:"\u2715"}),jsxs("div",{className:"p-6",children:[jsxs("div",{className:"flex items-center gap-3 mb-4",children:[jsx("div",{className:"w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center",children:jsx("span",{className:"text-white font-bold text-lg",children:"L"})}),jsxs("div",{children:[jsx("h3",{className:"text-white font-semibold text-sm",children:"Something went wrong"}),jsx("p",{className:"text-white/50 text-xs",children:"We're looking into it"})]})]}),i?jsxs("div",{className:"flex items-center gap-2 text-white/70 text-sm py-4",children:[jsx("div",{className:"w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin"}),jsx("span",{children:"Analyzing the issue..."})]}):o?jsx("div",{className:"bg-white/5 border border-white/10 rounded-xl p-4 mb-4",children:jsx("p",{className:"text-white/90 text-sm leading-relaxed",children:o.userMessage})}):jsx("div",{className:"bg-white/5 border border-white/10 rounded-xl p-4 mb-4",children:jsx("p",{className:"text-white/90 text-sm leading-relaxed",children:"We encountered an unexpected issue. Our team has been notified."})}),!t&&!c?jsxs("form",{onSubmit:v,className:"mb-4",children:[jsx("label",{className:"block text-white/60 text-xs mb-2",children:"What were you trying to do?"}),jsxs("div",{className:"relative",children:[jsx("input",{type:"text",value:d,onChange:m=>g(m.target.value),placeholder:"e.g., I was trying to save my changes...",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"}),jsx("button",{type:"submit",disabled:!d.trim(),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",children:"\u27A4"})]})]}):jsx("div",{className:"bg-green-500/10 border border-green-500/20 rounded-xl p-3 mb-4",children:jsx("p",{className:"text-green-400 text-xs text-center",children:"Thank you! Your feedback helps us improve."})}),jsxs("div",{className:"flex items-center gap-2",children:[jsx("button",{onClick: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",children:"\u2190 Go Back"}),jsx("button",{onClick:s,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",children:"\u21BB Try Again"})]})]})]})})};var u=class extends Component{constructor(t){super(t);this.isReporting=false;this.handleSubmitFeedback=async t=>{let{errorId:r}=this.state,{config:s}=this.props;if(!r||r==="no-db"||r==="db-error"){this.setState({feedbackSubmitted:true});return}try{await fetch("/api/lumely/update-feedback",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify({errorId:r,feedback:t})}),this.setState({feedbackSubmitted:!0});}catch(a){console.error("Lumely: Failed to submit feedback",a),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(t){return {hasError:true,error:t}}componentDidCatch(t,r){this.isReporting||(this.isReporting=true,this.setState({errorInfo:r,isLoading:true}),this.reportError(t,r));}async reportError(t,r){let{config:s}=this.props,a={errorMessage:t.message,errorStack:t.stack,componentStack:r.componentStack||void 0,context:{url:typeof window!="undefined"?window.location.href:"",userAgent:typeof navigator!="undefined"?navigator.userAgent:"",userId:s.userId,sessionId:s.sessionId,timestamp:new Date().toISOString()}};try{let n=await fetch("/api/lumely/report-error",{method:"POST",headers:{"Content-Type":"application/json","X-Lumely-Key":s.apiKey},body:JSON.stringify(a)});if(n.ok){let d=await n.json();this.setState({aiResponse:d.ai,errorId:d.errorId,isLoading:!1});}else this.setState({isLoading:!1});}catch(n){console.error("Lumely: Failed to report error",n),this.setState({isLoading:false});}s.onError&&s.onError(a);}render(){let{hasError:t,aiResponse:r,isLoading:s,feedbackSubmitted:a}=this.state,{children:n}=this.props;return t?jsxs(Fragment,{children:[n,jsx(p,{aiResponse:r||void 0,isLoading:s,feedbackSubmitted:a,onSubmitFeedback:this.handleSubmitFeedback,onRetry:this.handleRetry,onDismiss:this.handleDismiss,onGoBack:this.handleGoBack})]}):n}};var D=({children:o,apiKey:i,environment:t="production",userId:r,sessionId:s,onError:a})=>{let n={apiKey:i,environment:t,userId:r,sessionId:s,onError:a};return jsx(y,{config:n,children:jsx(u,{config:n,children:o})})};export{u as LumelyErrorBoundary,p as LumelyErrorOverlay,D as LumelyProvider,I as useLumelyContext};//# sourceMappingURL=index.mjs.map
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
@@ -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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumely-next",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "AI-powered error handling for Next.js applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",