@eventualize/core 1.0.0 → 2.1.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.
- package/dist/EvDbStream.test.d.ts +1 -0
- package/dist/EvDbStream.test.js +21 -0
- package/dist/EvDbStream.test.js.map +1 -0
- package/dist/adapters/IEvDbStorageAdapter.d.ts +7 -0
- package/dist/adapters/IEvDbStorageAdapter.js +2 -0
- package/dist/adapters/IEvDbStorageAdapter.js.map +1 -0
- package/dist/codegen/generateStreamFactory.d.ts +18 -0
- package/dist/codegen/generateStreamFactory.js +97 -0
- package/dist/codegen/generateStreamFactory.js.map +1 -0
- package/dist/factories/EvDbStreamFactory.d.ts +50 -0
- package/dist/factories/EvDbStreamFactory.js +103 -0
- package/dist/factories/EvDbStreamFactory.js.map +1 -0
- package/dist/factories/EvDbStreamFactoryTypes.d.ts +20 -0
- package/dist/factories/EvDbStreamFactoryTypes.js +2 -0
- package/dist/factories/EvDbStreamFactoryTypes.js.map +1 -0
- package/dist/factories/EvDbViewFactory.d.ts +24 -0
- package/dist/{EvDbViewFactory.js → factories/EvDbViewFactory.js} +4 -4
- package/dist/factories/EvDbViewFactory.js.map +1 -0
- package/dist/factories/EvDbViewFactoryTypes.d.ts +24 -0
- package/dist/factories/EvDbViewFactoryTypes.js +2 -0
- package/dist/factories/EvDbViewFactoryTypes.js.map +1 -0
- package/dist/factories/StreamFactoryBuilder.d.ts +35 -0
- package/dist/factories/StreamFactoryBuilder.js +67 -0
- package/dist/factories/StreamFactoryBuilder.js.map +1 -0
- package/dist/store/EvDbEventStore.d.ts +68 -0
- package/dist/{EvDbEventStore.js → store/EvDbEventStore.js} +3 -94
- package/dist/store/EvDbEventStore.js.map +1 -0
- package/dist/store/EvDbEventStoreBuilder.d.ts +18 -0
- package/dist/store/EvDbEventStoreBuilder.js +44 -0
- package/dist/store/EvDbEventStoreBuilder.js.map +1 -0
- package/dist/store/EvDbEventStoreTypes.d.ts +11 -0
- package/dist/store/EvDbEventStoreTypes.js +2 -0
- package/dist/store/EvDbEventStoreTypes.js.map +1 -0
- package/dist/store/EvDbStream.d.ts +150 -0
- package/dist/store/EvDbStream.js +192 -0
- package/dist/store/EvDbStream.js.map +1 -0
- package/dist/stream/IEvDbStream.d.ts +0 -0
- package/dist/stream/IEvDbStream.js +2 -0
- package/dist/stream/IEvDbStream.js.map +1 -0
- package/dist/view/EvDbView.d.ts +19 -0
- package/dist/view/EvDbView.js +26 -0
- package/dist/view/EvDbView.js.map +1 -0
- package/dist/view/EvDbViewRaw.d.ts +22 -0
- package/dist/view/EvDbViewRaw.js +41 -0
- package/dist/view/EvDbViewRaw.js.map +1 -0
- package/package.json +18 -4
- package/dist/EvDbEventStore.d.ts +0 -123
- package/dist/EvDbEventStore.js.map +0 -1
- package/dist/EvDbStream.d.ts +0 -49
- package/dist/EvDbStream.js +0 -115
- package/dist/EvDbStream.js.map +0 -1
- package/dist/EvDbStreamFactory.d.ts +0 -97
- package/dist/EvDbStreamFactory.js +0 -155
- package/dist/EvDbStreamFactory.js.map +0 -1
- package/dist/EvDbView.d.ts +0 -34
- package/dist/EvDbView.js +0 -64
- package/dist/EvDbView.js.map +0 -1
- package/dist/EvDbViewFactory.d.ts +0 -45
- package/dist/EvDbViewFactory.js.map +0 -1
- package/src/EvDbEventStore.ts +0 -302
- package/src/EvDbStream.ts +0 -184
- package/src/EvDbStreamFactory.ts +0 -290
- package/src/EvDbView.ts +0 -100
- package/src/EvDbViewFactory.ts +0 -123
- package/tsconfig.json +0 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { test, describe } from "node:test";
|
|
2
|
+
import * as assert from "node:assert";
|
|
3
|
+
describe("EvDbStream", () => {
|
|
4
|
+
test("module can be imported", async () => {
|
|
5
|
+
const module = await import("./store/EvDbStream.js");
|
|
6
|
+
assert.ok(module.default, "EvDbStream should be exported as default");
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
describe("EvDbView", () => {
|
|
10
|
+
test("module can be imported", async () => {
|
|
11
|
+
const module = await import("./view/EvDbView.js");
|
|
12
|
+
assert.ok(module.EvDbView, "EvDbView should be exported");
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe("EvDbEventStore", () => {
|
|
16
|
+
test("module can be imported", async () => {
|
|
17
|
+
const module = await import("./store/EvDbEventStoreBuilder.js");
|
|
18
|
+
assert.ok(module.EvDbEventStoreBuilder, "EvDbEventStoreBuilder should be exported");
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=EvDbStream.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvDbStream.test.js","sourceRoot":"","sources":["../src/EvDbStream.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,0CAA0C,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAI,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;QAChE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,EAAE,0CAA0C,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type IEvDbStorageSnapshotAdapter from "@eventualize/types/adapters/IEvDbStorageSnapshotAdapter";
|
|
2
|
+
import type IEvDbStorageStreamAdapter from "@eventualize/types/adapters/IEvDbStorageStreamAdapter";
|
|
3
|
+
/**
|
|
4
|
+
* Combined storage adapter interface
|
|
5
|
+
*/
|
|
6
|
+
export interface IEvDbStorageAdapter extends IEvDbStorageStreamAdapter, IEvDbStorageSnapshotAdapter {
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IEvDbStorageAdapter.js","sourceRoot":"","sources":["../../src/adapters/IEvDbStorageAdapter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* EvDb Stream Factory Code Generator
|
|
4
|
+
*
|
|
5
|
+
* Scans a *Events/ directory, extracts `payloadType` literals from POCO event types,
|
|
6
|
+
* and regenerates the sibling *StreamFactory.ts file.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* tsx packages/core/src/codegen/generateStreamFactory.ts <events-dir> <stream-type>
|
|
10
|
+
*
|
|
11
|
+
* Example:
|
|
12
|
+
* tsx packages/core/src/codegen/generateStreamFactory.ts \
|
|
13
|
+
* apps/sample-app/src/eventstore/FundsStream/FundsEvents \
|
|
14
|
+
* funds-stream
|
|
15
|
+
*
|
|
16
|
+
* The generated factory file is written next to the events directory.
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* EvDb Stream Factory Code Generator
|
|
4
|
+
*
|
|
5
|
+
* Scans a *Events/ directory, extracts `payloadType` literals from POCO event types,
|
|
6
|
+
* and regenerates the sibling *StreamFactory.ts file.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* tsx packages/core/src/codegen/generateStreamFactory.ts <events-dir> <stream-type>
|
|
10
|
+
*
|
|
11
|
+
* Example:
|
|
12
|
+
* tsx packages/core/src/codegen/generateStreamFactory.ts \
|
|
13
|
+
* apps/sample-app/src/eventstore/FundsStream/FundsEvents \
|
|
14
|
+
* funds-stream
|
|
15
|
+
*
|
|
16
|
+
* The generated factory file is written next to the events directory.
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from "node:fs";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
/**
|
|
21
|
+
* Extracts the exported type/class name and its `payloadType` literal from a TS source file.
|
|
22
|
+
* Handles both:
|
|
23
|
+
* export type Foo = ... & { readonly payloadType: "Foo"; ... }
|
|
24
|
+
* export class Foo implements ... { readonly payloadType = "Foo"; }
|
|
25
|
+
*/
|
|
26
|
+
function extractEventInfo(filePath) {
|
|
27
|
+
const source = fs.readFileSync(filePath, "utf-8");
|
|
28
|
+
// Match: payloadType: "SomeLiteral" (type alias)
|
|
29
|
+
// or: payloadType = "SomeLiteral" (class property)
|
|
30
|
+
const payloadTypeMatch = source.match(/payloadType[:\s=]+["']([^"']+)["']/);
|
|
31
|
+
if (!payloadTypeMatch)
|
|
32
|
+
return null;
|
|
33
|
+
const payloadType = payloadTypeMatch[1];
|
|
34
|
+
// Match exported type or class name
|
|
35
|
+
const exportMatch = source.match(/export\s+(?:type|class)\s+(\w+)/);
|
|
36
|
+
if (!exportMatch)
|
|
37
|
+
return null;
|
|
38
|
+
const typeName = exportMatch[1];
|
|
39
|
+
return { typeName, payloadType, importPath: filePath };
|
|
40
|
+
}
|
|
41
|
+
function generateFactory(eventsDir, streamType) {
|
|
42
|
+
const absoluteEventsDir = path.resolve(eventsDir);
|
|
43
|
+
if (!fs.existsSync(absoluteEventsDir)) {
|
|
44
|
+
throw new Error(`Events directory not found: ${absoluteEventsDir}`);
|
|
45
|
+
}
|
|
46
|
+
const eventFiles = fs
|
|
47
|
+
.readdirSync(absoluteEventsDir)
|
|
48
|
+
.filter((f) => f.endsWith(".ts") && !f.endsWith(".test.ts"))
|
|
49
|
+
.map((f) => path.join(absoluteEventsDir, f));
|
|
50
|
+
const events = [];
|
|
51
|
+
for (const file of eventFiles) {
|
|
52
|
+
const info = extractEventInfo(file);
|
|
53
|
+
if (info)
|
|
54
|
+
events.push(info);
|
|
55
|
+
}
|
|
56
|
+
if (events.length === 0) {
|
|
57
|
+
throw new Error(`No event types found in: ${absoluteEventsDir}`);
|
|
58
|
+
}
|
|
59
|
+
// Determine output path: sibling of eventsDir named <ParentStream>Factory.ts
|
|
60
|
+
const parentDir = path.dirname(absoluteEventsDir);
|
|
61
|
+
const eventsDirName = path.basename(absoluteEventsDir); // e.g. "FundsEvents"
|
|
62
|
+
const streamName = eventsDirName.replace(/Events$/, ""); // e.g. "Funds"
|
|
63
|
+
const outputPath = path.join(parentDir, `${streamName}StreamFactory.ts`);
|
|
64
|
+
// Relative import paths from the factory file to each event file
|
|
65
|
+
const relativeEventsDir = `./${eventsDirName}`;
|
|
66
|
+
const imports = events
|
|
67
|
+
.map((e) => `import type { ${e.typeName} } from "${relativeEventsDir}/${e.typeName}.js";`)
|
|
68
|
+
.join("\n");
|
|
69
|
+
// Zero-arg withEvent calls — type inference only, Proxy handles runtime dispatch
|
|
70
|
+
const withEventCalls = events.map((e) => ` .withEvent<${e.typeName}>()`).join("\n");
|
|
71
|
+
const streamVarName = `${streamName}StreamFactory`;
|
|
72
|
+
const output = `// @generated by evdb-codegen — do not edit manually
|
|
73
|
+
// Source: ${path.relative(parentDir, absoluteEventsDir)}
|
|
74
|
+
import { StreamFactoryBuilder } from "@eventualize/core/factories/StreamFactoryBuilder";
|
|
75
|
+
${imports}
|
|
76
|
+
|
|
77
|
+
const ${streamVarName} = new StreamFactoryBuilder("${streamType}")
|
|
78
|
+
${withEventCalls}
|
|
79
|
+
.build();
|
|
80
|
+
|
|
81
|
+
export default ${streamVarName};
|
|
82
|
+
|
|
83
|
+
export type ${streamName}StreamType = typeof ${streamVarName}.StreamType;
|
|
84
|
+
`;
|
|
85
|
+
fs.writeFileSync(outputPath, output, "utf-8");
|
|
86
|
+
console.log(`Generated: ${outputPath}`);
|
|
87
|
+
events.forEach((e) => console.log(` - ${e.typeName} (payloadType: "${e.payloadType}")`));
|
|
88
|
+
}
|
|
89
|
+
// CLI entry point
|
|
90
|
+
const [eventsDir, streamType] = process.argv.slice(2);
|
|
91
|
+
if (!eventsDir || !streamType) {
|
|
92
|
+
console.error("Usage: tsx generateStreamFactory.ts <events-dir> <stream-type>\n" +
|
|
93
|
+
"Example: tsx generateStreamFactory.ts apps/sample-app/src/eventstore/FundsStream/FundsEvents funds-stream");
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
generateFactory(eventsDir, streamType);
|
|
97
|
+
//# sourceMappingURL=generateStreamFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateStreamFactory.js","sourceRoot":"","sources":["../../src/codegen/generateStreamFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type IEvDbStorageSnapshotAdapter from "@eventualize/types/adapters/IEvDbStorageSnapshotAdapter";
|
|
2
|
+
import type IEvDbStorageStreamAdapter from "@eventualize/types/adapters/IEvDbStorageStreamAdapter";
|
|
3
|
+
import type IEvDbEventPayload from "@eventualize/types/events/IEvDbEventPayload";
|
|
4
|
+
import EvDbStream from "../store/EvDbStream.js";
|
|
5
|
+
import type { EvDbView } from "../view/EvDbView.js";
|
|
6
|
+
import type { EvDbStreamFactoryConfig } from "./EvDbStreamFactoryTypes.js";
|
|
7
|
+
/**
|
|
8
|
+
* Type helper to extract event methods
|
|
9
|
+
*/
|
|
10
|
+
type EventMethods<TEvents extends IEvDbEventPayload> = {
|
|
11
|
+
[K in TEvents as `appendEvent${K["payloadType"]}`]: (event: Omit<K, "payloadType">) => Promise<void>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Type helper to create view accessors map
|
|
15
|
+
*/
|
|
16
|
+
type ViewAccessors<TViews extends Record<string, EvDbView<any>>> = {
|
|
17
|
+
readonly views: TViews;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Combined stream type with event methods and view accessors
|
|
21
|
+
*/
|
|
22
|
+
export type StreamWithEventMethods<TEvents extends IEvDbEventPayload, TViews extends Record<string, EvDbView<any>> = {}> = EvDbStream & EventMethods<TEvents> & ViewAccessors<TViews>;
|
|
23
|
+
/**
|
|
24
|
+
* Stream Factory - creates stream instances with configured views and dynamic event methods
|
|
25
|
+
*/
|
|
26
|
+
export declare class EvDbStreamFactory<TEvents extends IEvDbEventPayload, TStreamType extends string, TViews extends Record<string, EvDbView<any>> = {}> {
|
|
27
|
+
private readonly config;
|
|
28
|
+
private DynamicStreamClass;
|
|
29
|
+
constructor(config: EvDbStreamFactoryConfig<TEvents, TStreamType>);
|
|
30
|
+
/**
|
|
31
|
+
* Creates a dynamic stream class with event-specific methods and view accessors
|
|
32
|
+
*/
|
|
33
|
+
private createDynamicStreamClass;
|
|
34
|
+
/**
|
|
35
|
+
* Creates a stream instance with all configured views and dynamic event methods
|
|
36
|
+
*/
|
|
37
|
+
create(streamId: string, streamStorageAdapter: IEvDbStorageStreamAdapter, snapshotStorageAdapter?: IEvDbStorageSnapshotAdapter | undefined, lastStreamOffset?: number): StreamWithEventMethods<TEvents, TViews>;
|
|
38
|
+
private createViews;
|
|
39
|
+
private getViews;
|
|
40
|
+
/**
|
|
41
|
+
* Fetches from storage a stream instance with all configured views and dynamic event methods
|
|
42
|
+
*/
|
|
43
|
+
get(streamId: string, streamStorageAdapter: IEvDbStorageStreamAdapter, snapshotStorageAdapter?: IEvDbStorageSnapshotAdapter | undefined): Promise<StreamWithEventMethods<TEvents, TViews>>;
|
|
44
|
+
getStreamType(): TStreamType;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Factory function to create a StreamFactory
|
|
48
|
+
*/
|
|
49
|
+
export declare function createEvDbStreamFactory<TEvents extends IEvDbEventPayload, TStreamType extends string, TViews extends Record<string, EvDbView<any>> = {}>(config: EvDbStreamFactoryConfig<TEvents, TStreamType>): EvDbStreamFactory<TEvents, TStreamType, TViews>;
|
|
50
|
+
export type { EvDbStreamFactoryConfig, EventTypeConfig } from "./EvDbStreamFactoryTypes.js";
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import EvDbStreamCursor from "@eventualize/types/stream/EvDbStreamCursor";
|
|
2
|
+
import EvDbStreamAddress from "@eventualize/types/stream/EvDbStreamAddress";
|
|
3
|
+
import EvDbStream from "../store/EvDbStream.js";
|
|
4
|
+
/**
|
|
5
|
+
* Stream Factory - creates stream instances with configured views and dynamic event methods
|
|
6
|
+
*/
|
|
7
|
+
export class EvDbStreamFactory {
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.DynamicStreamClass = this.createDynamicStreamClass();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a dynamic stream class with event-specific methods and view accessors
|
|
14
|
+
*/
|
|
15
|
+
createDynamicStreamClass() {
|
|
16
|
+
const eventTypes = this.config.eventTypes;
|
|
17
|
+
const viewNames = this.config.viewNames;
|
|
18
|
+
const messagesProducer = (event, viewsState) => {
|
|
19
|
+
const eventType = eventTypes.find((e) => e.eventName === event.eventType);
|
|
20
|
+
if (!eventType || !eventType.eventMessagesProducer)
|
|
21
|
+
return [];
|
|
22
|
+
return eventType.eventMessagesProducer(event, viewsState);
|
|
23
|
+
};
|
|
24
|
+
class DynamicStream extends EvDbStream {
|
|
25
|
+
constructor(streamType, views, streamStorageAdapter, streamId, lastStreamOffset) {
|
|
26
|
+
super(streamType, views, streamStorageAdapter, streamId, lastStreamOffset, messagesProducer);
|
|
27
|
+
this.views = {};
|
|
28
|
+
// Create view accessors
|
|
29
|
+
views.forEach((view, index) => {
|
|
30
|
+
const viewName = viewNames[index];
|
|
31
|
+
if (viewName) {
|
|
32
|
+
this.views[viewName] = view;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Add dynamic methods for each event type
|
|
38
|
+
eventTypes.forEach(({ eventName, eventClass: _eventClass }) => {
|
|
39
|
+
const methodName = `appendEvent${eventName}`;
|
|
40
|
+
DynamicStream.prototype[methodName] = async function (event) {
|
|
41
|
+
return this.appendEvent({ ...event, payloadType: eventName });
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
return DynamicStream;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a stream instance with all configured views and dynamic event methods
|
|
48
|
+
*/
|
|
49
|
+
create(streamId, streamStorageAdapter, snapshotStorageAdapter = undefined, lastStreamOffset = 0) {
|
|
50
|
+
const views = snapshotStorageAdapter
|
|
51
|
+
? this.createViews(streamId, snapshotStorageAdapter)
|
|
52
|
+
: [];
|
|
53
|
+
return new this.DynamicStreamClass(this.config.streamType, views, streamStorageAdapter, streamId, lastStreamOffset);
|
|
54
|
+
}
|
|
55
|
+
createViews(streamId, snapshotStorageAdapter) {
|
|
56
|
+
const views = this.config.viewFactories.map((factory) => factory.create(streamId, snapshotStorageAdapter));
|
|
57
|
+
return views;
|
|
58
|
+
}
|
|
59
|
+
getViews(streamId, snapshotStorageAdapter) {
|
|
60
|
+
const getViewPromises = this.config.viewFactories.map((viewFactory) => viewFactory.get(streamId, snapshotStorageAdapter));
|
|
61
|
+
return getViewPromises;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetches from storage a stream instance with all configured views and dynamic event methods
|
|
65
|
+
*/
|
|
66
|
+
async get(streamId, streamStorageAdapter, snapshotStorageAdapter = undefined) {
|
|
67
|
+
const streamAddress = new EvDbStreamAddress(this.config.streamType, streamId);
|
|
68
|
+
const views = snapshotStorageAdapter
|
|
69
|
+
? await Promise.all(this.getViews(streamId, snapshotStorageAdapter))
|
|
70
|
+
: [];
|
|
71
|
+
if (!views.length) {
|
|
72
|
+
const lastStreamOffset = await streamStorageAdapter.getLastOffsetAsync(streamAddress);
|
|
73
|
+
const stream = this.create(streamId, streamStorageAdapter, snapshotStorageAdapter, lastStreamOffset);
|
|
74
|
+
return stream;
|
|
75
|
+
}
|
|
76
|
+
const lowestViewOffset = views.reduce((lowestOffset, currentView) => Math.min(lowestOffset, currentView.storeOffset), Number.MAX_VALUE);
|
|
77
|
+
let streamOffset = -1;
|
|
78
|
+
if (snapshotStorageAdapter) {
|
|
79
|
+
const streamCursor = new EvDbStreamCursor(streamAddress, lowestViewOffset + 1);
|
|
80
|
+
const events = await streamStorageAdapter.getEventsAsync(streamCursor);
|
|
81
|
+
streamOffset = lowestViewOffset;
|
|
82
|
+
for await (const event of events) {
|
|
83
|
+
views.forEach((view) => view.applyEvent(event));
|
|
84
|
+
streamOffset = event.streamCursor.offset;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
streamOffset = // TODO: get last offset from stream storage adapter if no snapshot adapter is provided
|
|
89
|
+
streamOffset = await streamStorageAdapter.getLastOffsetAsync(streamAddress);
|
|
90
|
+
}
|
|
91
|
+
return new this.DynamicStreamClass(this.config.streamType, views, streamStorageAdapter, streamId, streamOffset);
|
|
92
|
+
}
|
|
93
|
+
getStreamType() {
|
|
94
|
+
return this.config.streamType;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Factory function to create a StreamFactory
|
|
99
|
+
*/
|
|
100
|
+
export function createEvDbStreamFactory(config) {
|
|
101
|
+
return new EvDbStreamFactory(config);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=EvDbStreamFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvDbStreamFactory.js","sourceRoot":"","sources":["../../src/factories/EvDbStreamFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type IEvDbEventPayload from "@eventualize/types/events/IEvDbEventPayload";
|
|
2
|
+
import type EVDbMessagesProducer from "@eventualize/types/messages/EvDbMessagesProducer";
|
|
3
|
+
import type { ViewFactory } from "./EvDbViewFactory.js";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for creating a stream factory
|
|
6
|
+
*/
|
|
7
|
+
export interface EvDbStreamFactoryConfig<TEvents extends IEvDbEventPayload, TStreamType extends string> {
|
|
8
|
+
streamType: TStreamType;
|
|
9
|
+
viewFactories: ViewFactory<any, TEvents>[];
|
|
10
|
+
eventTypes: EventTypeConfig<TEvents>[];
|
|
11
|
+
viewNames: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for each event type
|
|
15
|
+
*/
|
|
16
|
+
export interface EventTypeConfig<TEvent extends IEvDbEventPayload> {
|
|
17
|
+
eventClass?: new (...args: any[]) => TEvent;
|
|
18
|
+
eventName: string;
|
|
19
|
+
eventMessagesProducer?: EVDbMessagesProducer;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvDbStreamFactoryTypes.js","sourceRoot":"","sources":["../../src/factories/EvDbStreamFactoryTypes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EvDbView } from "../view/EvDbView.js";
|
|
2
|
+
import type IEvDbEventPayload from "@eventualize/types/events/IEvDbEventPayload";
|
|
3
|
+
import type IEvDbStorageSnapshotAdapter from "@eventualize/types/adapters/IEvDbStorageSnapshotAdapter";
|
|
4
|
+
import type { ViewConfig } from "./EvDbViewFactoryTypes.js";
|
|
5
|
+
/**
|
|
6
|
+
* View Factory - creates view instances with the handlers map
|
|
7
|
+
*/
|
|
8
|
+
export declare class ViewFactory<TState, TEvents extends IEvDbEventPayload> {
|
|
9
|
+
private readonly config;
|
|
10
|
+
constructor(config: ViewConfig<TState, TEvents>);
|
|
11
|
+
/**
|
|
12
|
+
* Creates a view instance
|
|
13
|
+
*/
|
|
14
|
+
create(streamId: string, storageAdapter: IEvDbStorageSnapshotAdapter): EvDbView<TState>;
|
|
15
|
+
/**
|
|
16
|
+
* Get a view instance from event store
|
|
17
|
+
*/
|
|
18
|
+
get(streamId: string, storageAdapter: IEvDbStorageSnapshotAdapter): Promise<EvDbView<TState>>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Factory function to create a ViewFactory
|
|
22
|
+
*/
|
|
23
|
+
export declare function createViewFactory<TState, TEvents extends IEvDbEventPayload>(config: ViewConfig<TState, TEvents>): ViewFactory<TState, TEvents>;
|
|
24
|
+
export type { EvDbStreamEventHandlersMap, ViewConfig } from "./EvDbViewFactoryTypes.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { EvDbView } from
|
|
2
|
-
import EvDbViewAddress from
|
|
3
|
-
import EvDbStreamAddress from
|
|
4
|
-
import { EvDbStoredSnapshotResult } from
|
|
1
|
+
import { EvDbView } from "../view/EvDbView.js";
|
|
2
|
+
import EvDbViewAddress from "@eventualize/types/view/EvDbViewAddress";
|
|
3
|
+
import EvDbStreamAddress from "@eventualize/types/stream/EvDbStreamAddress";
|
|
4
|
+
import { EvDbStoredSnapshotResult } from "@eventualize/types/snapshots/EvDbStoredSnapshotResult";
|
|
5
5
|
/**
|
|
6
6
|
* Generic View class that uses the handlers map
|
|
7
7
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvDbViewFactory.js","sourceRoot":"","sources":["../../src/factories/EvDbViewFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAI/C,OAAO,eAAe,MAAM,yCAAyC,CAAC;AACtE,OAAO,iBAAiB,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AAGjG;;GAEG;AACH,MAAM,WAAuD,SAAQ,QAAgB;IACnF,YACE,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;IACvB,CAAC;IAED;;OAEG;IACI,aAAa,CAAC,QAAgB,EAAE,KAAc,EAAE,QAA4B;QACjF,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;YACb,yEAAyE;YACzE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,OAAO,OAAO,CAAC,QAAQ,EAAE,KAAY,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,WAAW;IACtB,YAA6B,MAAmC;QAAnC,WAAM,GAAN,MAAM,CAA6B;IAAG,CAAC;IAEpE;;OAEG;IACI,MAAM,CAAC,QAAgB,EAAE,cAA2C;QACzE,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,CACpB,WAAW,EACX,cAAc,EACd,wBAAwB,CAAC,aAAa,EAAU,EAChD,IAAI,CAAC,MAAM,CACZ,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,GAAG,CACd,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,CAAC;QAEpE,OAAO,IAAI,WAAW,CAAkB,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9F,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAmC;IAEnC,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type IEvDbEventPayload from "@eventualize/types/events/IEvDbEventPayload";
|
|
2
|
+
import type IEvDbEventMetadata from "@eventualize/types/events/IEvDbEventMetadata";
|
|
3
|
+
/**
|
|
4
|
+
* Handler function type for applying an event to state
|
|
5
|
+
*/
|
|
6
|
+
export type EvDbViewEventHandler<TState, TEvent extends IEvDbEventPayload> = (oldState: TState, event: TEvent, metadata: IEvDbEventMetadata) => TState;
|
|
7
|
+
/**
|
|
8
|
+
* Map of event handlers - one handler per event type in the union
|
|
9
|
+
* Key is the payloadType string, value is the handler function
|
|
10
|
+
*/
|
|
11
|
+
export type EvDbStreamEventHandlersMap<TState, TEvents extends IEvDbEventPayload> = {
|
|
12
|
+
[K in TEvents["payloadType"]]: EvDbViewEventHandler<TState, Extract<TEvents, {
|
|
13
|
+
payloadType: K;
|
|
14
|
+
}>>;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for creating a view
|
|
18
|
+
*/
|
|
19
|
+
export interface ViewConfig<TState, TEvents extends IEvDbEventPayload> {
|
|
20
|
+
viewName: string;
|
|
21
|
+
streamType: string;
|
|
22
|
+
defaultState: TState;
|
|
23
|
+
handlers: Partial<EvDbStreamEventHandlersMap<TState, TEvents>>;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EvDbViewFactoryTypes.js","sourceRoot":"","sources":["../../src/factories/EvDbViewFactoryTypes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type IEvDbEventPayload from "@eventualize/types/events/IEvDbEventPayload";
|
|
2
|
+
import type EVDbMessagesProducer from "@eventualize/types/messages/EvDbMessagesProducer";
|
|
3
|
+
import { EvDbStreamFactory } from "./EvDbStreamFactory.js";
|
|
4
|
+
import type { StreamWithEventMethods } from "./EvDbStreamFactory.js";
|
|
5
|
+
import type { ViewFactory, EvDbStreamEventHandlersMap } from "./EvDbViewFactory.js";
|
|
6
|
+
import type { EvDbView } from "../view/EvDbView.js";
|
|
7
|
+
/**
|
|
8
|
+
* Fluent builder for creating stream factories with inferred event types
|
|
9
|
+
*/
|
|
10
|
+
export declare class StreamFactoryBuilder<TStreamType extends string, TEvents extends IEvDbEventPayload = never, TViews extends Record<string, EvDbView<any>> = {}> {
|
|
11
|
+
private streamType;
|
|
12
|
+
private viewFactories;
|
|
13
|
+
private eventTypes;
|
|
14
|
+
private viewNames;
|
|
15
|
+
constructor(streamType: TStreamType);
|
|
16
|
+
/**
|
|
17
|
+
* Register event type for dynamic method generation - infers the event name from class name
|
|
18
|
+
*/
|
|
19
|
+
withEventType<TEvent extends IEvDbEventPayload>(eventClass: new (...args: any[]) => TEvent, eventMessagesProducer?: EVDbMessagesProducer): StreamFactoryBuilder<TStreamType, TEvents | TEvent, TViews>;
|
|
20
|
+
/**
|
|
21
|
+
* Add a view with inline handler definition
|
|
22
|
+
* This can only be called AFTER withEventType calls to ensure type safety
|
|
23
|
+
*/
|
|
24
|
+
withView<TViewName extends string, TState>(viewName: TViewName, defaultState: TState, handlers: EvDbStreamEventHandlersMap<TState, TEvents>): StreamFactoryBuilder<TStreamType, TEvents, TViews & Record<TViewName, EvDbView<TState>>>;
|
|
25
|
+
/**
|
|
26
|
+
* Add a pre-created view factory (legacy support)
|
|
27
|
+
*/
|
|
28
|
+
withViewFactory<TViewName extends string, TState>(viewName: TViewName, viewFactory: ViewFactory<TState, TEvents>): StreamFactoryBuilder<TStreamType, TEvents, TViews & Record<TViewName, EvDbView<TState>>>;
|
|
29
|
+
/**
|
|
30
|
+
* Build the stream factory using event types registered via `withEventType`.
|
|
31
|
+
*/
|
|
32
|
+
build(): EvDbStreamFactory<TEvents, TStreamType, TViews> & {
|
|
33
|
+
StreamType: StreamWithEventMethods<TEvents, TViews>;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { EvDbStreamFactory } from "./EvDbStreamFactory.js";
|
|
2
|
+
import { createViewFactory } from "./EvDbViewFactory.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fluent builder for creating stream factories with inferred event types
|
|
5
|
+
*/
|
|
6
|
+
export class StreamFactoryBuilder {
|
|
7
|
+
constructor(streamType) {
|
|
8
|
+
this.streamType = streamType;
|
|
9
|
+
this.viewFactories = [];
|
|
10
|
+
this.eventTypes = [];
|
|
11
|
+
this.viewNames = [];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Register event type for dynamic method generation - infers the event name from class name
|
|
15
|
+
*/
|
|
16
|
+
withEventType(eventClass, eventMessagesProducer) {
|
|
17
|
+
// Use the class name as the event name
|
|
18
|
+
const eventName = eventClass.name;
|
|
19
|
+
this.eventTypes.push({
|
|
20
|
+
eventClass,
|
|
21
|
+
eventName,
|
|
22
|
+
eventMessagesProducer,
|
|
23
|
+
});
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Add a view with inline handler definition
|
|
28
|
+
* This can only be called AFTER withEventType calls to ensure type safety
|
|
29
|
+
*/
|
|
30
|
+
withView(viewName, defaultState, handlers) {
|
|
31
|
+
// Create the view factory
|
|
32
|
+
const viewFactory = createViewFactory({
|
|
33
|
+
viewName,
|
|
34
|
+
streamType: this.streamType,
|
|
35
|
+
defaultState,
|
|
36
|
+
handlers,
|
|
37
|
+
});
|
|
38
|
+
this.viewFactories.push(viewFactory);
|
|
39
|
+
this.viewNames.push(viewName);
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Add a pre-created view factory (legacy support)
|
|
44
|
+
*/
|
|
45
|
+
withViewFactory(viewName, viewFactory) {
|
|
46
|
+
this.viewFactories.push(viewFactory);
|
|
47
|
+
this.viewNames.push(viewName);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the stream factory using event types registered via `withEventType`.
|
|
52
|
+
*/
|
|
53
|
+
build() {
|
|
54
|
+
const factory = new EvDbStreamFactory({
|
|
55
|
+
streamType: this.streamType,
|
|
56
|
+
viewFactories: this.viewFactories,
|
|
57
|
+
eventTypes: this.eventTypes,
|
|
58
|
+
viewNames: this.viewNames,
|
|
59
|
+
});
|
|
60
|
+
// Return factory with type helper for stream type extraction
|
|
61
|
+
return Object.assign(factory, {
|
|
62
|
+
// This is a type-only property for extracting the stream type
|
|
63
|
+
StreamType: null,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=StreamFactoryBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamFactoryBuilder.js","sourceRoot":"","sources":["../../src/factories/StreamFactoryBuilder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAS/B,YAAoB,UAAuB;QAAvB,eAAU,GAAV,UAAU,CAAa;QAJnC,kBAAa,GAAgC,EAAE,CAAC;QAChD,eAAU,GAA2B,EAAE,CAAC;QACxC,cAAS,GAAa,EAAE,CAAC;IAEa,CAAC;IAE/C;;OAEG;IACH,aAAa,CACX,UAA0C,EAC1C,qBAA4C;QAE5C,uCAAuC;QACvC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC;QAElC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,UAAU;YACV,SAAS;YACT,qBAAqB;SACK,CAAC,CAAC;QAC9B,OAAO,IAAW,CAAC;IACrB,CAAC;IAED;;;OAGG;IACI,QAAQ,CACb,QAAmB,EACnB,YAAoB,EACpB,QAAqD;QAErD,0BAA0B;QAC1B,MAAM,WAAW,GAAG,iBAAiB,CAAkB;YACrD,QAAQ;YACR,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY;YACZ,QAAQ;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,IAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,eAAe,CACpB,QAAmB,EACnB,WAAyC;QAEzC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,IAAW,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,KAAK;QACV,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC;YACpC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAoD,CAAC;QAEtD,6DAA6D;QAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE;YAC5B,8DAA8D;YAC9D,UAAU,EAAE,IAA0D;SACvE,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type EvDbStream from "./EvDbStream.js";
|
|
2
|
+
import type IEvDbStorageSnapshotAdapter from "@eventualize/types/adapters/IEvDbStorageSnapshotAdapter";
|
|
3
|
+
import type IEvDbStorageStreamAdapter from "@eventualize/types/adapters/IEvDbStorageStreamAdapter";
|
|
4
|
+
import type { EvDbStreamFactory } from "../factories/EvDbStreamFactory.js";
|
|
5
|
+
import type { StreamCreatorMethods } from "./EvDbEventStoreTypes.js";
|
|
6
|
+
/**
|
|
7
|
+
* Storage configuration - either separate adapters or combined
|
|
8
|
+
*/
|
|
9
|
+
interface StorageConfig {
|
|
10
|
+
streamAdapter: IEvDbStorageStreamAdapter;
|
|
11
|
+
snapshotAdapter: IEvDbStorageSnapshotAdapter;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Registry of stream factories by stream type
|
|
15
|
+
*/
|
|
16
|
+
interface StreamFactoryRegistry {
|
|
17
|
+
[streamType: string]: EvDbStreamFactory<any, any>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Store class - manages stream creation with configured adapters and factories
|
|
21
|
+
*/
|
|
22
|
+
export declare class BaseStore {
|
|
23
|
+
private readonly storage;
|
|
24
|
+
private readonly streamFactories;
|
|
25
|
+
constructor(storage: StorageConfig, streamFactories: StreamFactoryRegistry);
|
|
26
|
+
/**
|
|
27
|
+
* Create a stream instance by stream type and ID
|
|
28
|
+
*/
|
|
29
|
+
createStream(streamType: string, streamId: string): EvDbStream;
|
|
30
|
+
/**
|
|
31
|
+
* Get a stream instance from the event store by stream type and ID
|
|
32
|
+
*/
|
|
33
|
+
getStream(streamType: string, streamId: string): Promise<EvDbStream>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if a stream type is registered
|
|
36
|
+
*/
|
|
37
|
+
hasStreamType(streamType: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Get all registered stream types
|
|
40
|
+
*/
|
|
41
|
+
getStreamTypes(): string[];
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Type-safe store that knows about specific stream types
|
|
46
|
+
*/
|
|
47
|
+
export declare class EvDbEventStore<TStreamTypes extends Record<string, EvDbStreamFactory<any, any>>> {
|
|
48
|
+
private readonly store;
|
|
49
|
+
constructor(store: BaseStore);
|
|
50
|
+
/**
|
|
51
|
+
* Create a stream with type-safe stream type parameter (fallback method)
|
|
52
|
+
*/
|
|
53
|
+
createStream<K extends keyof TStreamTypes & string>(streamType: K, streamId: string): EvDbStream;
|
|
54
|
+
/**
|
|
55
|
+
* Fetch a stream from the event store with type-safe stream type parameter (fallback method)
|
|
56
|
+
*/
|
|
57
|
+
getStream<K extends keyof TStreamTypes & string>(streamType: K, streamId: string): Promise<EvDbStream>;
|
|
58
|
+
/**
|
|
59
|
+
* Create dynamic methods for each registered stream factory
|
|
60
|
+
*/
|
|
61
|
+
private createDynamicMethods;
|
|
62
|
+
/**
|
|
63
|
+
* Get the underlying store
|
|
64
|
+
*/
|
|
65
|
+
getStore(): BaseStore;
|
|
66
|
+
}
|
|
67
|
+
export type TypedStoreType<TStreamTypes extends Record<string, EvDbStreamFactory<any, any>>> = StreamCreatorMethods<TStreamTypes>;
|
|
68
|
+
export {};
|