feat: version 2 beta
This commit is contained in:
196
types/adapter.ts
Normal file
196
types/adapter.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
import type { EventRecord } from "../libraries/event.ts";
|
||||
import type { EventReadOptions } from "./query.ts";
|
||||
|
||||
export type EventStoreAdapter<TDatabase> = {
|
||||
readonly db: TDatabase;
|
||||
readonly providers: {
|
||||
readonly events: EventsProvider;
|
||||
readonly relations: RelationsProvider;
|
||||
readonly snapshots: SnapshotsProvider;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Events Provider
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
export type EventsProvider = {
|
||||
/**
|
||||
* Insert a new event record to the events table.
|
||||
*
|
||||
* @param record - Event record to insert.
|
||||
*/
|
||||
insert(record: EventRecord): Promise<void>;
|
||||
|
||||
/**
|
||||
* Insert many new event records to the events table.
|
||||
*
|
||||
* @param records - Event records to insert.
|
||||
* @param batchSize - Batch size for the insert loop. Default: 1_000
|
||||
*/
|
||||
insertMany(records: EventRecord[], batchSize?: number): Promise<void>;
|
||||
|
||||
/**
|
||||
* Retrieve all the events in the events table. Optionally a cursor and direction
|
||||
* can be provided to reduce the list of events returned.
|
||||
*
|
||||
* @param options - Find options.
|
||||
*/
|
||||
get(options?: EventReadOptions): Promise<EventRecord[]>;
|
||||
|
||||
/**
|
||||
* Get events within the given stream.
|
||||
*
|
||||
* @param stream - Stream to fetch events for.
|
||||
* @param options - Read options for modifying the result.
|
||||
*/
|
||||
getByStream(stream: string, options?: EventReadOptions): Promise<EventRecord[]>;
|
||||
|
||||
/**
|
||||
* Get events within given list of streams.
|
||||
*
|
||||
* @param streams - Stream to get events for.
|
||||
* @param options - Read options for modifying the result.
|
||||
*/
|
||||
getByStreams(streams: string[], options?: EventReadOptions): Promise<EventRecord[]>;
|
||||
|
||||
/**
|
||||
* Get a single event by its id.
|
||||
*
|
||||
* @param id - Event id.
|
||||
*/
|
||||
getById(id: string): Promise<EventRecord | undefined>;
|
||||
|
||||
/**
|
||||
* Check if the given event is outdated in relation to the local event data.
|
||||
*/
|
||||
checkOutdated({ stream, type, created }: EventRecord): Promise<boolean>;
|
||||
};
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Relations
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
export type RelationsProvider = {
|
||||
/**
|
||||
* Handle incoming relation operations.
|
||||
*
|
||||
* @param relations - List of relation operations to execute.
|
||||
*/
|
||||
handle(relations: Relation[]): Promise<void>;
|
||||
|
||||
/**
|
||||
* Add stream to the relations table.
|
||||
*
|
||||
* @param key - Relational key to add stream to.
|
||||
* @param stream - Stream to add to the key.
|
||||
*/
|
||||
insert(key: string, stream: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Add stream to many relational keys onto the relations table.
|
||||
*
|
||||
* @param relations - Relations to insert.
|
||||
* @param batchSize - Batch size for the insert loop. Default: 1_000
|
||||
*/
|
||||
insertMany(relations: RelationPayload[], batchSize?: number): Promise<void>;
|
||||
|
||||
/**
|
||||
* Get a list of event streams registered under the given relational key.
|
||||
*
|
||||
* @param key - Relational key to get event streams for.
|
||||
*/
|
||||
getByKey(key: string): Promise<string[]>;
|
||||
|
||||
/**
|
||||
* Get a list of event streams registered under the given relational keys.
|
||||
*
|
||||
* @param keys - Relational keys to get event streams for.
|
||||
*/
|
||||
getByKeys(keys: string[]): Promise<string[]>;
|
||||
|
||||
/**
|
||||
* Removes a stream from the relational table.
|
||||
*
|
||||
* @param key - Relational key to remove stream from.
|
||||
* @param stream - Stream to remove from relation.
|
||||
*/
|
||||
remove(key: string, stream: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Removes multiple relational entries.
|
||||
*
|
||||
* @param relations - Relations to remove stream from.
|
||||
* @param batchSize - Batch size for the insert loop. Default: 1_000
|
||||
*/
|
||||
removeMany(relations: RelationPayload[], batchSize?: number): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove all relations bound to the given relational keys.
|
||||
*
|
||||
* @param keys - Relational keys to remove from the relational table.
|
||||
*/
|
||||
removeByKeys(keys: string[]): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove all relations bound to the given streams.
|
||||
*
|
||||
* @param streams - Streams to remove from the relational table.
|
||||
*/
|
||||
removeByStreams(streams: string[]): Promise<void>;
|
||||
};
|
||||
|
||||
export type RelationHandler<TRecord extends EventRecord> = (record: TRecord) => Promise<Omit<Relation, "stream">[]>;
|
||||
|
||||
export type RelationPayload = Omit<Relation, "op">;
|
||||
|
||||
export type Relation = {
|
||||
op: "insert" | "remove";
|
||||
key: string;
|
||||
stream: string;
|
||||
};
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Snapshots
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
export type SnapshotsProvider = {
|
||||
/**
|
||||
* Add snapshot state under given reducer stream.
|
||||
*
|
||||
* @param name - Name of the reducer the snapshot is attached to.
|
||||
* @param stream - Stream the snapshot is attached to.
|
||||
* @param cursor - Cursor timestamp for the last event used in the snapshot.
|
||||
* @param state - State of the reduced events.
|
||||
*/
|
||||
insert(name: string, stream: string, cursor: string, state: Record<string, unknown>): Promise<void>;
|
||||
|
||||
/**
|
||||
* Get snapshot state by stream.
|
||||
*
|
||||
* @param name - Name of the reducer which the state was created.
|
||||
* @param stream - Stream the state was reduced for.
|
||||
*/
|
||||
getByStream(name: string, stream: string): Promise<Snapshot | undefined>;
|
||||
|
||||
/**
|
||||
* Removes a snapshot for the given reducer stream.
|
||||
*
|
||||
* @param name - Name of the reducer the snapshot is attached to.
|
||||
* @param stream - Stream to remove from snapshots.
|
||||
*/
|
||||
remove(name: string, stream: string): Promise<void>;
|
||||
};
|
||||
|
||||
export type Snapshot = {
|
||||
stream: string;
|
||||
name: string;
|
||||
cursor: string;
|
||||
state: Record<string, unknown>;
|
||||
};
|
||||
32
types/common.ts
Normal file
32
types/common.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Represents an empty object.
|
||||
*/
|
||||
export type Empty = Record<string, never>;
|
||||
|
||||
/**
|
||||
* Represent an unknown object.
|
||||
*/
|
||||
export type Unknown = Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* Represents a subscription that exposes a way to unsubscribe.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* function subscribe(): Subscription {
|
||||
* const interval = setInterval(() => console.log("foo"), 1000);
|
||||
* return {
|
||||
* unsubscribe() {
|
||||
* clearInterval(interval);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export type Subscription = {
|
||||
/**
|
||||
* Gracefully terminate a decoupled subscriber.
|
||||
*/
|
||||
unsubscribe: () => void;
|
||||
};
|
||||
50
types/projector.ts
Normal file
50
types/projector.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import type { EventRecord } from "../libraries/event.ts";
|
||||
|
||||
export type BatchedProjectorListeners<TRecord extends EventRecord = EventRecord> = Record<string, Set<BatchedProjectorListenerFn<TRecord>> | undefined>;
|
||||
|
||||
export type ProjectorListeners<TRecord extends EventRecord = EventRecord> = Record<string, Set<ProjectorListenerFn<TRecord>> | undefined>;
|
||||
|
||||
export type ProjectorMessage<TRecord extends EventRecord = EventRecord> = {
|
||||
record: TRecord;
|
||||
status: ProjectionStatus;
|
||||
};
|
||||
|
||||
export type BatchedProjectorListenerFn<TRecord extends EventRecord = EventRecord> = (records: TRecord[]) => void;
|
||||
|
||||
export type ProjectorListenerFn<TRecord extends EventRecord = EventRecord> = (record: TRecord, status: ProjectionStatus) => void;
|
||||
|
||||
export type ProjectionHandler<TRecord extends EventRecord = EventRecord, TSuccessData extends Record<string, any> | void = void> = TSuccessData extends void
|
||||
? (record: TRecord) => Promise<void>
|
||||
: (record: TRecord) => Promise<TSuccessData>;
|
||||
|
||||
export type BatchedProjectionHandler<TRecord extends EventRecord = EventRecord> = (records: TRecord[]) => Promise<void>;
|
||||
|
||||
export type ProjectionStatus = {
|
||||
/**
|
||||
* Has the event run through projections previously. In which case we do
|
||||
* not want to re-run one time projections that should not execute during
|
||||
* replay events.
|
||||
*/
|
||||
hydrated: boolean;
|
||||
|
||||
/**
|
||||
* Is the incoming event older than another event of the same type in
|
||||
* the same stream.
|
||||
*/
|
||||
outdated: boolean;
|
||||
};
|
||||
|
||||
export type ProjectionFilter = {
|
||||
/**
|
||||
* Hydrated events represents events that are not seen for the first time
|
||||
* in the entirety of its lifetime across all distributed instances.
|
||||
*/
|
||||
allowHydratedEvents: boolean;
|
||||
|
||||
/**
|
||||
* Outdated events represents events that have already seen the same type
|
||||
* at a later occurrence. Eg. If incoming event is older than the latest
|
||||
* local event of the same type, it is considered outdated.
|
||||
*/
|
||||
allowOutdatedEvents: boolean;
|
||||
};
|
||||
72
types/query.ts
Normal file
72
types/query.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { Reducer } from "../libraries/reducer.ts";
|
||||
|
||||
export type ReduceQuery<TReducer extends Reducer> =
|
||||
| ({
|
||||
/**
|
||||
* Name of the reducer, must be a unique identifier as its used by snapshotter
|
||||
* to store, and manage state snapshots for event streams.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Stream to fetch events from and pass to the reducer method.
|
||||
*/
|
||||
stream: string;
|
||||
|
||||
/**
|
||||
* Reducer method to pass resolved events to.
|
||||
*/
|
||||
reducer: TReducer;
|
||||
|
||||
relation?: never;
|
||||
} & EventReadFilter)
|
||||
| ({
|
||||
/**
|
||||
* Name of the reducer, must be a unique identifier as its used by snapshotter
|
||||
* to store, and manage state snapshots for event streams.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Relational key resolving streams to fetch events from and pass to the
|
||||
* reducer method.
|
||||
*/
|
||||
relation: string;
|
||||
|
||||
/**
|
||||
* Reducer method to pass resolved events to.
|
||||
*/
|
||||
reducer: TReducer;
|
||||
|
||||
stream?: never;
|
||||
} & EventReadFilter);
|
||||
|
||||
export type EventReadOptions = EventReadFilter & {
|
||||
/**
|
||||
* Fetches events from the specific cursor, which uses the local event
|
||||
* records `recorded` timestamp.
|
||||
*/
|
||||
cursor?: string;
|
||||
|
||||
/**
|
||||
* Fetch events in ascending or descending order. Default: "asc"
|
||||
*/
|
||||
direction?: 1 | -1 | "asc" | "desc";
|
||||
|
||||
/**
|
||||
* Limit the number of events returned.
|
||||
*/
|
||||
limit?: number;
|
||||
};
|
||||
|
||||
export type EventReadFilter = {
|
||||
/**
|
||||
* Filter options for how events are pulled from the store.
|
||||
*/
|
||||
filter?: {
|
||||
/**
|
||||
* Only include events in the given types.
|
||||
*/
|
||||
types?: string[];
|
||||
};
|
||||
};
|
||||
5
types/utilities.ts
Normal file
5
types/utilities.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Empty } from "./common.ts";
|
||||
|
||||
export type ExcludeEmptyFields<T> = {
|
||||
[K in keyof T as T[K] extends Empty ? never : K]: T[K];
|
||||
};
|
||||
Reference in New Issue
Block a user