Skip to content

Commit 7bf96d4

Browse files
stepaniukmoskardudycz
authored andcommitted
Added basic inMemoryDatabase
1 parent 3eda928 commit 7bf96d4

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { JSONParser } from '../serialization';
2+
3+
export interface DocumentsCollection<T> {
4+
store: (id: string, obj: T) => void;
5+
delete: (id: string) => void;
6+
get: (id: string) => T | null;
7+
}
8+
9+
export type DocumentHandler<T> =
10+
| ((document: T | null) => T | null)
11+
| ((document: T | null) => Promise<T | null>);
12+
13+
export interface Database {
14+
collection: <T>(name: string) => DocumentsCollection<T>;
15+
}
16+
17+
export const getInMemoryDatabase = (): Database => {
18+
const storage = new Map<string, unknown>();
19+
20+
return {
21+
collection: <T>(
22+
collectionName: string,
23+
_collectionOptions: {
24+
errors?: { throwOnOperationFailures?: boolean } | undefined;
25+
} = {},
26+
): DocumentsCollection<T> => {
27+
const toFullId = (id: string) => `${collectionName}-${id}`;
28+
29+
const collection = {
30+
store: (id: string, obj: T): void => {
31+
storage.set(toFullId(id), obj);
32+
},
33+
delete: (id: string): void => {
34+
storage.delete(toFullId(id));
35+
},
36+
get: (id: string): T | null => {
37+
const result = storage.get(toFullId(id));
38+
39+
return result
40+
? // Clone to simulate getting new instance on loading
41+
(JSONParser.parse(JSONParser.stringify(result)) as T)
42+
: null;
43+
},
44+
};
45+
46+
return collection;
47+
},
48+
};
49+
};

src/packages/emmett/src/eventStore/inMemoryEventStore.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,27 @@ import {
1919
} from './eventStore';
2020
import { assertExpectedVersionMatchesCurrent } from './expectedVersion';
2121
import { StreamingCoordinator } from './subscriptions';
22+
import type { ProjectionRegistration } from '../projections';
2223

2324
export const InMemoryEventStoreDefaultStreamVersion = 0n;
2425

2526
export type InMemoryEventStore =
2627
EventStore<ReadEventMetadataWithGlobalPosition>;
2728

29+
export type InMemoryReadEventMetadata = ReadEventMetadataWithGlobalPosition;
30+
31+
export type InMemoryProjectionHandlerContext = {
32+
eventStore: InMemoryEventStore;
33+
};
34+
2835
export type InMemoryEventStoreOptions =
29-
DefaultEventStoreOptions<InMemoryEventStore>;
36+
DefaultEventStoreOptions<InMemoryEventStore> & {
37+
projections?: ProjectionRegistration<
38+
'inline',
39+
InMemoryReadEventMetadata,
40+
InMemoryProjectionHandlerContext
41+
>[];
42+
};
3043

3144
export type InMemoryReadEvent<EventType extends Event = Event> = ReadEvent<
3245
EventType,
@@ -48,6 +61,10 @@ export const getInMemoryEventStore = (
4861
.reduce((p, c) => p + c, 0);
4962
};
5063

64+
const _inlineProjections = (eventStoreOptions?.projections ?? [])
65+
.filter(({ type }) => type === 'inline')
66+
.map(({ projection }) => projection);
67+
5168
return {
5269
async aggregateStream<State, EventType extends Event>(
5370
streamName: string,

0 commit comments

Comments
 (0)