Track expiration in repository

This commit is contained in:
Jon Staab
2025-07-15 10:57:22 -07:00
parent 3249346b95
commit fd84b80734
2 changed files with 102 additions and 74 deletions
+32 -3
View File
@@ -43,6 +43,7 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
eventsByAuthor = new Map<string, E[]>()
eventsByKind = new Map<number, E[]>()
deletes = new Map<string, number>()
expired = new Map<string, number>()
static get() {
if (!repositorySingleton) {
@@ -75,6 +76,7 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
this.eventsByAuthor.clear()
this.eventsByKind.clear()
this.deletes.clear()
this.expired.clear()
const added = []
@@ -103,6 +105,11 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
removed.add(id)
}
// Anything expired has been removed
for (const id of this.expired.keys()) {
removed.add(id)
}
this.emit("update", {added, removed})
}
@@ -146,7 +153,10 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
}
}
query = (filters: Filter[], {includeDeleted = false, shouldSort = true} = {}) => {
query = (
filters: Filter[],
{includeDeleted = false, includeExpired = false, shouldSort = true} = {},
) => {
const result: E[][] = []
for (const originalFilter of filters) {
if (originalFilter.limit !== undefined && !shouldSort) {
@@ -169,6 +179,10 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
continue
}
if (!includeExpired && this.isExpired(event)) {
continue
}
if (matchFilter(filter, event)) {
chunk.push(event)
}
@@ -190,8 +204,8 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
return false
}
// If we've already seen this event, or it's been deleted, we're done
if (this.eventsById.get(event.id) || this.isDeleted(event)) {
// If we've already seen this event we're done
if (this.eventsById.get(event.id)) {
return false
}
@@ -247,6 +261,15 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
}
}
}
// Keep track of whether this event is expired
if (tag[0] === "expiration") {
const expiration = parseInt(tag[1] || "")
if (!isNaN(expiration)) {
this.expired.set(event.id, expiration)
}
}
}
if (shouldNotify) {
@@ -262,6 +285,12 @@ export class Repository<E extends HashedEvent = TrustedEvent> extends Emitter {
isDeleted = (event: E) => this.isDeletedByAddress(event) || this.isDeletedById(event)
isExpired = (event: E) => {
const ts = this.expired.get(event.id)
return Boolean(ts && ts < now())
}
// Utilities
_sortEvents = (shouldSort: boolean, events: E[]) =>