feat(cache): send oldValue to onCache

Internally handle the cache events to prevent race conditions
and resolve #618.
Improved types.
This commit is contained in:
Linden
2024-08-13 14:11:27 +10:00
parent 03db59cce5
commit 6b12831817
2 changed files with 49 additions and 8 deletions

View File

@@ -91,9 +91,6 @@ end
local lib = setmetatable({ local lib = setmetatable({
name = ox_lib, name = ox_lib,
context = context, context = context,
onCache = function(key, cb)
AddEventHandler(('ox_lib:cache:%s'):format(key), cb)
end
}, { }, {
__index = call, __index = call,
__call = call, __call = call,
@@ -173,14 +170,27 @@ end
---Caches the result of a function, optionally clearing it after timeout ms. ---Caches the result of a function, optionally clearing it after timeout ms.
function cache(key, func, timeout) end function cache(key, func, timeout) end
local cacheEvents = {}
local cache = setmetatable({ game = GetGameName(), resource = resourceName }, { local cache = setmetatable({ game = GetGameName(), resource = resourceName }, {
__index = context == 'client' and function(self, key) __index = function(self, key)
cacheEvents[key] = {}
AddEventHandler(('ox_lib:cache:%s'):format(key), function(value) AddEventHandler(('ox_lib:cache:%s'):format(key), function(value)
local oldValue = self[key]
local events = cacheEvents[key]
for i = 1, #events do
Citizen.CreateThreadNow(function()
events[i](value, oldValue)
end)
end
self[key] = value self[key] = value
end) end)
return rawset(self, key, export.cache(nil, key) or false)[key] return rawset(self, key, export.cache(nil, key) or false)[key]
end or nil, end,
__call = function(self, key, func, timeout) __call = function(self, key, func, timeout)
local value = rawget(self, key) local value = rawget(self, key)
@@ -197,6 +207,14 @@ local cache = setmetatable({ game = GetGameName(), resource = resourceName }, {
end, end,
}) })
function lib.onCache(key, cb)
if not cacheEvents[key] then
getmetatable(cache).__index(cache, key)
end
table.insert(cacheEvents[key], cb)
end
_ENV.cache = cache _ENV.cache = cache
local notifyEvent = ('__ox_notify_%s'):format(cache.resource) local notifyEvent = ('__ox_notify_%s'):format(cache.resource)

View File

@@ -1,13 +1,34 @@
export const cache: Record<string, any> = new Proxy( interface OxCache {
ped: number;
vehicle: number | false;
seat: number | false;
game: string;
resource: string;
playerId: number;
serverId: number;
[key: string]: unknown;
}
const cacheEvents: Record<keyof OxCache, Function[]> = {};
export const cache: OxCache = new Proxy(
{ {
resource: GetCurrentResourceName(), resource: GetCurrentResourceName(),
game: GetGameName(),
}, },
{ {
get(target: any, key: string) { get(target: any, key: string) {
const result = key ? target[key] : target; const result = key ? target[key] : target;
if (result !== undefined) return result; if (result !== undefined) return result;
cacheEvents[key] = [];
AddEventHandler(`ox_lib:cache:${key}`, (value: any) => { AddEventHandler(`ox_lib:cache:${key}`, (value: any) => {
const oldValue = target[key];
const events = cacheEvents[key];
events.forEach((cb) => cb(value, oldValue));
target[key] = value; target[key] = value;
}); });
@@ -17,6 +38,8 @@ export const cache: Record<string, any> = new Proxy(
} }
); );
export const onCache = <T = any>(key: string, cb: (value: T) => void) => { export const onCache = <T extends keyof OxCache>(key: T, cb: (value: OxCache[T], oldValue: OxCache[T]) => void) => {
AddEventHandler(`ox_lib:cache:${key}`, cb); if (!cacheEvents[key]) cache[key];
cacheEvents[key].push(cb);
}; };