pg-cache package
PostgreSQL-managed cache on Redis for @imqueue service methods: results are memoised, and PostgreSQL itself says when to drop them.
Decorate the service class with PgCache(), then mark cached methods with cacheWith() or cacheBy() to declare which tables they depend on.
Remarks
The point is invalidation that is neither a guessed TTL nor a manual del() call. PgCache() installs a change-notify trigger on each declared table and subscribes to one LISTEN/NOTIFY channel per table; when a row changes, the entries tagged with that table are dropped. So an entry lives exactly as long as the data behind it is unchanged.
Two things to know. The triggers and the subscription are established in start(), so a service that never starts is never cached. And a ChannelFilter given as an array of ChannelOperation is an EXCLUSION list — the operations named in it do not invalidate — which reads the opposite way round from how it looks.
Example
import { PgCache, cacheWith } from '@imqueue/pg-cache';
@PgCache({
postgres: process.env.DB_URL!,
redis: { host: 'localhost', port: 6379 },
})
class UserService extends IMQService {
@cacheWith({ channels: ['users'] })
public async list(): Promise<User[]> {
return this.db.query('SELECT * FROM users');
}
}
Enumerations
|
Enumeration |
Description |
|---|---|
|
The row-level operation that produced a change notification. Matches the PostgreSQL trigger's |
Functions
|
Function |
Description |
|---|---|
|
Decorator factory | |
|
Decorator factory | |
|
Retrieves table names as channels from the given model and filter them by a given fields map, if passed. Returns result as list of table names. | |
|
Walks up from a constructed instance to the prototype that actually declares the given method, mirroring legacy decoration where the decorator target is the declaring prototype. Falls back to the instance's own prototype. | |
|
Reads a boolean environment variable, accepting the human-friendly spellings 1/true/yes/on and 0/false/no/off (case-insensitive). The previous | |
|
Reports a failed cache read at warning level. The caller then falls through to the real method, so a read failure costs latency rather than correctness. | |
|
Reports that a cached method ran before the cache existed — the service was decorated but | |
|
Returns true if the decorator was invoked in standard (TC39) mode, i.e. its second argument is a decorator context object carrying a | |
|
Makes channel entry from a given channel name, class method name and options. | |
|
Class decorator turning an It installs a change-notify trigger on every table the service's cacheWith() and cacheBy() decorators declare a dependency on, and subscribes to one LISTEN/NOTIFY channel per table. When a row changes, the matching cached results are invalidated by tag — so a cache entry lives exactly as long as the data behind it is unchanged, rather than for a guessed TTL.
Applied to the class, it wraps Works both as a standard (TC39) decorator and as a legacy ( Redis is resolved in order: | |
|
Registers pg-cache channel entries for a method on the given prototype exactly once, even when called from a per-construction initializer. | |
|
Reports a failed cache write at warning level. Always logs: a write failure matters even when tracing is off. | |
|
Reports a successful cache write and passes the value straight through, so it can be used inline in a return position. Logs only when PG_CACHE_DEBUG is on. |
Interfaces
|
Interface |
Description |
|---|---|
|
Options expected by | |
|
Options for the cacheWith() method decorator: which tables invalidate the cached result, how long it may live, and the tag it is stored under. | |
|
Payload delivered on a table's notification channel by the installed trigger, describing a single row change. | |
|
Map of table name to the filter that decides which of its changes matter, for method decorators that watch several tables with different rules. | |
|
Minimal logger interface accepted by this package. Structurally compatible with the console object and with | |
|
What the PgCache() decorator adds to the class it is applied to. A decorated service gains these three members, so code inside the service can reach the cache and the subscription directly. | |
|
Registry of cached methods keyed by the PostgreSQL notification channel that invalidates them. The key is a table name: the installed trigger uses the table name as its NOTIFY channel, so the two are the same string. | |
|
Options for the PgCache() class decorator: where PostgreSQL and redis live, and how the change-notify triggers behave. Exactly one of |
Variables
|
Variable |
Description |
|---|---|
|
Default lifetime of a cached entry, in milliseconds — 24 hours. A TTL is a backstop, not the primary invalidation mechanism: entries are normally dropped by a PostgreSQL change notification long before it expires. It exists so an entry cannot outlive its data indefinitely if a notification is ever missed. | |
|
Whether verbose cache tracing is on, read once from the When enabled, cache saves, fetches and trigger installation are logged at info level. Warnings are logged regardless. Because it is read at import time, changing the variable afterwards has no effect. | |
|
Default PL/pgSQL trigger function installed on every watched table. It builds a JSON payload of the changed row and issues Column values are read out of Note PostgreSQL caps a NOTIFY payload at 8000 bytes; a change to a very wide row can exceed that and the notification will be rejected. Override with |
Type Aliases
|
Type Alias |
Description |
|---|---|
|
Narrows which changes to a table invalidate a cached method. The two forms behave in OPPOSITE directions, which is easy to get wrong:
Omitting the filter invalidates on every change to the table. | |
|
Predicate deciding whether one change should invalidate the cached method. Returning | |
|
A dual-mode class decorator: called as Supporting both is what lets this package decorate | |
|
A dual-mode method decorator: called as Use isStandardDecorator() on the second argument to tell the two apart. | |
|
One registered dependency of a cached method: the method to invalidate, and an optional filter narrowing which changes should trigger it. Position 0 is the decorated method name; position 1 is the filter, or |
Read this page as plain markdown — no HTML, no navigation. For pasting into an LLM, or for an agent to fetch.