@kurai-io/redis
Version:
Schema-based abstraction layer for redis database interactions
2 lines (1 loc) • 2.27 kB
JavaScript
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("node:crypto"),o=require("crypto"),r=require("jsonpack");function c(i){if(i&&i.__esModule)return i;const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const e in i)if(e!=="default"){const n=Object.getOwnPropertyDescriptor(i,e);Object.defineProperty(t,e,n.get?n:{enumerable:!0,get:()=>i[e]})}}return t.default=i,Object.freeze(t)}const l=c(o);class u{client;options;randomKeyBytesCount=16;constructor(t,e,n){const s=e?.namespace??a.createHash("shake256",{outputLength:n?.randomNamespaceLength||8}).update(JSON.stringify([e])).digest("base64url");this.client=t,this.options={ttl:e?.ttl,readOnce:e?.readOnce??!1,namespace:s},n?.randomKeyBytesCount&&(this.randomKeyBytesCount=n.randomKeyBytesCount)}async set(t,e){await this.waitWhenReady();const n=r.pack(e);return typeof this.options.ttl=="number"?this.client.setEx(this.fullKey(t),this.options.ttl,n):this.client.set(this.fullKey(t),n),t}async expire(t,e,n){typeof e=="number"?this.client.expire(t,e,n):this.client.expireAt(t,e,n)}async get(t,e){await this.waitWhenReady();const n=await this.client.get(this.fullKey(t));if(!n){if(e)throw new Error(`Key ${t} not found`);return null}return this.options.readOnce&&this.delete(t),r.unpack(Buffer.isBuffer(n)?n.toString("utf8"):n)}async delete(t){return await this.waitWhenReady(),this.client.del(this.fullKey(t))}async with(t,e){const n=await this.get(t);return n?e(n):null}get randomKey(){const t=this;return{set(e){const n=l.randomBytes(t.randomKeyBytesCount).toString("base64url");return t.set(n,e)}}}fullKey(t){return this.options.namespace+"+"+t}async waitWhenReady(){if(this.client.isReady)return;let t=0;return new Promise(e=>{const n=setInterval(()=>{if(t+=1,t>300)throw clearInterval(n),new Error("Redis initialization timeout, if this is only error you encounter, double-check that Sigil app starts listening BEFORE any redis interactions");this.client.isReady&&(clearInterval(n),e())},100)})}}class h{client;#t;constructor(t,e){this.client=t,this.#t=e||{}}model(t){return new u(this.client,t,this.#t)}destroy(){this.client.destroy()}async connect(){return await this.client.connect(),this.client}}exports.default=h;