UNPKG

file-routing-expressjs

Version:

A dependency-free, flexible, system-based file routing for Express.

1 lines 4.07 kB
{"version":3,"sources":["../../src/plugins/cache.ts"],"sourcesContent":["import { CacheConfig, CacheEntry, Plugin } from \"../types\";\nimport { RequestHandler } from \"express\";\n\nconst store = new Map<string, CacheEntry>();\n\nconst CACHE_KEY = Symbol(\"cache-key\");\nconst CACHE_BODY = Symbol(\"cache-body\");\n\nconst cachePlugin: Plugin<CacheConfig> = {\n name: \"cache\",\n\n validateConfig(config) {\n if (!config || typeof config.ttl !== \"number\" || config.ttl <= 0) {\n throw new Error(`[cache] \"ttl\" must be a positive number`);\n }\n\n if (config.max !== undefined && (typeof config.max !== \"number\" || config.max <= 0)) {\n throw new Error(`[cache] \"max\" must be a positive number`);\n }\n },\n\n async onRequest(ctx, next) {\n const key = `${ctx.req.method}:${ctx.req.originalUrl}`;\n const entry = store.get(key);\n\n if (entry && entry.expires > Date.now()) {\n store.delete(key);\n store.set(key, entry);\n\n ctx.res.status(entry.status);\n ctx.res.send(entry.body);\n return;\n }\n\n ctx.state[CACHE_KEY] = key;\n return next();\n },\n\n async onResponse(ctx) {\n const key = ctx.state[CACHE_KEY];\n if (!key) return;\n\n const ttl = ctx.config?.ttl ?? 0;\n if (!ttl) return;\n\n const body = (ctx.req as any)[CACHE_BODY];\n if (body === undefined) return;\n\n const entry: CacheEntry = {\n expires: Date.now() + ttl,\n status: ctx.res.statusCode,\n body\n };\n\n if (store.has(key)) {\n store.delete(key);\n }\n\n store.set(key, entry);\n\n const max = ctx.config?.max ?? 500;\n if (max && store.size > max) {\n const oldestKey = store.keys().next().value;\n if (oldestKey) store.delete(oldestKey);\n }\n },\n\n wrap(handler: RequestHandler): RequestHandler {\n return async (req, res, next) => {\n let body: any;\n\n const originalSend = res.send.bind(res);\n\n res.send = (data: any) => {\n body = data;\n return originalSend(data);\n };\n\n try {\n await handler(req, res, next);\n } finally {\n (req as any)[CACHE_BODY] = body;\n }\n };\n }\n};\n\nexport default cachePlugin;"],"mappings":";;;;;;;;;;;;;;;;;;;;AAGA,MAAM,QAAQ,oBAAI,IAAwB;AAE1C,MAAM,YAAY,OAAO,WAAW;AACpC,MAAM,aAAa,OAAO,YAAY;AAEtC,MAAM,cAAmC;AAAA,EACrC,MAAM;AAAA,EAEN,eAAe,QAAQ;AACnB,QAAI,CAAC,UAAU,OAAO,OAAO,QAAQ,YAAY,OAAO,OAAO,GAAG;AAC9D,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC7D;AAEA,QAAI,OAAO,QAAQ,WAAc,OAAO,OAAO,QAAQ,YAAY,OAAO,OAAO,IAAI;AACjF,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC7D;AAAA,EACJ;AAAA,EAEM,UAAU,KAAK,MAAM;AAAA;AACvB,YAAM,MAAM,GAAG,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,WAAW;AACpD,YAAM,QAAQ,MAAM,IAAI,GAAG;AAE3B,UAAI,SAAS,MAAM,UAAU,KAAK,IAAI,GAAG;AACrC,cAAM,OAAO,GAAG;AAChB,cAAM,IAAI,KAAK,KAAK;AAEpB,YAAI,IAAI,OAAO,MAAM,MAAM;AAC3B,YAAI,IAAI,KAAK,MAAM,IAAI;AACvB;AAAA,MACJ;AAEA,UAAI,MAAM,SAAS,IAAI;AACvB,aAAO,KAAK;AAAA,IAChB;AAAA;AAAA,EAEM,WAAW,KAAK;AAAA;AAtC1B;AAuCQ,YAAM,MAAM,IAAI,MAAM,SAAS;AAC/B,UAAI,CAAC,IAAK;AAEV,YAAM,OAAM,eAAI,WAAJ,mBAAY,QAAZ,YAAmB;AAC/B,UAAI,CAAC,IAAK;AAEV,YAAM,OAAQ,IAAI,IAAY,UAAU;AACxC,UAAI,SAAS,OAAW;AAExB,YAAM,QAAoB;AAAA,QACtB,SAAS,KAAK,IAAI,IAAI;AAAA,QACtB,QAAQ,IAAI,IAAI;AAAA,QAChB;AAAA,MACJ;AAEA,UAAI,MAAM,IAAI,GAAG,GAAG;AAChB,cAAM,OAAO,GAAG;AAAA,MACpB;AAEA,YAAM,IAAI,KAAK,KAAK;AAEpB,YAAM,OAAM,eAAI,WAAJ,mBAAY,QAAZ,YAAmB;AAC/B,UAAI,OAAO,MAAM,OAAO,KAAK;AACzB,cAAM,YAAY,MAAM,KAAK,EAAE,KAAK,EAAE;AACtC,YAAI,UAAW,OAAM,OAAO,SAAS;AAAA,MACzC;AAAA,IACJ;AAAA;AAAA,EAEA,KAAK,SAAyC;AAC1C,WAAO,CAAO,KAAK,KAAK,SAAS;AAC7B,UAAI;AAEJ,YAAM,eAAe,IAAI,KAAK,KAAK,GAAG;AAEtC,UAAI,OAAO,CAAC,SAAc;AACtB,eAAO;AACP,eAAO,aAAa,IAAI;AAAA,MAC5B;AAEA,UAAI;AACA,cAAM,QAAQ,KAAK,KAAK,IAAI;AAAA,MAChC,UAAE;AACE,QAAC,IAAY,UAAU,IAAI;AAAA,MAC/B;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,IAAO,gBAAQ;","names":[]}