109 lines
2.6 KiB
TypeScript
109 lines
2.6 KiB
TypeScript
|
|
import * as plugins from '../plugins.js';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Base class for all cached documents with TTL support
|
||
|
|
*
|
||
|
|
* Extends smartdata's SmartDataDbDoc to add:
|
||
|
|
* - Automatic timestamps (createdAt, lastAccessedAt)
|
||
|
|
* - TTL/expiration support (expiresAt)
|
||
|
|
* - Helper methods for TTL management
|
||
|
|
*/
|
||
|
|
export abstract class CachedDocument<T extends CachedDocument<T>> extends plugins.smartdata.SmartDataDbDoc<T, T> {
|
||
|
|
/**
|
||
|
|
* Timestamp when the document was created
|
||
|
|
*/
|
||
|
|
@plugins.smartdata.svDb()
|
||
|
|
public createdAt: Date = new Date();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Timestamp when the document expires and should be cleaned up
|
||
|
|
*/
|
||
|
|
@plugins.smartdata.svDb()
|
||
|
|
public expiresAt: Date;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Timestamp of last access (for LRU-style eviction if needed)
|
||
|
|
*/
|
||
|
|
@plugins.smartdata.svDb()
|
||
|
|
public lastAccessedAt: Date = new Date();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the TTL (time to live) for this document
|
||
|
|
* @param ttlMs Time to live in milliseconds
|
||
|
|
*/
|
||
|
|
public setTTL(ttlMs: number): void {
|
||
|
|
this.expiresAt = new Date(Date.now() + ttlMs);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set TTL using days
|
||
|
|
* @param days Number of days until expiration
|
||
|
|
*/
|
||
|
|
public setTTLDays(days: number): void {
|
||
|
|
this.setTTL(days * 24 * 60 * 60 * 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set TTL using hours
|
||
|
|
* @param hours Number of hours until expiration
|
||
|
|
*/
|
||
|
|
public setTTLHours(hours: number): void {
|
||
|
|
this.setTTL(hours * 60 * 60 * 1000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if this document has expired
|
||
|
|
*/
|
||
|
|
public isExpired(): boolean {
|
||
|
|
if (!this.expiresAt) {
|
||
|
|
return false; // No expiration set
|
||
|
|
}
|
||
|
|
return new Date() > this.expiresAt;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update the lastAccessedAt timestamp
|
||
|
|
*/
|
||
|
|
public touch(): void {
|
||
|
|
this.lastAccessedAt = new Date();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get remaining TTL in milliseconds
|
||
|
|
* Returns 0 if expired, -1 if no expiration set
|
||
|
|
*/
|
||
|
|
public getRemainingTTL(): number {
|
||
|
|
if (!this.expiresAt) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
const remaining = this.expiresAt.getTime() - Date.now();
|
||
|
|
return remaining > 0 ? remaining : 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Extend the TTL by the specified milliseconds from now
|
||
|
|
* @param ttlMs Additional time to live in milliseconds
|
||
|
|
*/
|
||
|
|
public extendTTL(ttlMs: number): void {
|
||
|
|
this.expiresAt = new Date(Date.now() + ttlMs);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the document to never expire (100 years in the future)
|
||
|
|
*/
|
||
|
|
public setNeverExpires(): void {
|
||
|
|
this.expiresAt = new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* TTL constants in milliseconds
|
||
|
|
*/
|
||
|
|
export const TTL = {
|
||
|
|
HOURS_1: 1 * 60 * 60 * 1000,
|
||
|
|
HOURS_24: 24 * 60 * 60 * 1000,
|
||
|
|
DAYS_7: 7 * 24 * 60 * 60 * 1000,
|
||
|
|
DAYS_30: 30 * 24 * 60 * 60 * 1000,
|
||
|
|
DAYS_90: 90 * 24 * 60 * 60 * 1000,
|
||
|
|
} as const;
|