tapeworm_persistence_store_hybrid 1.0.1 → 1.0.2
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/HybridPartition.d.ts +22 -0
- package/dist/HybridPersistence.d.ts +38 -0
- package/dist/index.d.ts +3 -0
- package/dist/utils.d.ts +24 -0
- package/package.json +39 -39
- package/src/HybridPartition.ts +162 -0
- package/src/HybridPersistence.ts +82 -0
- package/src/index.ts +4 -0
- package/src/utils.ts +25 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import BluebirdPromise from 'bluebird';
|
|
2
|
+
import { Commit } from 'tapeworm';
|
|
3
|
+
import { LoggingOptions, Partition, queryStreamCallback, truncateStreamFromCallback } from './HybridPersistence';
|
|
4
|
+
import { Snapshot } from './utils';
|
|
5
|
+
declare class HybridPartition implements Partition {
|
|
6
|
+
private localPartition;
|
|
7
|
+
private remotePartition;
|
|
8
|
+
private snapshotLifeTime;
|
|
9
|
+
private loggingOptions;
|
|
10
|
+
constructor(localPartition: Partition, remotePartition: Partition, autoCleanLocalPartition: boolean, snapshotLifeTime: number, loggingOptions: LoggingOptions);
|
|
11
|
+
private cleanPartition;
|
|
12
|
+
open(): BluebirdPromise<this>;
|
|
13
|
+
append(commit: Commit<Record<string, any>>): BluebirdPromise<import("./utils").Commit<Record<string, any>>[]>;
|
|
14
|
+
storeSnapshot(streamId: string, snapshot: Snapshot, version: number): BluebirdPromise<void>;
|
|
15
|
+
private checkIsSnapshotToOld;
|
|
16
|
+
loadSnapshot(streamId: string, callback?: (err: Error, snapshot: Snapshot) => void): BluebirdPromise<Snapshot>;
|
|
17
|
+
queryStream(streamId: string, fromEventSequence?: number | queryStreamCallback, callback?: queryStreamCallback): BluebirdPromise<any[]>;
|
|
18
|
+
removeSnapshot(streamId: string): BluebirdPromise<void>;
|
|
19
|
+
truncateStreamFrom(streamId: string, commit: Commit<Record<string, any>>, remove: boolean | truncateStreamFromCallback, callback?: truncateStreamFromCallback): BluebirdPromise<void>;
|
|
20
|
+
applyCommitHeader(streamId: string, commit: Commit<Record<string, any>>, remove: any, callback: () => void): BluebirdPromise<void>;
|
|
21
|
+
}
|
|
22
|
+
export default HybridPartition;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import BluebirdPromise from 'bluebird';
|
|
2
|
+
import { Commit, Snapshot } from './utils';
|
|
3
|
+
export declare type truncateStreamFromCallback = (error: Error, result: Record<string, any>) => void;
|
|
4
|
+
declare type TruncateStreamFrom = (streamId: string, commitSequence: number, remove: boolean | truncateStreamFromCallback, callback?: truncateStreamFromCallback) => BluebirdPromise<void>;
|
|
5
|
+
export declare type queryStreamCallback = (err: Error, steam: Commit<Record<string, any>>[]) => void;
|
|
6
|
+
declare type QueryStream = (streamId: string, fromEventSequence?: number | queryStreamCallback, callback?: queryStreamCallback) => BluebirdPromise<Commit<Record<string, any>>[]>;
|
|
7
|
+
export declare type Partition = {
|
|
8
|
+
open: () => BluebirdPromise<Partition>;
|
|
9
|
+
storeSnapshot: (streamId: string, snapshot: Snapshot['snapshot'], version: number) => BluebirdPromise<void>;
|
|
10
|
+
loadSnapshot: (streamId: string, callback?: (err: Error, snapshot: Snapshot | undefined) => void) => BluebirdPromise<Snapshot | undefined>;
|
|
11
|
+
queryStream: QueryStream;
|
|
12
|
+
append: (commit: Commit<Record<string, any>>) => BluebirdPromise<Commit<Record<string, any>>[]>;
|
|
13
|
+
removeSnapshot: (streamId: string) => BluebirdPromise<void>;
|
|
14
|
+
removeSnapshots?: (streamIds: string[]) => BluebirdPromise<void>;
|
|
15
|
+
truncateStreamFrom: TruncateStreamFrom;
|
|
16
|
+
applyCommitHeader: (streamId: string, commit: Commit<Record<string, any>>, remove: any, callback: () => void) => BluebirdPromise<void>;
|
|
17
|
+
querySnapshotsOlderThanMaxDate?: (dateTime: string) => BluebirdPromise<Snapshot[]>;
|
|
18
|
+
};
|
|
19
|
+
export interface LoggingOptions {
|
|
20
|
+
loggingEnabled: boolean;
|
|
21
|
+
loadSnapshotMaxTime?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare type Persistence = {
|
|
24
|
+
openPartition: (partitionId?: string) => BluebirdPromise<Partition>;
|
|
25
|
+
};
|
|
26
|
+
declare class HybridPersistence {
|
|
27
|
+
private localPersistence;
|
|
28
|
+
private remotePersistence;
|
|
29
|
+
private autoCleanLocalPartition;
|
|
30
|
+
private snapshotLifeTime;
|
|
31
|
+
private loggingOptions;
|
|
32
|
+
private partitions;
|
|
33
|
+
constructor(localPersistence: Persistence, remotePersistence: Persistence, autoCleanLocalPartition: boolean, snapshotLifeTime: number, loggingOptions: LoggingOptions);
|
|
34
|
+
openPartition(partitionId?: string): BluebirdPromise<unknown>;
|
|
35
|
+
private getPartition;
|
|
36
|
+
private setPartition;
|
|
37
|
+
}
|
|
38
|
+
export default HybridPersistence;
|
package/dist/index.d.ts
ADDED
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface Event<Payload = Record<string, any>> {
|
|
2
|
+
type: string;
|
|
3
|
+
aggregateId: string;
|
|
4
|
+
correlationId: string;
|
|
5
|
+
payload: Payload;
|
|
6
|
+
id?: string;
|
|
7
|
+
dateTime?: string;
|
|
8
|
+
headers?: Record<string, any>;
|
|
9
|
+
version?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface Commit<Payload> {
|
|
12
|
+
id: string;
|
|
13
|
+
partitionId: string;
|
|
14
|
+
streamId: string;
|
|
15
|
+
commitSequence: number;
|
|
16
|
+
events: Event<Payload>[];
|
|
17
|
+
}
|
|
18
|
+
export interface Snapshot {
|
|
19
|
+
id: string;
|
|
20
|
+
version: number;
|
|
21
|
+
storedDateTime?: string;
|
|
22
|
+
snapshot?: Record<string, any>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "tapeworm_persistence_store_hybrid",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"prettier": "prettier-config-surikaterna",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"test": "jest",
|
|
10
|
-
"prepare": "npm test && npm run build",
|
|
11
|
-
"build": "tsc"
|
|
12
|
-
},
|
|
13
|
-
"repository": {
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/surikaterna/tapeworm_persistence_store_hybrid.git"
|
|
16
|
-
},
|
|
17
|
-
"author": "Gustav Albertsson",
|
|
18
|
-
"license": "ISC",
|
|
19
|
-
"bugs": {
|
|
20
|
-
"url": "https://github.com/surikaterna/tapeworm_persistence_store_hybrid/issues"
|
|
21
|
-
},
|
|
22
|
-
"homepage": "https://github.com/surikaterna/tapeworm_persistence_store_hybrid#readme",
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"@types/bluebird": "^3.5.36",
|
|
25
|
-
"@types/jest": "^27.0.1",
|
|
26
|
-
"fake-indexeddb": "^3.1.3",
|
|
27
|
-
"jest": "^27.3.1",
|
|
28
|
-
"prettier": "^2.3.2",
|
|
29
|
-
"prettier-config-surikaterna": "^1.0.1",
|
|
30
|
-
"tapeworm": "^0.3.5",
|
|
31
|
-
"tapeworm_persistence_store_indexeddb": "^0.2.6",
|
|
32
|
-
"ts-jest": "^27.0.5",
|
|
33
|
-
"typescript": "^4.4.2"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"bluebird": "^3.7.2",
|
|
37
|
-
"slf": "^1.0.3"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "tapeworm_persistence_store_hybrid",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"prettier": "prettier-config-surikaterna",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"prepare": "npm test && npm run build",
|
|
11
|
+
"build": "tsc"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/surikaterna/tapeworm_persistence_store_hybrid.git"
|
|
16
|
+
},
|
|
17
|
+
"author": "Gustav Albertsson",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/surikaterna/tapeworm_persistence_store_hybrid/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/surikaterna/tapeworm_persistence_store_hybrid#readme",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/bluebird": "^3.5.36",
|
|
25
|
+
"@types/jest": "^27.0.1",
|
|
26
|
+
"fake-indexeddb": "^3.1.3",
|
|
27
|
+
"jest": "^27.3.1",
|
|
28
|
+
"prettier": "^2.3.2",
|
|
29
|
+
"prettier-config-surikaterna": "^1.0.1",
|
|
30
|
+
"tapeworm": "^0.3.5",
|
|
31
|
+
"tapeworm_persistence_store_indexeddb": "^0.2.6",
|
|
32
|
+
"ts-jest": "^27.0.5",
|
|
33
|
+
"typescript": "^4.4.2"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"bluebird": "^3.7.2",
|
|
37
|
+
"slf": "^1.0.3"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import BluebirdPromise from 'bluebird';
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { Commit } from 'tapeworm';
|
|
4
|
+
import { LoggingOptions, Partition, queryStreamCallback, truncateStreamFromCallback } from './HybridPersistence';
|
|
5
|
+
import { LoggerFactory } from 'slf';
|
|
6
|
+
import { Snapshot } from './utils';
|
|
7
|
+
|
|
8
|
+
const log = LoggerFactory.getLogger('tapeworm-persistence-hybrid:hybrid-partition');
|
|
9
|
+
|
|
10
|
+
const DEFAULT_LOAD_SNAPSHOT_MAX_TIME = 10;
|
|
11
|
+
|
|
12
|
+
class HybridPartition implements Partition {
|
|
13
|
+
private loggingOptions: LoggingOptions;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param localPartition
|
|
17
|
+
* @param remotePartition
|
|
18
|
+
* @param autoCleanLocalPartition If set to true the partition will automatically clean out data older than dataLifeTime minutes dataLifeTime.
|
|
19
|
+
* @param snapshotLifeTime Number of minutes before data will be considered old.
|
|
20
|
+
* @param loggingOptions Options for logging
|
|
21
|
+
*/
|
|
22
|
+
constructor(
|
|
23
|
+
private localPartition: Partition,
|
|
24
|
+
private remotePartition: Partition,
|
|
25
|
+
autoCleanLocalPartition: boolean,
|
|
26
|
+
private snapshotLifeTime: number,
|
|
27
|
+
loggingOptions: LoggingOptions
|
|
28
|
+
) {
|
|
29
|
+
this.loggingOptions = loggingOptions;
|
|
30
|
+
if (!this.loggingOptions.loadSnapshotMaxTime) {
|
|
31
|
+
this.loggingOptions.loadSnapshotMaxTime = DEFAULT_LOAD_SNAPSHOT_MAX_TIME;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (autoCleanLocalPartition) {
|
|
35
|
+
if (!localPartition.querySnapshotsOlderThanMaxDate) {
|
|
36
|
+
throw new Error('Unable to start auto clean of local partition since it does not support it.');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
log.info('Starting auto clean of local partition');
|
|
40
|
+
setInterval(() => {
|
|
41
|
+
this.cleanPartition();
|
|
42
|
+
}, 1000 * 60 * 30); //Clean every 30 minutes
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private cleanPartition() {
|
|
47
|
+
log.info('Auto cleaning partition');
|
|
48
|
+
const snapshotTTLDate = new Date();
|
|
49
|
+
snapshotTTLDate.setMinutes(snapshotTTLDate.getMinutes() - this.snapshotLifeTime);
|
|
50
|
+
this.localPartition.querySnapshotsOlderThanMaxDate(snapshotTTLDate.toISOString()).then((snapshots) => {
|
|
51
|
+
log.info('cleaning %s snapshots', snapshots.length);
|
|
52
|
+
const snapshotIdsToRemove = snapshots.map((snapshot) => snapshot.id);
|
|
53
|
+
this.localPartition.removeSnapshots(snapshotIdsToRemove);
|
|
54
|
+
snapshotIdsToRemove.forEach((snapshotId) => this.localPartition.truncateStreamFrom(snapshotId, 0, true));
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
open() {
|
|
59
|
+
return BluebirdPromise.resolve(this);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
append(commit: Commit<Record<string, any>>) {
|
|
63
|
+
return this.localPartition.append(commit);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
storeSnapshot(streamId: string, snapshot: Snapshot, version: number) {
|
|
67
|
+
return this.localPartition.storeSnapshot(streamId, snapshot, version);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private checkIsSnapshotToOld(snapshot?: Snapshot) {
|
|
71
|
+
if (!snapshot) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (snapshot.storedDateTime) {
|
|
76
|
+
const storedDateEpoch = new Date(snapshot.storedDateTime).getTime();
|
|
77
|
+
const nowEpoch = new Date().getTime();
|
|
78
|
+
|
|
79
|
+
const elapsedTimeInMilliSeconds = nowEpoch - storedDateEpoch;
|
|
80
|
+
const snapshotLifetimeMilliSeconds = this.snapshotLifeTime * 60 * 1000;
|
|
81
|
+
|
|
82
|
+
return elapsedTimeInMilliSeconds > snapshotLifetimeMilliSeconds;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
loadSnapshot(streamId: string, callback?: (err: Error, snapshot: Snapshot) => void) {
|
|
89
|
+
const startTime = Date.now();
|
|
90
|
+
return new BluebirdPromise<Snapshot>((resolve) => {
|
|
91
|
+
this.localPartition.loadSnapshot(streamId).then((localSnapshot) => {
|
|
92
|
+
const isSnapshotToOld = this.checkIsSnapshotToOld(localSnapshot);
|
|
93
|
+
if (localSnapshot && !isSnapshotToOld) {
|
|
94
|
+
log.info('loadSnapshot: Using local snapshot');
|
|
95
|
+
callback?.(null, localSnapshot);
|
|
96
|
+
resolve(localSnapshot);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.remotePartition
|
|
101
|
+
.loadSnapshot(streamId)
|
|
102
|
+
.then((remoteSnapshot) => {
|
|
103
|
+
log.info('loadSnapshot: Using remote snapshot');
|
|
104
|
+
if (remoteSnapshot) {
|
|
105
|
+
this.localPartition.storeSnapshot(remoteSnapshot.id, remoteSnapshot.snapshot, remoteSnapshot.version);
|
|
106
|
+
this.localPartition.truncateStreamFrom(remoteSnapshot.id, 0, true);
|
|
107
|
+
}
|
|
108
|
+
callback?.(null, remoteSnapshot);
|
|
109
|
+
resolve(remoteSnapshot);
|
|
110
|
+
})
|
|
111
|
+
.catch((error) => {
|
|
112
|
+
log.warn('Failed to load snapshot with stream id %s from remote partition', streamId);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}).finally(() => {
|
|
116
|
+
const endTime = Date.now();
|
|
117
|
+
const queryTime = (endTime - startTime) / 1000;
|
|
118
|
+
if (this.loggingOptions.loggingEnabled && queryTime > this.loggingOptions.loadSnapshotMaxTime) {
|
|
119
|
+
log.warn('Loading snapshot with id %s, took %s seconds. Allowed max time is %s seconds.', streamId, queryTime, this.loggingOptions.loadSnapshotMaxTime);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
queryStream(streamId: string, fromEventSequence?: number | queryStreamCallback, callback?: queryStreamCallback) {
|
|
125
|
+
log.debug('queryStream, streamId %s ,fromEventSequence %s', streamId, fromEventSequence);
|
|
126
|
+
return new BluebirdPromise<Commit<Record<string, any>>[]>((resolve) => {
|
|
127
|
+
this.localPartition.loadSnapshot(streamId).then((localSnapshot) => {
|
|
128
|
+
let currentPartition = this.localPartition;
|
|
129
|
+
const isSnapshotToOld = this.checkIsSnapshotToOld(localSnapshot);
|
|
130
|
+
|
|
131
|
+
if (!localSnapshot || isSnapshotToOld) {
|
|
132
|
+
currentPartition = this.remotePartition;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
currentPartition.queryStream(streamId, fromEventSequence).then((queryStream) => {
|
|
136
|
+
callback?.(null, queryStream);
|
|
137
|
+
resolve(queryStream);
|
|
138
|
+
return;
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
removeSnapshot(streamId: string) {
|
|
145
|
+
return this.localPartition.removeSnapshot(streamId);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
truncateStreamFrom(
|
|
149
|
+
streamId: string,
|
|
150
|
+
commit: Commit<Record<string, any>>,
|
|
151
|
+
remove: boolean | truncateStreamFromCallback,
|
|
152
|
+
callback?: truncateStreamFromCallback
|
|
153
|
+
) {
|
|
154
|
+
return this.localPartition.truncateStreamFrom(streamId, commit, remove, callback);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
applyCommitHeader(streamId: string, commit: Commit<Record<string, any>>, remove: any, callback: () => void) {
|
|
158
|
+
return this.localPartition.applyCommitHeader(streamId, commit, remove, callback);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export default HybridPartition;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import BluebirdPromise from 'bluebird';
|
|
2
|
+
import HybridPartition from './HybridPartition';
|
|
3
|
+
import { Commit, Snapshot } from './utils';
|
|
4
|
+
|
|
5
|
+
export type truncateStreamFromCallback = (error: Error, result: Record<string, any>) => void;
|
|
6
|
+
type TruncateStreamFrom = (
|
|
7
|
+
streamId: string,
|
|
8
|
+
commitSequence: number,
|
|
9
|
+
remove: boolean | truncateStreamFromCallback,
|
|
10
|
+
callback?: truncateStreamFromCallback
|
|
11
|
+
) => BluebirdPromise<void>;
|
|
12
|
+
|
|
13
|
+
export type queryStreamCallback = (err: Error, steam: Commit<Record<string, any>>[]) => void;
|
|
14
|
+
type QueryStream = (
|
|
15
|
+
streamId: string,
|
|
16
|
+
fromEventSequence?: number | queryStreamCallback,
|
|
17
|
+
callback?: queryStreamCallback
|
|
18
|
+
) => BluebirdPromise<Commit<Record<string, any>>[]>;
|
|
19
|
+
|
|
20
|
+
export type Partition = {
|
|
21
|
+
open: () => BluebirdPromise<Partition>;
|
|
22
|
+
storeSnapshot: (streamId: string, snapshot: Snapshot['snapshot'], version: number) => BluebirdPromise<void>;
|
|
23
|
+
loadSnapshot: (streamId: string, callback?: (err: Error, snapshot: Snapshot | undefined) => void) => BluebirdPromise<Snapshot | undefined>;
|
|
24
|
+
queryStream: QueryStream;
|
|
25
|
+
append: (commit: Commit<Record<string, any>>) => BluebirdPromise<Commit<Record<string, any>>[]>;
|
|
26
|
+
removeSnapshot: (streamId: string) => BluebirdPromise<void>;
|
|
27
|
+
removeSnapshots?: (streamIds: string[]) => BluebirdPromise<void>;
|
|
28
|
+
truncateStreamFrom: TruncateStreamFrom;
|
|
29
|
+
applyCommitHeader: (streamId: string, commit: Commit<Record<string, any>>, remove: any, callback: () => void) => BluebirdPromise<void>;
|
|
30
|
+
querySnapshotsOlderThanMaxDate?: (dateTime: string) => BluebirdPromise<Snapshot[]>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export interface LoggingOptions {
|
|
34
|
+
loggingEnabled: boolean;
|
|
35
|
+
loadSnapshotMaxTime?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type Persistence = {
|
|
39
|
+
openPartition: (partitionId?: string) => BluebirdPromise<Partition>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const DEFAULT_PARTITION = 'master';
|
|
43
|
+
|
|
44
|
+
class HybridPersistence {
|
|
45
|
+
private partitions: Record<string, Partition> = {};
|
|
46
|
+
|
|
47
|
+
constructor(
|
|
48
|
+
private localPersistence: Persistence,
|
|
49
|
+
private remotePersistence: Persistence,
|
|
50
|
+
private autoCleanLocalPartition: boolean,
|
|
51
|
+
private snapshotLifeTime: number,
|
|
52
|
+
private loggingOptions: LoggingOptions
|
|
53
|
+
) {}
|
|
54
|
+
|
|
55
|
+
openPartition(partitionId: string = DEFAULT_PARTITION) {
|
|
56
|
+
return new BluebirdPromise(async (resolve) => {
|
|
57
|
+
const partition = this.getPartition(partitionId);
|
|
58
|
+
if (partition) {
|
|
59
|
+
resolve(partition);
|
|
60
|
+
} else {
|
|
61
|
+
const localPartition = await this.localPersistence.openPartition(partitionId);
|
|
62
|
+
const remotePartition = await this.remotePersistence.openPartition(partitionId);
|
|
63
|
+
const newPartition = new HybridPartition(localPartition, remotePartition, this.autoCleanLocalPartition, this.snapshotLifeTime, this.loggingOptions);
|
|
64
|
+
this.setPartition(partitionId, newPartition);
|
|
65
|
+
newPartition.open().then(() => {
|
|
66
|
+
resolve(newPartition);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private getPartition(partitionId: string = DEFAULT_PARTITION) {
|
|
73
|
+
return this.partitions[partitionId];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private setPartition(partitionId?: string, partition?: Partition) {
|
|
77
|
+
this.partitions[partitionId || DEFAULT_PARTITION] = partition;
|
|
78
|
+
return partition;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default HybridPersistence;
|
package/src/index.ts
ADDED
package/src/utils.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface Event<Payload = Record<string, any>> {
|
|
2
|
+
type: string;
|
|
3
|
+
aggregateId: string;
|
|
4
|
+
correlationId: string;
|
|
5
|
+
payload: Payload;
|
|
6
|
+
id?: string;
|
|
7
|
+
dateTime?: string;
|
|
8
|
+
headers?: Record<string, any>;
|
|
9
|
+
version?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface Commit<Payload> {
|
|
13
|
+
id: string;
|
|
14
|
+
partitionId: string;
|
|
15
|
+
streamId: string;
|
|
16
|
+
commitSequence: number;
|
|
17
|
+
events: Event<Payload>[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface Snapshot {
|
|
21
|
+
id: string;
|
|
22
|
+
version: number;
|
|
23
|
+
storedDateTime?: string;
|
|
24
|
+
snapshot?: Record<string, any>;
|
|
25
|
+
}
|