UNPKG

memoradb

Version:

A lightweight in-memory key-value store similar to Redis

130 lines (129 loc) 4.55 kB
#!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const net_1 = __importDefault(require("net")); const port = process.argv[2] ? parseInt(process.argv[2]) : 6379; class MemoraDB { constructor() { this.store = new Map(); this.expirations = new Map(); } set(key, value, expiry = null) { this.store.set(key, value); if (expiry) { this.setExpiry(key, expiry); } return "OK"; } get(key) { return this.store.has(key) ? this.store.get(key) : null; } del(key) { this.store.delete(key); this.expirations.delete(key); return "OK"; } expire(key, seconds) { if (this.store.has(key)) { this.setExpiry(key, seconds); return 1; } return 0; } ttl(key) { if (!this.expirations.has(key)) return -1; const expiryTime = this.expirations.get(key); const remaining = Math.ceil((expiryTime - Date.now()) / 1000); return remaining > 0 ? remaining : -2; } persist(key) { return this.expirations.delete(key) ? 1 : 0; } flushAll() { this.store.clear(); this.expirations.clear(); return "OK"; } incr(key) { if (!this.store.has(key) || isNaN(Number(this.store.get(key)))) { this.store.set(key, 0); } this.store.set(key, Number(this.store.get(key)) + 1); return Number(this.store.get(key)); } decr(key) { if (!this.store.has(key) || isNaN(Number(this.store.get(key)))) { this.store.set(key, 0); } this.store.set(key, Number(this.store.get(key)) - 1); return Number(this.store.get(key)); } setExpiry(key, seconds) { const expiryTime = Date.now() + seconds * 1000; this.expirations.set(key, expiryTime); setTimeout(() => { if (Date.now() >= expiryTime) { this.del(key); } }, seconds * 1000); } } const db = new MemoraDB(); const server = net_1.default.createServer((socket) => { socket.write(`MemoraDB Server Connected\nMemoraDB:${port}> `); let buffer = ""; socket.on("data", (data) => { buffer += data.toString(); if (buffer.includes("\n")) { const lines = buffer.split("\n"); buffer = lines.pop() || ""; lines.forEach((line) => { var _a, _b; const input = line.trim().split(/\s+/); const command = (_a = input[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase(); let response = "Unknown command"; switch (command) { case "SET": response = db.set(input[1], input[2], input[3] === "EX" ? parseInt(input[4]) : null); break; case "GET": response = ((_b = db.get(input[1])) === null || _b === void 0 ? void 0 : _b.toString()) || "(nil)"; break; case "DEL": response = db.del(input[1]); break; case "EXPIRE": response = db.expire(input[1], parseInt(input[2])).toString(); break; case "TTL": response = db.ttl(input[1]).toString(); break; case "PERSIST": response = db.persist(input[1]).toString(); break; case "FLUSHALL": response = db.flushAll(); break; case "INCR": response = db.incr(input[1]).toString(); break; case "DECR": response = db.decr(input[1]).toString(); break; default: response = "Unknown command"; } socket.write(response + "\nMemoraDB:" + port + "> "); }); } }); socket.on("end", () => console.log("Client disconnected")); }); server.listen(port, () => { console.log(`MemoraDB Server listening on port ${port}`); }); exports.default = MemoraDB;