@eventualize/core 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,155 @@
1
+ import EvDbStreamCursor from '@eventualize/types/EvDbStreamCursor';
2
+ import EvDbStreamAddress from '@eventualize/types/EvDbStreamAddress';
3
+ import EvDbStream from './EvDbStream.js';
4
+ import { createViewFactory } from './EvDbViewFactory.js';
5
+ /**
6
+ * Stream Factory - creates stream instances with configured views and dynamic event methods
7
+ */
8
+ export class EvDbStreamFactory {
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.DynamicStreamClass = this.createDynamicStreamClass();
12
+ }
13
+ /**
14
+ * Creates a dynamic stream class with event-specific methods and view accessors
15
+ */
16
+ createDynamicStreamClass() {
17
+ const eventTypes = this.config.eventTypes;
18
+ const viewNames = this.config.viewNames;
19
+ const messagesProducer = (event, viewsState) => {
20
+ const eventType = eventTypes.find(e => e.eventName === event.eventType);
21
+ if (!eventType || !eventType.eventMessagesProducer)
22
+ return [];
23
+ return eventType.eventMessagesProducer(event, viewsState);
24
+ };
25
+ class DynamicStream extends EvDbStream {
26
+ constructor(streamType, views, streamStorageAdapter, streamId, lastStreamOffset) {
27
+ super(streamType, views, streamStorageAdapter, streamId, lastStreamOffset, messagesProducer);
28
+ this.views = {};
29
+ // Create view accessors
30
+ views.forEach((view, index) => {
31
+ const viewName = viewNames[index];
32
+ if (viewName) {
33
+ this.views[viewName] = view;
34
+ }
35
+ });
36
+ }
37
+ }
38
+ // Add dynamic methods for each event type
39
+ eventTypes.forEach(({ eventName }) => {
40
+ const methodName = `appendEvent${eventName}`;
41
+ DynamicStream.prototype[methodName] = async function (event) {
42
+ return this.appendEvent(event);
43
+ };
44
+ });
45
+ return DynamicStream;
46
+ }
47
+ /**
48
+ * Creates a stream instance with all configured views and dynamic event methods
49
+ */
50
+ create(streamId, streamStorageAdapter, snapshotStorageAdapter, lastStreamOffset = 0) {
51
+ const views = this.createViews(streamId, snapshotStorageAdapter);
52
+ return new this.DynamicStreamClass(this.config.streamType, views, streamStorageAdapter, streamId, lastStreamOffset);
53
+ }
54
+ createViews(streamId, snapshotStorageAdapter) {
55
+ const views = this.config.viewFactories.map(factory => factory.create(streamId, snapshotStorageAdapter));
56
+ return views;
57
+ }
58
+ getViews(streamId, snapshotStorageAdapter) {
59
+ const getViewPromises = this.config.viewFactories.map(viewFactory => viewFactory.get(streamId, snapshotStorageAdapter));
60
+ return getViewPromises;
61
+ }
62
+ /**
63
+ * Fetches from storage a stream instance with all configured views and dynamic event methods
64
+ */
65
+ async get(streamId, streamStorageAdapter, snapshotStorageAdapter) {
66
+ const streamAddress = new EvDbStreamAddress(this.config.streamType, streamId);
67
+ const views = await Promise.all(this.getViews(streamId, snapshotStorageAdapter));
68
+ if (!views.length) {
69
+ const lastStreamOffset = await streamStorageAdapter.getLastOffsetAsync(streamAddress);
70
+ const stream = this.create(streamId, streamStorageAdapter, snapshotStorageAdapter, lastStreamOffset);
71
+ return stream;
72
+ }
73
+ const lowestViewOffset = views.reduce((lowestOffset, currentView) => Math.min(lowestOffset, currentView.storeOffset), Number.MAX_VALUE);
74
+ const streamCursor = new EvDbStreamCursor(streamAddress, lowestViewOffset + 1);
75
+ const events = await streamStorageAdapter.getEventsAsync(streamCursor);
76
+ let streamOffset = lowestViewOffset;
77
+ for await (const event of events) {
78
+ views.forEach(view => view.applyEvent(event));
79
+ streamOffset = event.streamCursor.offset;
80
+ }
81
+ return new this.DynamicStreamClass(this.config.streamType, views, streamStorageAdapter, streamId, streamOffset);
82
+ }
83
+ getStreamType() {
84
+ return this.config.streamType;
85
+ }
86
+ }
87
+ /**
88
+ * Factory function to create a StreamFactory
89
+ */
90
+ export function createEvDbStreamFactory(config) {
91
+ return new EvDbStreamFactory(config);
92
+ }
93
+ /**
94
+ * Fluent builder for creating stream factories with inferred event types
95
+ */
96
+ export class StreamFactoryBuilder {
97
+ constructor(streamType) {
98
+ this.streamType = streamType;
99
+ this.viewFactories = [];
100
+ this.eventTypes = [];
101
+ this.viewNames = [];
102
+ }
103
+ /**
104
+ * Register event type for dynamic method generation - infers the event name from class name
105
+ */
106
+ withEventType(eventClass, eventMessagesProducer) {
107
+ // Use the class name as the event name
108
+ const eventName = eventClass.name;
109
+ this.eventTypes.push({ eventClass, eventName, eventMessagesProducer });
110
+ return this;
111
+ }
112
+ /**
113
+ * Add a view with inline handler definition
114
+ * This can only be called AFTER withEventType calls to ensure type safety
115
+ */
116
+ withView(viewName, stateClass, handlers) {
117
+ // Create default state instance
118
+ const defaultState = new stateClass();
119
+ // Create the view factory
120
+ const viewFactory = createViewFactory({
121
+ viewName,
122
+ streamType: this.streamType,
123
+ defaultState,
124
+ handlers
125
+ });
126
+ this.viewFactories.push(viewFactory);
127
+ this.viewNames.push(viewName);
128
+ return this;
129
+ }
130
+ /**
131
+ * Add a pre-created view factory (legacy support)
132
+ */
133
+ withViewFactory(viewName, viewFactory) {
134
+ this.viewFactories.push(viewFactory);
135
+ this.viewNames.push(viewName);
136
+ return this;
137
+ }
138
+ /**
139
+ * Build the stream factory
140
+ */
141
+ build() {
142
+ const factory = new EvDbStreamFactory({
143
+ streamType: this.streamType,
144
+ viewFactories: this.viewFactories,
145
+ eventTypes: this.eventTypes,
146
+ viewNames: this.viewNames
147
+ });
148
+ // Return factory with type helper for stream type extraction
149
+ return Object.assign(factory, {
150
+ // This is a type-only property for extracting the stream type
151
+ StreamType: null
152
+ });
153
+ }
154
+ }
155
+ //# sourceMappingURL=EvDbStreamFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDbStreamFactory.js","sourceRoot":"","sources":["../src/EvDbStreamFactory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import IEvDbViewStore, { IEvDbViewStoreGeneric } from "@eventualize/types/IEvDbViewStore";
2
+ import EvDbViewAddress from "@eventualize/types/EvDbViewAddress";
3
+ import IEvDbStorageSnapshotAdapter from "@eventualize/types/IEvDbStorageSnapshotAdapter";
4
+ import EvDbEvent from "@eventualize/types/src/EvDbEvent";
5
+ import { EvDbStoredSnapshotData } from "@eventualize/types/EvDbStoredSnapshotData";
6
+ import { EvDbStoredSnapshotResult } from "@eventualize/types/EvDbStoredSnapshotResult";
7
+ import IEvDbEventMetadata from "@eventualize/types/IEvDbEventMetadata";
8
+ import IEvDbEventPayload from "@eventualize/types/IEvDbEventPayload";
9
+ export declare abstract class EvDbViewRaw implements IEvDbViewStore {
10
+ private readonly _storageAdapter;
11
+ readonly address: EvDbViewAddress;
12
+ private _memoryOffset;
13
+ private _storeOffset;
14
+ private _storedAt;
15
+ protected constructor(_storageAdapter: IEvDbStorageSnapshotAdapter, address: EvDbViewAddress, snapshot: EvDbStoredSnapshotResult<any>);
16
+ abstract getSnapshotData(): EvDbStoredSnapshotData;
17
+ get storedAt(): Date;
18
+ get storeOffset(): number;
19
+ get memoryOffset(): number;
20
+ shouldStoreSnapshot(offsetGapFromLastSave: number, durationSinceLastSaveMs: number): boolean;
21
+ applyEvent(e: EvDbEvent): void;
22
+ store(): Promise<void>;
23
+ protected abstract onApplyEvent(e: EvDbEvent): void;
24
+ }
25
+ export declare abstract class EvDbView<TState> extends EvDbViewRaw implements IEvDbViewStoreGeneric<TState> {
26
+ readonly defaultState: TState;
27
+ protected getDefaultState(): TState;
28
+ protected _state: TState;
29
+ get state(): TState;
30
+ constructor(address: EvDbViewAddress, storageAdapter: IEvDbStorageSnapshotAdapter, snapshot: EvDbStoredSnapshotResult<TState>, defaultState: TState);
31
+ getSnapshotData(): EvDbStoredSnapshotData;
32
+ abstract handleOnApply(oldState: TState, event: IEvDbEventPayload, metadata: IEvDbEventMetadata): TState;
33
+ protected onApplyEvent(e: EvDbEvent): void;
34
+ }
@@ -0,0 +1,64 @@
1
+ import { EvDbStoredSnapshotData } from "@eventualize/types/EvDbStoredSnapshotData";
2
+ export class EvDbViewRaw {
3
+ constructor(_storageAdapter, address, snapshot) {
4
+ this._storageAdapter = _storageAdapter;
5
+ this.address = address;
6
+ const storeOffset = snapshot.offset ?? 0;
7
+ this._memoryOffset = storeOffset;
8
+ this._storeOffset = storeOffset;
9
+ this._storedAt = snapshot.storedAt ?? new Date();
10
+ }
11
+ get storedAt() { return this._storedAt; }
12
+ ;
13
+ get storeOffset() { return this._storeOffset; }
14
+ ;
15
+ get memoryOffset() { return this._memoryOffset; }
16
+ ;
17
+ shouldStoreSnapshot(offsetGapFromLastSave, durationSinceLastSaveMs) {
18
+ return true;
19
+ }
20
+ applyEvent(e) {
21
+ const offset = e.streamCursor.offset;
22
+ if (this.memoryOffset >= offset) {
23
+ return;
24
+ }
25
+ this.onApplyEvent(e);
26
+ this._memoryOffset = offset;
27
+ }
28
+ async store() {
29
+ const eventsSinceLatestSnapshot = this.memoryOffset - this.storeOffset;
30
+ const secondsSinceLatestSnapshot = new Date().getTime() - this.storedAt.getTime();
31
+ if (!this.shouldStoreSnapshot(eventsSinceLatestSnapshot, secondsSinceLatestSnapshot)) {
32
+ return;
33
+ }
34
+ const snapshotData = this.getSnapshotData();
35
+ await this._storageAdapter.storeSnapshotAsync(snapshotData);
36
+ this._storeOffset = this._memoryOffset;
37
+ }
38
+ }
39
+ export class EvDbView extends EvDbViewRaw {
40
+ getDefaultState() {
41
+ return this.defaultState;
42
+ }
43
+ ;
44
+ get state() { return this._state; }
45
+ // public getState(): TState {
46
+ // return this._state;
47
+ // }
48
+ constructor(address, storageAdapter, snapshot, defaultState) {
49
+ super(storageAdapter, address, snapshot);
50
+ this.defaultState = defaultState;
51
+ this._state = this.getDefaultState();
52
+ if (snapshot.offset === 0)
53
+ this._state = this.getDefaultState();
54
+ else
55
+ this._state = snapshot.state;
56
+ }
57
+ getSnapshotData() {
58
+ return EvDbStoredSnapshotData.fromAddress(this.address, this.memoryOffset, this.storeOffset, this._state);
59
+ }
60
+ onApplyEvent(e) {
61
+ this._state = this.handleOnApply(this._state, e.payload, e);
62
+ }
63
+ }
64
+ //# sourceMappingURL=EvDbView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDbView.js","sourceRoot":"","sources":["../src/EvDbView.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { EvDbView } from './EvDbView.js';
2
+ import IEvDbEventPayload from "@eventualize/types/IEvDbEventPayload";
3
+ import IEvDbEventMetadata from '@eventualize/types/IEvDbEventMetadata';
4
+ import IEvDbStorageSnapshotAdapter from '@eventualize/types/IEvDbStorageSnapshotAdapter';
5
+ /**
6
+ * Handler function type for applying an event to state
7
+ */
8
+ export type EvDbViewEventHandler<TState, TEvent extends IEvDbEventPayload> = (oldState: TState, event: TEvent, metadata: IEvDbEventMetadata) => TState;
9
+ /**
10
+ * Map of event handlers - one handler per event type in the union
11
+ * Key is the payloadType string, value is the handler function
12
+ */
13
+ export type EvDbStreamEventHandlersMap<TState, TEvents extends IEvDbEventPayload> = {
14
+ [K in TEvents['payloadType']]: EvDbViewEventHandler<TState, Extract<TEvents, {
15
+ payloadType: K;
16
+ }>>;
17
+ };
18
+ /**
19
+ * Configuration for creating a view
20
+ */
21
+ export interface ViewConfig<TState, TEvents extends IEvDbEventPayload> {
22
+ viewName: string;
23
+ streamType: string;
24
+ defaultState: TState;
25
+ handlers: Partial<EvDbStreamEventHandlersMap<TState, TEvents>>;
26
+ }
27
+ /**
28
+ * View Factory - creates view instances with the handlers map
29
+ */
30
+ export declare class ViewFactory<TState, TEvents extends IEvDbEventPayload> {
31
+ private readonly config;
32
+ constructor(config: ViewConfig<TState, TEvents>);
33
+ /**
34
+ * Creates a view instance
35
+ */
36
+ create(streamId: string, storageAdapter: IEvDbStorageSnapshotAdapter): EvDbView<TState>;
37
+ /**
38
+ * Get a view instance from event store
39
+ */
40
+ get(streamId: string, storageAdapter: IEvDbStorageSnapshotAdapter): Promise<EvDbView<TState>>;
41
+ }
42
+ /**
43
+ * Factory function to create a ViewFactory
44
+ */
45
+ export declare function createViewFactory<TState, TEvents extends IEvDbEventPayload>(config: ViewConfig<TState, TEvents>): ViewFactory<TState, TEvents>;
@@ -0,0 +1,58 @@
1
+ import { EvDbView } from './EvDbView.js';
2
+ import EvDbViewAddress from '@eventualize/types/EvDbViewAddress';
3
+ import EvDbStreamAddress from '@eventualize/types/EvDbStreamAddress';
4
+ import { EvDbStoredSnapshotResult } from '@eventualize/types/EvDbStoredSnapshotResult';
5
+ /**
6
+ * Generic View class that uses the handlers map
7
+ */
8
+ class GenericView extends EvDbView {
9
+ constructor(viewAddress, storageAdapter, snapshot, config) {
10
+ super(viewAddress, storageAdapter, snapshot, config.defaultState);
11
+ this.config = config;
12
+ this.config = config;
13
+ }
14
+ /**
15
+ * Dynamically applies events based on the handlers map
16
+ */
17
+ handleOnApply(oldState, event, metadata) {
18
+ const payloadType = event.payloadType;
19
+ const handler = this.config.handlers[payloadType];
20
+ if (!handler) {
21
+ // console.warn(`No handler found for event type: ${event.payloadType}`);
22
+ return oldState;
23
+ }
24
+ return handler(oldState, event, metadata);
25
+ }
26
+ }
27
+ /**
28
+ * View Factory - creates view instances with the handlers map
29
+ */
30
+ export class ViewFactory {
31
+ constructor(config) {
32
+ this.config = config;
33
+ }
34
+ /**
35
+ * Creates a view instance
36
+ */
37
+ create(streamId, storageAdapter) {
38
+ const streamAddress = new EvDbStreamAddress(this.config.streamType, streamId);
39
+ const viewAddress = new EvDbViewAddress(streamAddress, this.config.viewName);
40
+ return new GenericView(viewAddress, storageAdapter, EvDbStoredSnapshotResult.getEmptyState(), this.config);
41
+ }
42
+ /**
43
+ * Get a view instance from event store
44
+ */
45
+ async get(streamId, storageAdapter) {
46
+ const streamAddress = new EvDbStreamAddress(this.config.streamType, streamId);
47
+ const viewAddress = new EvDbViewAddress(streamAddress, this.config.viewName);
48
+ const snapshot = await storageAdapter.getSnapshotAsync(viewAddress);
49
+ return new GenericView(viewAddress, storageAdapter, snapshot, this.config);
50
+ }
51
+ }
52
+ /**
53
+ * Factory function to create a ViewFactory
54
+ */
55
+ export function createViewFactory(config) {
56
+ return new ViewFactory(config);
57
+ }
58
+ //# sourceMappingURL=EvDbViewFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvDbViewFactory.js","sourceRoot":"","sources":["../src/EvDbViewFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,eAAe,MAAM,oCAAoC,CAAC;AACjE,OAAO,iBAAiB,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AA+BvF;;GAEG;AACH,MAAM,WAAuD,SAAQ,QAAgB;IAEjF,YACI,WAA4B,EAC5B,cAA2C,EAC3C,QAA0C,EAC1B,MAAmC;QAEnD,KAAK,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QAFlD,WAAM,GAAN,MAAM,CAA6B;QAGnD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAGD;;OAEG;IACI,aAAa,CAAC,QAAgB,EAAE,KAAc,EAAE,QAA4B;QAC/E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAgD,CAAC;QAC3E,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,yEAAyE;YACzE,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAY,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,OAAO,WAAW;IACpB,YAA6B,MAAmC;QAAnC,WAAM,GAAN,MAAM,CAA6B;IAAI,CAAC;IAErE;;OAEG;IACI,MAAM,CACT,QAAgB,EAChB,cAA2C;QAE3C,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC9E,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE7E,OAAO,IAAI,WAAW,CAClB,WAAW,EACX,cAAc,EACd,wBAAwB,CAAC,aAAa,EAAU,EAChD,IAAI,CAAC,MAAM,CACd,CAAC;IACN,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,GAAG,CACZ,QAAgB,EAChB,cAA2C;QAE3C,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC9E,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE7E,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAEnE,OAAO,IAAI,WAAW,CAClB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,IAAI,CAAC,MAAM,CACd,CAAC;IACN,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAmC;IAEnC,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@eventualize/core",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ },
12
+ "./*": "./dist/*.js"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc --build",
16
+ "clean": "rimraf dist",
17
+ "rebuild": "npm run clean && npm run build",
18
+ "test": "echo not tests implemented yet."
19
+ },
20
+ "dependencies": {
21
+ "@eventualize/types": "1.0.0"
22
+ },
23
+ "license": "ISC",
24
+ "type": "module"
25
+ }