@anabranch/eventlog 0.1.3 → 0.2.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.
package/README.md CHANGED
@@ -10,26 +10,26 @@ consumer resumption.
10
10
  ## Usage
11
11
 
12
12
  ```ts
13
- import { createInMemory, EventLog } from "@anabranch/eventlog";
13
+ import { createInMemory, EventLog } from '@anabranch/eventlog'
14
14
 
15
- const connector = createInMemory();
16
- const log = await EventLog.connect(connector).run();
15
+ const connector = createInMemory()
16
+ const log = await EventLog.connect(connector).run()
17
17
 
18
18
  // Append an event
19
- await log.append("users", { type: "created", userId: 123 }).run();
19
+ await log.append('users', { type: 'created', userId: 123 }).run()
20
20
 
21
21
  // Consume events with cursor-based resumption
22
22
  const { successes, errors } = await log
23
- .consume("users", "my-processor", { batchSize: 10 })
23
+ .consume('users', 'my-processor', { batchSize: 10 })
24
24
  .withConcurrency(5)
25
25
  .map(async (batch) => {
26
26
  for (const event of batch.events) {
27
- await handleEvent(event.data);
27
+ await handleEvent(event.data)
28
28
  }
29
29
  // Manual commit for at-least-once delivery
30
- await log.commit(batch.topic, batch.consumerGroup, batch.cursor).run();
30
+ await log.commit(batch.topic, batch.consumerGroup, batch.cursor).run()
31
31
  })
32
- .partition();
32
+ .partition()
33
33
  ```
34
34
 
35
35
  ## Installation
package/esm/adapter.d.ts CHANGED
@@ -1,96 +1,117 @@
1
+ import { Promisable } from 'anabranch';
2
+ import { EventLogConsumeFailed } from './errors.js';
1
3
  /**
2
- * Event log adapter interface for event-sourced systems.
3
- *
4
- * Implement this interface to create drivers for specific event stores.
5
- * The EventLog class wraps adapters with Task/Stream semantics.
6
- *
7
- * For connection lifecycle management, use EventLogConnector which produces adapters.
8
- * The adapter's close() method releases the connection rather than terminating it.
4
+ * A single event in the event log.
9
5
  */
10
- /** A single event in the log. */
11
6
  export interface Event<T = unknown> {
12
- /** Unique event identifier (globally unique) */
7
+ /** Unique identifier for this event. */
13
8
  id: string;
14
- /** Topic/stream this event belongs to */
9
+ /** The topic this event belongs to. */
15
10
  topic: string;
16
- /** Event payload */
11
+ /** The event data payload. */
17
12
  data: T;
18
- /** Partition key for ordering guarantees */
13
+ /** Partition key for ordering guarantees. */
19
14
  partitionKey: string;
20
- /** Event sequence number within the topic */
21
- sequenceNumber: number;
22
- /** Timestamp when the event was created */
15
+ /** Monotonically increasing sequence number within the topic. Represented as a string to support bigint while remaining serializable. */
16
+ sequenceNumber: string;
17
+ /** Unix timestamp in milliseconds when the event was created. */
23
18
  timestamp: number;
24
- /** Optional metadata attached to the event */
19
+ /** Optional metadata associated with the event. */
25
20
  metadata?: Record<string, unknown>;
26
21
  }
27
- /** A batch of events consumed from a topic. */
28
- export interface EventBatch<T = unknown> {
29
- /** Topic these events belong to */
22
+ /**
23
+ * A batch of events delivered to a consumer.
24
+ */
25
+ export interface EventBatch<T = unknown, Cursor = string> {
26
+ /** The topic this batch was received from. */
30
27
  topic: string;
31
- /** Consumer group that consumed these events */
28
+ /** The consumer group that received this batch. */
32
29
  consumerGroup: string;
33
- /** Events in this batch */
30
+ /** Events in this batch. */
34
31
  events: Event<T>[];
35
- /** Cursor position for this batch (opaque to caller) */
36
- cursor: string;
32
+ /** Cursor representing the position after this batch. Use for manual commits. */
33
+ cursor: Cursor;
34
+ /**
35
+ * Commit this batch's cursor to mark progress.
36
+ *
37
+ * After processing events successfully, call this to save the cursor position.
38
+ * On restart, the consumer will resume from this position.
39
+ */
40
+ commit(): Promise<void>;
37
41
  }
38
42
  /**
39
- * Event log adapter interface for low-level operations.
43
+ * Low-level adapter interface for event log implementations.
44
+ *
45
+ * Adapters handle the actual communication with the underlying event store
46
+ * (in-memory, Kafka, etc.). Use connectors to create adapter instances.
40
47
  */
41
- export interface EventLogAdapter {
42
- /** Append an event to a topic. Returns the event ID. */
48
+ export interface EventLogAdapter<Cursor = string> {
49
+ /**
50
+ * Append an event to a topic.
51
+ */
43
52
  append<T>(topic: string, data: T, options?: AppendOptions): Promise<string>;
44
- /** Get a single event by ID. */
45
- get<T>(topic: string, sequenceNumber: number): Promise<Event<T> | null>;
46
- /** List events in a topic with optional filtering. */
47
- list<T>(topic: string, options?: ListOptions): Promise<Event<T>[]>;
48
- /** Consume events from a topic as a streaming async iterable. */
49
- consume<T>(topic: string, consumerGroup: string, options?: ConsumeOptions): AsyncIterable<EventBatch<T>>;
50
- /** Commit a cursor position for a consumer group. */
51
- commitCursor(topic: string, consumerGroup: string, cursor: string): Promise<void>;
52
- /** Get the committed cursor position for a consumer group. */
53
- getCursor(topic: string, consumerGroup: string): Promise<string | null>;
54
- /** Close the adapter connection. */
53
+ /**
54
+ * Consume events from a topic.
55
+ */
56
+ consume<T>(topic: string, consumerGroup: string, onBatch: (batch: EventBatch<T, Cursor>) => Promisable<void>, onError: (error: EventLogConsumeFailed) => Promisable<void>, options?: ConsumeOptions<Cursor>): {
57
+ close: () => Promise<void>;
58
+ };
59
+ /**
60
+ * Get the last committed cursor for a consumer group.
61
+ */
62
+ getCursor(topic: string, consumerGroup: string): Promise<Cursor | null>;
63
+ /**
64
+ * Commit a cursor for a consumer group.
65
+ */
66
+ commitCursor(topic: string, consumerGroup: string, cursor: Cursor): Promise<void>;
67
+ /** Close the adapter and release resources. */
55
68
  close(): Promise<void>;
56
69
  }
57
- /** Options for appending an event. */
70
+ /** Options for appending events. */
58
71
  export interface AppendOptions {
59
- /** Partition key for ordering guarantees within the topic */
72
+ /** Key for partitioning and ordering. Events with the same key are ordered. */
60
73
  partitionKey?: string;
61
- /** Optional metadata attached to the event */
74
+ /** Custom metadata to attach to the event. */
62
75
  metadata?: Record<string, unknown>;
63
- /** Timestamp for the event (defaults to now) */
76
+ /** Custom timestamp in milliseconds. Defaults to Date.now(). */
64
77
  timestamp?: number;
65
78
  }
66
- /** Options for listing events. */
67
- export interface ListOptions {
68
- /** Starting sequence number (inclusive) */
69
- fromSequenceNumber?: number;
70
- /** Maximum number of events to return */
71
- limit?: number;
72
- /** Filter by partition key */
73
- partitionKey?: string;
74
- }
75
79
  /** Options for consuming events. */
76
- export interface ConsumeOptions {
77
- /** Signal for cancellation */
80
+ export interface ConsumeOptions<Cursor = string> {
81
+ /** Abort signal to cancel consumption. */
78
82
  signal?: AbortSignal;
79
- /** Starting cursor (null means from beginning) */
80
- cursor?: string | null;
81
- /** Batch size for events */
83
+ /** Cursor to resume from. If null, starts from the beginning. */
84
+ cursor?: Cursor | null;
85
+ /** Maximum number of events per batch. Defaults to adapter-specific value. */
82
86
  batchSize?: number;
87
+ /** Maximum number of batches to buffer. Defaults to adapter-specific value.
88
+ * When the buffer is full, new batches will be dropped and onError will be called with an EventLogConsumeFailed error.
89
+ * @default Infinity
90
+ */
91
+ bufferSize?: number;
83
92
  }
84
- /** Connector that produces connected EventLogAdapter instances. */
85
- export interface EventLogConnector {
86
- /** Acquire a connected adapter. */
87
- connect(signal?: AbortSignal): Promise<EventLogAdapter>;
88
- /** Close all connections and clean up resources. */
93
+ /**
94
+ * Factory for creating event log connections.
95
+ *
96
+ * Connectors manage connection lifecycle and produce adapter instances.
97
+ * Use connectors in production code to properly manage resources.
98
+ */
99
+ export interface EventLogConnector<Cursor = string> {
100
+ /**
101
+ * Connect to the event log.
102
+ */
103
+ connect(signal?: AbortSignal): Promise<EventLogAdapter<Cursor>>;
104
+ /**
105
+ * End the connector and release all resources.
106
+ *
107
+ * After calling end(), all adapters created by this connector become
108
+ * invalid and subsequent connect() calls will fail.
109
+ */
89
110
  end(): Promise<void>;
90
111
  }
91
- /** Event log configuration options. */
112
+ /** Configuration options for event log implementations. */
92
113
  export interface EventLogOptions {
93
- /** Default partition key if not specified */
114
+ /** Default partition key for events without explicit keys. */
94
115
  defaultPartitionKey?: string;
95
116
  }
96
117
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
package/esm/adapter.js CHANGED
@@ -1,10 +1 @@
1
- /**
2
- * Event log adapter interface for event-sourced systems.
3
- *
4
- * Implement this interface to create drivers for specific event stores.
5
- * The EventLog class wraps adapters with Task/Stream semantics.
6
- *
7
- * For connection lifecycle management, use EventLogConnector which produces adapters.
8
- * The adapter's close() method releases the connection rather than terminating it.
9
- */
10
1
  export {};
package/esm/errors.d.ts CHANGED
@@ -10,13 +10,8 @@ export declare class EventLogAppendFailed extends Error {
10
10
  name: string;
11
11
  constructor(topic: string, message: string, cause?: unknown);
12
12
  }
13
- /** Error thrown when getting an event fails. */
14
- export declare class EventLogGetFailed extends Error {
15
- name: string;
16
- constructor(topic: string, sequenceNumber: number, message: string, cause?: unknown);
17
- }
18
- /** Error thrown when listing events fails. */
19
- export declare class EventLogListFailed extends Error {
13
+ /** Error thrown when consuming events fails. */
14
+ export declare class EventLogConsumeFailed extends Error {
20
15
  name: string;
21
16
  constructor(topic: string, message: string, cause?: unknown);
22
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACxC,IAAI,SAA8B;gBAC/B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,mDAAmD;AACnD,qBAAa,oBAAqB,SAAQ,KAAK;IACpC,IAAI,SAA0B;gBAC3B,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG5D;AAED,gDAAgD;AAChD,qBAAa,iBAAkB,SAAQ,KAAK;IACjC,IAAI,SAAuB;gBAElC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO;CAOlB;AAED,8CAA8C;AAC9C,qBAAa,kBAAmB,SAAQ,KAAK;IAClC,IAAI,SAAwB;gBACzB,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG5D;AAED,mDAAmD;AACnD,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAAgC;gBAE3C,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO;CAOlB;AAED,gDAAgD;AAChD,qBAAa,uBAAwB,SAAQ,KAAK;IACvC,IAAI,SAA6B;gBAExC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO;CAOlB;AAED,+DAA+D;AAC/D,qBAAa,mBAAoB,SAAQ,KAAK;IACnC,IAAI,SAAyB;gBAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACxC,IAAI,SAA6B;gBAC9B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED,mDAAmD;AACnD,qBAAa,oBAAqB,SAAQ,KAAK;IACpC,IAAI,SAAyB;gBAC1B,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG5D;AAED,gDAAgD;AAChD,qBAAa,qBAAsB,SAAQ,KAAK;IACrC,IAAI,SAA0B;gBAC3B,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG5D;AAED,mDAAmD;AACnD,qBAAa,0BAA2B,SAAQ,KAAK;IAC1C,IAAI,SAA+B;gBAE1C,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO;CAOlB;AAED,gDAAgD;AAChD,qBAAa,uBAAwB,SAAQ,KAAK;IACvC,IAAI,SAA4B;gBAEvC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO;CAOlB;AAED,+DAA+D;AAC/D,qBAAa,mBAAoB,SAAQ,KAAK;IACnC,IAAI,SAAwB;gBACzB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C"}
package/esm/errors.js CHANGED
@@ -8,7 +8,7 @@ export class EventLogConnectionFailed extends Error {
8
8
  enumerable: true,
9
9
  configurable: true,
10
10
  writable: true,
11
- value: "EventLogConnectionFailed"
11
+ value: 'EventLogConnectionFailed'
12
12
  });
13
13
  }
14
14
  }
@@ -20,31 +20,19 @@ export class EventLogAppendFailed extends Error {
20
20
  enumerable: true,
21
21
  configurable: true,
22
22
  writable: true,
23
- value: "EventLogAppendFailed"
23
+ value: 'EventLogAppendFailed'
24
24
  });
25
25
  }
26
26
  }
27
- /** Error thrown when getting an event fails. */
28
- export class EventLogGetFailed extends Error {
29
- constructor(topic, sequenceNumber, message, cause) {
30
- super(`Failed to get event ${sequenceNumber} from ${topic}: ${message}`, { cause });
31
- Object.defineProperty(this, "name", {
32
- enumerable: true,
33
- configurable: true,
34
- writable: true,
35
- value: "EventLogGetFailed"
36
- });
37
- }
38
- }
39
- /** Error thrown when listing events fails. */
40
- export class EventLogListFailed extends Error {
27
+ /** Error thrown when consuming events fails. */
28
+ export class EventLogConsumeFailed extends Error {
41
29
  constructor(topic, message, cause) {
42
- super(`Failed to list events from ${topic}: ${message}`, { cause });
30
+ super(`Failed to consume events from ${topic}: ${message}`, { cause });
43
31
  Object.defineProperty(this, "name", {
44
32
  enumerable: true,
45
33
  configurable: true,
46
34
  writable: true,
47
- value: "EventLogListFailed"
35
+ value: 'EventLogConsumeFailed'
48
36
  });
49
37
  }
50
38
  }
@@ -56,7 +44,7 @@ export class EventLogCommitCursorFailed extends Error {
56
44
  enumerable: true,
57
45
  configurable: true,
58
46
  writable: true,
59
- value: "EventLogCommitCursorFailed"
47
+ value: 'EventLogCommitCursorFailed'
60
48
  });
61
49
  }
62
50
  }
@@ -68,7 +56,7 @@ export class EventLogGetCursorFailed extends Error {
68
56
  enumerable: true,
69
57
  configurable: true,
70
58
  writable: true,
71
- value: "EventLogGetCursorFailed"
59
+ value: 'EventLogGetCursorFailed'
72
60
  });
73
61
  }
74
62
  }
@@ -80,7 +68,7 @@ export class EventLogCloseFailed extends Error {
80
68
  enumerable: true,
81
69
  configurable: true,
82
70
  writable: true,
83
- value: "EventLogCloseFailed"
71
+ value: 'EventLogCloseFailed'
84
72
  });
85
73
  }
86
74
  }
package/esm/eventlog.d.ts CHANGED
@@ -1,8 +1,12 @@
1
- import { Source, Task } from "anabranch";
2
- import type { AppendOptions, ConsumeOptions, Event, EventBatch, EventLogAdapter, EventLogConnector, ListOptions } from "./adapter.js";
3
- import { EventLogAppendFailed, EventLogCloseFailed, EventLogCommitCursorFailed, EventLogConnectionFailed, EventLogGetCursorFailed, EventLogGetFailed, EventLogListFailed } from "./errors.js";
1
+ import { Channel, Task } from 'anabranch';
2
+ import type { AppendOptions, ConsumeOptions, EventBatch, EventLogAdapter, EventLogConnector } from './adapter.js';
3
+ import { EventLogAppendFailed, EventLogCloseFailed, EventLogCommitCursorFailed, EventLogConnectionFailed, EventLogConsumeFailed, EventLogGetCursorFailed } from './errors.js';
4
4
  /**
5
- * EventLog wrapper with Task/Stream semantics for event-sourced systems.
5
+ * Event log wrapper with Task/Stream semantics for event-sourced systems.
6
+ *
7
+ * Provides high-level methods for appending events, consuming streams,
8
+ * and managing cursors. All operations return Tasks for composable error
9
+ * handling.
6
10
  *
7
11
  * @example Basic usage
8
12
  * ```ts
@@ -12,35 +16,34 @@ import { EventLogAppendFailed, EventLogCloseFailed, EventLogCommitCursorFailed,
12
16
  * const log = await EventLog.connect(connector).run();
13
17
  *
14
18
  * // Append an event
15
- * const eventId = await log.append("users", { action: "created", userId: 123 }).run();
16
- *
17
- * // Get a specific event
18
- * const event = await log.get("users", 0).run();
19
- *
20
- * // List events
21
- * const events = await log.list("users").run();
22
- *
23
- * await log.close().run();
24
- * ```
19
+ * const eventId = await log.append("users", { userId: 123 }).run();
25
20
  *
26
- * @example Consuming events as a stream
27
- * ```ts
21
+ * // Consume events as a stream
28
22
  * const { successes, errors } = await log
29
- * .consume("users", "my-consumer-group")
23
+ * .consume("users", "my-processor")
30
24
  * .withConcurrency(5)
31
25
  * .map(async (batch) => {
32
26
  * for (const event of batch.events) {
33
- * await handleEvent(event.data);
27
+ * await processEvent(event.data);
34
28
  * }
35
- * // Explicitly commit after successful processing!
36
- * await log.commit(batch.topic, batch.consumerGroup, batch.cursor).run();
37
29
  * })
38
30
  * .partition();
31
+ *
32
+ * await log.close().run();
33
+ * ```
34
+ *
35
+ * @example Manual cursor management
36
+ * ```ts
37
+ * // Get current cursor position
38
+ * const cursor = await log.getCommittedCursor("users", "my-processor").run();
39
+ *
40
+ * // Save cursor after processing
41
+ * await log.commit("users", "my-processor", batch.cursor).run();
39
42
  * ```
40
43
  */
41
- export declare class EventLog {
44
+ export declare class EventLog<Cursor = string> {
42
45
  private readonly adapter;
43
- constructor(adapter: EventLogAdapter);
46
+ constructor(adapter: EventLogAdapter<Cursor>);
44
47
  /**
45
48
  * Connect to an event log via a connector.
46
49
  *
@@ -49,9 +52,11 @@ export declare class EventLog {
49
52
  * const log = await EventLog.connect(createInMemory()).run();
50
53
  * ```
51
54
  */
52
- static connect(connector: EventLogConnector): Task<EventLog, EventLogConnectionFailed>;
55
+ static connect<Cursor = string>(connector: EventLogConnector<Cursor>): Task<EventLog<Cursor>, EventLogConnectionFailed>;
53
56
  /**
54
- * Release the connection back to its source.
57
+ * Close the event log connection.
58
+ *
59
+ * After closing, no further operations can be performed on this instance.
55
60
  *
56
61
  * @example
57
62
  * ```ts
@@ -62,110 +67,87 @@ export declare class EventLog {
62
67
  /**
63
68
  * Append an event to a topic.
64
69
  *
65
- * @example Basic append
66
- * ```ts
67
- * const eventId = await log.append("users", { action: "created", userId: 123 }).run();
68
- * ```
70
+ * Returns the event ID which can be used for logging or correlation.
69
71
  *
70
- * @example With partition key
72
+ * @example
71
73
  * ```ts
72
- * const eventId = await log.append("orders", orderData, {
73
- * partitionKey: orderData.userId,
74
+ * const eventId = await log.append("users", { action: "created" }).run();
75
+ *
76
+ * // With options
77
+ * await log.append("orders", order, {
78
+ * partitionKey: order.userId,
79
+ * metadata: { source: "checkout" },
74
80
  * }).run();
75
81
  * ```
76
82
  */
77
83
  append<T>(topic: string, data: T, options?: AppendOptions): Task<string, EventLogAppendFailed>;
78
84
  /**
79
- * Get a single event by topic and sequence number.
80
- *
81
- * @example
82
- * ```ts
83
- * const event = await log.get("users", 0).run();
84
- * if (event) {
85
- * console.log(event.data);
86
- * }
87
- * ```
88
- */
89
- get<T>(topic: string, sequenceNumber: number): Task<Event<T> | null, EventLogGetFailed>;
90
- /**
91
- * List events in a topic with optional filtering and pagination.
85
+ * Consume events from a topic as a stream.
92
86
  *
93
- * @example List all events
94
- * ```ts
95
- * const events = await log.list("users").run();
96
- * ```
87
+ * Returns a Channel that yields batches of events. Each batch includes
88
+ * a cursor that can be committed to mark progress. Use stream methods
89
+ * like `withConcurrency()`, `map()`, and `partition()` for processing.
97
90
  *
98
- * @example With pagination
99
- * ```ts
100
- * const events = await log.list("users", {
101
- * fromSequenceNumber: 100,
102
- * limit: 50,
103
- * }).run();
104
- * ```
91
+ * Batches are delivered asynchronously as they become available. Use
92
+ * `take()` to limit iterations or pass an AbortSignal in options to
93
+ * cancel consumption.
105
94
  *
106
- * @example Filtered by partition key
95
+ * @example
107
96
  * ```ts
108
- * const events = await log.list("orders", {
109
- * partitionKey: "user-123",
110
- * }).run();
111
- * ```
112
- */
113
- list<T>(topic: string, options?: ListOptions): Task<Event<T>[], EventLogListFailed>;
114
- /**
115
- * Consume events from a topic as a Source for streaming.
97
+ * const ac = new AbortController();
116
98
  *
117
- * Note: You must manually commit the cursor after processing to guarantee
118
- * at-least-once delivery. Auto-commit is intentionally omitted to prevent
119
- * data loss when using concurrent processing.
120
- *
121
- * @example Basic consumption
122
- * ```ts
123
- * const { successes, errors } = await log
124
- * .consume("users", "processor-1")
125
- * .withConcurrency(5)
99
+ * await log.consume("users", "processor-1", { signal: ac.signal })
100
+ * .withConcurrency(10)
126
101
  * .map(async (batch) => {
127
102
  * for (const event of batch.events) {
128
- * await handleEvent(event.data);
103
+ * await processUser(event.data);
129
104
  * }
130
- * await log.commit(batch.topic, batch.consumerGroup, batch.cursor).run();
105
+ * await batch.commit(); // Mark progress
131
106
  * })
132
107
  * .partition();
108
+ *
109
+ * ac.abort(); // Stop consumption
133
110
  * ```
134
111
  *
135
- * @example From specific cursor position
112
+ * @example Resume from a saved cursor
136
113
  * ```ts
137
- * const lastCursor = await log.getCommittedCursor("users", "processor-1").run();
138
- * const { successes } = await log
139
- * .consume("users", "processor-1", { cursor: lastCursor })
140
- * .tap(async (batch) => {
141
- * for (const event of batch.events) {
142
- * console.log(event);
143
- * }
144
- * })
145
- * .partition();
114
+ * const cursor = await log.getCommittedCursor("users", "processor-1").run();
115
+ * const stream = log.consume("users", "processor-1", { cursor });
146
116
  * ```
147
117
  */
148
- consume<T>(topic: string, consumerGroup: string, options?: ConsumeOptions): Source<EventBatch<T>, EventLogListFailed>;
118
+ consume<T>(topic: string, consumerGroup: string, options?: ConsumeOptions<Cursor>): Channel<EventBatch<T, Cursor>, EventLogConsumeFailed>;
149
119
  /**
150
- * Commit a cursor position for a consumer group.
120
+ * Commit a cursor to mark progress for a consumer group.
121
+ *
122
+ * This is for administrative use cases where you can't commit in-band, preferably when you're
123
+ * not actively consuming events. For example, you might want to skip ahead after a downtime or reset to the beginning for reprocessing.
124
+ * Do prefer to commit in-band, i.e. after processing each batch, by calling `batch.commit()`.
125
+ *
126
+ * After processing events, commit the cursor to resume from that position
127
+ * on the next run. Cursors are obtained from `batch.cursor` in the consume
128
+ * stream or from `getCommittedCursor()`.
151
129
  *
152
130
  * @example
153
131
  * ```ts
154
- * await log.commit("users", "processor-1", cursor).run();
132
+ * await log.commit("users", "processor-1", batch.cursor).run();
155
133
  * ```
156
134
  */
157
- commit(topic: string, consumerGroup: string, cursor: string): Task<void, EventLogCommitCursorFailed>;
135
+ commit(topic: string, consumerGroup: string, cursor: Cursor): Task<void, EventLogCommitCursorFailed>;
158
136
  /**
159
- * Get the committed cursor position for a consumer group.
137
+ * Get the last committed cursor for a consumer group.
138
+ *
139
+ * Returns null if no cursor has been committed yet. Use this to resume
140
+ * consumption from the last processed position.
160
141
  *
161
142
  * @example
162
143
  * ```ts
163
144
  * const cursor = await log.getCommittedCursor("users", "processor-1").run();
164
145
  * if (cursor) {
165
- * console.log(`Resuming from cursor: ${cursor}`);
146
+ * // Resume from saved position
147
+ * const stream = log.consume("users", "processor-1", { cursor });
166
148
  * }
167
149
  * ```
168
150
  */
169
- getCommittedCursor(topic: string, consumerGroup: string): Task<string | null, EventLogGetCursorFailed>;
151
+ getCommittedCursor(topic: string, consumerGroup: string): Task<Cursor | null, EventLogGetCursorFailed>;
170
152
  }
171
153
  //# sourceMappingURL=eventlog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eventlog.d.ts","sourceRoot":"","sources":["../src/eventlog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,KAAK,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,QAAQ;IACP,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,eAAe;IAErD;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CACZ,SAAS,EAAE,iBAAiB,GAC3B,IAAI,CAAC,QAAQ,EAAE,wBAAwB,CAAC;IAa3C;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAaxC;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,CAAC,EACN,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,aAAa,GACtB,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAcrC;;;;;;;;;;OAUG;IACH,GAAG,CAAC,CAAC,EACH,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,GACrB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC;IAe3C;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,CAAC,CAAC,EACJ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,WAAW,GACpB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,kBAAkB,CAAC;IAcvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,OAAO,CAAC,CAAC,EACP,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC;IAmB5C;;;;;;;OAOG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAezC;;;;;;;;;;OAUG;IACH,kBAAkB,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,uBAAuB,CAAC;CAchD"}
1
+ {"version":3,"file":"eventlog.d.ts","sourceRoot":"","sources":["../src/eventlog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,eAAe,EACf,iBAAiB,EAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,aAAa,CAAA;AAEpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,QAAQ,CAAC,MAAM,GAAG,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;IAE7D;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,EAC5B,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,GACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAanD;;;;;;;;;OASG;IACH,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAaxC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,CAAC,EACN,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,aAAa,GACtB,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAcrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,OAAO,CAAC,CAAC,EACP,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAsDxD;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAezC;;;;;;;;;;;;;;OAcG;IACH,kBAAkB,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,uBAAuB,CAAC;CAchD"}