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) • 4.32 kB
JavaScript
import*as e from"../../shared.mjs";export default async a=>{const{socket:t,payload:s}=a,l=t.p3xrs.ioredis;try{e.ensureReadonlyConnection({socket:t});const{model:i}=s;switch(i.score=null===i.score?void 0:i.score,i.index=null===i.index?void 0:i.index,i.hashKey=null===i.hashKey?void 0:i.hashKey,i.type){case"stream":const a=[i.key,i.streamTimestamp].concat(e.argumentParser(i.value));await l.xadd(...a);break;case"string":await l.set(i.key,i.value);break;case"list":if(void 0===i.index)await l.rpush(i.key,i.value);else if(-1===i.index)await l.lpush(i.key,i.value);else{const e=await l.llen(i.key);if(!(i.index>-1&&i.index<e)){const e=new Error("list-out-of-bounds");throw e.code="list-out-of-bounds",e}await l.lset(i.key,i.index,i.value)}break;case"hash":s.hasOwnProperty("originalHashKey")&&await l.hdel(i.key,s.originalHashKey),await l.hset(i.key,i.hashKey,i.value);break;case"set":s.hasOwnProperty("originalValue")&&await l.srem(i.key,s.originalValue),await l.sadd(i.key,i.value);break;case"zset":s.hasOwnProperty("originalValue")&&await l.zrem(i.key,s.originalValue),await l.zadd(i.key,i.score,i.value);break;case"timeseries":if("add"===s.type||"append"===s.type){if("add"===s.type){try{const e=[i.key,"DUPLICATE_POLICY",i.tsDuplicatePolicy||"LAST"],a=parseInt(i.tsRetention);!isNaN(a)&&a>0&&e.push("RETENTION",a),await l.call("TS.CREATE",...e)}catch(e){if(!e.message.includes("already exists"))throw e}const e=i.tsLabels&&i.tsLabels.trim().length>0?i.tsLabels.trim():`key ${i.key}`;console.info("timeseries set labels:",i.key,e),await l.call("TS.ALTER",i.key,"LABELS",...e.split(/\s+/))}if(i.tsBulkMode){const e=parseInt(i.tsSpread)||6e4,a=i.value.split("\n").map(e=>e.trim()).filter(e=>e.length>0);let t=Date.now();for(const s of a){const a=s.split(/\s+/);if(a.length>=2){let s=a[0];"*"===s&&(s=t,t+=e),await l.call("TS.ADD",i.key,s,parseFloat(a[1]),"ON_DUPLICATE","LAST")}}}else await l.call("TS.ADD",i.key,i.tsTimestamp||"*",parseFloat(i.value),"ON_DUPLICATE","LAST")}else if("edit"===s.type){if(i.tsEditAll){const e=await l.call("TS.INFO",i.key);let a=0,t=0;for(let s=0;s<e.length;s+=2)"firstTimestamp"===e[s]&&(a=e[s+1]),"lastTimestamp"===e[s]&&(t=e[s+1]);0===a&&0===t||await l.call("TS.DEL",i.key,a,t);const s=parseInt(i.tsSpread)||6e4,r=i.value.split("\n").map(e=>e.trim()).filter(e=>e.length>0);let o=Date.now();for(const e of r){const a=e.split(/\s+/);if(a.length>=2){let e=a[0];"*"===e&&(e=o,o+=s),await l.call("TS.ADD",i.key,e,parseFloat(a[1]),"ON_DUPLICATE","LAST")}}}else void 0!==i.originalTimestamp&&await l.call("TS.DEL",i.key,i.originalTimestamp,i.originalTimestamp),await l.call("TS.ADD",i.key,i.tsTimestamp||"*",parseFloat(i.value),"ON_DUPLICATE","LAST");i.tsLabels&&i.tsLabels.trim().length>0&&await l.call("TS.ALTER",i.key,"LABELS",...i.tsLabels.trim().split(/\s+/))}break;case"json":try{JSON.parse(i.value)}catch(e){throw new Error("invalid-json-value")}await l.call("JSON.SET",i.key,"$",i.value);break;case"bloom":await l.call("BF.RESERVE",i.key,parseFloat(i.bloomErrorRate)||.01,parseInt(i.bloomCapacity)||100);break;case"cuckoo":await l.call("CF.RESERVE",i.key,parseInt(i.cuckooCapacity)||1024);break;case"topk":await l.call("TOPK.RESERVE",i.key,parseInt(i.topkK)||10,parseInt(i.topkWidth)||2e3,parseInt(i.topkDepth)||7,parseFloat(i.topkDecay)||.9);break;case"cms":await l.call("CMS.INITBYDIM",i.key,parseInt(i.cmsWidth)||2e3,parseInt(i.cmsDepth)||7);break;case"tdigest":await l.call("TDIGEST.CREATE",i.key,"COMPRESSION",parseInt(i.tdigestCompression)||100);break;case"vectorset":{const e=(i.vectorValues||"").split(",").map(e=>parseFloat(e.trim())).filter(e=>!isNaN(e));if(!e.length)throw new Error("Vector values are required");if(!i.vectorElement||!i.vectorElement.trim())throw new Error("Element name is required");const a=[i.key,"VALUES",e.length,...e,i.vectorElement.trim()];await l.call("VADD",...a);break}case"array":{const e=void 0!==i.index&&null!==i.index&&""!==`${i.index}`.trim(),a=s.originalIndex;if(null!=a&&""!==`${a}`.trim()&&`${a}`!=`${i.index}`&&await l.call("ARDEL",i.key,parseInt(a)),e)await l.call("ARSET",i.key,parseInt(i.index),i.value);else{const e=parseInt(await l.call("ARLEN",i.key))||0;await l.call("ARSET",i.key,e,i.value)}break}}t.emit(a.responseEvent,{status:"ok",key:i.key})}catch(e){console.error(e),t.emit(a.responseEvent,{status:"error",error:e.message})}};