lib_result-set.js

import { createHash } from 'crypto'
import { clear as clearCache } from '../lib/generic.js'

/**
 * Helper functions for managing `result-set` cache.
 *
 * @module Helper/ResultSet
 */

/**
 * Build a cache key for the result set.
 *
 * @param {object} [opts={}] - The options for building the cache key
 * @param {object} [opts.model] - The model associated with the result set
 * @param {string} [opts.id] - The ID of the result set
 * @param {object} [opts.filter] - The filter applied to the result set
 * @param {object} [opts.options] - Additional options for building the cache key
 * @returns {string} - Returns the generated cache key
 */
export function buildKey (opts = {}) {
  const { model, id, filter, options } = opts
  const { fmt, noResultSanitizer, refs } = options
  const { merge } = this.app.lib._
  let extra = merge({}, filter, { fmt, noResultSanitizer, refs })
  extra = createHash('md5').update(JSON.stringify(extra)).digest('hex')
  const key = `dobo|${model.name}|${options.action}|${id}|${extra}`
  return key
}

/**
 * Clear cached result set items.
 *
 * @async
 * @method
 * @param {object} [opts={}] - The options for clearing the cached result set
 * @returns {Promise<void>}
 */
export async function clear (opts = {}) {
  if (!this.instance) return
  await clearCache.call(this, opts)
}

/**
 * Get a cached result set item.
 *
 * @async
 * @method
 * @param {object} [opts={}] - The options for retrieving the cached result set
 * @returns {Promise<*>} - Returns the cached result set item or false if not found
 */
export async function get (opts = {}) {
  if (!this.instance) return
  const { isEmpty } = this.app.lib._
  if (opts.options.noCache || opts.model.cache.ttlDur === 0) return false
  const key = buildKey.call(this, opts)
  const result = await this.instance.get(key)
  return isEmpty(result) ? false : result
}

/**
 * Remove a cached result set item.
 *
 * @async
 * @method
 * @param {object} [opts={}] - The options for removing the cached result set
 * @returns {Promise<void>}
 */
export async function remove (opts = {}) {
  if (!this.instance) return
  if (opts.options.noCache || opts.model.cache.ttlDur === 0) return
  const key = buildKey.call(this, opts)
  await this.instance.delete(key)
}

/**
 * Set a cached result set item.
 *
 * @async
 * @method
 * @param {object} [opts={}] - The options for setting the cached result set
 * @returns {Promise<void>}
 */
export async function set (opts = {}) {
  if (!this.instance) return
  if (opts.options.noCache || opts.model.cache.ttlDur === 0) return
  let ttl = opts.ttl ?? opts.model.cache.ttlDur
  if (ttl <= 0) ttl = 1
  const key = buildKey.call(this, opts)
  const value = opts.result
  await this.instance.set(key, value, ttl)
}