Convert to class

3355c682ca1b0e88ede899ee0e4c4e975c9867fd

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +62 -51Ignore whitespace
server.js+2 -2
@@ -66,7 +66,7 @@ import { init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.
6666import { checkForNewContent } from './src/endpoints/content-manager.js';
6767import { init as settingsInit } from './src/endpoints/settings.js';
6868import { redirectDeprecatedEndpoints, ServerStartup, setupPrivateEndpoints } from './src/server-startup.js';
6969import { verifyCharactersDiskCachediskCache } from './src/endpoints/characters.js';
7070
7171// Unrestrict console logs display limit
7272util.inspect.defaultOptions.maxArrayLength = null;
@@ -269,7 +269,7 @@ async function preSetupTasks() {
269269 const directories = await getUserDirectoriesList();
270270 await checkForNewContent(directories);
271271 await ensureThumbnailCache();
272272 await verifyCharactersDiskCachediskCache.verify(directories);
273273 cleanUploads();
274274 migrateAccessLog();
275275
src/endpoints/characters.js+60 -49
@@ -32,90 +32,101 @@ const isAndroid = process.platform === 'android';
3232const useShallowCharacters = !!getConfigValue('performance.lazyLoadCharacters', false, 'boolean');
3333const useDiskCache = !!getConfigValue('performance.useDiskCache', true, 'boolean');
3434
3535const diskCacheclass =DiskCache {
36- /**
36+ /** @type {string} */
37- * @type {import('node-persist').LocalStorage?}
37+ static DIRECTORY = 'characters';
38- * @private
38+
39- */
39+ /** @type {number} */
40- _instance: null,
40+ static REMOVAL_INTERVAL = 60000;
41+
42+ /** @type {import('node-persist').LocalStorage} */
43+ #instance;
44+
45+ /** @type {NodeJS.Timeout} */
46+ #removalInterval;
47+
4148 /**
42- * @type {NodeJS.Timeout?}
49+ * Queue for removal of cache entries.
43- * @private
50+ * @type {Set<string>}
4451 */
45- _removalInterval: null,
52+ removalQueue = new Set();
53+
4654 /**
4755 * Processes the removal queue.
4856 * @returns {Promise<void>}
49- * @private
5057 */
5158 _removeCacheEntries: async function#removeCacheEntries() {
5259 try {
5360 if (!useDiskCache || this.removalQueue.size === 0) {
5461 return;
5562 }
5663
5764 const keys = await diskCachethis.instance().then(i => i.keys());
5865 for (const item of this.removalQueue) {
5966 const key = keys.find(k => k.startsWith(item));
6067 if (key) {
6168 await diskCachethis.instance().then(i => i.removeItem(key));
6269 }
6370 }
6471 this.removalQueue.clear();
6572 } catch (error) {
6673 console.error('Error while removing cache entries:', error);
6774 }
6875 },;
76+
6977 /**
7078 * Gets the disk cache instance.
7179 * @returns {Promise<import('node-persist').LocalStorage>}
7280 */
7381 instance: async functioninstance() {
7482 if (this._instance#instance) {
7583 return this._instance#instance;
7684 }
7785
7886 const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', 'characters'DiskCache.DIRECTORY);
7987 this._instance#instance = storage.create({ dir: cacheDir, ttl: false });
8088 await this._instance#instance.init();
8189 this._removalInterval#removalInterval = setInterval(this._removeCacheEntries#removeCacheEntries.bind(this), 60000DiskCache.REMOVAL_INTERVAL);
8290 return this._instance#instance;
8391 },
92+
8493 /**
8594 * QueueVerifies fordisk removalcache ofsize cacheand entriesprunes it if necessary.
86- * @type {Set<string>}
95+ * @param {import('../users.js').UserDirectoryList[]} directoriesList List of user directories
96+ * @returns {Promise<void>}
8797 */
88- removalQueue: new Set(),
98+ async verify(directoriesList) {
89-};
99+ if (!useDiskCache) {
90-
100+ return;
91-/**
101+ }
92- * Verifies disk cache size and prunes it if necessary.
93- * @param {import('../users.js').UserDirectoryList[]} directoriesList List of user directories
94- * @returns {Promise<void>}
95- */
96-export async function verifyCharactersDiskCache(directoriesList) {
97- if (!useDiskCache) {
98- return;
99- }
100102
101103 const cache = await diskCachethis.instance();
102104 const validKeys = [];
103105 for (const dir of directoriesList) {
104106 const files = fs.readdirSync(dir.characters);
105107 for (const file of files) {
106108 const filePath = path.join(dir.characters, file);
107109 const stat = fs.statSync(filePath);
108110 validKeys.push(`${filePath}-${stat.mtimeMs}`);
111+ }
112+ }
113+ const cacheKeys = await cache.keys();
114+ for (const key of cacheKeys) {
115+ if (!validKeys.includes(key)) {
116+ await cache.removeItem(key);
117+ }
109118 }
110119 }
111- const cacheKeys = await cache.keys();
120+
112121 for dispose(const key of cacheKeys) {
113122 if (!validKeysthis.includes(key)#removalInterval) {
114- await cache.removeItem(key);
123+ clearInterval(this.#removalInterval);
115124 }
116125 }
117126}
118127
128+export const diskCache = new DiskCache();
129+
119130/**
120131 * Reads the character card from the specified image file.
121132 * @param {string} inputFile - Path to the image file