UNPKG

p3x-redis-ui-server

Version:

🏍️ P3X Redis UI server — Socket.IO backend for the dual Angular + React frontend with AI queries, 54 languages, and auto data decompression

2 lines (1 loc) 6.29 kB
import{cloneDeep as e}from"lodash-es";const s=e=>{const{connectionId:s,code:t,socket:o}=e;p3xrs.redisConnections.hasOwnProperty(s)&&(delete p3xrs.redisConnections[s],o.p3xrs.io.emit("redis-disconnected",{connectionId:s,status:"code",code:t}),n({socket:o}))},n=e=>{const{socket:s}=e,n={};Object.keys(p3xrs.redisConnections).forEach(e=>{n[e]={},Object.keys(p3xrs.redisConnections[e]).forEach(s=>{n[e][s]=p3xrs.redisConnections[e][s]})}),s.p3xrs.io.emit("redis-status",{redisConnections:n})},t="socket.io shared disconnect redis",o=e=>{const{socket:s}=e;if(p3xrs.redisConnections.hasOwnProperty(s.p3xrs.connectionId))if(console.warn(t,`includes ${p3xrs.redisConnections[s.p3xrs.connectionId].clients.includes(s.id)} length === 1 ${p3xrs.redisConnections[s.p3xrs.connectionId].clients.length}`),p3xrs.redisConnections[s.p3xrs.connectionId].clients.includes(s.id)&&1===p3xrs.redisConnections[s.p3xrs.connectionId].clients.length)delete p3xrs.redisConnections[s.p3xrs.connectionId];else{let e=p3xrs.redisConnections[s.p3xrs.connectionId].clients.indexOf(s.id);console.warn(t,s.p3xrs.connectionId,p3xrs.redisConnections[s.p3xrs.connectionId].clients,s.id,e),e>-1&&p3xrs.redisConnections[s.p3xrs.connectionId].clients.splice(e,1)}p3xrs.redisConnections.hasOwnProperty(s.p3xrs.connectionId)&&p3xrs.redisConnections[s.p3xrs.connectionId].hasOwnProperty("clients")&&0===p3xrs.redisConnections[s.p3xrs.connectionId].clients.length&&delete p3xrs.redisConnections[s.p3xrs.connectionId],i(e),s.p3xrs.connectionId=void 0},r=s=>{const{socket:n}=s,t=e(p3xrs.connections);let o=t.list.map(e=>(delete e.password,delete e.tlsCrt,delete e.tlsKey,delete e.tlsCa,delete e.sshPassword,delete e.sshPrivateKey,Array.isArray(e.nodes)&&(e.nodes=e.nodes.map(e=>(delete e.password,e))),e));t.list=o,n.p3xrs.io.emit("connections",{status:"ok",connections:t})},i=e=>{const{socket:s}=e;if(console.warn("shared disconnectRedisIo","try"),void 0!==s.p3xrs.ioredis&&(console.warn("shared disconnectRedisIo","executed"),s.p3xrs.ioredis.disconnect(),s.p3xrs.ioredisSubscriber.disconnect(),s.p3xrs.ioredis=void 0,s.p3xrs.ioredisSubscriber=void 0),Array.isArray(s.p3xrs.tunnels)&&s.p3xrs.tunnels.length>0){for(const e of s.p3xrs.tunnels)e.close();s.p3xrs.tunnels=[]}s.p3xrs.sshClient&&(s.p3xrs.sshClient.end(),s.p3xrs.sshClient=void 0)},c=e=>{const{redis:s}=e;let{dbsize:n,maxKeys:t}=e;return new Promise(async(n,o)=>{try{(isNaN(t)||t<5||t>1e5)&&(t=1e4);let o=Math.round(t/10);o<5&&(o=5);const r=s.scanStream({match:e.match,count:o});let i=[],c=!1;r.on("data",e=>{t&&i.length<t?(i=i.concat(e),i.length>=t&&(c=!0,n(i))):c||(c=!0,n(i))}),r.on("end",()=>{c||n(i)})}catch(e){o(e)}})},a=async e=>{const{redis:s,keys:n}=e,t=s.pipeline();for(let e of n)t.type(e),t.ttl(e);const o=await t.exec(),r={},i=s.pipeline();for(let e in n){const s=2*e,t=o[s],c=o[s+1],a=n[e],l={type:t[1],ttl:c[1]};switch("ReJSON-RL"===l.type&&(l.type="json"),"TSDB-TYPE"===l.type&&(l.type="timeseries"),"MBbloom--"===l.type&&(l.type="bloom"),"MBbloomCF"===l.type&&(l.type="cuckoo"),"TopK-TYPE"===l.type&&(l.type="topk"),"CMSk-TYPE"===l.type&&(l.type="cms"),"TDIS-TYPE"===l.type&&(l.type="tdigest"),l.type){case"stream":i.xlen(a);break;case"hash":i.hlen(a);break;case"list":i.llen(a);break;case"set":i.scard(a);break;case"zset":i.zcard(a);break;case"timeseries":i.call("TS.INFO",a);break;case"bloom":i.call("BF.INFO",a);break;case"cuckoo":i.call("CF.INFO",a);break;case"topk":i.call("TOPK.INFO",a);break;case"cms":i.call("CMS.INFO",a);break;case"tdigest":i.call("TDIGEST.INFO",a);break;case"vectorset":i.call("VCARD",a)}r[a]=l}const c=await i.exec();for(let e in n){const s=r[n[e]];if(!["stream","hash","list","set","zset","timeseries","bloom","cuckoo","topk","cms","tdigest","vectorset"].includes(s.type))continue;const t=c.shift();if(void 0!==t)if("timeseries"===s.type){const e=t[1];if(Array.isArray(e))for(let n=0;n<e.length;n+=2)if("totalSamples"===e[n]){s.length=e[n+1];break}}else if("bloom"===s.type||"cuckoo"===s.type){const e=t[1];if(Array.isArray(e))for(let n=0;n<e.length;n+=2)if("Number of items inserted"===e[n]){s.length=e[n+1];break}}else if("topk"===s.type){const e=t[1];if(Array.isArray(e))for(let n=0;n<e.length;n+=2)if("k"===e[n]){s.length=e[n+1];break}}else if("cms"===s.type){const e=t[1];if(Array.isArray(e))for(let n=0;n<e.length;n+=2)if("count"===e[n]){s.length=e[n+1];break}}else if("tdigest"===s.type){const e=t[1];if(Array.isArray(e))for(let n=0;n<e.length;n+=2)if("Merged nodes"===e[n]){s.length=e[n+1];break}}else s.type,s.length=t[1]}return r},l=()=>{if(!0===p3xrs.cfg.readonlyConnections)throw new Error("readonly-connection-mode")},d=({socket:e})=>{if(!0===e.p3xrs.readonly)throw new Error("readonly-connection-mode")},p=async e=>{const{redis:s}=e;let{payload:n}=e;void 0===n&&(n={});const t=await s.dbsize(),o=await Promise.all([s.info(),c({dbsize:t,redis:s,match:n.match,maxKeys:n.maxKeys}),s.pubsub("channels","*")]),r=o[1];let i={};return r.length<11e4&&(i=await a({redis:s,keys:r})),{info:o[0],keys:r,keysInfo:i,dbsize:t,channels:o[2]}},y=async e=>{const{redis:s,socket:n,payload:t,setDb:o}=e;if(!0===o)try{await s.call("select",t.db||0)}catch(e){console.warn(e)}const r=await p({redis:s,payload:t});let{extend:i}=e;void 0===i&&(i={}),n.emit(e.responseEvent,Object.assign(i,{status:"ok",info:r.info,keys:r.keys,keysInfo:r.keysInfo,keysInfoFetchedAt:Date.now(),dbsize:r.dbsize}))},h=(e,s,n)=>{const t=s||/\s/g;let o=!1,r=!1,i=[];const c=[];console.log("argumentParser input",e);const a=e.split("");for(let e=0;e<a.length;++e){let l=a[e],d=l.match(t);"'"!==l||r?'"'!==l||o?o||r||!d?i.push(l):i.length>0?(c.push(i.join("")),i=[]):s&&c.push(l):(!0===n&&i.push(l),r=!r):(!0===n&&i.push(l),o=!o)}return i.length>0?c.push(i.join("")):s&&c.push(""),c},x=e=>{if(!Array.isArray(e))return[];const s=[];for(const n of e){if(!Array.isArray(n))continue;const e={};for(let s=0;s<n.length;s+=2)e[n[s]]=n[s+1];e.name&&s.push(e)}return s},f=async e=>{try{const s=await e.call("MODULE","LIST");return x(s)}catch(e){return[]}};export{h as argumentParser,l as ensureReadonlyConnections,s as triggerDisconnect,c as getStreamKeys,i as disconnectRedisIo,r as sendConnections,n as sendStatus,o as disconnectRedis,a as getKeysInfo,p as getFullInfo,y as getFullInfoAndSendSocket,d as ensureReadonlyConnection,x as parseModuleList,f as detectModules};