@agendajs/redis-backend 2.0.0 → 3.0.1

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/README.md CHANGED
@@ -125,6 +125,43 @@ This means:
125
125
 
126
126
  The backend uses Redis WATCH/MULTI/EXEC transactions to atomically lock jobs for processing, preventing duplicate execution across multiple Agenda instances.
127
127
 
128
+ ## Job Logging
129
+
130
+ RedisBackend includes a built-in `RedisJobLogger` that stores structured job lifecycle events using Redis sorted sets and hashes. The logger is lightweight and only creates its keys on first use.
131
+
132
+ ### Automatic Usage
133
+
134
+ When you enable logging in Agenda, the backend's built-in logger is used automatically:
135
+
136
+ ```typescript
137
+ const agenda = new Agenda({
138
+ backend: new RedisBackend({ connectionString: 'redis://localhost:6379' }),
139
+ logging: true // Uses RedisJobLogger automatically
140
+ });
141
+ ```
142
+
143
+ ### Standalone Usage
144
+
145
+ You can also use `RedisJobLogger` independently — for example, to log to Redis while using a different backend for storage:
146
+
147
+ ```typescript
148
+ import { RedisJobLogger } from '@agendajs/redis-backend';
149
+ import Redis from 'ioredis';
150
+
151
+ const logger = new RedisJobLogger({
152
+ redis: new Redis('redis://localhost:6379')
153
+ });
154
+
155
+ // Use with any backend
156
+ import { MongoBackend } from '@agendajs/mongo-backend';
157
+ const agenda = new Agenda({
158
+ backend: new MongoBackend({ mongo: db }),
159
+ logging: logger
160
+ });
161
+ ```
162
+
163
+ See the [Agenda README](https://github.com/agenda/agenda#persistent-job-logging) for full logging documentation.
164
+
128
165
  ## Persistence
129
166
 
130
167
  By default, Redis keeps data in memory. For production use with Agenda, configure Redis persistence:
@@ -1,4 +1,4 @@
1
- import type { AgendaBackend, JobRepository, NotificationChannel } from 'agenda';
1
+ import type { AgendaBackend, JobRepository, NotificationChannel, JobLogger } from 'agenda';
2
2
  import type { RedisBackendConfig } from './types.js';
3
3
  /**
4
4
  * Redis backend for Agenda
@@ -41,6 +41,7 @@ export declare class RedisBackend implements AgendaBackend {
41
41
  readonly name = "Redis";
42
42
  private _repository;
43
43
  private _notificationChannel;
44
+ private _logger;
44
45
  private config;
45
46
  private _ownsConnection;
46
47
  constructor(config: RedisBackendConfig);
@@ -48,6 +49,11 @@ export declare class RedisBackend implements AgendaBackend {
48
49
  * The job repository for storage operations
49
50
  */
50
51
  get repository(): JobRepository;
52
+ /**
53
+ * The job logger for persistent event logging.
54
+ * Always available; Agenda decides whether to activate it via its `logging` config.
55
+ */
56
+ get logger(): JobLogger;
51
57
  /**
52
58
  * The notification channel for real-time notifications via Pub/Sub
53
59
  */
@@ -1,5 +1,6 @@
1
1
  import debug from 'debug';
2
2
  import { RedisJobRepository } from './RedisJobRepository.js';
3
+ import { RedisJobLogger } from './RedisJobLogger.js';
3
4
  import { RedisNotificationChannel } from './RedisNotificationChannel.js';
4
5
  const log = debug('agenda:redis:backend');
5
6
  /**
@@ -43,6 +44,7 @@ export class RedisBackend {
43
44
  name = 'Redis';
44
45
  _repository;
45
46
  _notificationChannel;
47
+ _logger;
46
48
  config;
47
49
  _ownsConnection;
48
50
  constructor(config) {
@@ -58,6 +60,8 @@ export class RedisBackend {
58
60
  enabled: true
59
61
  }
60
62
  });
63
+ // Always create the logger (lightweight; only initializes on first use when Agenda activates it)
64
+ this._logger = new RedisJobLogger({ keyPrefix: config.keyPrefix });
61
65
  log('RedisBackend created with config: %O', {
62
66
  keyPrefix: config.keyPrefix || 'agenda:',
63
67
  channelName: config.channelName || 'agenda:jobs'
@@ -69,6 +73,13 @@ export class RedisBackend {
69
73
  get repository() {
70
74
  return this._repository;
71
75
  }
76
+ /**
77
+ * The job logger for persistent event logging.
78
+ * Always available; Agenda decides whether to activate it via its `logging` config.
79
+ */
80
+ get logger() {
81
+ return this._logger;
82
+ }
72
83
  /**
73
84
  * The notification channel for real-time notifications via Pub/Sub
74
85
  */
@@ -94,6 +105,8 @@ export class RedisBackend {
94
105
  await this._repository.connect();
95
106
  // Share the Redis client with notification channel
96
107
  this._notificationChannel.setRedis(this._repository.getRedis());
108
+ // Initialize the job logger with the shared Redis client
109
+ this._logger.setRedis(this._repository.getRedis());
97
110
  // Note: notification channel is connected by Agenda.start()
98
111
  // when it's needed, so we don't connect it here
99
112
  log('RedisBackend connected');
@@ -1 +1 @@
1
- {"version":3,"file":"RedisBackend.js","sourceRoot":"","sources":["../src/RedisBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,MAAM,GAAG,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,OAAO,CAAC;IAEhB,WAAW,CAAqB;IAChC,oBAAoB,CAA2B;IAC/C,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAEjC,YAAY,MAA0B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6DAA6D;QAC7D,IAAI,CAAC,eAAe,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAErC,oBAAoB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAElD,8BAA8B;QAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAwB,CAAC;YACxD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE;gBACV,OAAO,EAAE,IAAI;aACb;SACD,CAAC,CAAC;QAEH,GAAG,CAAC,sCAAsC,EAAE;YAC3C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,aAAa;SAChD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,IAAI,mBAAmB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,cAAc;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO;QACZ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE/B,2BAA2B;QAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mDAAmD;QACnD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhE,4DAA4D;QAC5D,gDAAgD;QAEhD,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU;QACf,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAElC,wDAAwD;QACxD,qDAAqD;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAEpC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAClC,CAAC;CACD"}
1
+ {"version":3,"file":"RedisBackend.js","sourceRoot":"","sources":["../src/RedisBackend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,MAAM,GAAG,GAAG,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,OAAO,CAAC;IAEhB,WAAW,CAAqB;IAChC,oBAAoB,CAA2B;IAC/C,OAAO,CAAiB;IACxB,MAAM,CAAqB;IAC3B,eAAe,CAAU;IAEjC,YAAY,MAA0B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,6DAA6D;QAC7D,IAAI,CAAC,eAAe,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAErC,oBAAoB;QACpB,IAAI,CAAC,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAElD,8BAA8B;QAC9B,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAwB,CAAC;YACxD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE;gBACV,OAAO,EAAE,IAAI;aACb;SACD,CAAC,CAAC;QAEH,iGAAiG;QACjG,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAEnE,GAAG,CAAC,sCAAsC,EAAE;YAC3C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;YACxC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,aAAa;SAChD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACb,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,IAAI,MAAM;QACT,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI,mBAAmB;QACtB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI,cAAc;QACjB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO;QACZ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAE/B,2BAA2B;QAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAEjC,mDAAmD;QACnD,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhE,yDAAyD;QACzD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEnD,4DAA4D;QAC5D,gDAAgD;QAEhD,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU;QACf,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAElC,wDAAwD;QACxD,qDAAqD;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAEpC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAClC,CAAC;CACD"}
@@ -0,0 +1,53 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { JobLogger, JobLogEntry, JobLogQuery, JobLogQueryResult } from 'agenda';
3
+ /**
4
+ * Redis implementation of JobLogger.
5
+ * Stores job lifecycle events using Redis sorted sets and hashes.
6
+ *
7
+ * Data structure:
8
+ * - `{prefix}log:{id}` - Hash for each log entry
9
+ * - `{prefix}logs:all` - Sorted set of all log IDs (score = timestamp)
10
+ * - `{prefix}logs:by_job:{jobId}` - Sorted set of log IDs per job
11
+ * - `{prefix}logs:by_name:{jobName}` - Sorted set of log IDs per job name
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Via backend (automatic connection sharing):
16
+ * import { RedisBackend } from '@agendajs/redis-backend';
17
+ *
18
+ * const backend = new RedisBackend({
19
+ * connectionString: 'redis://localhost:6379',
20
+ * logging: true // enables RedisJobLogger
21
+ * });
22
+ *
23
+ * // Standalone (e.g., log to Redis while using Mongo for storage):
24
+ * import { RedisJobLogger } from '@agendajs/redis-backend';
25
+ * import Redis from 'ioredis';
26
+ *
27
+ * const logger = new RedisJobLogger({ redis: new Redis('redis://localhost:6379') });
28
+ * const agenda = new Agenda({
29
+ * backend: new MongoBackend({ address: 'mongodb://...' }),
30
+ * logging: logger
31
+ * });
32
+ * ```
33
+ */
34
+ export declare class RedisJobLogger implements JobLogger {
35
+ private redis;
36
+ private readonly keyPrefix;
37
+ private idCounter;
38
+ constructor(options?: {
39
+ redis?: Redis;
40
+ keyPrefix?: string;
41
+ } | string);
42
+ private key;
43
+ /**
44
+ * Set the Redis client.
45
+ * Called by RedisBackend after the repository connects.
46
+ */
47
+ setRedis(redis: Redis): void;
48
+ private generateId;
49
+ log(entry: Omit<JobLogEntry, '_id'>): Promise<void>;
50
+ getLogs(query?: JobLogQuery): Promise<JobLogQueryResult>;
51
+ clearLogs(query?: JobLogQuery): Promise<number>;
52
+ private hashToEntry;
53
+ }
@@ -0,0 +1,217 @@
1
+ import debug from 'debug';
2
+ const log = debug('agenda:redis:logger');
3
+ /**
4
+ * Redis implementation of JobLogger.
5
+ * Stores job lifecycle events using Redis sorted sets and hashes.
6
+ *
7
+ * Data structure:
8
+ * - `{prefix}log:{id}` - Hash for each log entry
9
+ * - `{prefix}logs:all` - Sorted set of all log IDs (score = timestamp)
10
+ * - `{prefix}logs:by_job:{jobId}` - Sorted set of log IDs per job
11
+ * - `{prefix}logs:by_name:{jobName}` - Sorted set of log IDs per job name
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Via backend (automatic connection sharing):
16
+ * import { RedisBackend } from '@agendajs/redis-backend';
17
+ *
18
+ * const backend = new RedisBackend({
19
+ * connectionString: 'redis://localhost:6379',
20
+ * logging: true // enables RedisJobLogger
21
+ * });
22
+ *
23
+ * // Standalone (e.g., log to Redis while using Mongo for storage):
24
+ * import { RedisJobLogger } from '@agendajs/redis-backend';
25
+ * import Redis from 'ioredis';
26
+ *
27
+ * const logger = new RedisJobLogger({ redis: new Redis('redis://localhost:6379') });
28
+ * const agenda = new Agenda({
29
+ * backend: new MongoBackend({ address: 'mongodb://...' }),
30
+ * logging: logger
31
+ * });
32
+ * ```
33
+ */
34
+ export class RedisJobLogger {
35
+ redis;
36
+ keyPrefix;
37
+ idCounter = 0;
38
+ constructor(options) {
39
+ if (typeof options === 'string') {
40
+ // Legacy: constructor(keyPrefix)
41
+ this.keyPrefix = options;
42
+ }
43
+ else {
44
+ this.keyPrefix = options?.keyPrefix ?? 'agenda:';
45
+ if (options?.redis) {
46
+ this.redis = options.redis;
47
+ }
48
+ }
49
+ }
50
+ key(suffix) {
51
+ return `${this.keyPrefix}${suffix}`;
52
+ }
53
+ /**
54
+ * Set the Redis client.
55
+ * Called by RedisBackend after the repository connects.
56
+ */
57
+ setRedis(redis) {
58
+ this.redis = redis;
59
+ log('Redis client set for job logger');
60
+ }
61
+ generateId() {
62
+ return `${Date.now()}-${process.pid}-${++this.idCounter}`;
63
+ }
64
+ async log(entry) {
65
+ if (!this.redis) {
66
+ log('redis not initialized, skipping log entry');
67
+ return;
68
+ }
69
+ const id = this.generateId();
70
+ const score = entry.timestamp.getTime();
71
+ const hashKey = this.key(`log:${id}`);
72
+ const hashData = {
73
+ id,
74
+ timestamp: entry.timestamp.toISOString(),
75
+ level: entry.level,
76
+ event: entry.event,
77
+ jobName: entry.jobName,
78
+ message: entry.message
79
+ };
80
+ if (entry.jobId)
81
+ hashData.jobId = entry.jobId;
82
+ if (entry.duration !== undefined)
83
+ hashData.duration = String(entry.duration);
84
+ if (entry.error)
85
+ hashData.error = entry.error;
86
+ if (entry.failCount !== undefined)
87
+ hashData.failCount = String(entry.failCount);
88
+ if (entry.retryDelay !== undefined)
89
+ hashData.retryDelay = String(entry.retryDelay);
90
+ if (entry.retryAttempt !== undefined)
91
+ hashData.retryAttempt = String(entry.retryAttempt);
92
+ if (entry.agendaName)
93
+ hashData.agendaName = entry.agendaName;
94
+ if (entry.meta)
95
+ hashData.meta = JSON.stringify(entry.meta);
96
+ const pipeline = this.redis.pipeline();
97
+ pipeline.hset(hashKey, hashData);
98
+ pipeline.zadd(this.key('logs:all'), score, id);
99
+ if (entry.jobId) {
100
+ pipeline.zadd(this.key(`logs:by_job:${entry.jobId}`), score, id);
101
+ }
102
+ pipeline.zadd(this.key(`logs:by_name:${entry.jobName}`), score, id);
103
+ await pipeline.exec();
104
+ }
105
+ async getLogs(query) {
106
+ if (!this.redis) {
107
+ return { entries: [], total: 0 };
108
+ }
109
+ // Determine which sorted set to query
110
+ let setKey;
111
+ if (query?.jobId) {
112
+ setKey = this.key(`logs:by_job:${query.jobId}`);
113
+ }
114
+ else if (query?.jobName) {
115
+ setKey = this.key(`logs:by_name:${query.jobName}`);
116
+ }
117
+ else {
118
+ setKey = this.key('logs:all');
119
+ }
120
+ // Build score range for timestamp filtering
121
+ const minScore = query?.from ? query.from.getTime() : '-inf';
122
+ const maxScore = query?.to ? query.to.getTime() : '+inf';
123
+ // Get all matching IDs (we'll filter in memory for level/event)
124
+ const sortOrder = query?.sort === 'asc' ? 'asc' : 'desc';
125
+ let allIds;
126
+ if (sortOrder === 'desc') {
127
+ allIds = await this.redis.zrevrangebyscore(setKey, maxScore, minScore);
128
+ }
129
+ else {
130
+ allIds = await this.redis.zrangebyscore(setKey, minScore, maxScore);
131
+ }
132
+ if (allIds.length === 0) {
133
+ return { entries: [], total: 0 };
134
+ }
135
+ // Fetch all hash data for these IDs
136
+ const pipeline = this.redis.pipeline();
137
+ for (const id of allIds) {
138
+ pipeline.hgetall(this.key(`log:${id}`));
139
+ }
140
+ const results = await pipeline.exec();
141
+ // Convert and filter
142
+ let entries = [];
143
+ if (results) {
144
+ for (const [err, data] of results) {
145
+ if (err || !data || typeof data !== 'object' || Object.keys(data).length === 0)
146
+ continue;
147
+ const hash = data;
148
+ const entry = this.hashToEntry(hash);
149
+ // Apply level filter
150
+ if (query?.level) {
151
+ const levels = Array.isArray(query.level) ? query.level : [query.level];
152
+ if (!levels.includes(entry.level))
153
+ continue;
154
+ }
155
+ // Apply event filter
156
+ if (query?.event) {
157
+ const events = Array.isArray(query.event) ? query.event : [query.event];
158
+ if (!events.includes(entry.event))
159
+ continue;
160
+ }
161
+ entries.push(entry);
162
+ }
163
+ }
164
+ const total = entries.length;
165
+ const offset = query?.offset ?? 0;
166
+ const limit = query?.limit ?? 50;
167
+ entries = entries.slice(offset, offset + limit);
168
+ return { entries, total };
169
+ }
170
+ async clearLogs(query) {
171
+ if (!this.redis) {
172
+ return 0;
173
+ }
174
+ // Get IDs to delete
175
+ const { entries, total } = await this.getLogs({
176
+ ...query,
177
+ limit: Number.MAX_SAFE_INTEGER,
178
+ offset: 0
179
+ });
180
+ if (entries.length === 0)
181
+ return 0;
182
+ const pipeline = this.redis.pipeline();
183
+ for (const entry of entries) {
184
+ if (!entry._id)
185
+ continue;
186
+ // Remove hash
187
+ pipeline.del(this.key(`log:${entry._id}`));
188
+ // Remove from all sorted sets
189
+ pipeline.zrem(this.key('logs:all'), entry._id);
190
+ if (entry.jobId) {
191
+ pipeline.zrem(this.key(`logs:by_job:${entry.jobId}`), entry._id);
192
+ }
193
+ pipeline.zrem(this.key(`logs:by_name:${entry.jobName}`), entry._id);
194
+ }
195
+ await pipeline.exec();
196
+ return total;
197
+ }
198
+ hashToEntry(hash) {
199
+ return {
200
+ _id: hash.id,
201
+ timestamp: new Date(hash.timestamp),
202
+ level: hash.level,
203
+ event: hash.event,
204
+ jobId: hash.jobId || undefined,
205
+ jobName: hash.jobName,
206
+ message: hash.message,
207
+ duration: hash.duration ? parseInt(hash.duration, 10) : undefined,
208
+ error: hash.error || undefined,
209
+ failCount: hash.failCount ? parseInt(hash.failCount, 10) : undefined,
210
+ retryDelay: hash.retryDelay ? parseInt(hash.retryDelay, 10) : undefined,
211
+ retryAttempt: hash.retryAttempt ? parseInt(hash.retryAttempt, 10) : undefined,
212
+ agendaName: hash.agendaName || undefined,
213
+ meta: hash.meta ? JSON.parse(hash.meta) : undefined
214
+ };
215
+ }
216
+ }
217
+ //# sourceMappingURL=RedisJobLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedisJobLogger.js","sourceRoot":"","sources":["../src/RedisJobLogger.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@
26
26
  */
27
27
  export { RedisBackend } from './RedisBackend.js';
28
28
  export { RedisJobRepository } from './RedisJobRepository.js';
29
+ export { RedisJobLogger } from './RedisJobLogger.js';
29
30
  export { RedisNotificationChannel } from './RedisNotificationChannel.js';
30
31
  export type { RedisBackendConfig, RedisJobData } from './types.js';
31
32
  export type { RedisNotificationChannelConfig } from './RedisNotificationChannel.js';
package/dist/index.js CHANGED
@@ -26,5 +26,6 @@
26
26
  */
27
27
  export { RedisBackend } from './RedisBackend.js';
28
28
  export { RedisJobRepository } from './RedisJobRepository.js';
29
+ export { RedisJobLogger } from './RedisJobLogger.js';
29
30
  export { RedisNotificationChannel } from './RedisNotificationChannel.js';
30
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agendajs/redis-backend",
3
- "version": "2.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Redis backend for Agenda job scheduler with Pub/Sub notification support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,7 +41,7 @@
41
41
  "ioredis": "^5.4.0"
42
42
  },
43
43
  "peerDependencies": {
44
- "agenda": "6.1.0"
44
+ "agenda": "6.2.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/debug": "^4.1.12",
@@ -49,7 +49,7 @@
49
49
  "@vitest/coverage-v8": "^3.1.0",
50
50
  "tsx": "^4.21.0",
51
51
  "vitest": "^3.1.0",
52
- "agenda": "6.1.0"
52
+ "agenda": "6.2.1"
53
53
  },
54
54
  "scripts": {
55
55
  "build": "tsc -b",