@agentxjs/core 1.9.1-dev
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/package.json +31 -0
- package/src/agent/AgentStateMachine.ts +151 -0
- package/src/agent/README.md +296 -0
- package/src/agent/__tests__/AgentStateMachine.test.ts +346 -0
- package/src/agent/__tests__/createAgent.test.ts +728 -0
- package/src/agent/__tests__/engine/internal/messageAssemblerProcessor.test.ts +567 -0
- package/src/agent/__tests__/engine/internal/stateEventProcessor.test.ts +315 -0
- package/src/agent/__tests__/engine/internal/turnTrackerProcessor.test.ts +340 -0
- package/src/agent/__tests__/engine/mealy/Mealy.test.ts +370 -0
- package/src/agent/__tests__/engine/mealy/Store.test.ts +123 -0
- package/src/agent/__tests__/engine/mealy/combinators.test.ts +322 -0
- package/src/agent/createAgent.ts +467 -0
- package/src/agent/engine/AgentProcessor.ts +106 -0
- package/src/agent/engine/MealyMachine.ts +184 -0
- package/src/agent/engine/internal/index.ts +35 -0
- package/src/agent/engine/internal/messageAssemblerProcessor.ts +550 -0
- package/src/agent/engine/internal/stateEventProcessor.ts +313 -0
- package/src/agent/engine/internal/turnTrackerProcessor.ts +239 -0
- package/src/agent/engine/mealy/Mealy.ts +308 -0
- package/src/agent/engine/mealy/Processor.ts +70 -0
- package/src/agent/engine/mealy/Sink.ts +56 -0
- package/src/agent/engine/mealy/Source.ts +51 -0
- package/src/agent/engine/mealy/Store.ts +98 -0
- package/src/agent/engine/mealy/combinators.ts +176 -0
- package/src/agent/engine/mealy/index.ts +45 -0
- package/src/agent/index.ts +106 -0
- package/src/agent/types/engine.ts +395 -0
- package/src/agent/types/event.ts +478 -0
- package/src/agent/types/index.ts +197 -0
- package/src/agent/types/message.ts +387 -0
- package/src/common/index.ts +8 -0
- package/src/common/logger/ConsoleLogger.ts +137 -0
- package/src/common/logger/LoggerFactoryImpl.ts +123 -0
- package/src/common/logger/index.ts +26 -0
- package/src/common/logger/types.ts +98 -0
- package/src/container/Container.ts +185 -0
- package/src/container/index.ts +44 -0
- package/src/container/types.ts +71 -0
- package/src/driver/index.ts +42 -0
- package/src/driver/types.ts +363 -0
- package/src/event/EventBus.ts +260 -0
- package/src/event/README.md +237 -0
- package/src/event/__tests__/EventBus.test.ts +251 -0
- package/src/event/index.ts +46 -0
- package/src/event/types/agent.ts +512 -0
- package/src/event/types/base.ts +241 -0
- package/src/event/types/bus.ts +429 -0
- package/src/event/types/command.ts +749 -0
- package/src/event/types/container.ts +471 -0
- package/src/event/types/driver.ts +452 -0
- package/src/event/types/index.ts +26 -0
- package/src/event/types/session.ts +314 -0
- package/src/image/Image.ts +203 -0
- package/src/image/index.ts +36 -0
- package/src/image/types.ts +77 -0
- package/src/index.ts +20 -0
- package/src/mq/OffsetGenerator.ts +48 -0
- package/src/mq/README.md +166 -0
- package/src/mq/__tests__/OffsetGenerator.test.ts +121 -0
- package/src/mq/index.ts +18 -0
- package/src/mq/types.ts +172 -0
- package/src/network/RpcClient.ts +455 -0
- package/src/network/index.ts +76 -0
- package/src/network/jsonrpc.ts +336 -0
- package/src/network/protocol.ts +90 -0
- package/src/network/types.ts +284 -0
- package/src/persistence/index.ts +27 -0
- package/src/persistence/types.ts +226 -0
- package/src/runtime/AgentXRuntime.ts +501 -0
- package/src/runtime/index.ts +56 -0
- package/src/runtime/types.ts +236 -0
- package/src/session/Session.ts +71 -0
- package/src/session/index.ts +25 -0
- package/src/session/types.ts +77 -0
- package/src/workspace/index.ts +27 -0
- package/src/workspace/types.ts +131 -0
- package/tsconfig.json +10 -0
package/src/mq/README.md
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# @agentxjs/core/mq
|
|
2
|
+
|
|
3
|
+
MessageQueue - Reliable message delivery with persistence guarantee.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The mq module provides standard interfaces for message queue implementations. It defines platform-agnostic contracts that can be implemented by different providers:
|
|
8
|
+
|
|
9
|
+
- **Node.js**: SQLite persistence
|
|
10
|
+
- **Cloudflare Workers**: Durable Objects Storage
|
|
11
|
+
- **Browser**: IndexedDB
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
15
|
+
│ MessageQueue │
|
|
16
|
+
│ │
|
|
17
|
+
│ publish() ─────► Storage ─────► recover() │
|
|
18
|
+
│ │ │ │
|
|
19
|
+
│ ▼ │ │
|
|
20
|
+
│ RxJS Subject ──────┼────► subscribe() │
|
|
21
|
+
│ │ │
|
|
22
|
+
│ ack() ◄────────────┴────► getOffset() │
|
|
23
|
+
│ │
|
|
24
|
+
└─────────────────────────────────────────────────────────────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Key Concepts
|
|
28
|
+
|
|
29
|
+
### At-Least-Once Delivery
|
|
30
|
+
|
|
31
|
+
Messages are guaranteed to be delivered at least once through:
|
|
32
|
+
|
|
33
|
+
1. **Persistence**: Messages are stored before broadcast
|
|
34
|
+
2. **Offset Tracking**: Consumer position is persisted via `ack()`
|
|
35
|
+
3. **Recovery**: Missed messages can be fetched via `recover()`
|
|
36
|
+
|
|
37
|
+
### Real-time + Recovery
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// 1. Subscribe for real-time messages
|
|
41
|
+
queue.subscribe("session-123", (entry) => {
|
|
42
|
+
console.log("Received:", entry.event);
|
|
43
|
+
// After processing, acknowledge
|
|
44
|
+
await queue.ack("client-1", "session-123", entry.offset);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// 2. On reconnect, recover missed messages
|
|
48
|
+
const lastOffset = await queue.getOffset("client-1", "session-123");
|
|
49
|
+
const missed = await queue.recover("session-123", lastOffset);
|
|
50
|
+
for (const entry of missed) {
|
|
51
|
+
console.log("Missed:", entry.event);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Interfaces
|
|
56
|
+
|
|
57
|
+
### MessageQueue
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
interface MessageQueue {
|
|
61
|
+
// Publish message (async for cross-platform support)
|
|
62
|
+
publish(topic: string, event: unknown): Promise<string>;
|
|
63
|
+
|
|
64
|
+
// Subscribe to real-time messages (in-memory pub/sub)
|
|
65
|
+
subscribe(topic: string, handler: (entry: QueueEntry) => void): Unsubscribe;
|
|
66
|
+
|
|
67
|
+
// Acknowledge consumption (persist consumer offset)
|
|
68
|
+
ack(consumerId: string, topic: string, offset: string): Promise<void>;
|
|
69
|
+
|
|
70
|
+
// Get consumer's current offset
|
|
71
|
+
getOffset(consumerId: string, topic: string): Promise<string | null>;
|
|
72
|
+
|
|
73
|
+
// Recover historical messages
|
|
74
|
+
recover(topic: string, afterOffset?: string, limit?: number): Promise<QueueEntry[]>;
|
|
75
|
+
|
|
76
|
+
// Close and release resources
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### QueueEntry
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface QueueEntry {
|
|
85
|
+
readonly offset: string; // Unique, monotonically increasing
|
|
86
|
+
readonly topic: string; // Topic identifier
|
|
87
|
+
readonly event: unknown; // Message payload
|
|
88
|
+
readonly timestamp: number; // Unix milliseconds
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### MessageQueueProvider
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
interface MessageQueueProvider {
|
|
96
|
+
createQueue(config?: QueueConfig): Promise<MessageQueue>;
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Usage with Provider
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// Node.js
|
|
104
|
+
import { createNodeProvider } from "@agentxjs/node";
|
|
105
|
+
|
|
106
|
+
const provider = createNodeProvider({
|
|
107
|
+
sqlitePath: "./data/queue.db",
|
|
108
|
+
});
|
|
109
|
+
const queue = await provider.createQueue({ retentionMs: 86400000 });
|
|
110
|
+
|
|
111
|
+
// Cloudflare Workers
|
|
112
|
+
import { createCloudflareProvider } from "@agentxjs/cloudflare";
|
|
113
|
+
|
|
114
|
+
const provider = createCloudflareProvider(env);
|
|
115
|
+
const queue = await provider.createQueue();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## OffsetGenerator
|
|
119
|
+
|
|
120
|
+
Utility for generating monotonically increasing offsets:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { OffsetGenerator } from "@agentxjs/core/mq";
|
|
124
|
+
|
|
125
|
+
const generator = new OffsetGenerator();
|
|
126
|
+
|
|
127
|
+
const offset1 = generator.generate(); // "lq5x4g2-0000"
|
|
128
|
+
const offset2 = generator.generate(); // "lq5x4g2-0001"
|
|
129
|
+
|
|
130
|
+
// Compare offsets
|
|
131
|
+
OffsetGenerator.compare(offset1, offset2); // -1 (offset1 < offset2)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Offset Format
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
{timestamp_base36}-{sequence_padded}
|
|
138
|
+
lq5x4g2 - 0001
|
|
139
|
+
|
|
140
|
+
- timestamp: Base36 encoded Unix milliseconds
|
|
141
|
+
- sequence: Zero-padded counter for same-millisecond uniqueness
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Difference from EventBus
|
|
145
|
+
|
|
146
|
+
| | EventBus | MessageQueue |
|
|
147
|
+
| ----------- | -------------------- | ----------------- |
|
|
148
|
+
| Scope | Process-internal | Cross-process |
|
|
149
|
+
| Persistence | None | Platform-specific |
|
|
150
|
+
| Delivery | Best-effort | At-least-once |
|
|
151
|
+
| Recovery | No | Yes (via offset) |
|
|
152
|
+
| Use case | Component decoupling | Reliable delivery |
|
|
153
|
+
|
|
154
|
+
## Platform Independence
|
|
155
|
+
|
|
156
|
+
This module defines **interfaces only** - no platform-specific code:
|
|
157
|
+
|
|
158
|
+
- No `node:*` imports
|
|
159
|
+
- No `bun:*` imports
|
|
160
|
+
- No SQLite, IndexedDB, or Durable Objects
|
|
161
|
+
|
|
162
|
+
Implementations are provided by platform packages (`@agentxjs/node`, `@agentxjs/cloudflare`).
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
MIT
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OffsetGenerator.test.ts - Unit tests for OffsetGenerator
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach } from "bun:test";
|
|
6
|
+
import { OffsetGenerator } from "../OffsetGenerator";
|
|
7
|
+
|
|
8
|
+
describe("OffsetGenerator", () => {
|
|
9
|
+
let generator: OffsetGenerator;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
generator = new OffsetGenerator();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe("generate", () => {
|
|
16
|
+
it("should generate an offset string", () => {
|
|
17
|
+
const offset = generator.generate();
|
|
18
|
+
|
|
19
|
+
expect(typeof offset).toBe("string");
|
|
20
|
+
expect(offset.length).toBeGreaterThan(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should generate offsets in expected format", () => {
|
|
24
|
+
const offset = generator.generate();
|
|
25
|
+
|
|
26
|
+
// Format: {timestamp_base36}-{sequence_padded}
|
|
27
|
+
const parts = offset.split("-");
|
|
28
|
+
expect(parts).toHaveLength(2);
|
|
29
|
+
|
|
30
|
+
// First part should be base36 timestamp
|
|
31
|
+
const timestamp = parseInt(parts[0], 36);
|
|
32
|
+
expect(timestamp).toBeGreaterThan(0);
|
|
33
|
+
|
|
34
|
+
// Second part should be zero-padded sequence
|
|
35
|
+
expect(parts[1]).toMatch(/^\d{4}$/);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should generate monotonically increasing offsets", () => {
|
|
39
|
+
const offsets: string[] = [];
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < 100; i++) {
|
|
42
|
+
offsets.push(generator.generate());
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Each offset should be greater than the previous
|
|
46
|
+
for (let i = 1; i < offsets.length; i++) {
|
|
47
|
+
expect(OffsetGenerator.compare(offsets[i], offsets[i - 1])).toBeGreaterThan(0);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("should handle multiple offsets in same millisecond", () => {
|
|
52
|
+
// Generate many offsets rapidly (likely same millisecond)
|
|
53
|
+
const offsets = new Set<string>();
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < 1000; i++) {
|
|
56
|
+
offsets.add(generator.generate());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// All offsets should be unique
|
|
60
|
+
expect(offsets.size).toBe(1000);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("compare", () => {
|
|
65
|
+
it("should return negative when a < b", () => {
|
|
66
|
+
const a = generator.generate();
|
|
67
|
+
const b = generator.generate();
|
|
68
|
+
|
|
69
|
+
expect(OffsetGenerator.compare(a, b)).toBeLessThan(0);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should return positive when a > b", () => {
|
|
73
|
+
const a = generator.generate();
|
|
74
|
+
const b = generator.generate();
|
|
75
|
+
|
|
76
|
+
expect(OffsetGenerator.compare(b, a)).toBeGreaterThan(0);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should return 0 when a == b", () => {
|
|
80
|
+
const offset = generator.generate();
|
|
81
|
+
|
|
82
|
+
expect(OffsetGenerator.compare(offset, offset)).toBe(0);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should compare by timestamp first", () => {
|
|
86
|
+
// Create offsets with different timestamps
|
|
87
|
+
const earlier = "lq5x4g1-0005"; // Earlier timestamp, higher sequence
|
|
88
|
+
const later = "lq5x4g2-0001"; // Later timestamp, lower sequence
|
|
89
|
+
|
|
90
|
+
expect(OffsetGenerator.compare(earlier, later)).toBeLessThan(0);
|
|
91
|
+
expect(OffsetGenerator.compare(later, earlier)).toBeGreaterThan(0);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should compare by sequence when timestamps equal", () => {
|
|
95
|
+
const low = "lq5x4g2-0001";
|
|
96
|
+
const high = "lq5x4g2-0005";
|
|
97
|
+
|
|
98
|
+
expect(OffsetGenerator.compare(low, high)).toBeLessThan(0);
|
|
99
|
+
expect(OffsetGenerator.compare(high, low)).toBeGreaterThan(0);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("ordering consistency", () => {
|
|
104
|
+
it("should be usable for sorting", () => {
|
|
105
|
+
const offsets: string[] = [];
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < 50; i++) {
|
|
108
|
+
offsets.push(generator.generate());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Shuffle
|
|
112
|
+
const shuffled = [...offsets].sort(() => Math.random() - 0.5);
|
|
113
|
+
|
|
114
|
+
// Sort using compare
|
|
115
|
+
const sorted = shuffled.sort(OffsetGenerator.compare);
|
|
116
|
+
|
|
117
|
+
// Should match original order
|
|
118
|
+
expect(sorted).toEqual(offsets);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
package/src/mq/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageQueue Module
|
|
3
|
+
*
|
|
4
|
+
* Provides standard interfaces for reliable message delivery:
|
|
5
|
+
* - MessageQueue: Core queue interface
|
|
6
|
+
* - MessageQueueProvider: Factory for platform-specific implementations
|
|
7
|
+
* - OffsetGenerator: Utility for generating monotonic offsets
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
QueueEntry,
|
|
12
|
+
QueueConfig,
|
|
13
|
+
Unsubscribe,
|
|
14
|
+
MessageQueue,
|
|
15
|
+
MessageQueueProvider,
|
|
16
|
+
} from "./types";
|
|
17
|
+
|
|
18
|
+
export { OffsetGenerator } from "./OffsetGenerator";
|
package/src/mq/types.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageQueue - Reliable message delivery with persistence guarantee
|
|
3
|
+
*
|
|
4
|
+
* Standard interface for message queue implementations:
|
|
5
|
+
* - In-memory pub/sub for real-time delivery (RxJS)
|
|
6
|
+
* - Persistence for recovery guarantee (platform-specific)
|
|
7
|
+
* - Consumer offset tracking for at-least-once delivery
|
|
8
|
+
*
|
|
9
|
+
* Platform implementations:
|
|
10
|
+
* - Node.js: SQLite
|
|
11
|
+
* - Cloudflare Workers: Durable Objects Storage
|
|
12
|
+
* - Browser: IndexedDB
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Queue Entry
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* QueueEntry - A single entry in the message queue
|
|
21
|
+
*/
|
|
22
|
+
export interface QueueEntry {
|
|
23
|
+
/**
|
|
24
|
+
* Unique offset for this entry (monotonically increasing)
|
|
25
|
+
* Format: "{timestamp_base36}-{sequence}"
|
|
26
|
+
* Example: "lq5x4g2-0001"
|
|
27
|
+
*/
|
|
28
|
+
readonly offset: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Topic this entry belongs to (e.g., sessionId, agentId)
|
|
32
|
+
*/
|
|
33
|
+
readonly topic: string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The actual event payload
|
|
37
|
+
*/
|
|
38
|
+
readonly event: unknown;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Timestamp when the event was published (Unix milliseconds)
|
|
42
|
+
*/
|
|
43
|
+
readonly timestamp: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Queue Configuration
|
|
48
|
+
// ============================================================================
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* QueueConfig - Platform-agnostic configuration
|
|
52
|
+
*
|
|
53
|
+
* Platform-specific options (path, namespace, etc.) are handled by Provider.
|
|
54
|
+
*/
|
|
55
|
+
export interface QueueConfig {
|
|
56
|
+
/**
|
|
57
|
+
* Message retention timeout (milliseconds)
|
|
58
|
+
* Messages older than this may be deleted during cleanup
|
|
59
|
+
* @default 86400000 (24 hours)
|
|
60
|
+
*/
|
|
61
|
+
retentionMs?: number;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Maximum entries per topic (optional)
|
|
65
|
+
* When exceeded, oldest entries may be removed
|
|
66
|
+
*/
|
|
67
|
+
maxEntriesPerTopic?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// Unsubscribe
|
|
72
|
+
// ============================================================================
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Unsubscribe function - call to stop receiving messages
|
|
76
|
+
*/
|
|
77
|
+
export type Unsubscribe = () => void;
|
|
78
|
+
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// MessageQueue Interface
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* MessageQueue - Standard interface for message queue
|
|
85
|
+
*
|
|
86
|
+
* All methods that involve storage are async to support all platforms.
|
|
87
|
+
*/
|
|
88
|
+
export interface MessageQueue {
|
|
89
|
+
/**
|
|
90
|
+
* Publish an event to a topic
|
|
91
|
+
*
|
|
92
|
+
* - Persists to storage (async)
|
|
93
|
+
* - Broadcasts to all subscribers (in-memory, sync)
|
|
94
|
+
*
|
|
95
|
+
* @param topic - Topic identifier (e.g., sessionId)
|
|
96
|
+
* @param event - Event payload
|
|
97
|
+
* @returns Offset of the published entry
|
|
98
|
+
*/
|
|
99
|
+
publish(topic: string, event: unknown): Promise<string>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Subscribe to real-time events on a topic
|
|
103
|
+
*
|
|
104
|
+
* Receives events published after subscription (in-memory pub/sub).
|
|
105
|
+
* For historical events, use recover() first.
|
|
106
|
+
*
|
|
107
|
+
* @param topic - Topic identifier
|
|
108
|
+
* @param handler - Callback for each event entry
|
|
109
|
+
* @returns Unsubscribe function
|
|
110
|
+
*/
|
|
111
|
+
subscribe(topic: string, handler: (entry: QueueEntry) => void): Unsubscribe;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Acknowledge consumption (update consumer offset)
|
|
115
|
+
*
|
|
116
|
+
* Call this after successfully processing an event.
|
|
117
|
+
* The offset is persisted for recovery.
|
|
118
|
+
*
|
|
119
|
+
* @param consumerId - Consumer identifier (e.g., connectionId)
|
|
120
|
+
* @param topic - Topic identifier
|
|
121
|
+
* @param offset - Offset of the consumed entry
|
|
122
|
+
*/
|
|
123
|
+
ack(consumerId: string, topic: string, offset: string): Promise<void>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get consumer's current offset
|
|
127
|
+
*
|
|
128
|
+
* @param consumerId - Consumer identifier
|
|
129
|
+
* @param topic - Topic identifier
|
|
130
|
+
* @returns Offset or null if consumer not found
|
|
131
|
+
*/
|
|
132
|
+
getOffset(consumerId: string, topic: string): Promise<string | null>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Recover historical events from persistence
|
|
136
|
+
*
|
|
137
|
+
* Used for reconnection recovery - fetches events after an offset.
|
|
138
|
+
*
|
|
139
|
+
* @param topic - Topic identifier
|
|
140
|
+
* @param afterOffset - Start offset (exclusive), omit for all history
|
|
141
|
+
* @param limit - Maximum entries to return (default: 1000)
|
|
142
|
+
* @returns Array of event entries
|
|
143
|
+
*/
|
|
144
|
+
recover(topic: string, afterOffset?: string, limit?: number): Promise<QueueEntry[]>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Close the message queue and release resources
|
|
148
|
+
*/
|
|
149
|
+
close(): Promise<void>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// MessageQueue Provider
|
|
154
|
+
// ============================================================================
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* MessageQueueProvider - Factory for creating MessageQueue instances
|
|
158
|
+
*
|
|
159
|
+
* Each platform implements its own provider:
|
|
160
|
+
* - SqliteMessageQueueProvider (Node.js)
|
|
161
|
+
* - DurableMessageQueueProvider (Cloudflare Workers)
|
|
162
|
+
* - IndexedDBMessageQueueProvider (Browser)
|
|
163
|
+
*/
|
|
164
|
+
export interface MessageQueueProvider {
|
|
165
|
+
/**
|
|
166
|
+
* Create a MessageQueue instance
|
|
167
|
+
*
|
|
168
|
+
* @param config - Platform-agnostic configuration
|
|
169
|
+
* @returns MessageQueue instance
|
|
170
|
+
*/
|
|
171
|
+
createQueue(config?: QueueConfig): Promise<MessageQueue>;
|
|
172
|
+
}
|