1
+ // METADATA // {"ai-commented":{"service":"xai"}}
1
2
/*
2
3
* Copyright (C) 2024 Puter Technologies Inc.
3
4
*
@@ -23,6 +24,17 @@ const { DB_READ } = require("./database/consts");
23
24
24
25
const uuidv4 = require ( 'uuid' ) . v4 ;
25
26
27
+
28
+ /**
29
+ * @class AppInformationService
30
+ * @description
31
+ * The AppInformationService class manages application-related information,
32
+ * including caching, statistical data, and tags for applications within the Puter ecosystem.
33
+ * It provides methods for refreshing application data, managing app statistics,
34
+ * and handling tags associated with apps. This service is crucial for maintaining
35
+ * up-to-date information about applications, facilitating features like app listings,
36
+ * recent apps, and tag-based app discovery.
37
+ */
26
38
class AppInformationService {
27
39
constructor ( { services } ) {
28
40
this . services = services ;
@@ -37,33 +49,87 @@ class AppInformationService {
37
49
// await new Promise(rslv => setTimeout(rslv, 500))
38
50
39
51
await this . _refresh_app_cache ( ) ;
52
+ /**
53
+ * Refreshes the application cache by querying the database for all apps and updating the key-value store.
54
+ *
55
+ * This method is called periodically to ensure that the in-memory cache reflects the latest
56
+ * state from the database. It uses the 'database' service to fetch app data and then updates
57
+ * multiple cache entries for quick lookups by name, ID, and UID.
58
+ *
59
+ * @async
60
+ */
40
61
asyncSafeSetInterval ( async ( ) => {
41
62
this . _refresh_app_cache ( ) ;
42
63
} , 30 * 1000 ) ;
43
64
44
65
await this . _refresh_app_stats ( ) ;
66
+ /**
67
+ * Refreshes the cache of recently opened apps.
68
+ * This method updates the 'recent' collection with the UIDs of apps sorted by their most recent timestamp.
69
+ *
70
+ * @async
71
+ * @returns {Promise<void> } A promise that resolves when the cache has been refreshed.
72
+ */
45
73
asyncSafeSetInterval ( async ( ) => {
46
74
this . _refresh_app_stats ( ) ;
47
75
} , 120 * 1000 ) ;
48
76
49
77
// This stat is more expensive so we don't update it as often
50
78
await this . _refresh_app_stat_referrals ( ) ;
79
+ /**
80
+ * Refreshes the app referral statistics.
81
+ * This method is computationally expensive and thus runs less frequently.
82
+ * It queries the database for user counts referred by each app's origin URL.
83
+ *
84
+ * @async
85
+ */
51
86
asyncSafeSetInterval ( async ( ) => {
52
87
this . _refresh_app_stat_referrals ( ) ;
53
88
} , 15 * MINUTE ) ;
54
89
55
90
await this . _refresh_recent_cache ( ) ;
91
+ /**
92
+ * Refreshes the recent cache by updating the list of recently added or updated apps.
93
+ * This method fetches all app data, filters for approved apps, sorts them by timestamp,
94
+ * and updates the `this.collections.recent` array with the UIDs of the most recent 50 apps.
95
+ *
96
+ * @async
97
+ * @private
98
+ */
56
99
asyncSafeSetInterval ( async ( ) => {
57
100
this . _refresh_recent_cache ( ) ;
58
101
} , 120 * 1000 ) ;
59
102
60
103
await this . _refresh_tags ( ) ;
104
+ /**
105
+ * Refreshes the tags cache by iterating through all approved apps,
106
+ * extracting their tags, and organizing them into a structured format.
107
+ * This method updates the `this.tags` object with the latest tag information.
108
+ *
109
+ * @async
110
+ * @method
111
+ * @memberof AppInformationService
112
+ */
61
113
asyncSafeSetInterval ( async ( ) => {
62
114
this . _refresh_tags ( ) ;
63
115
} , 120 * 1000 ) ;
64
116
} ) ( ) ;
65
117
}
66
118
119
+
120
+ /**
121
+ * Retrieves and returns statistical data for a specific application.
122
+ *
123
+ * This method fetches various metrics such as the number of times the app has been opened,
124
+ * the count of unique users who have opened the app, and the number of referrals attributed to the app.
125
+ * It uses cached data where available to improve performance.
126
+ *
127
+ * @param {string } app_uid - The unique identifier for the application.
128
+ * @returns {Promise<Object> } An object containing:
129
+ * - {number} open_count - The total number of times the app has been opened.
130
+ * - {number} user_count - The count of unique users who have opened the app.
131
+ * - {number|null} referral_count - The number of referrals, or null if the data is not available or too expensive to retrieve.
132
+ */
67
133
async get_stats ( app_uid ) {
68
134
const db = this . services . get ( 'database' ) . get ( DB_READ , 'apps' ) ;
69
135
@@ -100,6 +166,19 @@ class AppInformationService {
100
166
} ;
101
167
}
102
168
169
+
170
+ /**
171
+ * Retrieves various statistics for a given app.
172
+ *
173
+ * This method fetches the open count, user count, and referral count for an app identified by its UID.
174
+ * It uses cached values where available to improve performance, but will query the database if necessary.
175
+ *
176
+ * @param {string } app_uid - The unique identifier of the app for which to retrieve stats.
177
+ * @returns {Promise<Object> } An object containing:
178
+ * - {number} open_count - Total number of times the app was opened.
179
+ * - {number} user_count - Number of unique users who opened the app.
180
+ * - {number|null} referral_count - Number of referrals attributed to the app. This value might not be reported if not cached.
181
+ */
103
182
async _refresh_app_cache ( ) {
104
183
this . log . tick ( 'refresh app cache' ) ;
105
184
@@ -114,6 +193,17 @@ class AppInformationService {
114
193
}
115
194
}
116
195
196
+
197
+ /**
198
+ * Refreshes the application cache by querying the database for all apps and updating the key-value store.
199
+ *
200
+ * @async
201
+ * @returns {Promise<void> } A promise that resolves when the cache refresh operation is complete.
202
+ *
203
+ * @notes
204
+ * - This method logs a tick event for performance monitoring.
205
+ * - It populates the cache with app data indexed by name, id, and uid.
206
+ */
117
207
async _refresh_app_stats ( ) {
118
208
this . log . tick ( 'refresh app stats' ) ;
119
209
@@ -144,6 +234,13 @@ class AppInformationService {
144
234
}
145
235
}
146
236
237
+
238
+ /**
239
+ * Refreshes the cache of app statistics including open and user counts.
240
+ * This method updates the cache every 120 seconds to ensure data freshness.
241
+ *
242
+ * @async
243
+ */
147
244
async _refresh_app_stat_referrals ( ) {
148
245
this . log . tick ( 'refresh app stat referrals' ) ;
149
246
@@ -176,6 +273,17 @@ class AppInformationService {
176
273
this . log . info ( 'DONE refresh app stat referrals' ) ;
177
274
}
178
275
276
+
277
+ /**
278
+ * Updates the cache with recently updated apps.
279
+ *
280
+ * @description This method refreshes the cache containing the most recently updated applications.
281
+ * It fetches all app UIDs, retrieves the corresponding app data, filters for approved apps,
282
+ * sorts them by timestamp in descending order, and updates the 'recent' collection with
283
+ * the UIDs of the top 50 most recent apps.
284
+ *
285
+ * @returns {Promise<void> } Resolves when the cache has been updated.
286
+ */
179
287
async _refresh_recent_cache ( ) {
180
288
const app_keys = kv . keys ( `apps:uid:*` ) ;
181
289
// console.log('APP KEYS', app_keys);
@@ -194,6 +302,16 @@ class AppInformationService {
194
302
this . collections . recent = apps . map ( app => app . uid ) . slice ( 0 , 50 ) ;
195
303
}
196
304
305
+
306
+ /**
307
+ * Refreshes the cache of recently added or updated apps.
308
+ *
309
+ * This method retrieves all apps from the cache, filters for approved listings,
310
+ * sorts them by timestamp in descending order, and updates the `recent` collection
311
+ * with the UIDs of the most recent 50 apps.
312
+ *
313
+ * @returns {Promise<void> }
314
+ */
197
315
async _refresh_tags ( ) {
198
316
const app_keys = kv . keys ( `apps:uid:*` ) ;
199
317
// console.log('APP KEYS', app_keys);
@@ -229,6 +347,22 @@ class AppInformationService {
229
347
this . tags = new_tags ;
230
348
}
231
349
350
+
351
+ /**
352
+ * Deletes an application from the system.
353
+ *
354
+ * This method performs the following actions:
355
+ * - Retrieves the app data from cache or database if not provided.
356
+ * - Deletes the app record from the database.
357
+ * - Removes the app from all relevant caches (by name, id, and uid).
358
+ * - Removes the app from the recent collection if present.
359
+ * - Removes the app from any associated tags.
360
+ *
361
+ * @param {string } app_uid - The unique identifier of the app to be deleted.
362
+ * @param {Object } [app] - The app object, if already fetched. If not provided, it will be retrieved.
363
+ * @throws {Error } If the app is not found in either cache or database.
364
+ * @returns {Promise<void> } A promise that resolves when the app has been successfully deleted.
365
+ */
232
366
async delete_app ( app_uid , app ) {
233
367
const db = this . services . get ( 'database' ) . get ( DB_READ , 'apps' ) ;
234
368
0 commit comments