Skip to content

Commit

Permalink
Added basic inMemoryDatabase
Browse files Browse the repository at this point in the history
  • Loading branch information
stepaniukm authored and oskardudycz committed Feb 11, 2025
1 parent 3eda928 commit 7bf96d4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
49 changes: 49 additions & 0 deletions src/packages/emmett/src/database/inMemoryDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { JSONParser } from '../serialization';

export interface DocumentsCollection<T> {
store: (id: string, obj: T) => void;
delete: (id: string) => void;
get: (id: string) => T | null;
}

export type DocumentHandler<T> =
| ((document: T | null) => T | null)
| ((document: T | null) => Promise<T | null>);

export interface Database {
collection: <T>(name: string) => DocumentsCollection<T>;
}

export const getInMemoryDatabase = (): Database => {
const storage = new Map<string, unknown>();

return {
collection: <T>(
collectionName: string,
_collectionOptions: {
errors?: { throwOnOperationFailures?: boolean } | undefined;
} = {},
): DocumentsCollection<T> => {
const toFullId = (id: string) => `${collectionName}-${id}`;

const collection = {
store: (id: string, obj: T): void => {
storage.set(toFullId(id), obj);
},
delete: (id: string): void => {
storage.delete(toFullId(id));
},
get: (id: string): T | null => {
const result = storage.get(toFullId(id));

return result
? // Clone to simulate getting new instance on loading
(JSONParser.parse(JSONParser.stringify(result)) as T)
: null;
},
};

return collection;
},
};
};
19 changes: 18 additions & 1 deletion src/packages/emmett/src/eventStore/inMemoryEventStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,27 @@ import {
} from './eventStore';
import { assertExpectedVersionMatchesCurrent } from './expectedVersion';
import { StreamingCoordinator } from './subscriptions';
import type { ProjectionRegistration } from '../projections';

export const InMemoryEventStoreDefaultStreamVersion = 0n;

export type InMemoryEventStore =
EventStore<ReadEventMetadataWithGlobalPosition>;

export type InMemoryReadEventMetadata = ReadEventMetadataWithGlobalPosition;

export type InMemoryProjectionHandlerContext = {
eventStore: InMemoryEventStore;
};

export type InMemoryEventStoreOptions =
DefaultEventStoreOptions<InMemoryEventStore>;
DefaultEventStoreOptions<InMemoryEventStore> & {
projections?: ProjectionRegistration<
'inline',
InMemoryReadEventMetadata,
InMemoryProjectionHandlerContext
>[];
};

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

const _inlineProjections = (eventStoreOptions?.projections ?? [])
.filter(({ type }) => type === 'inline')
.map(({ projection }) => projection);

return {
async aggregateStream<State, EventType extends Event>(
streamName: string,
Expand Down

0 comments on commit 7bf96d4

Please sign in to comment.