@eventualize/dynamodb-storage-adapter 1.0.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.
@@ -0,0 +1,3 @@
1
+ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
+ export declare function listTables(client: DynamoDBClient): Promise<string[] | undefined>;
3
+ export declare function createDynamoDBClient(): DynamoDBClient;
@@ -0,0 +1,30 @@
1
+ // src/dynamo-client.ts
2
+ import { DynamoDBClient, ListTablesCommand } from "@aws-sdk/client-dynamodb";
3
+ export async function listTables(client) {
4
+ try {
5
+ const command = new ListTablesCommand({});
6
+ const response = await client.send(command);
7
+ console.log("Tables in DynamoDB Local:", response.TableNames);
8
+ return response.TableNames;
9
+ }
10
+ catch (error) {
11
+ console.error("Error listing tables:", error);
12
+ throw error;
13
+ }
14
+ }
15
+ export function createDynamoDBClient() {
16
+ const endpoint = process.env.DYNAMODB_URL;
17
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
18
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
19
+ const region = process.env.AWS_REGION || 'us-east-1';
20
+ if (!endpoint || !accessKeyId || !secretAccessKey) {
21
+ const envVars = { endpoint, accessKeyId, secretAccessKey };
22
+ throw new Error("AWS credentials are not set in environment variables: " + JSON.stringify(envVars));
23
+ }
24
+ const config = {};
25
+ config.endpoint = endpoint;
26
+ config.credentials = { accessKeyId, secretAccessKey };
27
+ config.region = region;
28
+ return new DynamoDBClient(config);
29
+ }
30
+ //# sourceMappingURL=DynamoDbClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamoDbClient.js","sourceRoot":"","sources":["../src/DynamoDbClient.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,cAAc,EAAwB,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEnG,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAsB;IACnD,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9D,OAAO,QAAQ,CAAC,UAAU,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC9C,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oBAAoB;IAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAClD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,WAAW,CAAC;IAErD,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,wDAAwD,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACxG,CAAC;IAED,MAAM,MAAM,GAAyB,EAAE,CAAC;IACxC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,WAAW,GAAG,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;IACtD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import IEvDbStorageAdmin from "@eventualize/types/IEvDbStorageAdmin";
2
+ export default class EvDbDynamoDbAdmin implements IEvDbStorageAdmin {
3
+ private dynamoDbClient;
4
+ constructor();
5
+ private extractKeys;
6
+ /**
7
+ * Scans a table for all items and deletes them in batches of 25.
8
+ * @param tableName The name of the table to clear.
9
+ */
10
+ private clearTableItems;
11
+ createEnvironmentAsync(): Promise<void>;
12
+ destroyEnvironmentAsync(): Promise<void>;
13
+ clearEnvironmentAsync(): Promise<void>;
14
+ dispose?(): void;
15
+ disposeAsync(): Promise<void>;
16
+ close(): Promise<void>;
17
+ }
@@ -0,0 +1,101 @@
1
+ import { BatchWriteItemCommand, ScanCommand } from "@aws-sdk/client-dynamodb";
2
+ import { createDynamoDBClient } from "./DynamoDbClient.js";
3
+ export default class EvDbDynamoDbAdmin {
4
+ constructor() {
5
+ this.dynamoDbClient = createDynamoDBClient();
6
+ }
7
+ ;
8
+ // Helper function to extract keys in raw DynamoDB format
9
+ extractKeys(tableName, items) {
10
+ return items.map(item => {
11
+ const deleteRequest = {
12
+ DeleteRequest: {
13
+ Key: {} // Must build the Key object manually
14
+ }
15
+ };
16
+ if (tableName === "events") {
17
+ deleteRequest.DeleteRequest.Key["stream_address"] = item["stream_address"];
18
+ deleteRequest.DeleteRequest.Key["offset"] = item["offset"];
19
+ }
20
+ else if (tableName === "snapshots") {
21
+ deleteRequest.DeleteRequest.Key["view_address"] = item["view_address"];
22
+ deleteRequest.DeleteRequest.Key["offset"] = item["offset"];
23
+ }
24
+ else if (tableName === "messages") {
25
+ // Assuming the schema typo was fixed to message_address
26
+ deleteRequest.DeleteRequest.Key["message_address"] = item["message_address"];
27
+ deleteRequest.DeleteRequest.Key["captured_at"] = item["captured_at"];
28
+ }
29
+ return deleteRequest;
30
+ });
31
+ }
32
+ /**
33
+ * Scans a table for all items and deletes them in batches of 25.
34
+ * @param tableName The name of the table to clear.
35
+ */
36
+ async clearTableItems(tableName) {
37
+ let items;
38
+ let exclusiveStartKey = undefined;
39
+ const BATCH_SIZE = 25;
40
+ do {
41
+ // Define ProjectionExpression and ExpressionAttributeNames dynamically
42
+ let projectionExpression;
43
+ let expressionAttributeNames = undefined;
44
+ if (tableName === "events") {
45
+ projectionExpression = "stream_address, #o";
46
+ expressionAttributeNames = { "#o": "offset" };
47
+ }
48
+ else if (tableName === "snapshots") {
49
+ projectionExpression = "view_address, #o";
50
+ expressionAttributeNames = { "#o": "offset" };
51
+ }
52
+ else { // "messages" table
53
+ projectionExpression = "message_address, captured_at";
54
+ // No offset in the projection for messages table, so no #o alias is needed
55
+ }
56
+ const scanCommand = new ScanCommand({
57
+ TableName: tableName,
58
+ ProjectionExpression: projectionExpression,
59
+ ExpressionAttributeNames: expressionAttributeNames, // Pass the dynamic object
60
+ Limit: BATCH_SIZE,
61
+ ExclusiveStartKey: exclusiveStartKey,
62
+ });
63
+ // ... (rest of the function for scanning and batch writing remains the same) ...
64
+ const scanResult = await this.dynamoDbClient.send(scanCommand);
65
+ items = scanResult.Items;
66
+ if (items && items.length > 0) {
67
+ const deleteRequests = this.extractKeys(tableName, items);
68
+ const batchWriteCommand = new BatchWriteItemCommand({
69
+ RequestItems: {
70
+ [tableName]: deleteRequests
71
+ }
72
+ });
73
+ await this.dynamoDbClient.send(batchWriteCommand);
74
+ console.log(`Deleted ${items.length} items from ${tableName}.`);
75
+ }
76
+ exclusiveStartKey = scanResult.LastEvaluatedKey;
77
+ } while (exclusiveStartKey);
78
+ console.log(`Finished item deletion for table: ${tableName}`);
79
+ }
80
+ createEnvironmentAsync() {
81
+ throw new Error("Method not implemented.");
82
+ }
83
+ destroyEnvironmentAsync() {
84
+ throw new Error("Method not implemented.");
85
+ }
86
+ async clearEnvironmentAsync() {
87
+ await this.clearTableItems("events");
88
+ await this.clearTableItems("snapshots");
89
+ await this.clearTableItems("messages");
90
+ }
91
+ dispose() {
92
+ throw new Error("Method not implemented.");
93
+ }
94
+ disposeAsync() {
95
+ throw new Error("Method not implemented.");
96
+ }
97
+ async close() {
98
+ return;
99
+ }
100
+ }
101
+ //# sourceMappingURL=EvDBDynamoDBAdmin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDBDynamoDBAdmin.js","sourceRoot":"","sources":["../src/EvDBDynamoDBAdmin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { IEvDbPayloadData } from '@eventualize/types/IEvDbEventPayload';
2
+ import IEvDbEventMetadata from '@eventualize/types/IEvDbEventMetadata';
3
+ import EvDbStreamCursor from '@eventualize/types/EvDbStreamCursor';
4
+ import EvDbMessage from '@eventualize/types/EvDbMessage';
5
+ import IEvDbStorageSnapshotAdapter from '@eventualize/types/IEvDbStorageSnapshotAdapter';
6
+ import IEvDbStorageStreamAdapter from '@eventualize/types/IEvDbStorageStreamAdapter';
7
+ import EvDbStreamAddress from '@eventualize/types/EvDbStreamAddress';
8
+ import EvDbViewAddress from '@eventualize/types/EvDbViewAddress';
9
+ import { EvDbStoredSnapshotResultRaw } from '@eventualize/types/EvDbStoredSnapshotResult';
10
+ import { EvDbStoredSnapshotData } from '@eventualize/types/EvDbStoredSnapshotData';
11
+ import EvDbEvent from '@eventualize/types/EvDbEvent';
12
+ import StreamStoreAffected from '@eventualize/types/StreamStoreAffected';
13
+ import EvDbContinuousFetchOptions from '@eventualize/types/EvDbContinuousFetchOptions';
14
+ import EvDbMessageFilter from '@eventualize/types/EvDbMessageFilter';
15
+ import { EvDbShardName } from '@eventualize/types/primitiveTypes';
16
+ import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
17
+ export interface EvDbEventRecord extends IEvDbEventMetadata {
18
+ id: string;
19
+ payload: IEvDbPayloadData;
20
+ }
21
+ export interface EvDbSnapshotRecord {
22
+ id: string;
23
+ streamType: string;
24
+ streamId: string;
25
+ viewName: string;
26
+ offset: bigint;
27
+ state: IEvDbPayloadData;
28
+ }
29
+ export interface IEvDbOutboxTransformer {
30
+ transform(message: EvDbMessage): EvDbMessage;
31
+ }
32
+ export interface EvDbStorageContext {
33
+ schema?: string;
34
+ shortId: string;
35
+ id: string;
36
+ }
37
+ /**
38
+ * Prisma-based storage adapter for EvDb
39
+ * Replaces SQL Server-specific adapter with database-agnostic Prisma implementation
40
+ */
41
+ export default class EvDbDynamoDbStorageAdapter implements IEvDbStorageSnapshotAdapter, IEvDbStorageStreamAdapter {
42
+ private dynamoDbClient;
43
+ constructor(dynamoDbClient?: DynamoDBClient);
44
+ getFromOutbox(filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<AsyncIterable<EvDbMessage>>;
45
+ getFromOutboxAsync(shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage>;
46
+ getRecordsFromOutboxAsync(filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage>;
47
+ getRecordsFromOutboxAsync(shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null, cancellation?: AbortSignal): AsyncIterable<EvDbMessage>;
48
+ subscribeToMessageAsync(handler: (message: EvDbMessage) => Promise<void>, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<void>;
49
+ subscribeToMessageAsync(handler: (message: EvDbMessage) => Promise<void>, shard: EvDbShardName, filter: EvDbMessageFilter, options?: EvDbContinuousFetchOptions | null): Promise<void>;
50
+ /**
51
+ * Store stream events in a transaction
52
+ */
53
+ storeStreamAsync(events: ReadonlyArray<EvDbEvent>, messages: ReadonlyArray<EvDbMessage>): Promise<StreamStoreAffected>;
54
+ /**
55
+ * Store outbox messages in a transaction
56
+ */
57
+ storeOutboxMessagesAsync(shardName: EvDbShardName, records: EvDbMessage[]): Promise<number>;
58
+ /**
59
+ * Get the last offset for a stream
60
+ */
61
+ getLastOffsetAsync(streamAddress: EvDbStreamAddress): Promise<number>;
62
+ /**
63
+ * Get events for a stream since a specific offset
64
+ */
65
+ getEventsAsync(streamCursor: EvDbStreamCursor, pageSize?: number): AsyncGenerator<EvDbEvent, void, undefined>;
66
+ /**
67
+ * Get snapshot for a stream view
68
+ */
69
+ getSnapshotAsync(viewAddress: EvDbViewAddress): Promise<EvDbStoredSnapshotResultRaw>;
70
+ /**
71
+ * Save a snapshot
72
+ */
73
+ storeSnapshotAsync(record: EvDbStoredSnapshotData): Promise<void>;
74
+ /**
75
+ * Check if an exception is an optimistic concurrency conflict
76
+ */
77
+ private isOccException;
78
+ /**
79
+ * Get table name for shard
80
+ */
81
+ private getTableNameForShard;
82
+ /**
83
+ * Close the database connection
84
+ */
85
+ close(): Promise<void>;
86
+ }
@@ -0,0 +1,160 @@
1
+ import { unmarshall } from "@aws-sdk/util-dynamodb";
2
+ import EvDbStreamCursor from '@eventualize/types/EvDbStreamCursor';
3
+ import { EvDbStoredSnapshotResultRaw } from '@eventualize/types/EvDbStoredSnapshotResult';
4
+ import StreamStoreAffected from '@eventualize/types/StreamStoreAffected';
5
+ import { createDynamoDBClient, listTables } from './DynamoDbClient.js';
6
+ import QueryProvider, { deserializeStreamAddress, EventRecord } from './EvDbDynamoDbStorageAdapterQueries.js';
7
+ import { TransactionCanceledException, TransactWriteItemsCommand } from '@aws-sdk/client-dynamodb';
8
+ const serializePayload = (payload) => Buffer.from(JSON.stringify(payload), 'utf-8');
9
+ const deserializePayload = (payload) => {
10
+ if (!!payload && typeof payload == 'object') {
11
+ return payload;
12
+ }
13
+ return {};
14
+ };
15
+ /**
16
+ * Prisma-based storage adapter for EvDb
17
+ * Replaces SQL Server-specific adapter with database-agnostic Prisma implementation
18
+ */
19
+ export default class EvDbDynamoDbStorageAdapter {
20
+ constructor(dynamoDbClient = createDynamoDBClient()) {
21
+ this.dynamoDbClient = dynamoDbClient;
22
+ }
23
+ getFromOutbox(filter, options) {
24
+ throw new Error('Method not implemented.');
25
+ }
26
+ getFromOutboxAsync(shard, filter, options, cancellation) {
27
+ throw new Error('Method not implemented.');
28
+ }
29
+ getRecordsFromOutboxAsync(shard, filter, options, cancellation) {
30
+ throw new Error('Method not implemented.');
31
+ }
32
+ subscribeToMessageAsync(handler, shard, filter, options) {
33
+ throw new Error('Method not implemented.');
34
+ }
35
+ /**
36
+ * Store stream events in a transaction
37
+ */
38
+ async storeStreamAsync(events, messages) {
39
+ try {
40
+ await listTables(this.dynamoDbClient);
41
+ const eventsToInsert = events.map((event) => EventRecord.createFromEvent(event));
42
+ const messagesToInsert = messages.map(message => {
43
+ return {
44
+ id: crypto.randomUUID(),
45
+ stream_cursor: message.streamCursor,
46
+ channel: message.channel,
47
+ message_type: message.messageType,
48
+ event_type: message.eventType,
49
+ captured_by: message.capturedBy,
50
+ captured_at: message.capturedAt,
51
+ payload: message.payload,
52
+ };
53
+ });
54
+ const storeEventsQuery = QueryProvider.saveEvents(eventsToInsert);
55
+ const storeMessagesQuery = QueryProvider.saveMessages(messagesToInsert);
56
+ const transactItems = { TransactItems: [...storeEventsQuery, ...storeMessagesQuery] };
57
+ const command = new TransactWriteItemsCommand(transactItems);
58
+ await this.dynamoDbClient.send(command);
59
+ const numEvents = eventsToInsert.length;
60
+ const numMessages = messagesToInsert
61
+ .reduce((prev, { message_type: t }) => Object.assign(prev, { [t]: (prev[t] ?? 0) + 1 }), {});
62
+ return new StreamStoreAffected(numEvents, new Map(Object.entries(numMessages)));
63
+ }
64
+ catch (error) {
65
+ if (this.isOccException(error)) {
66
+ throw new Error('OPTIMISTIC_CONCURRENCY_VIOLATION');
67
+ }
68
+ throw error;
69
+ }
70
+ }
71
+ /**
72
+ * Store outbox messages in a transaction
73
+ */
74
+ async storeOutboxMessagesAsync(shardName, records) {
75
+ throw new Error('Method not implemented.');
76
+ }
77
+ /**
78
+ * Get the last offset for a stream
79
+ */
80
+ async getLastOffsetAsync(streamAddress) {
81
+ const query = QueryProvider.getLastOffset(streamAddress);
82
+ const response = await this.dynamoDbClient.send(query);
83
+ if (!response.Items) {
84
+ return -1;
85
+ }
86
+ return parseInt(response.Items[0]?.offset.N ?? '-1', 10);
87
+ }
88
+ /**
89
+ * Get events for a stream since a specific offset
90
+ */
91
+ async *getEventsAsync(streamCursor, pageSize = 100) {
92
+ let queryCursor = undefined;
93
+ do {
94
+ const getEventsCommand = QueryProvider.getEvents(streamCursor);
95
+ const response = await this.dynamoDbClient.send(getEventsCommand);
96
+ if (response.Items && response.Items.length > 0) {
97
+ for (const item of response.Items) {
98
+ const res = unmarshall(item);
99
+ const streamAddress = deserializeStreamAddress(res.stream_address);
100
+ const r = new EventRecord(crypto.randomUUID(), new EvDbStreamCursor(streamAddress.streamType, streamAddress.streamId, res.offset), res.event_type, res.captured_by, new Date(res.captured_at), res.payload, new Date(res.stored_at));
101
+ yield r.toEvDbEvent();
102
+ }
103
+ }
104
+ queryCursor = response.LastEvaluatedKey;
105
+ } while (queryCursor);
106
+ }
107
+ /**
108
+ * Get snapshot for a stream view
109
+ */
110
+ async getSnapshotAsync(viewAddress) {
111
+ const { streamType, streamId, viewName } = viewAddress;
112
+ try {
113
+ const query = QueryProvider.getSnapshot(viewAddress);
114
+ const response = await this.dynamoDbClient.send(query);
115
+ if (!response.Items) {
116
+ return EvDbStoredSnapshotResultRaw.Empty;
117
+ }
118
+ const snapshot = unmarshall(response.Items[0]);
119
+ return new EvDbStoredSnapshotResultRaw(snapshot.offset, new Date(Number(snapshot.stored_at)), snapshot.state);
120
+ }
121
+ catch (error) {
122
+ throw error;
123
+ }
124
+ }
125
+ /**
126
+ * Save a snapshot
127
+ */
128
+ async storeSnapshotAsync(record) {
129
+ try {
130
+ const command = QueryProvider.saveSnapshot(record);
131
+ await this.dynamoDbClient.send(command);
132
+ }
133
+ catch (error) {
134
+ throw error;
135
+ }
136
+ }
137
+ /**
138
+ * Check if an exception is an optimistic concurrency conflict
139
+ */
140
+ isOccException(error) {
141
+ if (!(error instanceof TransactionCanceledException)) {
142
+ return false;
143
+ }
144
+ return !!error
145
+ .CancellationReasons?.some(({ Code }) => Code === 'ConditionalCheckFailed');
146
+ }
147
+ /**
148
+ * Get table name for shard
149
+ */
150
+ getTableNameForShard(shardName) {
151
+ throw new Error('Method not implemented.');
152
+ }
153
+ /**
154
+ * Close the database connection
155
+ */
156
+ async close() {
157
+ return;
158
+ }
159
+ }
160
+ //# sourceMappingURL=EvDbDynamoDbStorageAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDbDynamoDbStorageAdapter.js","sourceRoot":"","sources":["../src/EvDbDynamoDbStorageAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import IEvDbEventPayload, { IEvDbPayloadData } from "@eventualize/types/IEvDbEventPayload";
2
+ import { PutItemCommand, QueryCommand, TransactWriteItem } from "@aws-sdk/client-dynamodb";
3
+ import EvDbStreamCursor from "@eventualize/types/EvDbStreamCursor";
4
+ import EvDbStreamAddress from "@eventualize/types/EvDbStreamAddress";
5
+ import EvDbEvent from "@eventualize/types/EvDbEvent";
6
+ import EvDbViewAddress from "@eventualize/types/EvDbViewAddress";
7
+ import { EvDbStoredSnapshotData } from "@eventualize/types/EvDbStoredSnapshotData";
8
+ export declare class EventRecord {
9
+ readonly id: string;
10
+ readonly stream_cursor: EvDbStreamCursor;
11
+ readonly event_type: string;
12
+ readonly captured_by: string;
13
+ readonly captured_at: Date;
14
+ readonly payload: IEvDbEventPayload;
15
+ readonly stored_at?: Date | undefined;
16
+ constructor(id: string, stream_cursor: EvDbStreamCursor, event_type: string, captured_by: string, captured_at: Date, payload: IEvDbEventPayload, stored_at?: Date | undefined);
17
+ static createFromEvent(e: EvDbEvent): EventRecord;
18
+ toEvDbEvent(): EvDbEvent;
19
+ }
20
+ export type MessageRecord = {
21
+ id: string;
22
+ stream_cursor: EvDbStreamCursor;
23
+ channel: string;
24
+ message_type: string;
25
+ event_type: string;
26
+ captured_by: string;
27
+ captured_at: Date;
28
+ payload: IEvDbPayloadData;
29
+ stored_at?: Date;
30
+ };
31
+ export declare const deserializeStreamAddress: (streamAddressStr: string) => EvDbStreamAddress;
32
+ export default class EvDbDynamoDbStorageAdapterQueries {
33
+ static saveEvents(events: EventRecord[]): TransactWriteItem[];
34
+ static saveMessages(messages: MessageRecord[]): TransactWriteItem[];
35
+ static getLastOffset(streamAddress: EvDbStreamAddress): QueryCommand;
36
+ static getEvents(streamCursor: EvDbStreamCursor, queryCursor?: Record<string, any> | undefined, pageSize?: number): QueryCommand;
37
+ static getSnapshot(viewAddress: EvDbViewAddress): QueryCommand;
38
+ static saveSnapshot(snapshot: EvDbStoredSnapshotData): PutItemCommand;
39
+ }
@@ -0,0 +1,159 @@
1
+ import { PutItemCommand, QueryCommand } from "@aws-sdk/client-dynamodb";
2
+ import EvDbStreamAddress from "@eventualize/types/EvDbStreamAddress";
3
+ import EvDbEvent from "@eventualize/types/EvDbEvent";
4
+ import EvDbViewAddress from "@eventualize/types/EvDbViewAddress";
5
+ import { marshall } from "@aws-sdk/util-dynamodb";
6
+ export class EventRecord {
7
+ constructor(id, stream_cursor, event_type, captured_by, captured_at, payload, stored_at) {
8
+ this.id = id;
9
+ this.stream_cursor = stream_cursor;
10
+ this.event_type = event_type;
11
+ this.captured_by = captured_by;
12
+ this.captured_at = captured_at;
13
+ this.payload = payload;
14
+ this.stored_at = stored_at;
15
+ }
16
+ static createFromEvent(e) {
17
+ return new EventRecord(crypto.randomUUID(), e.streamCursor, e.eventType, e.capturedBy, e.capturedAt, e.payload, e.storedAt);
18
+ }
19
+ toEvDbEvent() {
20
+ return new EvDbEvent(this.event_type, this.stream_cursor, this.payload, this.captured_at, this.captured_by, new Date(Number(this.stored_at)));
21
+ }
22
+ }
23
+ const serializeStreamAddress = (streamAddress) => {
24
+ return `${streamAddress.streamType}::${streamAddress.streamId}`;
25
+ };
26
+ export const deserializeStreamAddress = (streamAddressStr) => {
27
+ const [streamType, streamId] = streamAddressStr.split('::');
28
+ return new EvDbStreamAddress(streamType, streamId);
29
+ };
30
+ const serializeMessageAddress = (m) => {
31
+ return `${m.channel}::${m.message_type}`;
32
+ };
33
+ const serializeViewAddress = (viewAddress) => {
34
+ return `${serializeStreamAddress(viewAddress)}::${viewAddress.viewName}`;
35
+ };
36
+ export default class EvDbDynamoDbStorageAdapterQueries {
37
+ static saveEvents(events) {
38
+ const TransactItems = events.map(e => ({
39
+ Put: {
40
+ TableName: "events",
41
+ Item: {
42
+ stream_address: { S: serializeStreamAddress(e.stream_cursor) },
43
+ offset: { N: e.stream_cursor.offset.toString() },
44
+ event_type: { S: e.event_type },
45
+ captured_by: { S: e.captured_by },
46
+ captured_at: { S: e.captured_at.getTime().toString() },
47
+ payload: {
48
+ M: marshall(e.payload, {
49
+ convertClassInstanceToMap: true,
50
+ removeUndefinedValues: true
51
+ })
52
+ },
53
+ stored_at: { S: Date.now().toString() }
54
+ },
55
+ ConditionExpression: "(attribute_not_exists(#sa)) Or (attribute_exists(#sa) And attribute_not_exists(#offset))",
56
+ ExpressionAttributeNames: {
57
+ "#sa": "stream_address",
58
+ "#offset": "offset"
59
+ }
60
+ }
61
+ }));
62
+ return TransactItems;
63
+ }
64
+ static saveMessages(messages) {
65
+ const TransactItems = messages.map(m => ({
66
+ Put: {
67
+ TableName: "messages",
68
+ Item: {
69
+ message_address: { S: serializeMessageAddress(m) },
70
+ stream_address: { S: serializeStreamAddress(m.stream_cursor) },
71
+ offset: { N: m.stream_cursor.offset.toString() },
72
+ event_type: { S: m.event_type },
73
+ captured_by: { S: m.captured_by },
74
+ captured_at: { S: `${m.captured_at.getTime().toString()}::${crypto.randomUUID()}` },
75
+ payload: {
76
+ M: marshall(m.payload, {
77
+ convertClassInstanceToMap: true,
78
+ removeUndefinedValues: true
79
+ })
80
+ },
81
+ stored_at: { S: Date.now().toString() }
82
+ }
83
+ }
84
+ }));
85
+ return TransactItems;
86
+ }
87
+ static getLastOffset(streamAddress) {
88
+ const queryParams = {
89
+ TableName: "events",
90
+ KeyConditionExpression: "stream_address = :pk",
91
+ ExpressionAttributeValues: {
92
+ ":pk": { S: serializeStreamAddress(streamAddress) }
93
+ },
94
+ ScanIndexForward: false,
95
+ Limit: 1
96
+ };
97
+ return new QueryCommand(queryParams);
98
+ }
99
+ static getEvents(streamCursor, queryCursor = undefined, pageSize = 100) {
100
+ const queryParams = {
101
+ TableName: "events",
102
+ KeyConditionExpression: "#sa = :sa AND #o >= :offsetValue",
103
+ ExpressionAttributeNames: {
104
+ "#o": "offset",
105
+ "#sa": "stream_address",
106
+ "#cb": "captured_by"
107
+ },
108
+ ExpressionAttributeValues: {
109
+ ":sa": { S: serializeStreamAddress(streamCursor) },
110
+ ":offsetValue": { N: streamCursor.offset.toString() }
111
+ },
112
+ ProjectionExpression: '#sa, #o, id, event_type, captured_at, #cb, stored_at, payload',
113
+ Limit: pageSize,
114
+ ExclusiveStartKey: queryCursor
115
+ };
116
+ return new QueryCommand(queryParams);
117
+ }
118
+ static getSnapshot(viewAddress) {
119
+ const queryParams = {
120
+ TableName: "snapshots",
121
+ KeyConditionExpression: "view_address = :sa",
122
+ ExpressionAttributeValues: {
123
+ ":sa": { S: serializeViewAddress(viewAddress) },
124
+ },
125
+ ProjectionExpression: '#o, #s, stored_at',
126
+ ExpressionAttributeNames: {
127
+ "#o": "offset",
128
+ "#s": "state"
129
+ },
130
+ ScanIndexForward: false, // false = descending order
131
+ Limit: 1
132
+ };
133
+ return new QueryCommand(queryParams);
134
+ }
135
+ static saveSnapshot(snapshot) {
136
+ const viewAddress = new EvDbViewAddress(snapshot.streamType, snapshot.streamId, snapshot.viewName);
137
+ const queryParams = {
138
+ TableName: "snapshots",
139
+ Item: {
140
+ view_address: { S: serializeViewAddress(viewAddress) },
141
+ offset: { N: snapshot.offset.toString() },
142
+ state: {
143
+ M: marshall(snapshot.state, {
144
+ convertClassInstanceToMap: true,
145
+ removeUndefinedValues: true
146
+ })
147
+ },
148
+ stored_at: { S: Date.now().toString() }
149
+ },
150
+ ConditionExpression: "(attribute_not_exists(#va)) Or (attribute_exists(#va) And attribute_not_exists(#offset))",
151
+ ExpressionAttributeNames: {
152
+ "#va": "view_address",
153
+ "#offset": "offset"
154
+ }
155
+ };
156
+ return new PutItemCommand(queryParams);
157
+ }
158
+ }
159
+ //# sourceMappingURL=EvDbDynamoDbStorageAdapterQueries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDbDynamoDbStorageAdapterQueries.js","sourceRoot":"","sources":["../src/EvDbDynamoDbStorageAdapterQueries.ts"],"names":[],"mappings":"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"}