react-logger-app 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var U=require('react'),idb=require('idb'),jsxRuntime=require('react/jsx-runtime'),reactVirtuoso=require('react-virtuoso');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var U__default=/*#__PURE__*/_interopDefault(U);function C(e,{insertAt:t}={}){if(typeof document>"u")return;let o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css",t==="top"&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e));}C(`:root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;z-index:100000;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none}}
2
- `);var w=class{key;constructor(t="ionic_react_logger_logs"){this.key=t;}async save(t){try{localStorage.setItem(this.key,JSON.stringify(t));}catch(o){console.error("Failed to save logs to localStorage",o);}}async load(){try{let t=localStorage.getItem(this.key);return t?JSON.parse(t):[]}catch(t){return console.error("Failed to load logs from localStorage",t),[]}}async clear(){localStorage.removeItem(this.key);}};var G="IonicReactLoggerDB",v="logs",F=1,E=class{dbPromise;constructor(){this.dbPromise=idb.openDB(G,F,{upgrade(t){t.objectStoreNames.contains(v)||t.createObjectStore(v,{keyPath:"id"});}});}async save(t){let r=(await this.dbPromise).transaction(v,"readwrite"),i=r.objectStore(v);await i.clear();for(let s of t)await i.put(s);await r.done;}async load(){return (await this.dbPromise).getAll(v)}async clear(){let o=(await this.dbPromise).transaction(v,"readwrite");await o.objectStore(v).clear(),await o.done;}};function R(e){return e==="indexedDB"?new E:new w}var p=class{static dispatch=null;static logBuffer=[];static onLogAddedCallback;static _setDispatcher(t,o){this.dispatch=t,this.onLogAddedCallback=o,this.logBuffer.length>0&&(this.logBuffer.forEach(r=>{this.dispatch({type:"ADD_LOG",log:r}),this.onLogAddedCallback?.(r);}),this.logBuffer=[]);}static createLog(t,o,r){return {id:Math.random().toString(36).substring(2,9),level:t,message:o,timestamp:new Date().toISOString(),...r}}static addLog(t){this.dispatch?(this.dispatch({type:"ADD_LOG",log:t}),this.onLogAddedCallback?.(t)):this.logBuffer.push(t);}static debug(t,o){this.addLog(this.createLog("DEBUG",t,{title:o}));}static error(t,o){let r=t instanceof Error?t.message:t,i=t instanceof Error?t.stack:void 0;this.addLog(this.createLog("ERROR",r,{title:o||"Error",stack:i}));}static object(t,o){this.addLog(this.createLog("OBJECT","Object visualization",{title:o||"Data Object",data:t}));}static clear(){this.dispatch?this.dispatch({type:"CLEAR_LOGS"}):this.logBuffer=[];}};var k={logs:[],config:{persistence:false,persistenceDriver:"localStorage",maxLogs:500},unreadCount:0};function X(e,t){switch(t.type){case "ADD_LOG":{let o=[t.log,...e.logs].slice(0,e.config.maxLogs);return {...e,logs:o}}case "SET_LOGS":return {...e,logs:[...e.logs,...t.logs].slice(0,e.config.maxLogs)};case "CLEAR_LOGS":return {...e,logs:[],unreadCount:0};case "SET_CONFIG":return {...e,config:{...e.config,...t.config}};case "RESET_UNREAD":return {...e,unreadCount:0};case "INCREMENT_UNREAD":return {...e,unreadCount:e.unreadCount+1};default:return e}}var N=U.createContext(void 0),ve=({children:e,config:t})=>{let[o,r]=U.useReducer(X,{...k,config:{...k.config,...t}}),[i,s]=U__default.default.useState(false),a=U.useRef(null);return U.useEffect(()=>{p._setDispatcher(r,o.config.onLogAdded),o.config.persistence&&(a.current=R(o.config.persistenceDriver||"localStorage"),a.current.load().then(n=>{r({type:"SET_LOGS",logs:n});}));},[o.config.persistence,o.config.persistenceDriver]),U.useEffect(()=>{o.config.persistence&&a.current&&a.current.save(o.logs);},[o.logs,o.config.persistence]),jsxRuntime.jsx(N.Provider,{value:{state:o,dispatch:r,isPanelOpen:i,setIsPanelOpen:s},children:e})},u=()=>{let e=U.useContext(N);if(!e)throw new Error("useLoggerContext must be used within a LoggerProvider");return e};var Ce=()=>{let{state:e}=u(),t=U.useCallback((a,n)=>{p.debug(a,n);},[]),o=U.useCallback((a,n)=>{p.error(a,n);},[]),r=U.useCallback((a,n)=>{p.object(a,n);},[]),i=U.useCallback(()=>{p.clear();},[]),s=U.useCallback(()=>{let a="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),n=document.createElement("a");n.setAttribute("href",a),n.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(n),n.click(),n.remove();},[e.logs]);return {debug:t,error:o,object:r,clear:i,exportLogs:s,logs:e.logs,unreadCount:e.unreadCount}};var T=()=>{let{state:e,setIsPanelOpen:t}=u(),[o,r]=U.useState(null),i=U.useRef(false),s=U.useRef({x:0,y:0}),a=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true,s.current={x:l.clientX-c.left,y:l.clientY-c.top};},n=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true;let g=l.touches[0];s.current={x:g.clientX-c.left,y:g.clientY-c.top};},m=U.useCallback((l,c)=>{if(!i.current)return;let g=Math.max(10,Math.min(window.innerWidth-60,l-s.current.x)),h=Math.max(10,Math.min(window.innerHeight-60,c-s.current.y));r({x:g,y:h});},[]);U.useEffect(()=>{let l=h=>m(h.clientX,h.clientY),c=h=>m(h.touches[0].clientX,h.touches[0].clientY),g=()=>{i.current=false;};return window.addEventListener("mousemove",l),window.addEventListener("touchmove",c,{passive:false}),window.addEventListener("mouseup",g),window.addEventListener("touchend",g),()=>{window.removeEventListener("mousemove",l),window.removeEventListener("touchmove",c),window.removeEventListener("mouseup",g),window.removeEventListener("touchend",g);}},[m]),U.useEffect(()=>{let l=()=>{o&&r(c=>c?{x:Math.min(c.x,window.innerWidth-60),y:Math.min(c.y,window.innerHeight-60)}:null);};return window.addEventListener("resize",l),()=>window.removeEventListener("resize",l)},[o]);let x=()=>{i.current||t(true);},b=o?{left:`${o.x}px`,top:`${o.y}px`,right:"auto",bottom:"auto"}:{};return jsxRuntime.jsx("div",{className:"liql-floatingButton",style:b,onMouseDown:a,onTouchStart:n,onClick:x,"aria-label":"Open Logger",children:e.unreadCount>0&&jsxRuntime.jsx("div",{className:"liql-badge",children:e.unreadCount})})};var B=({log:e})=>{let[t,o]=U.useState(false),r=n=>new Date(n).toTimeString().split(" ")[0],i=n=>{try{return jsxRuntime.jsx("pre",{className:"liql-expandedContent",children:JSON.stringify(n,null,2)})}catch{return jsxRuntime.jsx("div",{children:"Error parsing object"})}},s=n=>{switch(n){case "DEBUG":return "\u{1F41E}";case "ERROR":return "\u274C";case "OBJECT":return "\u{1F4E6}";default:return "\u{1F4DD}"}},a=e.level.toLowerCase();return jsxRuntime.jsxs("div",{className:`liql-logItem liql-logItem-${a}`,onClick:()=>o(!t),children:[jsxRuntime.jsxs("div",{className:"liql-logMeta",children:[jsxRuntime.jsxs("span",{className:`liql-statusTag liql-tag-${a}`,children:[s(e.level)," ",e.level]}),jsxRuntime.jsx("span",{className:"liql-logTime",children:r(e.timestamp)})]}),jsxRuntime.jsxs("div",{className:"liql-logContent",children:[e.title&&jsxRuntime.jsxs("strong",{style:{color:"var(--liql-primary)"},children:[e.title,": "]}),e.message]}),t&&jsxRuntime.jsxs("div",{className:"liql-expandedContent",children:[e.stack&&jsxRuntime.jsxs("div",{style:{color:"var(--liql-error)",marginBottom:"8px"},children:[jsxRuntime.jsx("strong",{children:"Stack Trace:"}),jsxRuntime.jsx("pre",{style:{whiteSpace:"pre-wrap",fontSize:"10px",marginTop:"4px"},children:e.stack})]}),e.data&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("strong",{children:"Payload:"}),i(e.data)]}),!e.data&&!e.stack&&jsxRuntime.jsxs("div",{children:["Full message: ",e.message]})]})]})};var P=({logs:e,filter:t,search:o})=>{let r=U__default.default.useMemo(()=>e.filter(i=>{let s=t==="ALL"||i.level===t,a=o===""||i.message.toLowerCase().includes(o.toLowerCase())||(i.title||"").toLowerCase().includes(o.toLowerCase());return s&&a}).reverse(),[e,t,o]);return jsxRuntime.jsx("div",{className:"liql-logListContainer",children:jsxRuntime.jsx(reactVirtuoso.Virtuoso,{style:{height:"100%"},data:r,itemContent:(i,s)=>jsxRuntime.jsx(B,{log:s},s.id)})})};var M=()=>{let{state:e,setIsPanelOpen:t,dispatch:o}=u(),[r,i]=U.useState("ALL"),[s,a]=U.useState(""),n=()=>{confirm("Are you sure you want to clear all logs?")&&o({type:"CLEAR_LOGS"});},m=()=>{let x="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),b=document.createElement("a");b.setAttribute("href",x),b.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(b),b.click(),b.remove();};return e?jsxRuntime.jsxs("div",{className:"liql-panel",style:{right:"20px",bottom:"20px",width:"440px",height:"680px"},children:[jsxRuntime.jsxs("div",{className:"liql-panelHeader",children:[jsxRuntime.jsx("div",{className:"liql-titleGroup",children:jsxRuntime.jsxs("span",{className:"liql-title",children:["ReactLoggerApp console [",e.logs.length,"]"]})}),jsxRuntime.jsxs("div",{className:"liql-controls",children:[jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:m,title:"Export JSON",children:"\u{1F4E5}"}),jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:n,title:"Clear Logs",children:"\u{1F5D1}\uFE0F"}),jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:()=>t(false),title:"Minimize",children:"\u2796"})]})]}),jsxRuntime.jsxs("div",{className:"liql-filterBar",children:[jsxRuntime.jsx("input",{type:"text",placeholder:"Search entries...",className:"liql-searchInput",value:s,onChange:x=>a(x.target.value)}),jsxRuntime.jsxs("select",{className:"liql-selectFilter",value:r,onChange:x=>i(x.target.value),children:[jsxRuntime.jsx("option",{value:"ALL",children:"ALL"}),jsxRuntime.jsx("option",{value:"DEBUG",children:"DEBUG"}),jsxRuntime.jsx("option",{value:"ERROR",children:"ERROR"}),jsxRuntime.jsx("option",{value:"OBJECT",children:"OBJECTS"})]})]}),jsxRuntime.jsx(P,{logs:e.logs,filter:r,search:s}),jsxRuntime.jsxs("div",{className:"liql-footerActions",children:[jsxRuntime.jsx("div",{className:"liql-storageInfo",children:e.config.persistence?`DRIVER: ${e.config.persistenceDriver?.toUpperCase()}`:"SESSION MODE"}),jsxRuntime.jsx("button",{className:"liql-btnClose",onClick:()=>t(false),children:"CLOSE CONSOLE"})]})]}):null};var We=()=>{let{isPanelOpen:e}=u();return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!e&&jsxRuntime.jsx(T,{}),e&&jsxRuntime.jsx(M,{})]})};exports.Logger=p;exports.LoggerProvider=ve;exports.LoggerViewer=We;exports.useLogger=Ce;exports.useLoggerContext=u;//# sourceMappingURL=index.js.map
1
+ 'use strict';var U=require('react'),idb=require('idb'),jsxRuntime=require('react/jsx-runtime'),reactVirtuoso=require('react-virtuoso');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var U__default=/*#__PURE__*/_interopDefault(U);function C(e,{insertAt:t}={}){if(typeof document>"u")return;let o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css",t==="top"&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e));}C(`:root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;width:440px;height:680px;right:20px;bottom:20px;z-index:999999;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none;background:#0f172a!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}}
2
+ `);var w=class{key;constructor(t="ionic_react_logger_logs"){this.key=t;}async save(t){try{localStorage.setItem(this.key,JSON.stringify(t));}catch(o){console.error("Failed to save logs to localStorage",o);}}async load(){try{let t=localStorage.getItem(this.key);return t?JSON.parse(t):[]}catch(t){return console.error("Failed to load logs from localStorage",t),[]}}async clear(){localStorage.removeItem(this.key);}};var G="IonicReactLoggerDB",v="logs",F=1,E=class{dbPromise;constructor(){this.dbPromise=idb.openDB(G,F,{upgrade(t){t.objectStoreNames.contains(v)||t.createObjectStore(v,{keyPath:"id"});}});}async save(t){let r=(await this.dbPromise).transaction(v,"readwrite"),i=r.objectStore(v);await i.clear();for(let s of t)await i.put(s);await r.done;}async load(){return (await this.dbPromise).getAll(v)}async clear(){let o=(await this.dbPromise).transaction(v,"readwrite");await o.objectStore(v).clear(),await o.done;}};function k(e){return e==="indexedDB"?new E:new w}var p=class{static dispatch=null;static logBuffer=[];static onLogAddedCallback;static _setDispatcher(t,o){this.dispatch=t,this.onLogAddedCallback=o,this.logBuffer.length>0&&(this.logBuffer.forEach(r=>{this.dispatch({type:"ADD_LOG",log:r}),this.onLogAddedCallback?.(r);}),this.logBuffer=[]);}static createLog(t,o,r){return {id:Math.random().toString(36).substring(2,9),level:t,message:o,timestamp:new Date().toISOString(),...r}}static addLog(t){this.dispatch?(this.dispatch({type:"ADD_LOG",log:t}),this.onLogAddedCallback?.(t)):this.logBuffer.push(t);}static debug(t,o){this.addLog(this.createLog("DEBUG",t,{title:o}));}static error(t,o){let r=t instanceof Error?t.message:t,i=t instanceof Error?t.stack:void 0;this.addLog(this.createLog("ERROR",r,{title:o||"Error",stack:i}));}static object(t,o){this.addLog(this.createLog("OBJECT","Object visualization",{title:o||"Data Object",data:t}));}static clear(){this.dispatch?this.dispatch({type:"CLEAR_LOGS"}):this.logBuffer=[];}};var D={logs:[],config:{persistence:false,persistenceDriver:"localStorage",maxLogs:500},unreadCount:0};function X(e,t){switch(t.type){case "ADD_LOG":{let o=[t.log,...e.logs].slice(0,e.config.maxLogs);return {...e,logs:o}}case "SET_LOGS":return {...e,logs:[...e.logs,...t.logs].slice(0,e.config.maxLogs)};case "CLEAR_LOGS":return {...e,logs:[],unreadCount:0};case "SET_CONFIG":return {...e,config:{...e.config,...t.config}};case "RESET_UNREAD":return {...e,unreadCount:0};case "INCREMENT_UNREAD":return {...e,unreadCount:e.unreadCount+1};default:return e}}var N=U.createContext(void 0),ve=({children:e,config:t})=>{let[o,r]=U.useReducer(X,{...D,config:{...D.config,...t}}),[i,s]=U__default.default.useState(false),a=U.useRef(null);return U.useEffect(()=>{p._setDispatcher(r,o.config.onLogAdded),o.config.persistence&&(a.current=k(o.config.persistenceDriver||"localStorage"),a.current.load().then(n=>{r({type:"SET_LOGS",logs:n});}));},[o.config.persistence,o.config.persistenceDriver]),U.useEffect(()=>{o.config.persistence&&a.current&&a.current.save(o.logs);},[o.logs,o.config.persistence]),jsxRuntime.jsx(N.Provider,{value:{state:o,dispatch:r,isPanelOpen:i,setIsPanelOpen:s},children:e})},u=()=>{let e=U.useContext(N);if(!e)throw new Error("useLoggerContext must be used within a LoggerProvider");return e};var Ce=()=>{let{state:e}=u(),t=U.useCallback((a,n)=>{p.debug(a,n);},[]),o=U.useCallback((a,n)=>{p.error(a,n);},[]),r=U.useCallback((a,n)=>{p.object(a,n);},[]),i=U.useCallback(()=>{p.clear();},[]),s=U.useCallback(()=>{let a="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),n=document.createElement("a");n.setAttribute("href",a),n.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(n),n.click(),n.remove();},[e.logs]);return {debug:t,error:o,object:r,clear:i,exportLogs:s,logs:e.logs,unreadCount:e.unreadCount}};var T=()=>{let{state:e,setIsPanelOpen:t}=u(),[o,r]=U.useState(null),i=U.useRef(false),s=U.useRef({x:0,y:0}),a=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true,s.current={x:l.clientX-c.left,y:l.clientY-c.top};},n=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true;let g=l.touches[0];s.current={x:g.clientX-c.left,y:g.clientY-c.top};},m=U.useCallback((l,c)=>{if(!i.current)return;let g=Math.max(10,Math.min(window.innerWidth-60,l-s.current.x)),h=Math.max(10,Math.min(window.innerHeight-60,c-s.current.y));r({x:g,y:h});},[]);U.useEffect(()=>{let l=h=>m(h.clientX,h.clientY),c=h=>m(h.touches[0].clientX,h.touches[0].clientY),g=()=>{i.current=false;};return window.addEventListener("mousemove",l),window.addEventListener("touchmove",c,{passive:false}),window.addEventListener("mouseup",g),window.addEventListener("touchend",g),()=>{window.removeEventListener("mousemove",l),window.removeEventListener("touchmove",c),window.removeEventListener("mouseup",g),window.removeEventListener("touchend",g);}},[m]),U.useEffect(()=>{let l=()=>{o&&r(c=>c?{x:Math.min(c.x,window.innerWidth-60),y:Math.min(c.y,window.innerHeight-60)}:null);};return window.addEventListener("resize",l),()=>window.removeEventListener("resize",l)},[o]);let x=()=>{i.current||t(true);},b=o?{left:`${o.x}px`,top:`${o.y}px`,right:"auto",bottom:"auto"}:{};return jsxRuntime.jsx("div",{className:"liql-floatingButton",style:b,onMouseDown:a,onTouchStart:n,onClick:x,"aria-label":"Open Logger",children:e.unreadCount>0&&jsxRuntime.jsx("div",{className:"liql-badge",children:e.unreadCount})})};var B=({log:e})=>{let[t,o]=U.useState(false),r=n=>new Date(n).toTimeString().split(" ")[0],i=n=>{try{return jsxRuntime.jsx("pre",{className:"liql-expandedContent",children:JSON.stringify(n,null,2)})}catch{return jsxRuntime.jsx("div",{children:"Error parsing object"})}},s=n=>{switch(n){case "DEBUG":return "\u{1F41E}";case "ERROR":return "\u274C";case "OBJECT":return "\u{1F4E6}";default:return "\u{1F4DD}"}},a=e.level.toLowerCase();return jsxRuntime.jsxs("div",{className:`liql-logItem liql-logItem-${a}`,onClick:()=>o(!t),children:[jsxRuntime.jsxs("div",{className:"liql-logMeta",children:[jsxRuntime.jsxs("span",{className:`liql-statusTag liql-tag-${a}`,children:[s(e.level)," ",e.level]}),jsxRuntime.jsx("span",{className:"liql-logTime",children:r(e.timestamp)})]}),jsxRuntime.jsxs("div",{className:"liql-logContent",children:[e.title&&jsxRuntime.jsxs("strong",{style:{color:"var(--liql-primary)"},children:[e.title,": "]}),e.message]}),t&&jsxRuntime.jsxs("div",{className:"liql-expandedContent",children:[e.stack&&jsxRuntime.jsxs("div",{style:{color:"var(--liql-error)",marginBottom:"8px"},children:[jsxRuntime.jsx("strong",{children:"Stack Trace:"}),jsxRuntime.jsx("pre",{style:{whiteSpace:"pre-wrap",fontSize:"10px",marginTop:"4px"},children:e.stack})]}),e.data&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsx("strong",{children:"Payload:"}),i(e.data)]}),!e.data&&!e.stack&&jsxRuntime.jsxs("div",{children:["Full message: ",e.message]})]})]})};var P=({logs:e,filter:t,search:o})=>{let r=U__default.default.useMemo(()=>e.filter(i=>{let s=t==="ALL"||i.level===t,a=o===""||i.message.toLowerCase().includes(o.toLowerCase())||(i.title||"").toLowerCase().includes(o.toLowerCase());return s&&a}).reverse(),[e,t,o]);return jsxRuntime.jsx("div",{className:"liql-logListContainer",children:jsxRuntime.jsx(reactVirtuoso.Virtuoso,{style:{height:"100%"},data:r,itemContent:(i,s)=>jsxRuntime.jsx(B,{log:s},s.id)})})};var M=()=>{let{state:e,setIsPanelOpen:t,dispatch:o}=u(),[r,i]=U.useState("ALL"),[s,a]=U.useState(""),n=()=>{confirm("Are you sure you want to clear all logs?")&&o({type:"CLEAR_LOGS"});},m=()=>{let x="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),b=document.createElement("a");b.setAttribute("href",x),b.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(b),b.click(),b.remove();};return e?jsxRuntime.jsxs("div",{className:"liql-panel",children:[jsxRuntime.jsxs("div",{className:"liql-panelHeader",children:[jsxRuntime.jsx("div",{className:"liql-titleGroup",children:jsxRuntime.jsxs("span",{className:"liql-title",children:["ReactLoggerApp console [",e.logs.length,"]"]})}),jsxRuntime.jsxs("div",{className:"liql-controls",children:[jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:m,title:"Export JSON",children:"\u{1F4E5}"}),jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:n,title:"Clear Logs",children:"\u{1F5D1}\uFE0F"}),jsxRuntime.jsx("button",{className:"liql-btnAction",onClick:()=>t(false),title:"Minimize",children:"\u2796"})]})]}),jsxRuntime.jsxs("div",{className:"liql-filterBar",children:[jsxRuntime.jsx("input",{type:"text",placeholder:"Search entries...",className:"liql-searchInput",value:s,onChange:x=>a(x.target.value)}),jsxRuntime.jsxs("select",{className:"liql-selectFilter",value:r,onChange:x=>i(x.target.value),children:[jsxRuntime.jsx("option",{value:"ALL",children:"ALL"}),jsxRuntime.jsx("option",{value:"DEBUG",children:"DEBUG"}),jsxRuntime.jsx("option",{value:"ERROR",children:"ERROR"}),jsxRuntime.jsx("option",{value:"OBJECT",children:"OBJECTS"})]})]}),jsxRuntime.jsx(P,{logs:e.logs,filter:r,search:s}),jsxRuntime.jsxs("div",{className:"liql-footerActions",children:[jsxRuntime.jsx("div",{className:"liql-storageInfo",children:e.config.persistence?`DRIVER: ${e.config.persistenceDriver?.toUpperCase()}`:"SESSION MODE"}),jsxRuntime.jsx("button",{className:"liql-btnClose",onClick:()=>t(false),children:"CLOSE CONSOLE"})]})]}):null};var We=()=>{let{isPanelOpen:e}=u();return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!e&&jsxRuntime.jsx(T,{}),e&&jsxRuntime.jsx(M,{})]})};exports.Logger=p;exports.LoggerProvider=ve;exports.LoggerViewer=We;exports.useLogger=Ce;exports.useLoggerContext=u;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["#style-inject:#style-inject","../src/styles/logger.css","../src/storage/localStorageDriver.ts","../src/storage/indexedDBDriver.ts","../src/storage/index.ts","../src/Logger.ts","../src/context/LoggerContext.tsx","../src/hooks/useLogger.ts","../src/components/FloatingButton.tsx","../src/components/LogItem.tsx","../src/components/LogList.tsx","../src/components/LogPanel.tsx","../src/components/LoggerViewer.tsx"],"names":["styleInject","css","insertAt","head","style","LocalStorageDriver","key","logs","e","data","DB_NAME","STORE_NAME","DB_VERSION","IndexedDBDriver","openDB","db","tx","store","log","getStorageDriver","type","Logger","dispatch","onLogAdded","level","message","extra","title","err","stack","initialState","loggerReducer","state","action","newLogs","LoggerContext","createContext","LoggerProvider","children","config","useReducer","isPanelOpen","setIsPanelOpen","React","storageRef","useRef","useEffect","loadedLogs","jsx","useLoggerContext","context","useContext","useLogger","debug","useCallback","error","object","clear","exportLogs","dataStr","downloadAnchorNode","FloatingButton","position","setPosition","useState","isDragging","dragOffset","handleMouseDown","rect","handleTouchStart","touch","handleMove","clientX","clientY","nextX","nextY","onMouseMove","onTouchMove","onEnd","handleResize","prev","handleClick","dynamicStyle","LogItem","isExpanded","setIsExpanded","formatTime","isoString","renderJson","getIcon","levelClass","jsxs","LogList","filter","search","filteredLogs","matchesFilter","matchesSearch","Virtuoso","_index","LogPanel","setFilter","setSearch","clearLogs","LoggerViewer","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: \\\"Inter\\\", -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;z-index:100000;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none}}\\n\")","import { LogEntry, StorageDriver } from '../types';\n\nexport class LocalStorageDriver implements StorageDriver {\n private key: string;\n\n constructor(key: string = 'ionic_react_logger_logs') {\n this.key = key;\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n try {\n localStorage.setItem(this.key, JSON.stringify(logs));\n } catch (e) {\n console.error('Failed to save logs to localStorage', e);\n }\n }\n\n async load(): Promise<LogEntry[]> {\n try {\n const data = localStorage.getItem(this.key);\n return data ? JSON.parse(data) : [];\n } catch (e) {\n console.error('Failed to load logs from localStorage', e);\n return [];\n }\n }\n\n async clear(): Promise<void> {\n localStorage.removeItem(this.key);\n }\n}\n","import { openDB, IDBPDatabase } from 'idb';\nimport { LogEntry, StorageDriver } from '../types';\n\nconst DB_NAME = 'IonicReactLoggerDB';\nconst STORE_NAME = 'logs';\nconst DB_VERSION = 1;\n\nexport class IndexedDBDriver implements StorageDriver {\n private dbPromise: Promise<IDBPDatabase>;\n\n constructor() {\n this.dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n },\n });\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const store = tx.objectStore(STORE_NAME);\n\n // Clear existing logs first or manage them as needed\n // Simple implementation: clear and re-save everything to match the expected behavior of StorageDriver\n await store.clear();\n for (const log of logs) {\n await store.put(log);\n }\n await tx.done;\n }\n\n async load(): Promise<LogEntry[]> {\n const db = await this.dbPromise;\n return db.getAll(STORE_NAME);\n }\n\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n await tx.objectStore(STORE_NAME).clear();\n await tx.done;\n }\n}\n","import { StorageDriver, LogEntry } from '../types';\nimport { LocalStorageDriver } from './localStorageDriver';\nimport { IndexedDBDriver } from './indexedDBDriver';\n\nexport function getStorageDriver(type: 'localStorage' | 'indexedDB'): StorageDriver {\n if (type === 'indexedDB') {\n return new IndexedDBDriver();\n }\n return new LocalStorageDriver();\n}\n\nexport * from './localStorageDriver';\nexport * from './indexedDBDriver';\n","import { LogEntry, LogLevel } from './types';\n\ntype LoggerDispatch = (action: { type: 'ADD_LOG'; log: LogEntry } | { type: 'CLEAR_LOGS' }) => void;\n\n/**\n * Global Logger class to support logging from plain TypeScript classes\n * and handle early logs before the React Provider is mounted.\n */\nexport class Logger {\n private static dispatch: LoggerDispatch | null = null;\n private static logBuffer: LogEntry[] = [];\n private static onLogAddedCallback?: (log: LogEntry) => void;\n\n /**\n * Internal method to initialize the dispatcher from the React context.\n */\n static _setDispatcher(dispatch: LoggerDispatch, onLogAdded?: (log: LogEntry) => void) {\n this.dispatch = dispatch;\n this.onLogAddedCallback = onLogAdded;\n\n // Flush buffer\n if (this.logBuffer.length > 0) {\n this.logBuffer.forEach(log => {\n this.dispatch!({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n });\n this.logBuffer = [];\n }\n }\n\n private static createLog(level: LogLevel, message: string, extra?: { title?: string, data?: any, stack?: string }): LogEntry {\n return {\n id: Math.random().toString(36).substring(2, 9),\n level,\n message,\n timestamp: new Date().toISOString(),\n ...extra\n };\n }\n\n private static addLog(log: LogEntry) {\n if (this.dispatch) {\n this.dispatch({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n } else {\n this.logBuffer.push(log);\n }\n }\n\n /**\n * Log a debug message (Blue neon)\n */\n static debug(message: string, title?: string) {\n this.addLog(this.createLog('DEBUG', message, { title }));\n }\n\n /**\n * Log an error (Red neon). Supports Error objects for automatic stack trace capture.\n */\n static error(err: string | Error, title?: string) {\n const message = err instanceof Error ? err.message : err;\n const stack = err instanceof Error ? err.stack : undefined;\n this.addLog(this.createLog('ERROR', message, { title: title || 'Error', stack }));\n }\n\n /**\n * Log an object for visualization (Green neon).\n */\n static object(data: any, title?: string) {\n this.addLog(this.createLog('OBJECT', 'Object visualization', { title: title || 'Data Object', data }));\n }\n\n /**\n * Clear all logs.\n */\n static clear() {\n if (this.dispatch) {\n this.dispatch({ type: 'CLEAR_LOGS' });\n } else {\n this.logBuffer = [];\n }\n }\n}\n","import React, { createContext, useContext, useReducer, useEffect, useCallback, useRef } from 'react';\nimport { LogEntry, LogLevel, LoggerConfig, StorageDriver } from '../types';\nimport { getStorageDriver } from '../storage';\nimport { Logger } from '../Logger';\n\ninterface LoggerState {\n logs: LogEntry[];\n config: LoggerConfig;\n unreadCount: number;\n}\n\ntype LoggerAction =\n | { type: 'ADD_LOG'; log: LogEntry }\n | { type: 'SET_LOGS'; logs: LogEntry[] }\n | { type: 'CLEAR_LOGS' }\n | { type: 'SET_CONFIG'; config: Partial<LoggerConfig> }\n | { type: 'RESET_UNREAD' }\n | { type: 'INCREMENT_UNREAD' };\n\nconst initialState: LoggerState = {\n logs: [],\n config: {\n persistence: false,\n persistenceDriver: 'localStorage',\n maxLogs: 500,\n },\n unreadCount: 0,\n};\n\nfunction loggerReducer(state: LoggerState, action: LoggerAction): LoggerState {\n switch (action.type) {\n case 'ADD_LOG': {\n const newLogs = [action.log, ...state.logs].slice(0, state.config.maxLogs);\n return {\n ...state,\n logs: newLogs,\n };\n }\n case 'SET_LOGS':\n return { ...state, logs: [...state.logs, ...action.logs].slice(0, state.config.maxLogs) };\n case 'CLEAR_LOGS':\n return { ...state, logs: [], unreadCount: 0 };\n case 'SET_CONFIG':\n return { ...state, config: { ...state.config, ...action.config } };\n case 'RESET_UNREAD':\n return { ...state, unreadCount: 0 };\n case 'INCREMENT_UNREAD':\n return { ...state, unreadCount: state.unreadCount + 1 };\n default:\n return state;\n }\n}\n\ninterface LoggerContextType {\n state: LoggerState;\n dispatch: React.Dispatch<LoggerAction>;\n isPanelOpen: boolean;\n setIsPanelOpen: (open: boolean) => void;\n}\n\nconst LoggerContext = createContext<LoggerContextType | undefined>(undefined);\n\n/**\n * Provides the logging context to all child components.\n * This should wrap your entire application (e.g. in App.tsx).\n * \n * @param config Optional initial configuration for persistence and limits.\n */\nexport const LoggerProvider: React.FC<{ children: React.ReactNode; config?: LoggerConfig }> = ({\n children,\n config,\n}) => {\n const [state, dispatch] = useReducer(loggerReducer, {\n ...initialState,\n config: { ...initialState.config, ...config },\n });\n const [isPanelOpen, setIsPanelOpen] = React.useState(false);\n const storageRef = useRef<StorageDriver | null>(null);\n\n // Initialize storage driver and Logger singleton\n useEffect(() => {\n Logger._setDispatcher(dispatch, state.config.onLogAdded);\n\n if (state.config.persistence) {\n storageRef.current = getStorageDriver(state.config.persistenceDriver || 'localStorage');\n storageRef.current.load().then((loadedLogs) => {\n dispatch({ type: 'SET_LOGS', logs: loadedLogs });\n });\n }\n }, [state.config.persistence, state.config.persistenceDriver]);\n\n // Persist logs when they change\n useEffect(() => {\n if (state.config.persistence && storageRef.current) {\n storageRef.current.save(state.logs);\n }\n }, [state.logs, state.config.persistence]);\n\n return (\n <LoggerContext.Provider value={{ state, dispatch, isPanelOpen, setIsPanelOpen }}>\n {children}\n </LoggerContext.Provider>\n );\n};\n\n/**\n * Internal hook to access the logger context state.\n * Use the public `useLogger` hook for standard logging operations.\n */\nexport const useLoggerContext = () => {\n const context = useContext(LoggerContext);\n if (!context) {\n throw new Error('useLoggerContext must be used within a LoggerProvider');\n }\n return context;\n};\n","import { useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { Logger } from '../Logger';\n\n/**\n * Main hook to interact with the Liquid Glass Logger.\n * \n * Provides methods for different logging levels and allows accessing\n * the current state of logs.\n * \n * @example\n * ```tsx\n * const { debug, error, object } = useLogger();\n * \n * debug('App started');\n * error(new Error('Failed to fetch'), 'API Error');\n * object({ user: 'John' }, 'Current User');\n * ```\n */\nexport const useLogger = () => {\n const { state } = useLoggerContext();\n\n /**\n * Log a debug message (Blue neon)\n */\n const debug = useCallback((message: string, title?: string) => {\n Logger.debug(message, title);\n }, []);\n\n /**\n * Log an error. If an Error object is passed, it automatically captures the stack trace.\n * (Red neon)\n */\n const error = useCallback((err: string | Error, title?: string) => {\n Logger.error(err, title);\n }, []);\n\n /**\n * Log a data object for inspection.\n * (Green neon)\n */\n const object = useCallback((data: any, title?: string) => {\n Logger.object(data, title);\n }, []);\n\n /**\n * Clears all logs from the current session and persistent storage.\n */\n const clear = useCallback(() => {\n Logger.clear();\n }, []);\n\n /**\n * Exports all logs as a JSON file download.\n */\n const exportLogs = useCallback(() => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n }, [state.logs]);\n\n return {\n /** Register a debug message */\n debug,\n /** Register an error or exception */\n error,\n /** Register an object for JSON visualization */\n object,\n /** Clear all history */\n clear,\n /** Download history as JSON */\n exportLogs,\n /** List of all captured logs */\n logs: state.logs,\n /** Count of logs not yet viewed */\n unreadCount: state.unreadCount,\n };\n};\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\n\n/**\n * Draggable floating trigger button.\n * Uses hybrid positioning (CSS initial + JS drag) for maximum compatibility.\n */\nexport const FloatingButton: React.FC = () => {\n const { state, setIsPanelOpen } = useLoggerContext();\n\n // Default to null to use CSS positioning initially\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null);\n const isDragging = useRef(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n\n const handleMouseDown = (e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top\n };\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n const touch = e.touches[0];\n dragOffset.current = {\n x: touch.clientX - rect.left,\n y: touch.clientY - rect.top\n };\n };\n\n const handleMove = useCallback((clientX: number, clientY: number) => {\n if (!isDragging.current) return;\n\n // Keep button within viewport\n const nextX = Math.max(10, Math.min(window.innerWidth - 60, clientX - dragOffset.current.x));\n const nextY = Math.max(10, Math.min(window.innerHeight - 60, clientY - dragOffset.current.y));\n\n setPosition({ x: nextX, y: nextY });\n }, []);\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => handleMove(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent) => handleMove(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n isDragging.current = false;\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n window.addEventListener('mouseup', onEnd);\n window.addEventListener('touchend', onEnd);\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('mouseup', onEnd);\n window.removeEventListener('touchend', onEnd);\n };\n }, [handleMove]);\n\n // Handle window resize to keep button in bounds\n useEffect(() => {\n const handleResize = () => {\n if (position) {\n setPosition(prev => {\n if (!prev) return null;\n return {\n x: Math.min(prev.x, window.innerWidth - 60),\n y: Math.min(prev.y, window.innerHeight - 60)\n };\n });\n }\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [position]);\n\n const handleClick = () => {\n if (isDragging.current) return;\n setIsPanelOpen(true);\n };\n\n // If never moved, let CSS handle it. If moved, use absolute pixel coordinates.\n const dynamicStyle: React.CSSProperties = position\n ? { left: `${position.x}px`, top: `${position.y}px`, right: 'auto', bottom: 'auto' }\n : {};\n\n return (\n <div\n className=\"liql-floatingButton\"\n style={dynamicStyle}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n onClick={handleClick}\n aria-label=\"Open Logger\"\n >\n {state.unreadCount > 0 && (\n <div className=\"liql-badge\">{state.unreadCount}</div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { LogEntry } from '../types';\n\ninterface LogItemProps {\n log: LogEntry;\n}\n\nexport const LogItem: React.FC<LogItemProps> = ({ log }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const formatTime = (isoString: string) => {\n const date = new Date(isoString);\n return date.toTimeString().split(' ')[0];\n };\n\n const renderJson = (data: any) => {\n try {\n return (\n <pre className=\"liql-expandedContent\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n } catch (e) {\n return <div>Error parsing object</div>;\n }\n };\n\n const getIcon = (level: string) => {\n switch (level) {\n case 'DEBUG': return '🐞';\n case 'ERROR': return '❌';\n case 'OBJECT': return '📦';\n default: return '📝';\n }\n };\n\n const levelClass = log.level.toLowerCase();\n\n return (\n <div\n className={`liql-logItem liql-logItem-${levelClass}`}\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"liql-logMeta\">\n <span className={`liql-statusTag liql-tag-${levelClass}`}>\n {getIcon(log.level)} {log.level}\n </span>\n <span className=\"liql-logTime\">{formatTime(log.timestamp)}</span>\n </div>\n <div className=\"liql-logContent\">\n {log.title && <strong style={{ color: 'var(--liql-primary)' }}>{log.title}: </strong>}\n {log.message}\n </div>\n\n {isExpanded && (\n <div className=\"liql-expandedContent\">\n {log.stack && (\n <div style={{ color: 'var(--liql-error)', marginBottom: '8px' }}>\n <strong>Stack Trace:</strong>\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: '10px', marginTop: '4px' }}>{log.stack}</pre>\n </div>\n )}\n {log.data && (\n <div>\n <strong>Payload:</strong>\n {renderJson(log.data)}\n </div>\n )}\n {!log.data && !log.stack && <div>Full message: {log.message}</div>}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { Virtuoso } from 'react-virtuoso';\nimport { LogItem } from './LogItem';\nimport { LogEntry } from '../types';\n\ninterface LogListProps {\n logs: LogEntry[];\n filter: string;\n search: string;\n}\n\nexport const LogList: React.FC<LogListProps> = ({ logs, filter, search }) => {\n const filteredLogs = React.useMemo(() => {\n return logs.filter(log => {\n const matchesFilter = filter === 'ALL' || log.level === filter;\n const matchesSearch = search === '' ||\n log.message.toLowerCase().includes(search.toLowerCase()) ||\n (log.title || '').toLowerCase().includes(search.toLowerCase());\n return matchesFilter && matchesSearch;\n }).reverse();\n }, [logs, filter, search]);\n\n return (\n <div className=\"liql-logListContainer\">\n <Virtuoso\n style={{ height: '100%' }}\n data={filteredLogs}\n itemContent={(_index: number, log: LogEntry) => <LogItem key={log.id} log={log} />}\n />\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { LogList } from './LogList';\n\n/**\n * Main 'Liquid Glass' logging console.\n * Contains the log list, filtering, search, and action controls.\n */\nexport const LogPanel: React.FC = () => {\n const { state, setIsPanelOpen, dispatch } = useLoggerContext();\n const [filter, setFilter] = useState('ALL');\n const [search, setSearch] = useState('');\n\n const clearLogs = () => {\n if (confirm('Are you sure you want to clear all logs?')) {\n dispatch({ type: 'CLEAR_LOGS' });\n }\n };\n\n const exportLogs = () => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n };\n\n if (!state) return null;\n\n return (\n <div className=\"liql-panel\" style={{ right: '20px', bottom: '20px', width: '440px', height: '680px' }}>\n <div className=\"liql-panelHeader\">\n <div className=\"liql-titleGroup\">\n <span className=\"liql-title\">ReactLoggerApp console [{state.logs.length}]</span>\n </div>\n <div className=\"liql-controls\">\n <button className=\"liql-btnAction\" onClick={exportLogs} title=\"Export JSON\">📥</button>\n <button className=\"liql-btnAction\" onClick={clearLogs} title=\"Clear Logs\">🗑️</button>\n <button className=\"liql-btnAction\" onClick={() => setIsPanelOpen(false)} title=\"Minimize\">➖</button>\n </div>\n </div>\n\n <div className=\"liql-filterBar\">\n <input\n type=\"text\"\n placeholder=\"Search entries...\"\n className=\"liql-searchInput\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n <select\n className=\"liql-selectFilter\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n >\n <option value=\"ALL\">ALL</option>\n <option value=\"DEBUG\">DEBUG</option>\n <option value=\"ERROR\">ERROR</option>\n <option value=\"OBJECT\">OBJECTS</option>\n </select>\n </div>\n\n <LogList logs={state.logs} filter={filter} search={search} />\n\n <div className=\"liql-footerActions\">\n <div className=\"liql-storageInfo\">\n {state.config.persistence ? `DRIVER: ${state.config.persistenceDriver?.toUpperCase()}` : 'SESSION MODE'}\n </div>\n <button className=\"liql-btnClose\" onClick={() => setIsPanelOpen(false)}>CLOSE CONSOLE</button>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { FloatingButton } from './FloatingButton';\nimport { LogPanel } from './LogPanel';\n\n/**\n * Main entry point for the Logger UI.\n * Renders the floating trigger button and conditionally shows the glass panel.\n * Should be placed at the root level of your application.\n */\nexport const LoggerViewer: React.FC = () => {\n const { isPanelOpen } = useLoggerContext();\n\n return (\n <>\n {!isPanelOpen && <FloatingButton />}\n {isPanelOpen && <LogPanel />}\n </>\n );\n};\n"]}
1
+ {"version":3,"sources":["#style-inject:#style-inject","../src/styles/logger.css","../src/storage/localStorageDriver.ts","../src/storage/indexedDBDriver.ts","../src/storage/index.ts","../src/Logger.ts","../src/context/LoggerContext.tsx","../src/hooks/useLogger.ts","../src/components/FloatingButton.tsx","../src/components/LogItem.tsx","../src/components/LogList.tsx","../src/components/LogPanel.tsx","../src/components/LoggerViewer.tsx"],"names":["styleInject","css","insertAt","head","style","LocalStorageDriver","key","logs","e","data","DB_NAME","STORE_NAME","DB_VERSION","IndexedDBDriver","openDB","db","tx","store","log","getStorageDriver","type","Logger","dispatch","onLogAdded","level","message","extra","title","err","stack","initialState","loggerReducer","state","action","newLogs","LoggerContext","createContext","LoggerProvider","children","config","useReducer","isPanelOpen","setIsPanelOpen","React","storageRef","useRef","useEffect","loadedLogs","jsx","useLoggerContext","context","useContext","useLogger","debug","useCallback","error","object","clear","exportLogs","dataStr","downloadAnchorNode","FloatingButton","position","setPosition","useState","isDragging","dragOffset","handleMouseDown","rect","handleTouchStart","touch","handleMove","clientX","clientY","nextX","nextY","onMouseMove","onTouchMove","onEnd","handleResize","prev","handleClick","dynamicStyle","LogItem","isExpanded","setIsExpanded","formatTime","isoString","renderJson","getIcon","levelClass","jsxs","LogList","filter","search","filteredLogs","matchesFilter","matchesSearch","Virtuoso","_index","LogPanel","setFilter","setSearch","clearLogs","LoggerViewer","Fragment"],"mappings":"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","file":"index.js","sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: \\\"Inter\\\", -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;width:440px;height:680px;right:20px;bottom:20px;z-index:999999;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none;background:#0f172a!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}}\\n\")","import { LogEntry, StorageDriver } from '../types';\n\nexport class LocalStorageDriver implements StorageDriver {\n private key: string;\n\n constructor(key: string = 'ionic_react_logger_logs') {\n this.key = key;\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n try {\n localStorage.setItem(this.key, JSON.stringify(logs));\n } catch (e) {\n console.error('Failed to save logs to localStorage', e);\n }\n }\n\n async load(): Promise<LogEntry[]> {\n try {\n const data = localStorage.getItem(this.key);\n return data ? JSON.parse(data) : [];\n } catch (e) {\n console.error('Failed to load logs from localStorage', e);\n return [];\n }\n }\n\n async clear(): Promise<void> {\n localStorage.removeItem(this.key);\n }\n}\n","import { openDB, IDBPDatabase } from 'idb';\nimport { LogEntry, StorageDriver } from '../types';\n\nconst DB_NAME = 'IonicReactLoggerDB';\nconst STORE_NAME = 'logs';\nconst DB_VERSION = 1;\n\nexport class IndexedDBDriver implements StorageDriver {\n private dbPromise: Promise<IDBPDatabase>;\n\n constructor() {\n this.dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n },\n });\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const store = tx.objectStore(STORE_NAME);\n\n // Clear existing logs first or manage them as needed\n // Simple implementation: clear and re-save everything to match the expected behavior of StorageDriver\n await store.clear();\n for (const log of logs) {\n await store.put(log);\n }\n await tx.done;\n }\n\n async load(): Promise<LogEntry[]> {\n const db = await this.dbPromise;\n return db.getAll(STORE_NAME);\n }\n\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n await tx.objectStore(STORE_NAME).clear();\n await tx.done;\n }\n}\n","import { StorageDriver, LogEntry } from '../types';\nimport { LocalStorageDriver } from './localStorageDriver';\nimport { IndexedDBDriver } from './indexedDBDriver';\n\nexport function getStorageDriver(type: 'localStorage' | 'indexedDB'): StorageDriver {\n if (type === 'indexedDB') {\n return new IndexedDBDriver();\n }\n return new LocalStorageDriver();\n}\n\nexport * from './localStorageDriver';\nexport * from './indexedDBDriver';\n","import { LogEntry, LogLevel } from './types';\n\ntype LoggerDispatch = (action: { type: 'ADD_LOG'; log: LogEntry } | { type: 'CLEAR_LOGS' }) => void;\n\n/**\n * Global Logger class to support logging from plain TypeScript classes\n * and handle early logs before the React Provider is mounted.\n */\nexport class Logger {\n private static dispatch: LoggerDispatch | null = null;\n private static logBuffer: LogEntry[] = [];\n private static onLogAddedCallback?: (log: LogEntry) => void;\n\n /**\n * Internal method to initialize the dispatcher from the React context.\n */\n static _setDispatcher(dispatch: LoggerDispatch, onLogAdded?: (log: LogEntry) => void) {\n this.dispatch = dispatch;\n this.onLogAddedCallback = onLogAdded;\n\n // Flush buffer\n if (this.logBuffer.length > 0) {\n this.logBuffer.forEach(log => {\n this.dispatch!({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n });\n this.logBuffer = [];\n }\n }\n\n private static createLog(level: LogLevel, message: string, extra?: { title?: string, data?: any, stack?: string }): LogEntry {\n return {\n id: Math.random().toString(36).substring(2, 9),\n level,\n message,\n timestamp: new Date().toISOString(),\n ...extra\n };\n }\n\n private static addLog(log: LogEntry) {\n if (this.dispatch) {\n this.dispatch({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n } else {\n this.logBuffer.push(log);\n }\n }\n\n /**\n * Log a debug message (Blue neon)\n */\n static debug(message: string, title?: string) {\n this.addLog(this.createLog('DEBUG', message, { title }));\n }\n\n /**\n * Log an error (Red neon). Supports Error objects for automatic stack trace capture.\n */\n static error(err: string | Error, title?: string) {\n const message = err instanceof Error ? err.message : err;\n const stack = err instanceof Error ? err.stack : undefined;\n this.addLog(this.createLog('ERROR', message, { title: title || 'Error', stack }));\n }\n\n /**\n * Log an object for visualization (Green neon).\n */\n static object(data: any, title?: string) {\n this.addLog(this.createLog('OBJECT', 'Object visualization', { title: title || 'Data Object', data }));\n }\n\n /**\n * Clear all logs.\n */\n static clear() {\n if (this.dispatch) {\n this.dispatch({ type: 'CLEAR_LOGS' });\n } else {\n this.logBuffer = [];\n }\n }\n}\n","import React, { createContext, useContext, useReducer, useEffect, useCallback, useRef } from 'react';\nimport { LogEntry, LogLevel, LoggerConfig, StorageDriver } from '../types';\nimport { getStorageDriver } from '../storage';\nimport { Logger } from '../Logger';\n\ninterface LoggerState {\n logs: LogEntry[];\n config: LoggerConfig;\n unreadCount: number;\n}\n\ntype LoggerAction =\n | { type: 'ADD_LOG'; log: LogEntry }\n | { type: 'SET_LOGS'; logs: LogEntry[] }\n | { type: 'CLEAR_LOGS' }\n | { type: 'SET_CONFIG'; config: Partial<LoggerConfig> }\n | { type: 'RESET_UNREAD' }\n | { type: 'INCREMENT_UNREAD' };\n\nconst initialState: LoggerState = {\n logs: [],\n config: {\n persistence: false,\n persistenceDriver: 'localStorage',\n maxLogs: 500,\n },\n unreadCount: 0,\n};\n\nfunction loggerReducer(state: LoggerState, action: LoggerAction): LoggerState {\n switch (action.type) {\n case 'ADD_LOG': {\n const newLogs = [action.log, ...state.logs].slice(0, state.config.maxLogs);\n return {\n ...state,\n logs: newLogs,\n };\n }\n case 'SET_LOGS':\n return { ...state, logs: [...state.logs, ...action.logs].slice(0, state.config.maxLogs) };\n case 'CLEAR_LOGS':\n return { ...state, logs: [], unreadCount: 0 };\n case 'SET_CONFIG':\n return { ...state, config: { ...state.config, ...action.config } };\n case 'RESET_UNREAD':\n return { ...state, unreadCount: 0 };\n case 'INCREMENT_UNREAD':\n return { ...state, unreadCount: state.unreadCount + 1 };\n default:\n return state;\n }\n}\n\ninterface LoggerContextType {\n state: LoggerState;\n dispatch: React.Dispatch<LoggerAction>;\n isPanelOpen: boolean;\n setIsPanelOpen: (open: boolean) => void;\n}\n\nconst LoggerContext = createContext<LoggerContextType | undefined>(undefined);\n\n/**\n * Provides the logging context to all child components.\n * This should wrap your entire application (e.g. in App.tsx).\n * \n * @param config Optional initial configuration for persistence and limits.\n */\nexport const LoggerProvider: React.FC<{ children: React.ReactNode; config?: LoggerConfig }> = ({\n children,\n config,\n}) => {\n const [state, dispatch] = useReducer(loggerReducer, {\n ...initialState,\n config: { ...initialState.config, ...config },\n });\n const [isPanelOpen, setIsPanelOpen] = React.useState(false);\n const storageRef = useRef<StorageDriver | null>(null);\n\n // Initialize storage driver and Logger singleton\n useEffect(() => {\n Logger._setDispatcher(dispatch, state.config.onLogAdded);\n\n if (state.config.persistence) {\n storageRef.current = getStorageDriver(state.config.persistenceDriver || 'localStorage');\n storageRef.current.load().then((loadedLogs) => {\n dispatch({ type: 'SET_LOGS', logs: loadedLogs });\n });\n }\n }, [state.config.persistence, state.config.persistenceDriver]);\n\n // Persist logs when they change\n useEffect(() => {\n if (state.config.persistence && storageRef.current) {\n storageRef.current.save(state.logs);\n }\n }, [state.logs, state.config.persistence]);\n\n return (\n <LoggerContext.Provider value={{ state, dispatch, isPanelOpen, setIsPanelOpen }}>\n {children}\n </LoggerContext.Provider>\n );\n};\n\n/**\n * Internal hook to access the logger context state.\n * Use the public `useLogger` hook for standard logging operations.\n */\nexport const useLoggerContext = () => {\n const context = useContext(LoggerContext);\n if (!context) {\n throw new Error('useLoggerContext must be used within a LoggerProvider');\n }\n return context;\n};\n","import { useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { Logger } from '../Logger';\n\n/**\n * Main hook to interact with the Liquid Glass Logger.\n * \n * Provides methods for different logging levels and allows accessing\n * the current state of logs.\n * \n * @example\n * ```tsx\n * const { debug, error, object } = useLogger();\n * \n * debug('App started');\n * error(new Error('Failed to fetch'), 'API Error');\n * object({ user: 'John' }, 'Current User');\n * ```\n */\nexport const useLogger = () => {\n const { state } = useLoggerContext();\n\n /**\n * Log a debug message (Blue neon)\n */\n const debug = useCallback((message: string, title?: string) => {\n Logger.debug(message, title);\n }, []);\n\n /**\n * Log an error. If an Error object is passed, it automatically captures the stack trace.\n * (Red neon)\n */\n const error = useCallback((err: string | Error, title?: string) => {\n Logger.error(err, title);\n }, []);\n\n /**\n * Log a data object for inspection.\n * (Green neon)\n */\n const object = useCallback((data: any, title?: string) => {\n Logger.object(data, title);\n }, []);\n\n /**\n * Clears all logs from the current session and persistent storage.\n */\n const clear = useCallback(() => {\n Logger.clear();\n }, []);\n\n /**\n * Exports all logs as a JSON file download.\n */\n const exportLogs = useCallback(() => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n }, [state.logs]);\n\n return {\n /** Register a debug message */\n debug,\n /** Register an error or exception */\n error,\n /** Register an object for JSON visualization */\n object,\n /** Clear all history */\n clear,\n /** Download history as JSON */\n exportLogs,\n /** List of all captured logs */\n logs: state.logs,\n /** Count of logs not yet viewed */\n unreadCount: state.unreadCount,\n };\n};\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\n\n/**\n * Draggable floating trigger button.\n * Uses hybrid positioning (CSS initial + JS drag) for maximum compatibility.\n */\nexport const FloatingButton: React.FC = () => {\n const { state, setIsPanelOpen } = useLoggerContext();\n\n // Default to null to use CSS positioning initially\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null);\n const isDragging = useRef(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n\n const handleMouseDown = (e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top\n };\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n const touch = e.touches[0];\n dragOffset.current = {\n x: touch.clientX - rect.left,\n y: touch.clientY - rect.top\n };\n };\n\n const handleMove = useCallback((clientX: number, clientY: number) => {\n if (!isDragging.current) return;\n\n // Keep button within viewport\n const nextX = Math.max(10, Math.min(window.innerWidth - 60, clientX - dragOffset.current.x));\n const nextY = Math.max(10, Math.min(window.innerHeight - 60, clientY - dragOffset.current.y));\n\n setPosition({ x: nextX, y: nextY });\n }, []);\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => handleMove(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent) => handleMove(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n isDragging.current = false;\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n window.addEventListener('mouseup', onEnd);\n window.addEventListener('touchend', onEnd);\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('mouseup', onEnd);\n window.removeEventListener('touchend', onEnd);\n };\n }, [handleMove]);\n\n // Handle window resize to keep button in bounds\n useEffect(() => {\n const handleResize = () => {\n if (position) {\n setPosition(prev => {\n if (!prev) return null;\n return {\n x: Math.min(prev.x, window.innerWidth - 60),\n y: Math.min(prev.y, window.innerHeight - 60)\n };\n });\n }\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [position]);\n\n const handleClick = () => {\n if (isDragging.current) return;\n setIsPanelOpen(true);\n };\n\n // If never moved, let CSS handle it. If moved, use absolute pixel coordinates.\n const dynamicStyle: React.CSSProperties = position\n ? { left: `${position.x}px`, top: `${position.y}px`, right: 'auto', bottom: 'auto' }\n : {};\n\n return (\n <div\n className=\"liql-floatingButton\"\n style={dynamicStyle}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n onClick={handleClick}\n aria-label=\"Open Logger\"\n >\n {state.unreadCount > 0 && (\n <div className=\"liql-badge\">{state.unreadCount}</div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { LogEntry } from '../types';\n\ninterface LogItemProps {\n log: LogEntry;\n}\n\nexport const LogItem: React.FC<LogItemProps> = ({ log }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const formatTime = (isoString: string) => {\n const date = new Date(isoString);\n return date.toTimeString().split(' ')[0];\n };\n\n const renderJson = (data: any) => {\n try {\n return (\n <pre className=\"liql-expandedContent\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n } catch (e) {\n return <div>Error parsing object</div>;\n }\n };\n\n const getIcon = (level: string) => {\n switch (level) {\n case 'DEBUG': return '🐞';\n case 'ERROR': return '❌';\n case 'OBJECT': return '📦';\n default: return '📝';\n }\n };\n\n const levelClass = log.level.toLowerCase();\n\n return (\n <div\n className={`liql-logItem liql-logItem-${levelClass}`}\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"liql-logMeta\">\n <span className={`liql-statusTag liql-tag-${levelClass}`}>\n {getIcon(log.level)} {log.level}\n </span>\n <span className=\"liql-logTime\">{formatTime(log.timestamp)}</span>\n </div>\n <div className=\"liql-logContent\">\n {log.title && <strong style={{ color: 'var(--liql-primary)' }}>{log.title}: </strong>}\n {log.message}\n </div>\n\n {isExpanded && (\n <div className=\"liql-expandedContent\">\n {log.stack && (\n <div style={{ color: 'var(--liql-error)', marginBottom: '8px' }}>\n <strong>Stack Trace:</strong>\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: '10px', marginTop: '4px' }}>{log.stack}</pre>\n </div>\n )}\n {log.data && (\n <div>\n <strong>Payload:</strong>\n {renderJson(log.data)}\n </div>\n )}\n {!log.data && !log.stack && <div>Full message: {log.message}</div>}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { Virtuoso } from 'react-virtuoso';\nimport { LogItem } from './LogItem';\nimport { LogEntry } from '../types';\n\ninterface LogListProps {\n logs: LogEntry[];\n filter: string;\n search: string;\n}\n\nexport const LogList: React.FC<LogListProps> = ({ logs, filter, search }) => {\n const filteredLogs = React.useMemo(() => {\n return logs.filter(log => {\n const matchesFilter = filter === 'ALL' || log.level === filter;\n const matchesSearch = search === '' ||\n log.message.toLowerCase().includes(search.toLowerCase()) ||\n (log.title || '').toLowerCase().includes(search.toLowerCase());\n return matchesFilter && matchesSearch;\n }).reverse();\n }, [logs, filter, search]);\n\n return (\n <div className=\"liql-logListContainer\">\n <Virtuoso\n style={{ height: '100%' }}\n data={filteredLogs}\n itemContent={(_index: number, log: LogEntry) => <LogItem key={log.id} log={log} />}\n />\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { LogList } from './LogList';\n\n/**\n * Main 'Liquid Glass' logging console.\n * Contains the log list, filtering, search, and action controls.\n */\nexport const LogPanel: React.FC = () => {\n const { state, setIsPanelOpen, dispatch } = useLoggerContext();\n const [filter, setFilter] = useState('ALL');\n const [search, setSearch] = useState('');\n\n const clearLogs = () => {\n if (confirm('Are you sure you want to clear all logs?')) {\n dispatch({ type: 'CLEAR_LOGS' });\n }\n };\n\n const exportLogs = () => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n };\n\n if (!state) return null;\n\n return (\n <div className=\"liql-panel\">\n <div className=\"liql-panelHeader\">\n <div className=\"liql-titleGroup\">\n <span className=\"liql-title\">ReactLoggerApp console [{state.logs.length}]</span>\n </div>\n <div className=\"liql-controls\">\n <button className=\"liql-btnAction\" onClick={exportLogs} title=\"Export JSON\">📥</button>\n <button className=\"liql-btnAction\" onClick={clearLogs} title=\"Clear Logs\">🗑️</button>\n <button className=\"liql-btnAction\" onClick={() => setIsPanelOpen(false)} title=\"Minimize\">➖</button>\n </div>\n </div>\n\n <div className=\"liql-filterBar\">\n <input\n type=\"text\"\n placeholder=\"Search entries...\"\n className=\"liql-searchInput\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n <select\n className=\"liql-selectFilter\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n >\n <option value=\"ALL\">ALL</option>\n <option value=\"DEBUG\">DEBUG</option>\n <option value=\"ERROR\">ERROR</option>\n <option value=\"OBJECT\">OBJECTS</option>\n </select>\n </div>\n\n <LogList logs={state.logs} filter={filter} search={search} />\n\n <div className=\"liql-footerActions\">\n <div className=\"liql-storageInfo\">\n {state.config.persistence ? `DRIVER: ${state.config.persistenceDriver?.toUpperCase()}` : 'SESSION MODE'}\n </div>\n <button className=\"liql-btnClose\" onClick={() => setIsPanelOpen(false)}>CLOSE CONSOLE</button>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { FloatingButton } from './FloatingButton';\nimport { LogPanel } from './LogPanel';\n\n/**\n * Main entry point for the Logger UI.\n * Renders the floating trigger button and conditionally shows the glass panel.\n * Should be placed at the root level of your application.\n */\nexport const LoggerViewer: React.FC = () => {\n const { isPanelOpen } = useLoggerContext();\n\n return (\n <>\n {!isPanelOpen && <FloatingButton />}\n {isPanelOpen && <LogPanel />}\n </>\n );\n};\n"]}
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import U,{createContext,useReducer,useRef,useEffect,useContext,useCallback,useState}from'react';import {openDB}from'idb';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {Virtuoso}from'react-virtuoso';function C(e,{insertAt:t}={}){if(typeof document>"u")return;let o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css",t==="top"&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e));}C(`:root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;z-index:100000;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none}}
2
- `);var w=class{key;constructor(t="ionic_react_logger_logs"){this.key=t;}async save(t){try{localStorage.setItem(this.key,JSON.stringify(t));}catch(o){console.error("Failed to save logs to localStorage",o);}}async load(){try{let t=localStorage.getItem(this.key);return t?JSON.parse(t):[]}catch(t){return console.error("Failed to load logs from localStorage",t),[]}}async clear(){localStorage.removeItem(this.key);}};var G="IonicReactLoggerDB",v="logs",F=1,E=class{dbPromise;constructor(){this.dbPromise=openDB(G,F,{upgrade(t){t.objectStoreNames.contains(v)||t.createObjectStore(v,{keyPath:"id"});}});}async save(t){let r=(await this.dbPromise).transaction(v,"readwrite"),i=r.objectStore(v);await i.clear();for(let s of t)await i.put(s);await r.done;}async load(){return (await this.dbPromise).getAll(v)}async clear(){let o=(await this.dbPromise).transaction(v,"readwrite");await o.objectStore(v).clear(),await o.done;}};function R(e){return e==="indexedDB"?new E:new w}var p=class{static dispatch=null;static logBuffer=[];static onLogAddedCallback;static _setDispatcher(t,o){this.dispatch=t,this.onLogAddedCallback=o,this.logBuffer.length>0&&(this.logBuffer.forEach(r=>{this.dispatch({type:"ADD_LOG",log:r}),this.onLogAddedCallback?.(r);}),this.logBuffer=[]);}static createLog(t,o,r){return {id:Math.random().toString(36).substring(2,9),level:t,message:o,timestamp:new Date().toISOString(),...r}}static addLog(t){this.dispatch?(this.dispatch({type:"ADD_LOG",log:t}),this.onLogAddedCallback?.(t)):this.logBuffer.push(t);}static debug(t,o){this.addLog(this.createLog("DEBUG",t,{title:o}));}static error(t,o){let r=t instanceof Error?t.message:t,i=t instanceof Error?t.stack:void 0;this.addLog(this.createLog("ERROR",r,{title:o||"Error",stack:i}));}static object(t,o){this.addLog(this.createLog("OBJECT","Object visualization",{title:o||"Data Object",data:t}));}static clear(){this.dispatch?this.dispatch({type:"CLEAR_LOGS"}):this.logBuffer=[];}};var k={logs:[],config:{persistence:false,persistenceDriver:"localStorage",maxLogs:500},unreadCount:0};function X(e,t){switch(t.type){case "ADD_LOG":{let o=[t.log,...e.logs].slice(0,e.config.maxLogs);return {...e,logs:o}}case "SET_LOGS":return {...e,logs:[...e.logs,...t.logs].slice(0,e.config.maxLogs)};case "CLEAR_LOGS":return {...e,logs:[],unreadCount:0};case "SET_CONFIG":return {...e,config:{...e.config,...t.config}};case "RESET_UNREAD":return {...e,unreadCount:0};case "INCREMENT_UNREAD":return {...e,unreadCount:e.unreadCount+1};default:return e}}var N=createContext(void 0),ve=({children:e,config:t})=>{let[o,r]=useReducer(X,{...k,config:{...k.config,...t}}),[i,s]=U.useState(false),a=useRef(null);return useEffect(()=>{p._setDispatcher(r,o.config.onLogAdded),o.config.persistence&&(a.current=R(o.config.persistenceDriver||"localStorage"),a.current.load().then(n=>{r({type:"SET_LOGS",logs:n});}));},[o.config.persistence,o.config.persistenceDriver]),useEffect(()=>{o.config.persistence&&a.current&&a.current.save(o.logs);},[o.logs,o.config.persistence]),jsx(N.Provider,{value:{state:o,dispatch:r,isPanelOpen:i,setIsPanelOpen:s},children:e})},u=()=>{let e=useContext(N);if(!e)throw new Error("useLoggerContext must be used within a LoggerProvider");return e};var Ce=()=>{let{state:e}=u(),t=useCallback((a,n)=>{p.debug(a,n);},[]),o=useCallback((a,n)=>{p.error(a,n);},[]),r=useCallback((a,n)=>{p.object(a,n);},[]),i=useCallback(()=>{p.clear();},[]),s=useCallback(()=>{let a="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),n=document.createElement("a");n.setAttribute("href",a),n.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(n),n.click(),n.remove();},[e.logs]);return {debug:t,error:o,object:r,clear:i,exportLogs:s,logs:e.logs,unreadCount:e.unreadCount}};var T=()=>{let{state:e,setIsPanelOpen:t}=u(),[o,r]=useState(null),i=useRef(false),s=useRef({x:0,y:0}),a=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true,s.current={x:l.clientX-c.left,y:l.clientY-c.top};},n=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true;let g=l.touches[0];s.current={x:g.clientX-c.left,y:g.clientY-c.top};},m=useCallback((l,c)=>{if(!i.current)return;let g=Math.max(10,Math.min(window.innerWidth-60,l-s.current.x)),h=Math.max(10,Math.min(window.innerHeight-60,c-s.current.y));r({x:g,y:h});},[]);useEffect(()=>{let l=h=>m(h.clientX,h.clientY),c=h=>m(h.touches[0].clientX,h.touches[0].clientY),g=()=>{i.current=false;};return window.addEventListener("mousemove",l),window.addEventListener("touchmove",c,{passive:false}),window.addEventListener("mouseup",g),window.addEventListener("touchend",g),()=>{window.removeEventListener("mousemove",l),window.removeEventListener("touchmove",c),window.removeEventListener("mouseup",g),window.removeEventListener("touchend",g);}},[m]),useEffect(()=>{let l=()=>{o&&r(c=>c?{x:Math.min(c.x,window.innerWidth-60),y:Math.min(c.y,window.innerHeight-60)}:null);};return window.addEventListener("resize",l),()=>window.removeEventListener("resize",l)},[o]);let x=()=>{i.current||t(true);},b=o?{left:`${o.x}px`,top:`${o.y}px`,right:"auto",bottom:"auto"}:{};return jsx("div",{className:"liql-floatingButton",style:b,onMouseDown:a,onTouchStart:n,onClick:x,"aria-label":"Open Logger",children:e.unreadCount>0&&jsx("div",{className:"liql-badge",children:e.unreadCount})})};var B=({log:e})=>{let[t,o]=useState(false),r=n=>new Date(n).toTimeString().split(" ")[0],i=n=>{try{return jsx("pre",{className:"liql-expandedContent",children:JSON.stringify(n,null,2)})}catch{return jsx("div",{children:"Error parsing object"})}},s=n=>{switch(n){case "DEBUG":return "\u{1F41E}";case "ERROR":return "\u274C";case "OBJECT":return "\u{1F4E6}";default:return "\u{1F4DD}"}},a=e.level.toLowerCase();return jsxs("div",{className:`liql-logItem liql-logItem-${a}`,onClick:()=>o(!t),children:[jsxs("div",{className:"liql-logMeta",children:[jsxs("span",{className:`liql-statusTag liql-tag-${a}`,children:[s(e.level)," ",e.level]}),jsx("span",{className:"liql-logTime",children:r(e.timestamp)})]}),jsxs("div",{className:"liql-logContent",children:[e.title&&jsxs("strong",{style:{color:"var(--liql-primary)"},children:[e.title,": "]}),e.message]}),t&&jsxs("div",{className:"liql-expandedContent",children:[e.stack&&jsxs("div",{style:{color:"var(--liql-error)",marginBottom:"8px"},children:[jsx("strong",{children:"Stack Trace:"}),jsx("pre",{style:{whiteSpace:"pre-wrap",fontSize:"10px",marginTop:"4px"},children:e.stack})]}),e.data&&jsxs("div",{children:[jsx("strong",{children:"Payload:"}),i(e.data)]}),!e.data&&!e.stack&&jsxs("div",{children:["Full message: ",e.message]})]})]})};var P=({logs:e,filter:t,search:o})=>{let r=U.useMemo(()=>e.filter(i=>{let s=t==="ALL"||i.level===t,a=o===""||i.message.toLowerCase().includes(o.toLowerCase())||(i.title||"").toLowerCase().includes(o.toLowerCase());return s&&a}).reverse(),[e,t,o]);return jsx("div",{className:"liql-logListContainer",children:jsx(Virtuoso,{style:{height:"100%"},data:r,itemContent:(i,s)=>jsx(B,{log:s},s.id)})})};var M=()=>{let{state:e,setIsPanelOpen:t,dispatch:o}=u(),[r,i]=useState("ALL"),[s,a]=useState(""),n=()=>{confirm("Are you sure you want to clear all logs?")&&o({type:"CLEAR_LOGS"});},m=()=>{let x="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),b=document.createElement("a");b.setAttribute("href",x),b.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(b),b.click(),b.remove();};return e?jsxs("div",{className:"liql-panel",style:{right:"20px",bottom:"20px",width:"440px",height:"680px"},children:[jsxs("div",{className:"liql-panelHeader",children:[jsx("div",{className:"liql-titleGroup",children:jsxs("span",{className:"liql-title",children:["ReactLoggerApp console [",e.logs.length,"]"]})}),jsxs("div",{className:"liql-controls",children:[jsx("button",{className:"liql-btnAction",onClick:m,title:"Export JSON",children:"\u{1F4E5}"}),jsx("button",{className:"liql-btnAction",onClick:n,title:"Clear Logs",children:"\u{1F5D1}\uFE0F"}),jsx("button",{className:"liql-btnAction",onClick:()=>t(false),title:"Minimize",children:"\u2796"})]})]}),jsxs("div",{className:"liql-filterBar",children:[jsx("input",{type:"text",placeholder:"Search entries...",className:"liql-searchInput",value:s,onChange:x=>a(x.target.value)}),jsxs("select",{className:"liql-selectFilter",value:r,onChange:x=>i(x.target.value),children:[jsx("option",{value:"ALL",children:"ALL"}),jsx("option",{value:"DEBUG",children:"DEBUG"}),jsx("option",{value:"ERROR",children:"ERROR"}),jsx("option",{value:"OBJECT",children:"OBJECTS"})]})]}),jsx(P,{logs:e.logs,filter:r,search:s}),jsxs("div",{className:"liql-footerActions",children:[jsx("div",{className:"liql-storageInfo",children:e.config.persistence?`DRIVER: ${e.config.persistenceDriver?.toUpperCase()}`:"SESSION MODE"}),jsx("button",{className:"liql-btnClose",onClick:()=>t(false),children:"CLOSE CONSOLE"})]})]}):null};var We=()=>{let{isPanelOpen:e}=u();return jsxs(Fragment,{children:[!e&&jsx(T,{}),e&&jsx(M,{})]})};export{p as Logger,ve as LoggerProvider,We as LoggerViewer,Ce as useLogger,u as useLoggerContext};//# sourceMappingURL=index.mjs.map
1
+ import U,{createContext,useReducer,useRef,useEffect,useContext,useCallback,useState}from'react';import {openDB}from'idb';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {Virtuoso}from'react-virtuoso';function C(e,{insertAt:t}={}){if(typeof document>"u")return;let o=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css",t==="top"&&o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e));}C(`:root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;width:440px;height:680px;right:20px;bottom:20px;z-index:999999;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none;background:#0f172a!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}}
2
+ `);var w=class{key;constructor(t="ionic_react_logger_logs"){this.key=t;}async save(t){try{localStorage.setItem(this.key,JSON.stringify(t));}catch(o){console.error("Failed to save logs to localStorage",o);}}async load(){try{let t=localStorage.getItem(this.key);return t?JSON.parse(t):[]}catch(t){return console.error("Failed to load logs from localStorage",t),[]}}async clear(){localStorage.removeItem(this.key);}};var G="IonicReactLoggerDB",v="logs",F=1,E=class{dbPromise;constructor(){this.dbPromise=openDB(G,F,{upgrade(t){t.objectStoreNames.contains(v)||t.createObjectStore(v,{keyPath:"id"});}});}async save(t){let r=(await this.dbPromise).transaction(v,"readwrite"),i=r.objectStore(v);await i.clear();for(let s of t)await i.put(s);await r.done;}async load(){return (await this.dbPromise).getAll(v)}async clear(){let o=(await this.dbPromise).transaction(v,"readwrite");await o.objectStore(v).clear(),await o.done;}};function k(e){return e==="indexedDB"?new E:new w}var p=class{static dispatch=null;static logBuffer=[];static onLogAddedCallback;static _setDispatcher(t,o){this.dispatch=t,this.onLogAddedCallback=o,this.logBuffer.length>0&&(this.logBuffer.forEach(r=>{this.dispatch({type:"ADD_LOG",log:r}),this.onLogAddedCallback?.(r);}),this.logBuffer=[]);}static createLog(t,o,r){return {id:Math.random().toString(36).substring(2,9),level:t,message:o,timestamp:new Date().toISOString(),...r}}static addLog(t){this.dispatch?(this.dispatch({type:"ADD_LOG",log:t}),this.onLogAddedCallback?.(t)):this.logBuffer.push(t);}static debug(t,o){this.addLog(this.createLog("DEBUG",t,{title:o}));}static error(t,o){let r=t instanceof Error?t.message:t,i=t instanceof Error?t.stack:void 0;this.addLog(this.createLog("ERROR",r,{title:o||"Error",stack:i}));}static object(t,o){this.addLog(this.createLog("OBJECT","Object visualization",{title:o||"Data Object",data:t}));}static clear(){this.dispatch?this.dispatch({type:"CLEAR_LOGS"}):this.logBuffer=[];}};var D={logs:[],config:{persistence:false,persistenceDriver:"localStorage",maxLogs:500},unreadCount:0};function X(e,t){switch(t.type){case "ADD_LOG":{let o=[t.log,...e.logs].slice(0,e.config.maxLogs);return {...e,logs:o}}case "SET_LOGS":return {...e,logs:[...e.logs,...t.logs].slice(0,e.config.maxLogs)};case "CLEAR_LOGS":return {...e,logs:[],unreadCount:0};case "SET_CONFIG":return {...e,config:{...e.config,...t.config}};case "RESET_UNREAD":return {...e,unreadCount:0};case "INCREMENT_UNREAD":return {...e,unreadCount:e.unreadCount+1};default:return e}}var N=createContext(void 0),ve=({children:e,config:t})=>{let[o,r]=useReducer(X,{...D,config:{...D.config,...t}}),[i,s]=U.useState(false),a=useRef(null);return useEffect(()=>{p._setDispatcher(r,o.config.onLogAdded),o.config.persistence&&(a.current=k(o.config.persistenceDriver||"localStorage"),a.current.load().then(n=>{r({type:"SET_LOGS",logs:n});}));},[o.config.persistence,o.config.persistenceDriver]),useEffect(()=>{o.config.persistence&&a.current&&a.current.save(o.logs);},[o.logs,o.config.persistence]),jsx(N.Provider,{value:{state:o,dispatch:r,isPanelOpen:i,setIsPanelOpen:s},children:e})},u=()=>{let e=useContext(N);if(!e)throw new Error("useLoggerContext must be used within a LoggerProvider");return e};var Ce=()=>{let{state:e}=u(),t=useCallback((a,n)=>{p.debug(a,n);},[]),o=useCallback((a,n)=>{p.error(a,n);},[]),r=useCallback((a,n)=>{p.object(a,n);},[]),i=useCallback(()=>{p.clear();},[]),s=useCallback(()=>{let a="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),n=document.createElement("a");n.setAttribute("href",a),n.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(n),n.click(),n.remove();},[e.logs]);return {debug:t,error:o,object:r,clear:i,exportLogs:s,logs:e.logs,unreadCount:e.unreadCount}};var T=()=>{let{state:e,setIsPanelOpen:t}=u(),[o,r]=useState(null),i=useRef(false),s=useRef({x:0,y:0}),a=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true,s.current={x:l.clientX-c.left,y:l.clientY-c.top};},n=l=>{let c=l.currentTarget.getBoundingClientRect();i.current=true;let g=l.touches[0];s.current={x:g.clientX-c.left,y:g.clientY-c.top};},m=useCallback((l,c)=>{if(!i.current)return;let g=Math.max(10,Math.min(window.innerWidth-60,l-s.current.x)),h=Math.max(10,Math.min(window.innerHeight-60,c-s.current.y));r({x:g,y:h});},[]);useEffect(()=>{let l=h=>m(h.clientX,h.clientY),c=h=>m(h.touches[0].clientX,h.touches[0].clientY),g=()=>{i.current=false;};return window.addEventListener("mousemove",l),window.addEventListener("touchmove",c,{passive:false}),window.addEventListener("mouseup",g),window.addEventListener("touchend",g),()=>{window.removeEventListener("mousemove",l),window.removeEventListener("touchmove",c),window.removeEventListener("mouseup",g),window.removeEventListener("touchend",g);}},[m]),useEffect(()=>{let l=()=>{o&&r(c=>c?{x:Math.min(c.x,window.innerWidth-60),y:Math.min(c.y,window.innerHeight-60)}:null);};return window.addEventListener("resize",l),()=>window.removeEventListener("resize",l)},[o]);let x=()=>{i.current||t(true);},b=o?{left:`${o.x}px`,top:`${o.y}px`,right:"auto",bottom:"auto"}:{};return jsx("div",{className:"liql-floatingButton",style:b,onMouseDown:a,onTouchStart:n,onClick:x,"aria-label":"Open Logger",children:e.unreadCount>0&&jsx("div",{className:"liql-badge",children:e.unreadCount})})};var B=({log:e})=>{let[t,o]=useState(false),r=n=>new Date(n).toTimeString().split(" ")[0],i=n=>{try{return jsx("pre",{className:"liql-expandedContent",children:JSON.stringify(n,null,2)})}catch{return jsx("div",{children:"Error parsing object"})}},s=n=>{switch(n){case "DEBUG":return "\u{1F41E}";case "ERROR":return "\u274C";case "OBJECT":return "\u{1F4E6}";default:return "\u{1F4DD}"}},a=e.level.toLowerCase();return jsxs("div",{className:`liql-logItem liql-logItem-${a}`,onClick:()=>o(!t),children:[jsxs("div",{className:"liql-logMeta",children:[jsxs("span",{className:`liql-statusTag liql-tag-${a}`,children:[s(e.level)," ",e.level]}),jsx("span",{className:"liql-logTime",children:r(e.timestamp)})]}),jsxs("div",{className:"liql-logContent",children:[e.title&&jsxs("strong",{style:{color:"var(--liql-primary)"},children:[e.title,": "]}),e.message]}),t&&jsxs("div",{className:"liql-expandedContent",children:[e.stack&&jsxs("div",{style:{color:"var(--liql-error)",marginBottom:"8px"},children:[jsx("strong",{children:"Stack Trace:"}),jsx("pre",{style:{whiteSpace:"pre-wrap",fontSize:"10px",marginTop:"4px"},children:e.stack})]}),e.data&&jsxs("div",{children:[jsx("strong",{children:"Payload:"}),i(e.data)]}),!e.data&&!e.stack&&jsxs("div",{children:["Full message: ",e.message]})]})]})};var P=({logs:e,filter:t,search:o})=>{let r=U.useMemo(()=>e.filter(i=>{let s=t==="ALL"||i.level===t,a=o===""||i.message.toLowerCase().includes(o.toLowerCase())||(i.title||"").toLowerCase().includes(o.toLowerCase());return s&&a}).reverse(),[e,t,o]);return jsx("div",{className:"liql-logListContainer",children:jsx(Virtuoso,{style:{height:"100%"},data:r,itemContent:(i,s)=>jsx(B,{log:s},s.id)})})};var M=()=>{let{state:e,setIsPanelOpen:t,dispatch:o}=u(),[r,i]=useState("ALL"),[s,a]=useState(""),n=()=>{confirm("Are you sure you want to clear all logs?")&&o({type:"CLEAR_LOGS"});},m=()=>{let x="data:text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(e.logs,null,2)),b=document.createElement("a");b.setAttribute("href",x),b.setAttribute("download",`logs_${new Date().getTime()}.json`),document.body.appendChild(b),b.click(),b.remove();};return e?jsxs("div",{className:"liql-panel",children:[jsxs("div",{className:"liql-panelHeader",children:[jsx("div",{className:"liql-titleGroup",children:jsxs("span",{className:"liql-title",children:["ReactLoggerApp console [",e.logs.length,"]"]})}),jsxs("div",{className:"liql-controls",children:[jsx("button",{className:"liql-btnAction",onClick:m,title:"Export JSON",children:"\u{1F4E5}"}),jsx("button",{className:"liql-btnAction",onClick:n,title:"Clear Logs",children:"\u{1F5D1}\uFE0F"}),jsx("button",{className:"liql-btnAction",onClick:()=>t(false),title:"Minimize",children:"\u2796"})]})]}),jsxs("div",{className:"liql-filterBar",children:[jsx("input",{type:"text",placeholder:"Search entries...",className:"liql-searchInput",value:s,onChange:x=>a(x.target.value)}),jsxs("select",{className:"liql-selectFilter",value:r,onChange:x=>i(x.target.value),children:[jsx("option",{value:"ALL",children:"ALL"}),jsx("option",{value:"DEBUG",children:"DEBUG"}),jsx("option",{value:"ERROR",children:"ERROR"}),jsx("option",{value:"OBJECT",children:"OBJECTS"})]})]}),jsx(P,{logs:e.logs,filter:r,search:s}),jsxs("div",{className:"liql-footerActions",children:[jsx("div",{className:"liql-storageInfo",children:e.config.persistence?`DRIVER: ${e.config.persistenceDriver?.toUpperCase()}`:"SESSION MODE"}),jsx("button",{className:"liql-btnClose",onClick:()=>t(false),children:"CLOSE CONSOLE"})]})]}):null};var We=()=>{let{isPanelOpen:e}=u();return jsxs(Fragment,{children:[!e&&jsx(T,{}),e&&jsx(M,{})]})};export{p as Logger,ve as LoggerProvider,We as LoggerViewer,Ce as useLogger,u as useLoggerContext};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["#style-inject:#style-inject","../src/styles/logger.css","../src/storage/localStorageDriver.ts","../src/storage/indexedDBDriver.ts","../src/storage/index.ts","../src/Logger.ts","../src/context/LoggerContext.tsx","../src/hooks/useLogger.ts","../src/components/FloatingButton.tsx","../src/components/LogItem.tsx","../src/components/LogList.tsx","../src/components/LogPanel.tsx","../src/components/LoggerViewer.tsx"],"names":["styleInject","css","insertAt","head","style","LocalStorageDriver","key","logs","e","data","DB_NAME","STORE_NAME","DB_VERSION","IndexedDBDriver","openDB","db","tx","store","log","getStorageDriver","type","Logger","dispatch","onLogAdded","level","message","extra","title","err","stack","initialState","loggerReducer","state","action","newLogs","LoggerContext","createContext","LoggerProvider","children","config","useReducer","isPanelOpen","setIsPanelOpen","React","storageRef","useRef","useEffect","loadedLogs","jsx","useLoggerContext","context","useContext","useLogger","debug","useCallback","error","object","clear","exportLogs","dataStr","downloadAnchorNode","FloatingButton","position","setPosition","useState","isDragging","dragOffset","handleMouseDown","rect","handleTouchStart","touch","handleMove","clientX","clientY","nextX","nextY","onMouseMove","onTouchMove","onEnd","handleResize","prev","handleClick","dynamicStyle","LogItem","isExpanded","setIsExpanded","formatTime","isoString","renderJson","getIcon","levelClass","jsxs","LogList","filter","search","filteredLogs","matchesFilter","matchesSearch","Virtuoso","_index","LogPanel","setFilter","setSearch","clearLogs","LoggerViewer","Fragment"],"mappings":"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","file":"index.mjs","sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: \\\"Inter\\\", -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;z-index:100000;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none}}\\n\")","import { LogEntry, StorageDriver } from '../types';\n\nexport class LocalStorageDriver implements StorageDriver {\n private key: string;\n\n constructor(key: string = 'ionic_react_logger_logs') {\n this.key = key;\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n try {\n localStorage.setItem(this.key, JSON.stringify(logs));\n } catch (e) {\n console.error('Failed to save logs to localStorage', e);\n }\n }\n\n async load(): Promise<LogEntry[]> {\n try {\n const data = localStorage.getItem(this.key);\n return data ? JSON.parse(data) : [];\n } catch (e) {\n console.error('Failed to load logs from localStorage', e);\n return [];\n }\n }\n\n async clear(): Promise<void> {\n localStorage.removeItem(this.key);\n }\n}\n","import { openDB, IDBPDatabase } from 'idb';\nimport { LogEntry, StorageDriver } from '../types';\n\nconst DB_NAME = 'IonicReactLoggerDB';\nconst STORE_NAME = 'logs';\nconst DB_VERSION = 1;\n\nexport class IndexedDBDriver implements StorageDriver {\n private dbPromise: Promise<IDBPDatabase>;\n\n constructor() {\n this.dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n },\n });\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const store = tx.objectStore(STORE_NAME);\n\n // Clear existing logs first or manage them as needed\n // Simple implementation: clear and re-save everything to match the expected behavior of StorageDriver\n await store.clear();\n for (const log of logs) {\n await store.put(log);\n }\n await tx.done;\n }\n\n async load(): Promise<LogEntry[]> {\n const db = await this.dbPromise;\n return db.getAll(STORE_NAME);\n }\n\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n await tx.objectStore(STORE_NAME).clear();\n await tx.done;\n }\n}\n","import { StorageDriver, LogEntry } from '../types';\nimport { LocalStorageDriver } from './localStorageDriver';\nimport { IndexedDBDriver } from './indexedDBDriver';\n\nexport function getStorageDriver(type: 'localStorage' | 'indexedDB'): StorageDriver {\n if (type === 'indexedDB') {\n return new IndexedDBDriver();\n }\n return new LocalStorageDriver();\n}\n\nexport * from './localStorageDriver';\nexport * from './indexedDBDriver';\n","import { LogEntry, LogLevel } from './types';\n\ntype LoggerDispatch = (action: { type: 'ADD_LOG'; log: LogEntry } | { type: 'CLEAR_LOGS' }) => void;\n\n/**\n * Global Logger class to support logging from plain TypeScript classes\n * and handle early logs before the React Provider is mounted.\n */\nexport class Logger {\n private static dispatch: LoggerDispatch | null = null;\n private static logBuffer: LogEntry[] = [];\n private static onLogAddedCallback?: (log: LogEntry) => void;\n\n /**\n * Internal method to initialize the dispatcher from the React context.\n */\n static _setDispatcher(dispatch: LoggerDispatch, onLogAdded?: (log: LogEntry) => void) {\n this.dispatch = dispatch;\n this.onLogAddedCallback = onLogAdded;\n\n // Flush buffer\n if (this.logBuffer.length > 0) {\n this.logBuffer.forEach(log => {\n this.dispatch!({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n });\n this.logBuffer = [];\n }\n }\n\n private static createLog(level: LogLevel, message: string, extra?: { title?: string, data?: any, stack?: string }): LogEntry {\n return {\n id: Math.random().toString(36).substring(2, 9),\n level,\n message,\n timestamp: new Date().toISOString(),\n ...extra\n };\n }\n\n private static addLog(log: LogEntry) {\n if (this.dispatch) {\n this.dispatch({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n } else {\n this.logBuffer.push(log);\n }\n }\n\n /**\n * Log a debug message (Blue neon)\n */\n static debug(message: string, title?: string) {\n this.addLog(this.createLog('DEBUG', message, { title }));\n }\n\n /**\n * Log an error (Red neon). Supports Error objects for automatic stack trace capture.\n */\n static error(err: string | Error, title?: string) {\n const message = err instanceof Error ? err.message : err;\n const stack = err instanceof Error ? err.stack : undefined;\n this.addLog(this.createLog('ERROR', message, { title: title || 'Error', stack }));\n }\n\n /**\n * Log an object for visualization (Green neon).\n */\n static object(data: any, title?: string) {\n this.addLog(this.createLog('OBJECT', 'Object visualization', { title: title || 'Data Object', data }));\n }\n\n /**\n * Clear all logs.\n */\n static clear() {\n if (this.dispatch) {\n this.dispatch({ type: 'CLEAR_LOGS' });\n } else {\n this.logBuffer = [];\n }\n }\n}\n","import React, { createContext, useContext, useReducer, useEffect, useCallback, useRef } from 'react';\nimport { LogEntry, LogLevel, LoggerConfig, StorageDriver } from '../types';\nimport { getStorageDriver } from '../storage';\nimport { Logger } from '../Logger';\n\ninterface LoggerState {\n logs: LogEntry[];\n config: LoggerConfig;\n unreadCount: number;\n}\n\ntype LoggerAction =\n | { type: 'ADD_LOG'; log: LogEntry }\n | { type: 'SET_LOGS'; logs: LogEntry[] }\n | { type: 'CLEAR_LOGS' }\n | { type: 'SET_CONFIG'; config: Partial<LoggerConfig> }\n | { type: 'RESET_UNREAD' }\n | { type: 'INCREMENT_UNREAD' };\n\nconst initialState: LoggerState = {\n logs: [],\n config: {\n persistence: false,\n persistenceDriver: 'localStorage',\n maxLogs: 500,\n },\n unreadCount: 0,\n};\n\nfunction loggerReducer(state: LoggerState, action: LoggerAction): LoggerState {\n switch (action.type) {\n case 'ADD_LOG': {\n const newLogs = [action.log, ...state.logs].slice(0, state.config.maxLogs);\n return {\n ...state,\n logs: newLogs,\n };\n }\n case 'SET_LOGS':\n return { ...state, logs: [...state.logs, ...action.logs].slice(0, state.config.maxLogs) };\n case 'CLEAR_LOGS':\n return { ...state, logs: [], unreadCount: 0 };\n case 'SET_CONFIG':\n return { ...state, config: { ...state.config, ...action.config } };\n case 'RESET_UNREAD':\n return { ...state, unreadCount: 0 };\n case 'INCREMENT_UNREAD':\n return { ...state, unreadCount: state.unreadCount + 1 };\n default:\n return state;\n }\n}\n\ninterface LoggerContextType {\n state: LoggerState;\n dispatch: React.Dispatch<LoggerAction>;\n isPanelOpen: boolean;\n setIsPanelOpen: (open: boolean) => void;\n}\n\nconst LoggerContext = createContext<LoggerContextType | undefined>(undefined);\n\n/**\n * Provides the logging context to all child components.\n * This should wrap your entire application (e.g. in App.tsx).\n * \n * @param config Optional initial configuration for persistence and limits.\n */\nexport const LoggerProvider: React.FC<{ children: React.ReactNode; config?: LoggerConfig }> = ({\n children,\n config,\n}) => {\n const [state, dispatch] = useReducer(loggerReducer, {\n ...initialState,\n config: { ...initialState.config, ...config },\n });\n const [isPanelOpen, setIsPanelOpen] = React.useState(false);\n const storageRef = useRef<StorageDriver | null>(null);\n\n // Initialize storage driver and Logger singleton\n useEffect(() => {\n Logger._setDispatcher(dispatch, state.config.onLogAdded);\n\n if (state.config.persistence) {\n storageRef.current = getStorageDriver(state.config.persistenceDriver || 'localStorage');\n storageRef.current.load().then((loadedLogs) => {\n dispatch({ type: 'SET_LOGS', logs: loadedLogs });\n });\n }\n }, [state.config.persistence, state.config.persistenceDriver]);\n\n // Persist logs when they change\n useEffect(() => {\n if (state.config.persistence && storageRef.current) {\n storageRef.current.save(state.logs);\n }\n }, [state.logs, state.config.persistence]);\n\n return (\n <LoggerContext.Provider value={{ state, dispatch, isPanelOpen, setIsPanelOpen }}>\n {children}\n </LoggerContext.Provider>\n );\n};\n\n/**\n * Internal hook to access the logger context state.\n * Use the public `useLogger` hook for standard logging operations.\n */\nexport const useLoggerContext = () => {\n const context = useContext(LoggerContext);\n if (!context) {\n throw new Error('useLoggerContext must be used within a LoggerProvider');\n }\n return context;\n};\n","import { useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { Logger } from '../Logger';\n\n/**\n * Main hook to interact with the Liquid Glass Logger.\n * \n * Provides methods for different logging levels and allows accessing\n * the current state of logs.\n * \n * @example\n * ```tsx\n * const { debug, error, object } = useLogger();\n * \n * debug('App started');\n * error(new Error('Failed to fetch'), 'API Error');\n * object({ user: 'John' }, 'Current User');\n * ```\n */\nexport const useLogger = () => {\n const { state } = useLoggerContext();\n\n /**\n * Log a debug message (Blue neon)\n */\n const debug = useCallback((message: string, title?: string) => {\n Logger.debug(message, title);\n }, []);\n\n /**\n * Log an error. If an Error object is passed, it automatically captures the stack trace.\n * (Red neon)\n */\n const error = useCallback((err: string | Error, title?: string) => {\n Logger.error(err, title);\n }, []);\n\n /**\n * Log a data object for inspection.\n * (Green neon)\n */\n const object = useCallback((data: any, title?: string) => {\n Logger.object(data, title);\n }, []);\n\n /**\n * Clears all logs from the current session and persistent storage.\n */\n const clear = useCallback(() => {\n Logger.clear();\n }, []);\n\n /**\n * Exports all logs as a JSON file download.\n */\n const exportLogs = useCallback(() => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n }, [state.logs]);\n\n return {\n /** Register a debug message */\n debug,\n /** Register an error or exception */\n error,\n /** Register an object for JSON visualization */\n object,\n /** Clear all history */\n clear,\n /** Download history as JSON */\n exportLogs,\n /** List of all captured logs */\n logs: state.logs,\n /** Count of logs not yet viewed */\n unreadCount: state.unreadCount,\n };\n};\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\n\n/**\n * Draggable floating trigger button.\n * Uses hybrid positioning (CSS initial + JS drag) for maximum compatibility.\n */\nexport const FloatingButton: React.FC = () => {\n const { state, setIsPanelOpen } = useLoggerContext();\n\n // Default to null to use CSS positioning initially\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null);\n const isDragging = useRef(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n\n const handleMouseDown = (e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top\n };\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n const touch = e.touches[0];\n dragOffset.current = {\n x: touch.clientX - rect.left,\n y: touch.clientY - rect.top\n };\n };\n\n const handleMove = useCallback((clientX: number, clientY: number) => {\n if (!isDragging.current) return;\n\n // Keep button within viewport\n const nextX = Math.max(10, Math.min(window.innerWidth - 60, clientX - dragOffset.current.x));\n const nextY = Math.max(10, Math.min(window.innerHeight - 60, clientY - dragOffset.current.y));\n\n setPosition({ x: nextX, y: nextY });\n }, []);\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => handleMove(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent) => handleMove(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n isDragging.current = false;\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n window.addEventListener('mouseup', onEnd);\n window.addEventListener('touchend', onEnd);\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('mouseup', onEnd);\n window.removeEventListener('touchend', onEnd);\n };\n }, [handleMove]);\n\n // Handle window resize to keep button in bounds\n useEffect(() => {\n const handleResize = () => {\n if (position) {\n setPosition(prev => {\n if (!prev) return null;\n return {\n x: Math.min(prev.x, window.innerWidth - 60),\n y: Math.min(prev.y, window.innerHeight - 60)\n };\n });\n }\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [position]);\n\n const handleClick = () => {\n if (isDragging.current) return;\n setIsPanelOpen(true);\n };\n\n // If never moved, let CSS handle it. If moved, use absolute pixel coordinates.\n const dynamicStyle: React.CSSProperties = position\n ? { left: `${position.x}px`, top: `${position.y}px`, right: 'auto', bottom: 'auto' }\n : {};\n\n return (\n <div\n className=\"liql-floatingButton\"\n style={dynamicStyle}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n onClick={handleClick}\n aria-label=\"Open Logger\"\n >\n {state.unreadCount > 0 && (\n <div className=\"liql-badge\">{state.unreadCount}</div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { LogEntry } from '../types';\n\ninterface LogItemProps {\n log: LogEntry;\n}\n\nexport const LogItem: React.FC<LogItemProps> = ({ log }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const formatTime = (isoString: string) => {\n const date = new Date(isoString);\n return date.toTimeString().split(' ')[0];\n };\n\n const renderJson = (data: any) => {\n try {\n return (\n <pre className=\"liql-expandedContent\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n } catch (e) {\n return <div>Error parsing object</div>;\n }\n };\n\n const getIcon = (level: string) => {\n switch (level) {\n case 'DEBUG': return '🐞';\n case 'ERROR': return '❌';\n case 'OBJECT': return '📦';\n default: return '📝';\n }\n };\n\n const levelClass = log.level.toLowerCase();\n\n return (\n <div\n className={`liql-logItem liql-logItem-${levelClass}`}\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"liql-logMeta\">\n <span className={`liql-statusTag liql-tag-${levelClass}`}>\n {getIcon(log.level)} {log.level}\n </span>\n <span className=\"liql-logTime\">{formatTime(log.timestamp)}</span>\n </div>\n <div className=\"liql-logContent\">\n {log.title && <strong style={{ color: 'var(--liql-primary)' }}>{log.title}: </strong>}\n {log.message}\n </div>\n\n {isExpanded && (\n <div className=\"liql-expandedContent\">\n {log.stack && (\n <div style={{ color: 'var(--liql-error)', marginBottom: '8px' }}>\n <strong>Stack Trace:</strong>\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: '10px', marginTop: '4px' }}>{log.stack}</pre>\n </div>\n )}\n {log.data && (\n <div>\n <strong>Payload:</strong>\n {renderJson(log.data)}\n </div>\n )}\n {!log.data && !log.stack && <div>Full message: {log.message}</div>}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { Virtuoso } from 'react-virtuoso';\nimport { LogItem } from './LogItem';\nimport { LogEntry } from '../types';\n\ninterface LogListProps {\n logs: LogEntry[];\n filter: string;\n search: string;\n}\n\nexport const LogList: React.FC<LogListProps> = ({ logs, filter, search }) => {\n const filteredLogs = React.useMemo(() => {\n return logs.filter(log => {\n const matchesFilter = filter === 'ALL' || log.level === filter;\n const matchesSearch = search === '' ||\n log.message.toLowerCase().includes(search.toLowerCase()) ||\n (log.title || '').toLowerCase().includes(search.toLowerCase());\n return matchesFilter && matchesSearch;\n }).reverse();\n }, [logs, filter, search]);\n\n return (\n <div className=\"liql-logListContainer\">\n <Virtuoso\n style={{ height: '100%' }}\n data={filteredLogs}\n itemContent={(_index: number, log: LogEntry) => <LogItem key={log.id} log={log} />}\n />\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { LogList } from './LogList';\n\n/**\n * Main 'Liquid Glass' logging console.\n * Contains the log list, filtering, search, and action controls.\n */\nexport const LogPanel: React.FC = () => {\n const { state, setIsPanelOpen, dispatch } = useLoggerContext();\n const [filter, setFilter] = useState('ALL');\n const [search, setSearch] = useState('');\n\n const clearLogs = () => {\n if (confirm('Are you sure you want to clear all logs?')) {\n dispatch({ type: 'CLEAR_LOGS' });\n }\n };\n\n const exportLogs = () => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n };\n\n if (!state) return null;\n\n return (\n <div className=\"liql-panel\" style={{ right: '20px', bottom: '20px', width: '440px', height: '680px' }}>\n <div className=\"liql-panelHeader\">\n <div className=\"liql-titleGroup\">\n <span className=\"liql-title\">ReactLoggerApp console [{state.logs.length}]</span>\n </div>\n <div className=\"liql-controls\">\n <button className=\"liql-btnAction\" onClick={exportLogs} title=\"Export JSON\">📥</button>\n <button className=\"liql-btnAction\" onClick={clearLogs} title=\"Clear Logs\">🗑️</button>\n <button className=\"liql-btnAction\" onClick={() => setIsPanelOpen(false)} title=\"Minimize\">➖</button>\n </div>\n </div>\n\n <div className=\"liql-filterBar\">\n <input\n type=\"text\"\n placeholder=\"Search entries...\"\n className=\"liql-searchInput\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n <select\n className=\"liql-selectFilter\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n >\n <option value=\"ALL\">ALL</option>\n <option value=\"DEBUG\">DEBUG</option>\n <option value=\"ERROR\">ERROR</option>\n <option value=\"OBJECT\">OBJECTS</option>\n </select>\n </div>\n\n <LogList logs={state.logs} filter={filter} search={search} />\n\n <div className=\"liql-footerActions\">\n <div className=\"liql-storageInfo\">\n {state.config.persistence ? `DRIVER: ${state.config.persistenceDriver?.toUpperCase()}` : 'SESSION MODE'}\n </div>\n <button className=\"liql-btnClose\" onClick={() => setIsPanelOpen(false)}>CLOSE CONSOLE</button>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { FloatingButton } from './FloatingButton';\nimport { LogPanel } from './LogPanel';\n\n/**\n * Main entry point for the Logger UI.\n * Renders the floating trigger button and conditionally shows the glass panel.\n * Should be placed at the root level of your application.\n */\nexport const LoggerViewer: React.FC = () => {\n const { isPanelOpen } = useLoggerContext();\n\n return (\n <>\n {!isPanelOpen && <FloatingButton />}\n {isPanelOpen && <LogPanel />}\n </>\n );\n};\n"]}
1
+ {"version":3,"sources":["#style-inject:#style-inject","../src/styles/logger.css","../src/storage/localStorageDriver.ts","../src/storage/indexedDBDriver.ts","../src/storage/index.ts","../src/Logger.ts","../src/context/LoggerContext.tsx","../src/hooks/useLogger.ts","../src/components/FloatingButton.tsx","../src/components/LogItem.tsx","../src/components/LogList.tsx","../src/components/LogPanel.tsx","../src/components/LoggerViewer.tsx"],"names":["styleInject","css","insertAt","head","style","LocalStorageDriver","key","logs","e","data","DB_NAME","STORE_NAME","DB_VERSION","IndexedDBDriver","openDB","db","tx","store","log","getStorageDriver","type","Logger","dispatch","onLogAdded","level","message","extra","title","err","stack","initialState","loggerReducer","state","action","newLogs","LoggerContext","createContext","LoggerProvider","children","config","useReducer","isPanelOpen","setIsPanelOpen","React","storageRef","useRef","useEffect","loadedLogs","jsx","useLoggerContext","context","useContext","useLogger","debug","useCallback","error","object","clear","exportLogs","dataStr","downloadAnchorNode","FloatingButton","position","setPosition","useState","isDragging","dragOffset","handleMouseDown","rect","handleTouchStart","touch","handleMove","clientX","clientY","nextX","nextY","onMouseMove","onTouchMove","onEnd","handleResize","prev","handleClick","dynamicStyle","LogItem","isExpanded","setIsExpanded","formatTime","isoString","renderJson","getIcon","levelClass","jsxs","LogList","filter","search","filteredLogs","matchesFilter","matchesSearch","Virtuoso","_index","LogPanel","setFilter","setSearch","clearLogs","LoggerViewer","Fragment"],"mappings":"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","file":"index.mjs","sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\":root{--liql-primary: #6b21a8;--liql-primary-glow: rgba(107, 33, 168, .5);--liql-error: #ff4d4d;--liql-error-glow: rgba(255, 77, 77, .4);--liql-object: #00ff88;--liql-object-glow: rgba(0, 255, 136, .4);--liql-glass-bg: rgba(15, 23, 42, .9);--liql-glass-border: rgba(255, 255, 255, .1);--liql-glass-edge: rgba(255, 255, 255, .05);--liql-text-main: #f8fafc;--liql-text-muted: #94a3b8;--liql-font-family: \\\"Inter\\\", -apple-system, BlinkMacSystemFont, \\\"Segoe UI\\\", Roboto, sans-serif}.liql-floatingButton{position:fixed;right:20px;bottom:20px;width:50px;height:50px;border-radius:50%;background:radial-gradient(circle at 30% 30%,rgba(255,255,255,.15),transparent),linear-gradient(135deg,#6b21a8,#4c1d95);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 8px 32px #0006,0 0 15px var(--liql-primary-glow);display:flex;align-items:center;justify-content:center;cursor:grab;z-index:99999;border:1px solid var(--liql-glass-border);transition:all .4s cubic-bezier(.175,.885,.32,1.275);font-size:26px;color:#fff;user-select:none;touch-action:none}.liql-floatingButton:hover{transform:scale(1.1) rotate(5deg);box-shadow:0 12px 40px #00000080,0 0 25px var(--liql-primary-glow)}.liql-badge{position:absolute;top:-2px;right:-2px;background:var(--liql-error);color:#fff;border-radius:12px;min-width:20px;height:20px;padding:0 6px;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #0f172a;box-shadow:0 0 10px var(--liql-error-glow)}.liql-panel{position:fixed;background:var(--liql-glass-bg);backdrop-filter:blur(25px) saturate(180%);-webkit-backdrop-filter:blur(25px) saturate(180%);box-shadow:0 20px 50px #0009,inset 0 0 0 1px var(--liql-glass-edge);border:1px solid var(--liql-glass-border);border-radius:20px;display:flex;flex-direction:column;width:440px;height:680px;right:20px;bottom:20px;z-index:999999;overflow:hidden;font-family:var(--liql-font-family);color:var(--liql-text-main);animation:liql-slideUp .4s cubic-bezier(.23,1,.32,1)}.liql-panelHeader{background:#ffffff0d;padding:16px 20px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--liql-glass-border)}.liql-title{font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12px;color:var(--liql-text-muted)}.liql-controls{display:flex;gap:12px}.liql-btnAction{background:#ffffff14;border:1px solid var(--liql-glass-border);color:var(--liql-text-main);width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.liql-btnAction:hover{background:#ffffff26;transform:translateY(-2px)}.liql-filterBar{padding:12px 20px;display:flex;gap:10px;background:#0003;align-items:center}.liql-searchInput{flex:1;background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px 14px;color:#fff;font-size:13px}.liql-searchInput:focus{outline:none;border-color:var(--liql-primary);background:#ffffff14}.liql-selectFilter{background:#ffffff0d;border:1px solid var(--liql-glass-border);border-radius:10px;padding:8px;color:#fff;font-size:12px;cursor:pointer}.liql-logListContainer{flex:1;padding:10px}.liql-logItem{margin-bottom:10px;padding:16px;border-radius:14px;background:#ffffff08;border:1px solid var(--liql-glass-border);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden}.liql-logItem:hover{background:#ffffff0f;border-color:#fff3;transform:scale(1.01)}.liql-logItem-debug{border-left:4px solid var(--liql-primary)}.liql-logItem-error{border-left:4px solid var(--liql-error);box-shadow:inset 0 0 15px var(--liql-error-glow)}.liql-logItem-object{border-left:4px solid var(--liql-object);box-shadow:inset 0 0 15px var(--liql-object-glow)}.liql-logMeta{display:flex;justify-content:space-between;margin-bottom:8px;font-size:11px;font-weight:500;text-transform:uppercase}.liql-statusTag{padding:2px 8px;border-radius:6px;font-size:9px;font-weight:700}.liql-tag-debug{background:#3498db33;color:#3498db}.liql-tag-error{background:#ff4d4d33;color:#ff4d4d}.liql-tag-object{background:#0f83;color:#0f8}.liql-logTime{color:var(--liql-text-muted)}.liql-logContent{font-size:14px;line-height:1.5;color:#e2e8f0}.liql-expandedContent{margin-top:12px;padding:12px;background:#0000004d;border-radius:10px;font-family:JetBrains Mono,monospace;font-size:12px;border:1px solid var(--liql-glass-border);color:#a5f3fc;overflow-x:auto}.liql-footerActions{padding:14px 20px;background:#0003;display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--liql-glass-border)}.liql-storageInfo{font-size:10px;color:var(--liql-text-muted)}.liql-btnClose{background:linear-gradient(135deg,var(--liql-primary),#2980b9);border:none;padding:8px 16px;border-radius:8px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 4px 12px var(--liql-primary-glow)}@keyframes liql-slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@media(max-width:600px){.liql-panel{width:100%!important;height:100%!important;bottom:0!important;right:0!important;left:0!important;border-radius:0;animation:none;background:#0f172a!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important}}\\n\")","import { LogEntry, StorageDriver } from '../types';\n\nexport class LocalStorageDriver implements StorageDriver {\n private key: string;\n\n constructor(key: string = 'ionic_react_logger_logs') {\n this.key = key;\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n try {\n localStorage.setItem(this.key, JSON.stringify(logs));\n } catch (e) {\n console.error('Failed to save logs to localStorage', e);\n }\n }\n\n async load(): Promise<LogEntry[]> {\n try {\n const data = localStorage.getItem(this.key);\n return data ? JSON.parse(data) : [];\n } catch (e) {\n console.error('Failed to load logs from localStorage', e);\n return [];\n }\n }\n\n async clear(): Promise<void> {\n localStorage.removeItem(this.key);\n }\n}\n","import { openDB, IDBPDatabase } from 'idb';\nimport { LogEntry, StorageDriver } from '../types';\n\nconst DB_NAME = 'IonicReactLoggerDB';\nconst STORE_NAME = 'logs';\nconst DB_VERSION = 1;\n\nexport class IndexedDBDriver implements StorageDriver {\n private dbPromise: Promise<IDBPDatabase>;\n\n constructor() {\n this.dbPromise = openDB(DB_NAME, DB_VERSION, {\n upgrade(db) {\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME, { keyPath: 'id' });\n }\n },\n });\n }\n\n async save(logs: LogEntry[]): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n const store = tx.objectStore(STORE_NAME);\n\n // Clear existing logs first or manage them as needed\n // Simple implementation: clear and re-save everything to match the expected behavior of StorageDriver\n await store.clear();\n for (const log of logs) {\n await store.put(log);\n }\n await tx.done;\n }\n\n async load(): Promise<LogEntry[]> {\n const db = await this.dbPromise;\n return db.getAll(STORE_NAME);\n }\n\n async clear(): Promise<void> {\n const db = await this.dbPromise;\n const tx = db.transaction(STORE_NAME, 'readwrite');\n await tx.objectStore(STORE_NAME).clear();\n await tx.done;\n }\n}\n","import { StorageDriver, LogEntry } from '../types';\nimport { LocalStorageDriver } from './localStorageDriver';\nimport { IndexedDBDriver } from './indexedDBDriver';\n\nexport function getStorageDriver(type: 'localStorage' | 'indexedDB'): StorageDriver {\n if (type === 'indexedDB') {\n return new IndexedDBDriver();\n }\n return new LocalStorageDriver();\n}\n\nexport * from './localStorageDriver';\nexport * from './indexedDBDriver';\n","import { LogEntry, LogLevel } from './types';\n\ntype LoggerDispatch = (action: { type: 'ADD_LOG'; log: LogEntry } | { type: 'CLEAR_LOGS' }) => void;\n\n/**\n * Global Logger class to support logging from plain TypeScript classes\n * and handle early logs before the React Provider is mounted.\n */\nexport class Logger {\n private static dispatch: LoggerDispatch | null = null;\n private static logBuffer: LogEntry[] = [];\n private static onLogAddedCallback?: (log: LogEntry) => void;\n\n /**\n * Internal method to initialize the dispatcher from the React context.\n */\n static _setDispatcher(dispatch: LoggerDispatch, onLogAdded?: (log: LogEntry) => void) {\n this.dispatch = dispatch;\n this.onLogAddedCallback = onLogAdded;\n\n // Flush buffer\n if (this.logBuffer.length > 0) {\n this.logBuffer.forEach(log => {\n this.dispatch!({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n });\n this.logBuffer = [];\n }\n }\n\n private static createLog(level: LogLevel, message: string, extra?: { title?: string, data?: any, stack?: string }): LogEntry {\n return {\n id: Math.random().toString(36).substring(2, 9),\n level,\n message,\n timestamp: new Date().toISOString(),\n ...extra\n };\n }\n\n private static addLog(log: LogEntry) {\n if (this.dispatch) {\n this.dispatch({ type: 'ADD_LOG', log });\n this.onLogAddedCallback?.(log);\n } else {\n this.logBuffer.push(log);\n }\n }\n\n /**\n * Log a debug message (Blue neon)\n */\n static debug(message: string, title?: string) {\n this.addLog(this.createLog('DEBUG', message, { title }));\n }\n\n /**\n * Log an error (Red neon). Supports Error objects for automatic stack trace capture.\n */\n static error(err: string | Error, title?: string) {\n const message = err instanceof Error ? err.message : err;\n const stack = err instanceof Error ? err.stack : undefined;\n this.addLog(this.createLog('ERROR', message, { title: title || 'Error', stack }));\n }\n\n /**\n * Log an object for visualization (Green neon).\n */\n static object(data: any, title?: string) {\n this.addLog(this.createLog('OBJECT', 'Object visualization', { title: title || 'Data Object', data }));\n }\n\n /**\n * Clear all logs.\n */\n static clear() {\n if (this.dispatch) {\n this.dispatch({ type: 'CLEAR_LOGS' });\n } else {\n this.logBuffer = [];\n }\n }\n}\n","import React, { createContext, useContext, useReducer, useEffect, useCallback, useRef } from 'react';\nimport { LogEntry, LogLevel, LoggerConfig, StorageDriver } from '../types';\nimport { getStorageDriver } from '../storage';\nimport { Logger } from '../Logger';\n\ninterface LoggerState {\n logs: LogEntry[];\n config: LoggerConfig;\n unreadCount: number;\n}\n\ntype LoggerAction =\n | { type: 'ADD_LOG'; log: LogEntry }\n | { type: 'SET_LOGS'; logs: LogEntry[] }\n | { type: 'CLEAR_LOGS' }\n | { type: 'SET_CONFIG'; config: Partial<LoggerConfig> }\n | { type: 'RESET_UNREAD' }\n | { type: 'INCREMENT_UNREAD' };\n\nconst initialState: LoggerState = {\n logs: [],\n config: {\n persistence: false,\n persistenceDriver: 'localStorage',\n maxLogs: 500,\n },\n unreadCount: 0,\n};\n\nfunction loggerReducer(state: LoggerState, action: LoggerAction): LoggerState {\n switch (action.type) {\n case 'ADD_LOG': {\n const newLogs = [action.log, ...state.logs].slice(0, state.config.maxLogs);\n return {\n ...state,\n logs: newLogs,\n };\n }\n case 'SET_LOGS':\n return { ...state, logs: [...state.logs, ...action.logs].slice(0, state.config.maxLogs) };\n case 'CLEAR_LOGS':\n return { ...state, logs: [], unreadCount: 0 };\n case 'SET_CONFIG':\n return { ...state, config: { ...state.config, ...action.config } };\n case 'RESET_UNREAD':\n return { ...state, unreadCount: 0 };\n case 'INCREMENT_UNREAD':\n return { ...state, unreadCount: state.unreadCount + 1 };\n default:\n return state;\n }\n}\n\ninterface LoggerContextType {\n state: LoggerState;\n dispatch: React.Dispatch<LoggerAction>;\n isPanelOpen: boolean;\n setIsPanelOpen: (open: boolean) => void;\n}\n\nconst LoggerContext = createContext<LoggerContextType | undefined>(undefined);\n\n/**\n * Provides the logging context to all child components.\n * This should wrap your entire application (e.g. in App.tsx).\n * \n * @param config Optional initial configuration for persistence and limits.\n */\nexport const LoggerProvider: React.FC<{ children: React.ReactNode; config?: LoggerConfig }> = ({\n children,\n config,\n}) => {\n const [state, dispatch] = useReducer(loggerReducer, {\n ...initialState,\n config: { ...initialState.config, ...config },\n });\n const [isPanelOpen, setIsPanelOpen] = React.useState(false);\n const storageRef = useRef<StorageDriver | null>(null);\n\n // Initialize storage driver and Logger singleton\n useEffect(() => {\n Logger._setDispatcher(dispatch, state.config.onLogAdded);\n\n if (state.config.persistence) {\n storageRef.current = getStorageDriver(state.config.persistenceDriver || 'localStorage');\n storageRef.current.load().then((loadedLogs) => {\n dispatch({ type: 'SET_LOGS', logs: loadedLogs });\n });\n }\n }, [state.config.persistence, state.config.persistenceDriver]);\n\n // Persist logs when they change\n useEffect(() => {\n if (state.config.persistence && storageRef.current) {\n storageRef.current.save(state.logs);\n }\n }, [state.logs, state.config.persistence]);\n\n return (\n <LoggerContext.Provider value={{ state, dispatch, isPanelOpen, setIsPanelOpen }}>\n {children}\n </LoggerContext.Provider>\n );\n};\n\n/**\n * Internal hook to access the logger context state.\n * Use the public `useLogger` hook for standard logging operations.\n */\nexport const useLoggerContext = () => {\n const context = useContext(LoggerContext);\n if (!context) {\n throw new Error('useLoggerContext must be used within a LoggerProvider');\n }\n return context;\n};\n","import { useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { Logger } from '../Logger';\n\n/**\n * Main hook to interact with the Liquid Glass Logger.\n * \n * Provides methods for different logging levels and allows accessing\n * the current state of logs.\n * \n * @example\n * ```tsx\n * const { debug, error, object } = useLogger();\n * \n * debug('App started');\n * error(new Error('Failed to fetch'), 'API Error');\n * object({ user: 'John' }, 'Current User');\n * ```\n */\nexport const useLogger = () => {\n const { state } = useLoggerContext();\n\n /**\n * Log a debug message (Blue neon)\n */\n const debug = useCallback((message: string, title?: string) => {\n Logger.debug(message, title);\n }, []);\n\n /**\n * Log an error. If an Error object is passed, it automatically captures the stack trace.\n * (Red neon)\n */\n const error = useCallback((err: string | Error, title?: string) => {\n Logger.error(err, title);\n }, []);\n\n /**\n * Log a data object for inspection.\n * (Green neon)\n */\n const object = useCallback((data: any, title?: string) => {\n Logger.object(data, title);\n }, []);\n\n /**\n * Clears all logs from the current session and persistent storage.\n */\n const clear = useCallback(() => {\n Logger.clear();\n }, []);\n\n /**\n * Exports all logs as a JSON file download.\n */\n const exportLogs = useCallback(() => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n }, [state.logs]);\n\n return {\n /** Register a debug message */\n debug,\n /** Register an error or exception */\n error,\n /** Register an object for JSON visualization */\n object,\n /** Clear all history */\n clear,\n /** Download history as JSON */\n exportLogs,\n /** List of all captured logs */\n logs: state.logs,\n /** Count of logs not yet viewed */\n unreadCount: state.unreadCount,\n };\n};\n","import React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\n\n/**\n * Draggable floating trigger button.\n * Uses hybrid positioning (CSS initial + JS drag) for maximum compatibility.\n */\nexport const FloatingButton: React.FC = () => {\n const { state, setIsPanelOpen } = useLoggerContext();\n\n // Default to null to use CSS positioning initially\n const [position, setPosition] = useState<{ x: number; y: number } | null>(null);\n const isDragging = useRef(false);\n const dragOffset = useRef({ x: 0, y: 0 });\n\n const handleMouseDown = (e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n dragOffset.current = {\n x: e.clientX - rect.left,\n y: e.clientY - rect.top\n };\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n isDragging.current = true;\n const touch = e.touches[0];\n dragOffset.current = {\n x: touch.clientX - rect.left,\n y: touch.clientY - rect.top\n };\n };\n\n const handleMove = useCallback((clientX: number, clientY: number) => {\n if (!isDragging.current) return;\n\n // Keep button within viewport\n const nextX = Math.max(10, Math.min(window.innerWidth - 60, clientX - dragOffset.current.x));\n const nextY = Math.max(10, Math.min(window.innerHeight - 60, clientY - dragOffset.current.y));\n\n setPosition({ x: nextX, y: nextY });\n }, []);\n\n useEffect(() => {\n const onMouseMove = (e: MouseEvent) => handleMove(e.clientX, e.clientY);\n const onTouchMove = (e: TouchEvent) => handleMove(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n isDragging.current = false;\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('touchmove', onTouchMove, { passive: false });\n window.addEventListener('mouseup', onEnd);\n window.addEventListener('touchend', onEnd);\n\n return () => {\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('touchmove', onTouchMove);\n window.removeEventListener('mouseup', onEnd);\n window.removeEventListener('touchend', onEnd);\n };\n }, [handleMove]);\n\n // Handle window resize to keep button in bounds\n useEffect(() => {\n const handleResize = () => {\n if (position) {\n setPosition(prev => {\n if (!prev) return null;\n return {\n x: Math.min(prev.x, window.innerWidth - 60),\n y: Math.min(prev.y, window.innerHeight - 60)\n };\n });\n }\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [position]);\n\n const handleClick = () => {\n if (isDragging.current) return;\n setIsPanelOpen(true);\n };\n\n // If never moved, let CSS handle it. If moved, use absolute pixel coordinates.\n const dynamicStyle: React.CSSProperties = position\n ? { left: `${position.x}px`, top: `${position.y}px`, right: 'auto', bottom: 'auto' }\n : {};\n\n return (\n <div\n className=\"liql-floatingButton\"\n style={dynamicStyle}\n onMouseDown={handleMouseDown}\n onTouchStart={handleTouchStart}\n onClick={handleClick}\n aria-label=\"Open Logger\"\n >\n {state.unreadCount > 0 && (\n <div className=\"liql-badge\">{state.unreadCount}</div>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { LogEntry } from '../types';\n\ninterface LogItemProps {\n log: LogEntry;\n}\n\nexport const LogItem: React.FC<LogItemProps> = ({ log }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const formatTime = (isoString: string) => {\n const date = new Date(isoString);\n return date.toTimeString().split(' ')[0];\n };\n\n const renderJson = (data: any) => {\n try {\n return (\n <pre className=\"liql-expandedContent\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n } catch (e) {\n return <div>Error parsing object</div>;\n }\n };\n\n const getIcon = (level: string) => {\n switch (level) {\n case 'DEBUG': return '🐞';\n case 'ERROR': return '❌';\n case 'OBJECT': return '📦';\n default: return '📝';\n }\n };\n\n const levelClass = log.level.toLowerCase();\n\n return (\n <div\n className={`liql-logItem liql-logItem-${levelClass}`}\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"liql-logMeta\">\n <span className={`liql-statusTag liql-tag-${levelClass}`}>\n {getIcon(log.level)} {log.level}\n </span>\n <span className=\"liql-logTime\">{formatTime(log.timestamp)}</span>\n </div>\n <div className=\"liql-logContent\">\n {log.title && <strong style={{ color: 'var(--liql-primary)' }}>{log.title}: </strong>}\n {log.message}\n </div>\n\n {isExpanded && (\n <div className=\"liql-expandedContent\">\n {log.stack && (\n <div style={{ color: 'var(--liql-error)', marginBottom: '8px' }}>\n <strong>Stack Trace:</strong>\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: '10px', marginTop: '4px' }}>{log.stack}</pre>\n </div>\n )}\n {log.data && (\n <div>\n <strong>Payload:</strong>\n {renderJson(log.data)}\n </div>\n )}\n {!log.data && !log.stack && <div>Full message: {log.message}</div>}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { Virtuoso } from 'react-virtuoso';\nimport { LogItem } from './LogItem';\nimport { LogEntry } from '../types';\n\ninterface LogListProps {\n logs: LogEntry[];\n filter: string;\n search: string;\n}\n\nexport const LogList: React.FC<LogListProps> = ({ logs, filter, search }) => {\n const filteredLogs = React.useMemo(() => {\n return logs.filter(log => {\n const matchesFilter = filter === 'ALL' || log.level === filter;\n const matchesSearch = search === '' ||\n log.message.toLowerCase().includes(search.toLowerCase()) ||\n (log.title || '').toLowerCase().includes(search.toLowerCase());\n return matchesFilter && matchesSearch;\n }).reverse();\n }, [logs, filter, search]);\n\n return (\n <div className=\"liql-logListContainer\">\n <Virtuoso\n style={{ height: '100%' }}\n data={filteredLogs}\n itemContent={(_index: number, log: LogEntry) => <LogItem key={log.id} log={log} />}\n />\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { LogList } from './LogList';\n\n/**\n * Main 'Liquid Glass' logging console.\n * Contains the log list, filtering, search, and action controls.\n */\nexport const LogPanel: React.FC = () => {\n const { state, setIsPanelOpen, dispatch } = useLoggerContext();\n const [filter, setFilter] = useState('ALL');\n const [search, setSearch] = useState('');\n\n const clearLogs = () => {\n if (confirm('Are you sure you want to clear all logs?')) {\n dispatch({ type: 'CLEAR_LOGS' });\n }\n };\n\n const exportLogs = () => {\n const dataStr = \"data:text/json;charset=utf-8,\" + encodeURIComponent(JSON.stringify(state.logs, null, 2));\n const downloadAnchorNode = document.createElement('a');\n downloadAnchorNode.setAttribute(\"href\", dataStr);\n downloadAnchorNode.setAttribute(\"download\", `logs_${new Date().getTime()}.json`);\n document.body.appendChild(downloadAnchorNode);\n downloadAnchorNode.click();\n downloadAnchorNode.remove();\n };\n\n if (!state) return null;\n\n return (\n <div className=\"liql-panel\">\n <div className=\"liql-panelHeader\">\n <div className=\"liql-titleGroup\">\n <span className=\"liql-title\">ReactLoggerApp console [{state.logs.length}]</span>\n </div>\n <div className=\"liql-controls\">\n <button className=\"liql-btnAction\" onClick={exportLogs} title=\"Export JSON\">📥</button>\n <button className=\"liql-btnAction\" onClick={clearLogs} title=\"Clear Logs\">🗑️</button>\n <button className=\"liql-btnAction\" onClick={() => setIsPanelOpen(false)} title=\"Minimize\">➖</button>\n </div>\n </div>\n\n <div className=\"liql-filterBar\">\n <input\n type=\"text\"\n placeholder=\"Search entries...\"\n className=\"liql-searchInput\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n />\n <select\n className=\"liql-selectFilter\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n >\n <option value=\"ALL\">ALL</option>\n <option value=\"DEBUG\">DEBUG</option>\n <option value=\"ERROR\">ERROR</option>\n <option value=\"OBJECT\">OBJECTS</option>\n </select>\n </div>\n\n <LogList logs={state.logs} filter={filter} search={search} />\n\n <div className=\"liql-footerActions\">\n <div className=\"liql-storageInfo\">\n {state.config.persistence ? `DRIVER: ${state.config.persistenceDriver?.toUpperCase()}` : 'SESSION MODE'}\n </div>\n <button className=\"liql-btnClose\" onClick={() => setIsPanelOpen(false)}>CLOSE CONSOLE</button>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport { useLoggerContext } from '../context/LoggerContext';\nimport { FloatingButton } from './FloatingButton';\nimport { LogPanel } from './LogPanel';\n\n/**\n * Main entry point for the Logger UI.\n * Renders the floating trigger button and conditionally shows the glass panel.\n * Should be placed at the root level of your application.\n */\nexport const LoggerViewer: React.FC = () => {\n const { isPanelOpen } = useLoggerContext();\n\n return (\n <>\n {!isPanelOpen && <FloatingButton />}\n {isPanelOpen && <LogPanel />}\n </>\n );\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-logger-app",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "A professional visual logging system for Ionic React applications.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",