@gravito/stream 2.0.2 → 2.1.0

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.
Files changed (81) hide show
  1. package/README.md +27 -1
  2. package/dist/BatchConsumer.d.ts +81 -0
  3. package/dist/Consumer.d.ts +215 -0
  4. package/dist/DashboardProvider.d.ts +20 -0
  5. package/dist/Job.d.ts +183 -0
  6. package/dist/OrbitStream.d.ts +151 -0
  7. package/dist/QueueManager.d.ts +319 -0
  8. package/dist/Queueable.d.ts +91 -0
  9. package/dist/Scheduler.d.ts +214 -0
  10. package/dist/StreamEventBackend.d.ts +114 -0
  11. package/dist/SystemEventJob.d.ts +33 -0
  12. package/dist/Worker.d.ts +139 -0
  13. package/dist/benchmarks/PerformanceReporter.d.ts +99 -0
  14. package/dist/consumer/ConcurrencyGate.d.ts +55 -0
  15. package/dist/consumer/ConsumerStrategy.d.ts +41 -0
  16. package/dist/consumer/GroupSequencer.d.ts +57 -0
  17. package/dist/consumer/HeartbeatManager.d.ts +65 -0
  18. package/dist/consumer/JobExecutor.d.ts +61 -0
  19. package/dist/consumer/JobSourceGenerator.d.ts +31 -0
  20. package/dist/consumer/PollingStrategy.d.ts +42 -0
  21. package/dist/consumer/ReactiveStrategy.d.ts +41 -0
  22. package/dist/consumer/StreamingConsumer.d.ts +88 -0
  23. package/dist/consumer/index.d.ts +13 -0
  24. package/dist/consumer/types.d.ts +102 -0
  25. package/dist/drivers/BinaryJobFrame.d.ts +78 -0
  26. package/dist/drivers/BullMQDriver.d.ts +186 -0
  27. package/dist/drivers/DatabaseDriver.d.ts +131 -0
  28. package/dist/drivers/GrpcDriver.d.ts +16 -0
  29. package/dist/drivers/KafkaDriver.d.ts +148 -0
  30. package/dist/drivers/MemoryDriver.d.ts +108 -0
  31. package/dist/drivers/QueueDriver.d.ts +250 -0
  32. package/dist/drivers/RabbitMQDriver.d.ts +102 -0
  33. package/dist/drivers/RedisDriver.d.ts +294 -0
  34. package/dist/drivers/SQSDriver.d.ts +111 -0
  35. package/dist/drivers/kafka/BackpressureController.d.ts +60 -0
  36. package/dist/drivers/kafka/BatchProcessor.d.ts +50 -0
  37. package/dist/drivers/kafka/ConsumerLifecycleManager.d.ts +80 -0
  38. package/dist/drivers/kafka/ErrorCategorizer.d.ts +39 -0
  39. package/dist/drivers/kafka/ErrorRecoveryManager.d.ts +100 -0
  40. package/dist/drivers/kafka/HeartbeatManager.d.ts +57 -0
  41. package/dist/drivers/kafka/KafkaDriver.d.ts +138 -0
  42. package/dist/drivers/kafka/KafkaMetrics.d.ts +88 -0
  43. package/dist/drivers/kafka/KafkaNotifier.d.ts +54 -0
  44. package/dist/drivers/kafka/MessageBuffer.d.ts +71 -0
  45. package/dist/drivers/kafka/OffsetTracker.d.ts +63 -0
  46. package/dist/drivers/kafka/PerformanceMonitor.d.ts +88 -0
  47. package/dist/drivers/kafka/RateLimiter.d.ts +52 -0
  48. package/dist/drivers/kafka/RebalanceHandler.d.ts +104 -0
  49. package/dist/drivers/kafka/RingBuffer.d.ts +63 -0
  50. package/dist/drivers/kafka/index.d.ts +22 -0
  51. package/dist/drivers/kafka/types.d.ts +553 -0
  52. package/dist/drivers/prepareJobForTransport.d.ts +10 -0
  53. package/dist/index.cjs +5644 -5508
  54. package/dist/index.cjs.map +71 -0
  55. package/dist/index.d.ts +60 -4378
  56. package/dist/index.js +5609 -5453
  57. package/dist/index.js.map +71 -0
  58. package/dist/locks/DistributedLock.d.ts +175 -0
  59. package/dist/persistence/BufferedPersistence.d.ts +130 -0
  60. package/dist/persistence/BunBufferedPersistence.d.ts +173 -0
  61. package/dist/persistence/MySQLPersistence.d.ts +134 -0
  62. package/dist/persistence/SQLitePersistence.d.ts +133 -0
  63. package/dist/serializers/BinarySerializer.d.ts +42 -0
  64. package/dist/serializers/CachedSerializer.d.ts +38 -0
  65. package/dist/serializers/CborNativeSerializer.d.ts +56 -0
  66. package/dist/serializers/ClassNameSerializer.d.ts +58 -0
  67. package/dist/serializers/JobSerializer.d.ts +33 -0
  68. package/dist/serializers/JsonSerializer.d.ts +28 -0
  69. package/dist/serializers/JsonlSerializer.d.ts +90 -0
  70. package/dist/serializers/MessagePackSerializer.d.ts +29 -0
  71. package/dist/types.d.ts +653 -0
  72. package/dist/workers/BinaryWorkerProtocol.d.ts +77 -0
  73. package/dist/workers/BunWorker.d.ts +179 -0
  74. package/dist/workers/SandboxedWorker.d.ts +132 -0
  75. package/dist/workers/WorkerFactory.d.ts +128 -0
  76. package/dist/workers/WorkerPool.d.ts +186 -0
  77. package/dist/workers/bun-job-executor.d.ts +14 -0
  78. package/dist/workers/index.d.ts +13 -0
  79. package/dist/workers/job-executor.d.ts +9 -0
  80. package/package.json +6 -4
  81. package/dist/index.d.cts +0 -4387
package/README.md CHANGED
@@ -11,15 +11,33 @@
11
11
 
12
12
  ## ✨ Features
13
13
 
14
- - 🪐 **Orbit Integration** - Native integration with PlanetCore micro-kernel and dependency injection.
14
+ - 🪐 **Galaxy-Ready Orbit** - Native integration with PlanetCore micro-kernel and dependency injection.
15
15
  - 🔌 **Multi-Broker Support** - Built-in drivers for **Redis**, **SQS**, **Kafka**, **RabbitMQ**, **Database** (SQL), and **Memory**.
16
16
  - 🛠️ **Job-Based API** - Clean, class-based job definitions with built-in serialization and failure handling.
17
17
  - 🚀 **High Throughput** - Optimized for **Bun**, supporting batch consumption, concurrent processing, and adaptive polling.
18
+ - 📡 **Cross-Satellite Event Streaming** - Enable loosely coupled communication between isolated Satellites.
18
19
  - 🛡️ **Reliability** - Built-in exponential backoff retries, Dead Letter Queues (DLQ), and sequential job grouping.
19
20
  - 📝 **Audit & Persistence** - Optional SQL-based persistence layer for archiving job history and providing complete audit trails.
20
21
  - 🕒 **Scheduler** - Built-in CRON-based task scheduling for recurring jobs.
21
22
  - 🏢 **Worker Modes** - Run embedded workers during development or standalone worker processes in production.
22
23
 
24
+ ## 🌌 Role in Galaxy Architecture
25
+
26
+ In the **Gravito Galaxy Architecture**, Stream acts as the **Async Engine (Background Processing)**.
27
+
28
+ - **Satellite Decoupling**: Instead of Satellite A calling Satellite B synchronously and waiting for a response, Satellite A fires an event/job into Stream, and Satellite B consumes it asynchronously.
29
+ - **Resilience Backbone**: Works hand-in-hand with `@gravito/resilience` to ensure that failed web requests or heavy tasks are retried in the background without affecting the user experience.
30
+ - **Distributed State**: Facilitates event-driven architecture (EDA), allowing multiple Satellites to react to the same domain event reliably.
31
+
32
+ ```mermaid
33
+ graph TD
34
+ SatA[Satellite: Order] -- "Push Job" --> Stream{Stream Orbit}
35
+ Stream -- "Queue: emails" --> Worker1[Worker Pool]
36
+ Worker1 --> SatB[Satellite: Notification]
37
+ Stream -- "Queue: payments" --> Worker2[Worker Pool]
38
+ Worker2 --> SatC[Satellite: Finance]
39
+ ```
40
+
23
41
  ## 📦 Installation
24
42
 
25
43
  ```bash
@@ -148,6 +166,14 @@ Accessed via `c.get('queue')` or `core.container.make('queue')`.
148
166
  - **`backoff(seconds, multiplier?)`**: Configure retry strategy.
149
167
  - **`withPriority(priority)`**: Set job priority.
150
168
 
169
+ ## 📚 Documentation
170
+
171
+ Detailed guides and references for the Galaxy Architecture:
172
+
173
+ - [🏗️ **Architecture Overview**](./README.md) — Multi-broker queue and job system.
174
+ - [📡 **Event-Driven Architecture**](./doc/EVENT_DRIVEN_ARCHITECTURE.md) — **NEW**: Cross-Satellite communication and pub/sub.
175
+ - [⚙️ **Worker Configuration**](#-worker-modes) — Embedded vs standalone background workers.
176
+
151
177
  ## 🔌 Supported Drivers
152
178
 
153
179
  - **Redis** - Feature-rich (DLQ, Rate limiting, Priorities).
@@ -0,0 +1,81 @@
1
+ import type { Job } from './Job';
2
+ import type { QueueManager } from './QueueManager';
3
+ /**
4
+ * Configuration options for the BatchConsumer.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * const options: BatchConsumerOptions = {
9
+ * batchSize: 50,
10
+ * autoAck: false
11
+ * };
12
+ * ```
13
+ */
14
+ export interface BatchConsumerOptions {
15
+ /**
16
+ * The name of the queue to consume from.
17
+ * @default 'default'
18
+ */
19
+ queue?: string;
20
+ /**
21
+ * The connection name to use.
22
+ * @default The default connection of QueueManager
23
+ */
24
+ connection?: string;
25
+ /**
26
+ * The number of jobs to try to retrieve in each batch.
27
+ * @default 10
28
+ */
29
+ batchSize?: number;
30
+ /**
31
+ * The polling interval in milliseconds when the queue is empty.
32
+ * @default 1000
33
+ */
34
+ pollInterval?: number;
35
+ /**
36
+ * Whether to automatically complete jobs after the handler returns successfully.
37
+ *
38
+ * If set to `false`, the handler function is responsible for calling `manager.complete()`
39
+ * or `manager.fail()` for each job.
40
+ *
41
+ * @default true
42
+ */
43
+ autoAck?: boolean;
44
+ }
45
+ /**
46
+ * Specialized consumer for processing jobs in bulk.
47
+ *
48
+ * Unlike the standard `Consumer` which processes jobs individually (even if fetched in batches),
49
+ * the `BatchConsumer` passes an array of jobs to a single handler function. This is ideal for
50
+ * operations that benefit from bulk processing, such as database inserts or API calls that support batching.
51
+ *
52
+ * @public
53
+ * @example
54
+ * ```typescript
55
+ * const consumer = new BatchConsumer(manager, async (jobs) => {
56
+ * // Process 100 jobs at once
57
+ * await elasticsearch.bulkIndex(jobs.map(j => j.data));
58
+ * }, { batchSize: 100 });
59
+ *
60
+ * consumer.start();
61
+ * ```
62
+ */
63
+ export declare class BatchConsumer {
64
+ private manager;
65
+ private handler;
66
+ private running;
67
+ private options;
68
+ constructor(manager: QueueManager, handler: (jobs: Job[]) => Promise<void>, options?: BatchConsumerOptions);
69
+ /**
70
+ * Starts the batch consuming loop.
71
+ *
72
+ * Continuously polls for batches of jobs and passes them to the handler.
73
+ */
74
+ start(): Promise<void>;
75
+ /**
76
+ * Stops the consumer loop.
77
+ *
78
+ * Sets the running flag to false. The loop will exit after the current iteration finishes.
79
+ */
80
+ stop(): void;
81
+ }
@@ -0,0 +1,215 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { ConsumerStats } from './consumer/types';
3
+ import type { QueueManager } from './QueueManager';
4
+ import type { WorkerOptions } from './Worker';
5
+ /**
6
+ * Configuration options for the Consumer.
7
+ *
8
+ * Defines which queues to listen to, connection settings, concurrency levels,
9
+ * and advanced behavior like rate limiting and batch processing.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const options: ConsumerOptions = {
14
+ * queues: ['emails', 'notifications'],
15
+ * concurrency: 5,
16
+ * pollInterval: 2000
17
+ * };
18
+ * ```
19
+ */
20
+ export interface ConsumerOptions {
21
+ /**
22
+ * List of queue names to consume jobs from.
23
+ *
24
+ * The consumer will poll these queues in the order provided or based on driver logic.
25
+ */
26
+ queues: string[];
27
+ /**
28
+ * The connection name to use (e.g., 'redis', 'sqs').
29
+ *
30
+ * If not provided, uses the default connection from QueueManager.
31
+ */
32
+ connection?: string;
33
+ /**
34
+ * Configuration options passed to the underlying Worker.
35
+ */
36
+ workerOptions?: WorkerOptions;
37
+ /**
38
+ * The interval in milliseconds to wait before polling again when the queue is empty.
39
+ */
40
+ pollInterval?: number;
41
+ /**
42
+ * Whether to keep the process alive when queues are empty.
43
+ *
44
+ * If false, the consumer will exit the loop when no jobs are found (useful for one-off scripts).
45
+ */
46
+ keepAlive?: boolean;
47
+ /**
48
+ * Monitoring configuration.
49
+ *
50
+ * Can be a boolean to enable default monitoring, or an object for advanced configuration.
51
+ */
52
+ monitor?: boolean | {
53
+ /**
54
+ * The interval in milliseconds for sending heartbeat updates.
55
+ * @default 5000
56
+ */
57
+ interval?: number;
58
+ /**
59
+ * Additional metadata to include in heartbeat payloads.
60
+ */
61
+ extraInfo?: Record<string, unknown>;
62
+ /**
63
+ * Key prefix for monitoring events (e.g. for Redis Pub/Sub).
64
+ */
65
+ prefix?: string;
66
+ };
67
+ /**
68
+ * Rate limiting configuration per queue.
69
+ *
70
+ * Defines the maximum number of jobs to process within a given duration.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * { 'emails': { max: 10, duration: 1000 } } // 10 emails per second
75
+ * ```
76
+ */
77
+ rateLimits?: Record<string, {
78
+ max: number;
79
+ duration: number;
80
+ }>;
81
+ /**
82
+ * The maximum number of jobs to process concurrently.
83
+ *
84
+ * @default 1
85
+ */
86
+ concurrency?: number;
87
+ /**
88
+ * Whether to enforce sequential processing for jobs with the same `groupId`.
89
+ *
90
+ * If true, jobs sharing a `groupId` will be processed one after another,
91
+ * even if global concurrency is high.
92
+ *
93
+ * @default true
94
+ */
95
+ groupJobsSequential?: boolean;
96
+ /**
97
+ * The minimum polling interval in milliseconds for adaptive polling.
98
+ *
99
+ * @default 100
100
+ */
101
+ minPollInterval?: number;
102
+ /**
103
+ * The maximum polling interval in milliseconds for adaptive polling.
104
+ *
105
+ * @default 5000
106
+ */
107
+ maxPollInterval?: number;
108
+ /**
109
+ * The multiplier used to increase the polling interval when the queue is empty.
110
+ *
111
+ * @default 1.5
112
+ */
113
+ backoffMultiplier?: number;
114
+ /**
115
+ * The number of jobs to try to fetch in a single request.
116
+ *
117
+ * If supported by the driver, fetching multiple jobs reduces network round-trips.
118
+ *
119
+ * @default 1
120
+ */
121
+ batchSize?: number;
122
+ /**
123
+ * Whether to use blocking operations (like BLPOP in Redis) when polling.
124
+ *
125
+ * Significant optimization for low-latency job pickup. Only applies when `batchSize` is 1.
126
+ *
127
+ * @default true
128
+ */
129
+ useBlocking?: boolean;
130
+ /**
131
+ * The timeout in seconds for blocking operations.
132
+ *
133
+ * @default 5
134
+ */
135
+ blockingTimeout?: number;
136
+ /**
137
+ * Enable verbose debug logging for consumer activities.
138
+ *
139
+ * @default false
140
+ */
141
+ debug?: boolean;
142
+ /**
143
+ * 最大處理請求數量。
144
+ *
145
+ * 當 consumer 處理完這個數量的 job 後會自動停止(觸發 max_requests_reached 事件)。
146
+ * 適用於需要定期重啟 worker 的場景(避免記憶體累積、載入最新程式碼等)。
147
+ *
148
+ * @default undefined (無限制)
149
+ */
150
+ maxRequests?: number;
151
+ /**
152
+ * Optional event callback for external monitoring systems.
153
+ *
154
+ * Called whenever a job lifecycle event occurs (started, processed, failed, etc.).
155
+ */
156
+ onEvent?: (event: string, payload: unknown) => void;
157
+ /**
158
+ * Enable reactive (push-based) consumption mode.
159
+ *
160
+ * When enabled, the consumer listens for notifications and pulls jobs reactively
161
+ * instead of polling continuously. This reduces latency and resource usage.
162
+ *
163
+ * @default false
164
+ */
165
+ reactive?: boolean;
166
+ /**
167
+ * Fallback polling interval (ms) when no notifications are received.
168
+ *
169
+ * In reactive mode, if no notifications arrive for this duration,
170
+ * the consumer will fallback to polling to ensure jobs aren't missed.
171
+ * Prevents starvation if the notification system fails.
172
+ *
173
+ * @default 30000 (30 seconds)
174
+ */
175
+ reactivePollingFallback?: number;
176
+ }
177
+ /**
178
+ * Consumer 門面類別(Facade),提供向後相容的公開 API。
179
+ *
180
+ * 內部委派給 StreamingConsumer 實作,所有事件都通過 passthrough。
181
+ * 公開 API 與原始 Consumer 完全一致,不破壞現有使用者程式碼。
182
+ *
183
+ * @public
184
+ */
185
+ export declare class Consumer extends EventEmitter {
186
+ readonly queueManager: QueueManager;
187
+ readonly options: ConsumerOptions;
188
+ /** 內部 StreamingConsumer 實例 */
189
+ private streaming;
190
+ constructor(queueManager: QueueManager, options: ConsumerOptions);
191
+ /**
192
+ * 將 StreamingConsumer 的所有事件轉發給 Consumer。
193
+ */
194
+ private forwardEvents;
195
+ /**
196
+ * Starts the consumer loop.
197
+ */
198
+ start(): Promise<void>;
199
+ /**
200
+ * Gracefully stops the consumer.
201
+ */
202
+ stop(): Promise<void>;
203
+ /**
204
+ * Checks if the consumer is currently active.
205
+ */
206
+ isRunning(): boolean;
207
+ /**
208
+ * Retrieves current operational statistics.
209
+ */
210
+ getStats(): ConsumerStats;
211
+ /**
212
+ * Resets the internal statistics counters.
213
+ */
214
+ resetStats(): void;
215
+ }
@@ -0,0 +1,20 @@
1
+ import type { QueueManager } from './QueueManager';
2
+ /**
3
+ * Provides API routes for the Stream Monitoring Dashboard.
4
+ *
5
+ * This class encapsulates the logic for querying queue statistics,
6
+ * browsing archived jobs, and performing management actions like retrying jobs.
7
+ *
8
+ * @internal
9
+ */
10
+ export declare class DashboardProvider {
11
+ private manager;
12
+ constructor(manager: QueueManager);
13
+ /**
14
+ * Registers dashboard API routes on the provided core adapter.
15
+ *
16
+ * @param core - The PlanetCore instance.
17
+ * @param basePath - The base path for API routes (default: '/_flux').
18
+ */
19
+ registerRoutes(core: any, basePath?: string): void;
20
+ }
package/dist/Job.d.ts ADDED
@@ -0,0 +1,183 @@
1
+ import type { Queueable } from './Queueable';
2
+ /**
3
+ * Abstract base class for all background jobs.
4
+ *
5
+ * This class serves as the foundation for creating queueable tasks. It implements the `Queueable`
6
+ * interface for fluent configuration and provides the core structure for defining execution logic (`handle`)
7
+ * and failure handling (`failed`).
8
+ *
9
+ * Subclasses must implement the `handle` method.
10
+ *
11
+ * @public
12
+ * @example
13
+ * ```typescript
14
+ * export class SendEmailJob extends Job {
15
+ * constructor(private email: string, private subject: string) {
16
+ * super();
17
+ * }
18
+ *
19
+ * async handle(): Promise<void> {
20
+ * await emailService.send(this.email, this.subject);
21
+ * }
22
+ * }
23
+ *
24
+ * // Usage
25
+ * await queue.push(new SendEmailJob('user@example.com', 'Welcome'))
26
+ * .onQueue('emails')
27
+ * .delay(60);
28
+ * ```
29
+ */
30
+ export declare abstract class Job implements Queueable {
31
+ /**
32
+ * Unique identifier for the job instance.
33
+ *
34
+ * Assigned automatically when the job is pushed to the queue.
35
+ */
36
+ id?: string;
37
+ /**
38
+ * The name of the queue where this job will be processed.
39
+ */
40
+ queueName?: string;
41
+ /**
42
+ * The name of the connection used to transport this job.
43
+ */
44
+ connectionName?: string;
45
+ /**
46
+ * Delay in seconds before the job becomes available for processing.
47
+ */
48
+ delaySeconds?: number;
49
+ /**
50
+ * The current attempt number (starts at 1).
51
+ */
52
+ attempts?: number;
53
+ /**
54
+ * The maximum number of retry attempts allowed.
55
+ *
56
+ * Can be overridden by the worker configuration or per-job using `maxAttempts`.
57
+ */
58
+ maxAttempts?: number;
59
+ /**
60
+ * Group ID for sequential processing.
61
+ *
62
+ * Jobs with the same `groupId` will be processed in strict order (FIFO)
63
+ * if the consumer supports it.
64
+ */
65
+ groupId?: string;
66
+ /**
67
+ * Priority level of the job.
68
+ */
69
+ priority?: string | number;
70
+ /**
71
+ * Initial delay in seconds before the first retry attempt.
72
+ *
73
+ * Used for exponential backoff calculation.
74
+ */
75
+ retryAfterSeconds?: number;
76
+ /**
77
+ * Multiplier applied to the retry delay for each subsequent attempt.
78
+ *
79
+ * Used for exponential backoff calculation.
80
+ */
81
+ retryMultiplier?: number;
82
+ /**
83
+ * Sets the target queue for the job.
84
+ *
85
+ * @param queue - The name of the target queue.
86
+ * @returns The job instance for chaining.
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * job.onQueue('billing');
91
+ * ```
92
+ */
93
+ onQueue(queue: string): this;
94
+ /**
95
+ * Sets the target connection for the job.
96
+ *
97
+ * @param connection - The name of the connection (e.g., 'redis').
98
+ * @returns The job instance for chaining.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * job.onConnection('sqs-primary');
103
+ * ```
104
+ */
105
+ onConnection(connection: string): this;
106
+ /**
107
+ * Sets the priority of the job.
108
+ *
109
+ * @param priority - The priority level (e.g., 'high', 10).
110
+ * @returns The job instance for chaining.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * job.withPriority('high');
115
+ * ```
116
+ */
117
+ withPriority(priority: string | number): this;
118
+ /**
119
+ * Delays the job execution.
120
+ *
121
+ * @param delay - Delay in seconds.
122
+ * @returns The job instance for chaining.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * job.delay(60); // Run after 1 minute
127
+ * ```
128
+ */
129
+ delay(delay: number): this;
130
+ /**
131
+ * Configures the exponential backoff strategy for retries.
132
+ *
133
+ * @param seconds - Initial delay in seconds before the first retry.
134
+ * @param multiplier - Factor by which the delay increases for each subsequent attempt (default: 2).
135
+ * @returns The job instance for chaining.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * // Wait 5s, then 10s, then 20s...
140
+ * job.backoff(5, 2);
141
+ * ```
142
+ */
143
+ backoff(seconds: number, multiplier?: number): this;
144
+ /**
145
+ * Calculates the delay for the next retry attempt based on the backoff strategy.
146
+ *
147
+ * Uses the formula: `initialDelay * multiplier^(attempt - 1)`, capped at 1 hour.
148
+ *
149
+ * @param attempt - The current attempt number (1-based).
150
+ * @returns The calculated delay in milliseconds.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const nextDelay = job.getRetryDelay(2);
155
+ * ```
156
+ */
157
+ getRetryDelay(attempt: number): number;
158
+ /**
159
+ * Contains the main business logic of the job.
160
+ *
161
+ * This method is called by the worker to process the job.
162
+ * Implementations should be idempotent if possible.
163
+ *
164
+ * @throws {Error} If the job fails and should be retried.
165
+ */
166
+ abstract handle(): Promise<void>;
167
+ /**
168
+ * Optional handler for when the job has permanently failed.
169
+ *
170
+ * Called when the job has exhausted all retry attempts.
171
+ * Useful for cleaning up resources, sending alerts, or logging.
172
+ *
173
+ * @param _error - The error that caused the final failure.
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * async failed(error: Error) {
178
+ * await notifyAdmin(`Job failed: ${error.message}`);
179
+ * }
180
+ * ```
181
+ */
182
+ failed(_error: Error): Promise<void>;
183
+ }
@@ -0,0 +1,151 @@
1
+ import type { GravitoOrbit, PlanetCore } from '@gravito/core';
2
+ import type { ConsumerOptions } from './Consumer';
3
+ import { QueueManager } from './QueueManager';
4
+ import type { QueueConfig } from './types';
5
+ /**
6
+ * Configuration options for the OrbitStream extension.
7
+ *
8
+ * Extends the standard `QueueConfig` with specific options for integration into
9
+ * the Gravito lifecycle, such as auto-starting workers in development environments.
10
+ *
11
+ * @public
12
+ * @example
13
+ * ```typescript
14
+ * const options: OrbitStreamOptions = {
15
+ * default: 'redis',
16
+ * autoStartWorker: true
17
+ * };
18
+ * ```
19
+ */
20
+ export interface OrbitStreamOptions extends QueueConfig {
21
+ /**
22
+ * Automatically start an embedded worker process.
23
+ *
24
+ * If set to `true`, a background worker will be spawned within the main process.
25
+ * This is recommended for development or simple deployments but should be
26
+ * avoided in high-scale production to keep web servers stateless.
27
+ */
28
+ autoStartWorker?: boolean;
29
+ /**
30
+ * Configuration options for the embedded worker.
31
+ *
32
+ * Only used if `autoStartWorker` is true. Defines concurrency, polling intervals, etc.
33
+ */
34
+ workerOptions?: ConsumerOptions;
35
+ /**
36
+ * Configuration for the Stream Monitoring Dashboard API.
37
+ *
38
+ * If enabled, registers API routes for monitoring queue health and job history.
39
+ *
40
+ * @default false
41
+ */
42
+ dashboard?: boolean | {
43
+ /**
44
+ * Base path for the dashboard API routes.
45
+ * @default '/_flux'
46
+ */
47
+ path?: string;
48
+ };
49
+ }
50
+ /**
51
+ * The Queue Orbit (Plugin) for Gravito Framework.
52
+ *
53
+ * This class acts as the integration layer between the `@gravito/stream` package
54
+ * and the Gravito core system (`PlanetCore`). It registers the `QueueManager`
55
+ * service, injects it into the request context, and manages the lifecycle of
56
+ * embedded workers.
57
+ *
58
+ * @public
59
+ * @example
60
+ * ```typescript
61
+ * const stream = OrbitStream.configure({
62
+ * default: 'redis',
63
+ * connections: {
64
+ * redis: { driver: 'redis', client: redis }
65
+ * }
66
+ * });
67
+ *
68
+ * await PlanetCore.boot({ orbits: [stream] });
69
+ * ```
70
+ */
71
+ export declare class OrbitStream implements GravitoOrbit {
72
+ private options;
73
+ private queueManager?;
74
+ private consumer?;
75
+ private core?;
76
+ constructor(options?: OrbitStreamOptions);
77
+ /**
78
+ * Factory method for creating and configuring an OrbitStream instance.
79
+ *
80
+ * Provides a fluent way to instantiate the orbit during application bootstrap.
81
+ *
82
+ * @param options - Configuration options.
83
+ * @returns A new OrbitStream instance.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const orbit = OrbitStream.configure({ default: 'memory' });
88
+ * ```
89
+ */
90
+ static configure(options: OrbitStreamOptions): OrbitStream;
91
+ /**
92
+ * Installs the Queue system into the Gravito PlanetCore.
93
+ *
94
+ * This lifecycle method:
95
+ * 1. Initializes the `QueueManager`.
96
+ * 2. Registers the `queue` service in the dependency injection container.
97
+ * 3. Sets up a global middleware to inject `QueueManager` into the request context (`c.get('queue')`).
98
+ * 4. Automatically detects and registers database connections if available in the context.
99
+ * 5. Starts the embedded worker if configured.
100
+ *
101
+ * @param core - The PlanetCore instance.
102
+ */
103
+ install(core: PlanetCore): void;
104
+ /**
105
+ * Starts the embedded worker process.
106
+ *
107
+ * Launches a `Consumer` instance to process jobs in the background.
108
+ * Throws an error if `QueueManager` is not initialized or if a worker is already running.
109
+ *
110
+ * @param options - Consumer configuration options.
111
+ * @throws {Error} If QueueManager is missing or worker is already active.
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * orbit.startWorker({ queues: ['default'] });
116
+ * ```
117
+ */
118
+ startWorker(options: ConsumerOptions): void;
119
+ /**
120
+ * Stops the embedded worker process.
121
+ *
122
+ * Gracefully shuts down the consumer, waiting for active jobs to complete.
123
+ *
124
+ * @returns A promise that resolves when the worker has stopped.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * await orbit.stopWorker();
129
+ * ```
130
+ */
131
+ stopWorker(): Promise<void>;
132
+ /**
133
+ * Retrieves the underlying QueueManager instance.
134
+ *
135
+ * @returns The active QueueManager, or undefined if not installed.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const manager = orbit.getQueueManager();
140
+ * ```
141
+ */
142
+ getQueueManager(): QueueManager | undefined;
143
+ }
144
+ declare module '@gravito/core' {
145
+ interface GravitoVariables {
146
+ /** Queue manager for job processing */
147
+ queue?: QueueManager;
148
+ /** Database service (from orbit-db) */
149
+ db?: unknown;
150
+ }
151
+ }