UNPKG

@kurai-io/redis

Version:

Schema-based abstraction layer for redis database interactions

2 lines (1 loc) 2.75 kB
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("@sigiljs/seal"),o=require("node:crypto"),l=require("./seal-json-parser.js"),c=require("crypto");function u(i){if(i&&i.__esModule)return i;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const s in i)if(s!=="default"){const t=Object.getOwnPropertyDescriptor(i,s);Object.defineProperty(e,s,t.get?t:{enumerable:!0,get:()=>i[s]})}}return e.default=i,Object.freeze(e)}const h=u(c);class f{client;template;options;randomKeyBytesCount=16;constructor(e,s,t,r){const n=t?.namespace??o.createHash("shake256",{outputLength:r?.randomNamespaceLength||8}).update(JSON.stringify([a.seal.exportMetadataOf(s),t||{}])).digest("base64url");this.client=e,this.options={ttl:t?.ttl,readOnce:t?.readOnce??!1,namespace:n},this.template=s,r?.randomKeyBytesCount&&(this.randomKeyBytesCount=r.randomKeyBytesCount)}async set(e,s){await this.waitWhenReady();const t=JSON.stringify(this.serialize(s));return typeof this.options.ttl=="number"?this.client.setEx(this.fullKey(e),this.options.ttl,t):this.client.set(this.fullKey(e),t),e}async expire(e,s,t){typeof s=="number"?this.client.expire(e,s,t):this.client.expireAt(e,s,t)}async get(e,s){await this.waitWhenReady();const t=await this.client.get(this.fullKey(e));if(!t){if(s)throw new Error(`Key ${e} not found`);return null}return this.options.readOnce&&this.delete(e),l.default(Buffer.isBuffer(t)?t.toString("utf8"):t,this.template)}async delete(e){return await this.waitWhenReady(),this.client.del(this.fullKey(e))}async with(e,s){const t=await this.get(e);return t?s(t):null}get randomKey(){const e=this;return{set(s){const t=h.randomBytes(e.randomKeyBytesCount).toString("base64url");return e.set(t,s)}}}fullKey(e){return this.options.namespace+"+"+e}serialize(e){if(typeof e!="object")return e;const s=Object.keys(a.seal.exportMetadataOf(this.template).shape||{});if(s.length){const t=[];for(const r of s){const n=e[r];t.push(n&&typeof n=="object"?this.serialize(n):n)}return t}return Object.values(e).map(t=>t&&typeof t=="object"?this.serialize(t):t)}async waitWhenReady(){if(this.client.isReady)return;let e=0;return new Promise(s=>{const t=setInterval(()=>{if(e+=1,e>300)throw clearInterval(t),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(t),s())},100)})}}class y{client;#e;constructor(e,s){this.client=e,this.#e=s||{}}template(e){return a.seal.object(e)}model(e,s){return new f(this.client,e,s,this.#e)}destroy(){this.client.destroy()}async connect(){return await this.client.connect(),this.client}}exports.default=y;