@rmdes/indiekit-endpoint-microsub 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +6 -1
- package/lib/storage/items.js +62 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { microsubController } from "./lib/controllers/microsub.js";
|
|
|
6
6
|
import { readerController } from "./lib/controllers/reader.js";
|
|
7
7
|
import { handleMediaProxy } from "./lib/media/proxy.js";
|
|
8
8
|
import { startScheduler, stopScheduler } from "./lib/polling/scheduler.js";
|
|
9
|
-
import { createIndexes } from "./lib/storage/items.js";
|
|
9
|
+
import { cleanupAllReadItems, createIndexes } from "./lib/storage/items.js";
|
|
10
10
|
import { webmentionReceiver } from "./lib/webmention/receiver.js";
|
|
11
11
|
import { websubHandler } from "./lib/websub/handler.js";
|
|
12
12
|
|
|
@@ -157,6 +157,11 @@ export default class MicrosubEndpoint {
|
|
|
157
157
|
createIndexes(indiekit).catch((error) => {
|
|
158
158
|
console.warn("[Microsub] Index creation failed:", error.message);
|
|
159
159
|
});
|
|
160
|
+
|
|
161
|
+
// Cleanup old read items on startup
|
|
162
|
+
cleanupAllReadItems(indiekit).catch((error) => {
|
|
163
|
+
console.warn("[Microsub] Startup cleanup failed:", error.message);
|
|
164
|
+
});
|
|
160
165
|
} else {
|
|
161
166
|
console.warn(
|
|
162
167
|
"[Microsub] Database not available at init, scheduler not started",
|
package/lib/storage/items.js
CHANGED
|
@@ -328,6 +328,68 @@ async function cleanupOldReadItems(collection, channelObjectId, userId) {
|
|
|
328
328
|
}
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Cleanup all read items across all channels (startup cleanup)
|
|
333
|
+
* @param {object} application - Indiekit application
|
|
334
|
+
* @returns {Promise<number>} Total number of items deleted
|
|
335
|
+
*/
|
|
336
|
+
export async function cleanupAllReadItems(application) {
|
|
337
|
+
const collection = getCollection(application);
|
|
338
|
+
const channelsCollection = application.collections.get("microsub_channels");
|
|
339
|
+
|
|
340
|
+
// Get all channels
|
|
341
|
+
const channels = await channelsCollection.find({}).toArray();
|
|
342
|
+
let totalDeleted = 0;
|
|
343
|
+
|
|
344
|
+
for (const channel of channels) {
|
|
345
|
+
// Get unique userIds who have read items in this channel
|
|
346
|
+
const readByUsers = await collection.distinct("readBy", {
|
|
347
|
+
channelId: channel._id,
|
|
348
|
+
readBy: { $exists: true, $ne: [] },
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
for (const userId of readByUsers) {
|
|
352
|
+
if (!userId) continue;
|
|
353
|
+
|
|
354
|
+
const readCount = await collection.countDocuments({
|
|
355
|
+
channelId: channel._id,
|
|
356
|
+
readBy: userId,
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
if (readCount > MAX_READ_ITEMS) {
|
|
360
|
+
const itemsToDelete = await collection
|
|
361
|
+
.find({
|
|
362
|
+
channelId: channel._id,
|
|
363
|
+
readBy: userId,
|
|
364
|
+
})
|
|
365
|
+
.sort({ published: -1, _id: -1 })
|
|
366
|
+
.skip(MAX_READ_ITEMS)
|
|
367
|
+
.project({ _id: 1 })
|
|
368
|
+
.toArray();
|
|
369
|
+
|
|
370
|
+
if (itemsToDelete.length > 0) {
|
|
371
|
+
const idsToDelete = itemsToDelete.map((item) => item._id);
|
|
372
|
+
const deleteResult = await collection.deleteMany({
|
|
373
|
+
_id: { $in: idsToDelete },
|
|
374
|
+
});
|
|
375
|
+
totalDeleted += deleteResult.deletedCount;
|
|
376
|
+
console.info(
|
|
377
|
+
`[Microsub] Startup cleanup: deleted ${deleteResult.deletedCount} old items from channel "${channel.name}"`,
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (totalDeleted > 0) {
|
|
385
|
+
console.info(
|
|
386
|
+
`[Microsub] Startup cleanup complete: ${totalDeleted} total items deleted`,
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return totalDeleted;
|
|
391
|
+
}
|
|
392
|
+
|
|
331
393
|
export async function markItemsRead(application, channelId, entryIds, userId) {
|
|
332
394
|
const collection = getCollection(application);
|
|
333
395
|
const channelObjectId =
|
package/package.json
CHANGED