Convert to class

3355c682ca1b0e88ede899ee0e4c4e975c9867fd

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

2 files changed, +44 -33Showing whitespace changes
server.js+2 -2
@@ -66,7 +66,7 @@ import { init as statsInit, onExit as statsOnExit } from './src/endpoints/stats.
66import { checkForNewContent } from './src/endpoints/content-manager.js';66import { checkForNewContent } from './src/endpoints/content-manager.js';
67import { init as settingsInit } from './src/endpoints/settings.js';67import { init as settingsInit } from './src/endpoints/settings.js';
68import { redirectDeprecatedEndpoints, ServerStartup, setupPrivateEndpoints } from './src/server-startup.js';68import { redirectDeprecatedEndpoints, ServerStartup, setupPrivateEndpoints } from './src/server-startup.js';
69import { verifyCharactersDiskCache } from './src/endpoints/characters.js';69import { diskCache } from './src/endpoints/characters.js';
7070
71// Unrestrict console logs display limit71// Unrestrict console logs display limit
72util.inspect.defaultOptions.maxArrayLength = null;72util.inspect.defaultOptions.maxArrayLength = null;
@@ -269,7 +269,7 @@ async function preSetupTasks() {
269 const directories = await getUserDirectoriesList();269 const directories = await getUserDirectoriesList();
270 await checkForNewContent(directories);270 await checkForNewContent(directories);
271 await ensureThumbnailCache();271 await ensureThumbnailCache();
272 await verifyCharactersDiskCache(directories);272 await diskCache.verify(directories);
273 cleanUploads();273 cleanUploads();
274 migrateAccessLog();274 migrateAccessLog();
275275
src/endpoints/characters.js+42 -31
@@ -32,73 +32,75 @@ const isAndroid = process.platform === 'android';
32const useShallowCharacters = !!getConfigValue('performance.lazyLoadCharacters', false, 'boolean');32const useShallowCharacters = !!getConfigValue('performance.lazyLoadCharacters', false, 'boolean');
33const useDiskCache = !!getConfigValue('performance.useDiskCache', true, 'boolean');33const useDiskCache = !!getConfigValue('performance.useDiskCache', true, 'boolean');
3434
35const diskCache = {35class DiskCache {
36 /**36 /** @type {string} */
37 * @type {import('node-persist').LocalStorage?}37 static DIRECTORY = 'characters';
38 * @private38
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
41 /**48 /**
42 * @type {NodeJS.Timeout?}49 * Queue for removal of cache entries.
43 * @private50 * @type {Set<string>}
44 */51 */
45 _removalInterval: null,52 removalQueue = new Set();
53
46 /**54 /**
47 * Processes the removal queue.55 * Processes the removal queue.
48 * @returns {Promise<void>}56 * @returns {Promise<void>}
49 * @private
50 */57 */
51 _removeCacheEntries: async function() {58 async #removeCacheEntries() {
52 try {59 try {
53 if (!useDiskCache || this.removalQueue.size === 0) {60 if (!useDiskCache || this.removalQueue.size === 0) {
54 return;61 return;
55 }62 }
5663
57 const keys = await diskCache.instance().then(i => i.keys());64 const keys = await this.instance().then(i => i.keys());
58 for (const item of this.removalQueue) {65 for (const item of this.removalQueue) {
59 const key = keys.find(k => k.startsWith(item));66 const key = keys.find(k => k.startsWith(item));
60 if (key) {67 if (key) {
61 await diskCache.instance().then(i => i.removeItem(key));68 await this.instance().then(i => i.removeItem(key));
62 }69 }
63 }70 }
64 this.removalQueue.clear();71 this.removalQueue.clear();
65 } catch (error) {72 } catch (error) {
66 console.error('Error while removing cache entries:', error);73 console.error('Error while removing cache entries:', error);
67 }74 }
68 },75 };
76
69 /**77 /**
70 * Gets the disk cache instance.78 * Gets the disk cache instance.
71 * @returns {Promise<import('node-persist').LocalStorage>}79 * @returns {Promise<import('node-persist').LocalStorage>}
72 */80 */
73 instance: async function() {81 async instance() {
74 if (this._instance) {82 if (this.#instance) {
75 return this._instance;83 return this.#instance;
76 }84 }
7785
78 const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', 'characters');86 const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', DiskCache.DIRECTORY);
79 this._instance = storage.create({ dir: cacheDir, ttl: false });87 this.#instance = storage.create({ dir: cacheDir, ttl: false });
80 await this._instance.init();88 await this.#instance.init();
81 this._removalInterval = setInterval(this._removeCacheEntries.bind(this), 60000);89 this.#removalInterval = setInterval(this.#removeCacheEntries.bind(this), DiskCache.REMOVAL_INTERVAL);
82 return this._instance;90 return this.#instance;
83 },91 }
84 /**
85 * Queue for removal of cache entries.
86 * @type {Set<string>}
87 */
88 removalQueue: new Set(),
89};
9092
91 /**93 /**
92 * Verifies disk cache size and prunes it if necessary.94 * Verifies disk cache size and prunes it if necessary.
93 * @param {import('../users.js').UserDirectoryList[]} directoriesList List of user directories95 * @param {import('../users.js').UserDirectoryList[]} directoriesList List of user directories
94 * @returns {Promise<void>}96 * @returns {Promise<void>}
95 */97 */
96export async function verifyCharactersDiskCache(directoriesList) {98 async verify(directoriesList) {
97 if (!useDiskCache) {99 if (!useDiskCache) {
98 return;100 return;
99 }101 }
100102
101 const cache = await diskCache.instance();103 const cache = await this.instance();
102 const validKeys = [];104 const validKeys = [];
103 for (const dir of directoriesList) {105 for (const dir of directoriesList) {
104 const files = fs.readdirSync(dir.characters);106 const files = fs.readdirSync(dir.characters);
@@ -116,6 +118,15 @@ export async function verifyCharactersDiskCache(directoriesList) {
116 }118 }
117 }119 }
118120
121 dispose() {
122 if (this.#removalInterval) {
123 clearInterval(this.#removalInterval);
124 }
125 }
126}
127
128export const diskCache = new DiskCache();
129
119/**130/**
120 * Reads the character card from the specified image file.131 * Reads the character card from the specified image file.
121 * @param {string} inputFile - Path to the image file132 * @param {string} inputFile - Path to the image file