Skip to content

Commit

Permalink
refactor: encapsulate cache as decorator (#416)
Browse files Browse the repository at this point in the history
  • Loading branch information
mweberxyz authored Mar 1, 2024
1 parent 8113f2e commit 37cdde2
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 55 deletions.
40 changes: 27 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,23 @@ const { basename, dirname, extname, join, resolve } = require('node:path')
const HLRU = require('hashlru')
const supportedEngines = ['ejs', 'nunjucks', 'pug', 'handlebars', 'mustache', 'art-template', 'twig', 'liquid', 'dot', 'eta']

const viewCache = Symbol('@fastify/view/cache')

const fastifyViewCache = fp(
async function cachePlugin (fastify, opts) {
const lru = HLRU(opts?.maxCache || 100)
fastify.decorate(viewCache, lru)
},
{
fastify: '4.x',
name: '@fastify/view/cache'
}
)

async function fastifyView (fastify, opts) {
if (fastify[viewCache] === undefined) {
await fastify.register(fastifyViewCache, opts)
}
if (!opts.engine) {
throw new Error('Missing engine')
}
Expand All @@ -19,7 +35,6 @@ async function fastifyView (fastify, opts) {
const engine = opts.engine[type]
const globalOptions = opts.options || {}
const templatesDir = resolveTemplateDir(opts)
const lru = HLRU(opts.maxCache || 100)
const includeViewExtension = opts.includeViewExtension || false
const viewExt = opts.viewExt || ''
const prod = typeof opts.production === 'boolean' ? opts.production : process.env.NODE_ENV === 'production'
Expand Down Expand Up @@ -114,7 +129,7 @@ async function fastifyView (fastify, opts) {
}

viewDecorator.clearCache = function () {
lru.clear()
fastify[viewCache].clear()
}

fastify.decorate(propertyName, viewDecorator)
Expand Down Expand Up @@ -151,7 +166,7 @@ async function fastifyView (fastify, opts) {

function getPage (page, extension) {
const pageLRU = `getPage-${page}-${extension}`
let result = lru.get(pageLRU)
let result = fastify[viewCache].get(pageLRU)

if (typeof result === 'string') {
return result
Expand All @@ -160,7 +175,7 @@ async function fastifyView (fastify, opts) {
const filename = basename(page, extname(page))
result = join(dirname(page), filename + getExtension(page, extension))

lru.set(pageLRU, result)
fastify[viewCache].set(pageLRU, result)

return result
}
Expand Down Expand Up @@ -202,7 +217,7 @@ async function fastifyView (fastify, opts) {
if (type === 'handlebars') {
data = engine.compile(data, globalOptions.compileOptions)
}
lru.set(file, data)
fastify[viewCache].set(file, data)
return data
}

Expand All @@ -217,7 +232,7 @@ async function fastifyView (fastify, opts) {
isRaw = true
file = file.raw
}
const data = lru.get(file)
const data = fastify[viewCache].get(file)
if (data && prod) {
return data
}
Expand All @@ -231,7 +246,7 @@ async function fastifyView (fastify, opts) {
// Gets partials as collection of strings from LRU cache or filesystem.
const getPartials = async function (page, { partials, requestedPath }) {
const cacheKey = getPartialsCacheKey(page, partials, requestedPath)
const partialsObj = lru.get(cacheKey)
const partialsObj = fastify[viewCache].get(cacheKey)
if (partialsObj && prod) {
return partialsObj
} else {
Expand All @@ -243,7 +258,7 @@ async function fastifyView (fastify, opts) {
await Promise.all(partialKeys.map(async (key) => {
partialsHtml[key] = await readFileSemaphore(join(templatesDir, partials[key]))
}))
lru.set(cacheKey, partialsHtml)
fastify[viewCache].set(cacheKey, partialsHtml)
return partialsHtml
}
}
Expand Down Expand Up @@ -276,7 +291,7 @@ async function fastifyView (fastify, opts) {

const compiledPage = engine.compile(html, localOptions)

lru.set(page, compiledPage)
fastify[viewCache].set(page, compiledPage)
return compiledPage
}

Expand Down Expand Up @@ -326,7 +341,7 @@ async function fastifyView (fastify, opts) {
// append view extension
page = getPage(page, type)
}
const toHtml = lru.get(page)
const toHtml = fastify[viewCache].get(page)

if (toHtml && prod) {
return toHtml(data)
Expand Down Expand Up @@ -357,7 +372,7 @@ async function fastifyView (fastify, opts) {
// append view extension
page = getPage(page, type)
}
const toHtml = lru.get(page)
const toHtml = fastify[viewCache].get(page)

if (toHtml && prod) {
return toHtml(data)
Expand Down Expand Up @@ -562,8 +577,6 @@ async function fastifyView (fastify, opts) {
engine.templatesSync = globalOptions.templatesSync
}

lru.define = lru.set

engine.configure({
views: templatesDir,
cache: prod || globalOptions.templatesSync
Expand Down Expand Up @@ -648,3 +661,4 @@ module.exports = fp(fastifyView, {
})
module.exports.default = fastifyView
module.exports.fastifyView = fastifyView
module.exports.fastifyViewCache = viewCache
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"mustache": "^4.0.1",
"nunjucks": "^3.2.1",
"pino": "^8.0.0",
"proxyquire": "^2.1.3",
"pug": "^3.0.0",
"simple-get": "^4.0.0",
"split2": "^4.0.0",
Expand Down
35 changes: 14 additions & 21 deletions test/test-handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const sget = require('simple-get').concat
const Fastify = require('fastify')
const fs = require('node:fs')
const { join } = require('node:path')
const proxyquire = require('proxyquire')

require('./helper').handleBarsHtmlMinifierTests(t, true)
require('./helper').handleBarsHtmlMinifierTests(t, false)
Expand Down Expand Up @@ -616,17 +615,14 @@ test('reply.view with handlebars engine with partials in production mode should
t.plan(4)
const fastify = Fastify()
const handlebars = require('handlebars')
const POV = proxyquire('..', {
hashlru: function () {
return {
get: (key) => {
t.equal(key, 'handlebars|body:./templates/body.hbs|null-Partials')
},
set: (key, value) => {
t.equal(key, 'handlebars|body:./templates/body.hbs|null-Partials')
t.strictSame(value, { body: fs.readFileSync('./templates/body.hbs', 'utf8') })
}
}
const POV = require('..')
fastify.decorate(POV.fastifyViewCache, {
get: (key) => {
t.equal(key, 'handlebars|body:./templates/body.hbs|null-Partials')
},
set: (key, value) => {
t.equal(key, 'handlebars|body:./templates/body.hbs|null-Partials')
t.strictSame(value, { body: fs.readFileSync('./templates/body.hbs', 'utf8') })
}
})

Expand Down Expand Up @@ -921,15 +917,12 @@ test('reply.view with handlebars engine should return 500 if template fails in p
t.plan(4)
const fastify = Fastify()
const handlebars = require('handlebars')
const POV = proxyquire('..', {
hashlru: function () {
return {
get: () => {
return () => { throw Error('Template Error') }
},
set: () => { }
}
}
const POV = require('..')
fastify.decorate(POV.fastifyViewCache, {
get: () => {
return () => { throw Error('Template Error') }
},
set: () => { }
})

fastify.register(POV, {
Expand Down
17 changes: 7 additions & 10 deletions test/test-mustache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const sget = require('simple-get').concat
const Fastify = require('fastify')
const fs = require('node:fs')
const minifier = require('html-minifier-terser')
const proxyquire = require('proxyquire')
const minifierOpts = {
removeComments: true,
removeCommentsFromCDATA: true,
Expand Down Expand Up @@ -345,15 +344,13 @@ test('reply.view with mustache engine with partials in production mode should us
const fastify = Fastify()
const mustache = require('mustache')
const data = { text: 'text' }
const POV = proxyquire('..', {
hashlru: function () {
return {
get: () => {
return '<div>Cached Response</div>'
},
set: () => { }
}
}
const POV = require('..')

fastify.decorate(POV.fastifyViewCache, {
get: () => {
return '<div>Cached Response</div>'
},
set: () => { }
})

fastify.register(POV, {
Expand Down
17 changes: 7 additions & 10 deletions test/test-pug.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const test = t.test
const sget = require('simple-get').concat
const Fastify = require('fastify')
const fs = require('node:fs')
const proxyquire = require('proxyquire')

require('./helper').pugHtmlMinifierTests(t, true)
require('./helper').pugHtmlMinifierTests(t, false)
Expand Down Expand Up @@ -47,15 +46,13 @@ test('reply.view with pug engine in production mode should use cache', t => {
t.plan(6)
const fastify = Fastify()
const pug = require('pug')
const POV = proxyquire('..', {
hashlru: function () {
return {
get: () => {
return () => '<div>Cached Response</div>'
},
set: () => { }
}
}
const POV = require('..')

fastify.decorate(POV.fastifyViewCache, {
get: () => {
return () => '<div>Cached Response</div>'
},
set: () => { }
})

fastify.register(POV, {
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ declare namespace fastifyView {

export const fastifyView: FastifyView
export { fastifyView as default }
export const fastifyViewCache: Symbol
}

declare function fastifyView(...params: Parameters<FastifyView>): ReturnType<FastifyView>
Expand Down

0 comments on commit 37cdde2

Please sign in to comment.