-- Copyright 2025 David Vazgenovich Shakaryan local util = require('util') local mp_utils = require('mp.utils') local cacher = {} local function exec(obj, opts, call_opts, func, func_name, ...) local call_opts = call_opts or {} local fn = table.concat({opts.prefix, func_name, ...}, '.') local path = mp_utils.join_path(opts.directory, fn) local f = mp_utils.file_info(path) local data local miss = call_opts.force or not f or os.time() - f.mtime > opts.time if miss then if call_opts.before_miss then call_opts.before_miss() end data = func(obj, ...) if data then util.write_json_file(path, data) end else if call_opts.before_hit then call_opts.before_hit() end end if f and not data then print('using cached ' .. fn) data = util.read_json_file(path) end if miss then if call_opts.after_miss then call_opts.after_miss() end else if call_opts.after_hit then call_opts.after_hit() end end return data end function cacher.wrap(obj, opts) local proxy = {} function proxy:with_opts(f, ...) local n = select('#', ...) local args = {...} return exec( obj, opts, args[n], obj[f], f, unpack(args, 1, n - 1)) end setmetatable(proxy, { __index = function(t, k) local v = obj[k] if type(v) ~= 'function' or not opts.functions[k] then return v end local fn = function(_, ...) return exec(obj, opts, nil, v, k, ...) end t[k] = fn return fn end, }) return proxy end return cacher