event-storage 0.7.2 → 0.9.1
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/README.md +51 -392
- package/index.js +2 -1
- package/package.json +28 -19
- package/src/Clock.js +20 -8
- package/src/Consumer.js +68 -18
- package/src/EventStore.js +305 -94
- package/src/EventStream.js +171 -17
- package/src/Index/ReadableIndex.js +33 -13
- package/src/Index/WritableIndex.js +33 -17
- package/src/IndexEntry.js +5 -1
- package/src/JoinEventStream.js +32 -30
- package/src/Partition/ReadOnlyPartition.js +1 -0
- package/src/Partition/ReadablePartition.js +201 -49
- package/src/Partition/WritablePartition.js +134 -61
- package/src/Storage/ReadOnlyStorage.js +6 -3
- package/src/Storage/ReadableStorage.js +147 -19
- package/src/Storage/WritableStorage.js +205 -27
- package/src/Watcher.js +38 -29
- package/src/WatchesFile.js +9 -8
- package/src/metadataUtil.js +79 -0
- package/src/util.js +102 -65
- package/test/Consumer.spec.js +0 -268
- package/test/EventStore.spec.js +0 -591
- package/test/EventStream.spec.js +0 -120
- package/test/Index.spec.js +0 -590
- package/test/JoinEventStream.spec.js +0 -113
- package/test/Partition.spec.js +0 -384
- package/test/Storage.spec.js +0 -955
- package/test/Watcher.spec.js +0 -131
package/test/Consumer.spec.js
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
const expect = require('expect.js');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const Storage = require('../src/Storage');
|
|
4
|
-
const Consumer = require('../src/Consumer');
|
|
5
|
-
|
|
6
|
-
const dataDirectory = __dirname + '/data';
|
|
7
|
-
|
|
8
|
-
describe('Consumer', function() {
|
|
9
|
-
|
|
10
|
-
let consumer, storage;
|
|
11
|
-
|
|
12
|
-
beforeEach(function () {
|
|
13
|
-
fs.emptyDirSync(dataDirectory);
|
|
14
|
-
storage = new Storage({ dataDirectory });
|
|
15
|
-
storage.ensureIndex('foobar', (doc) => doc.type === 'Foobar');
|
|
16
|
-
storage.ensureIndex('bazinga', (doc) => doc.type === 'Bazinga');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
afterEach(function () {
|
|
20
|
-
if (storage) {
|
|
21
|
-
storage.close();
|
|
22
|
-
}
|
|
23
|
-
storage = null;
|
|
24
|
-
consumer = null;
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('throws when instanciated without a storage', function() {
|
|
28
|
-
expect(() => new Consumer('foobar', 'consumer1')).to.throwError(/storage/);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('throws when instanciated without an index name', function() {
|
|
32
|
-
expect(() => new Consumer(storage)).to.throwError(/index name/);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('throws when instanciated without an identifier', function() {
|
|
36
|
-
expect(() => new Consumer(storage, 'foobar')).to.throwError(/identifier/);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('creates consumer directory if not existing', function() {
|
|
40
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
41
|
-
expect(fs.existsSync(dataDirectory + '/consumers')).to.be(true);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('cleans up failed write left-overs', function() {
|
|
45
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
46
|
-
consumer.stop();
|
|
47
|
-
fs.writeFileSync(consumer.fileName + '.1', 'failed write!');
|
|
48
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
49
|
-
expect(fs.existsSync(consumer.fileName + '.1')).to.be(false);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('emits event when catching up', function(done){
|
|
53
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
54
|
-
consumer.stop();
|
|
55
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
56
|
-
consumer.on('caught-up', () => {
|
|
57
|
-
expect(consumer.position).to.be(1);
|
|
58
|
-
done();
|
|
59
|
-
});
|
|
60
|
-
consumer.start();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('continues emitting data after catching up', function(done){
|
|
64
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
65
|
-
consumer.stop();
|
|
66
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
67
|
-
consumer.on('caught-up', () => {
|
|
68
|
-
expect(consumer.position).to.be(1);
|
|
69
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
70
|
-
storage.write({ type: 'Foobar', id: 3 });
|
|
71
|
-
});
|
|
72
|
-
let expected = 0;
|
|
73
|
-
consumer.on('data', document => {
|
|
74
|
-
expect(document.id).to.be(++expected);
|
|
75
|
-
if (document.id === 3) {
|
|
76
|
-
done();
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
consumer.start();
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('receives new documents as they are added', function(done){
|
|
83
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
84
|
-
let expected = 0;
|
|
85
|
-
consumer.on('data', document => {
|
|
86
|
-
expect(document.id).to.be(++expected);
|
|
87
|
-
if (document.id === 3) {
|
|
88
|
-
done();
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
92
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
93
|
-
storage.write({ type: 'Foobar', id: 3 });
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('can start from arbitrary position', function(done){
|
|
97
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1', 2);
|
|
98
|
-
let expected = 3;
|
|
99
|
-
consumer.on('data', document => {
|
|
100
|
-
expect(document.id).to.be(expected);
|
|
101
|
-
done();
|
|
102
|
-
});
|
|
103
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
104
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
105
|
-
storage.write({ type: 'Foobar', id: 3 });
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('stops when pushing fails', function(done){
|
|
109
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
110
|
-
consumer.on('caught-up', () => {
|
|
111
|
-
storage.write({type: 'Foobar', id: 1});
|
|
112
|
-
storage.write({type: 'Foobar', id: 2});
|
|
113
|
-
storage.write({type: 'Foobar', id: 3});
|
|
114
|
-
});
|
|
115
|
-
const push = consumer.push.bind(consumer);
|
|
116
|
-
consumer.push = (doc) => push(doc) && false;
|
|
117
|
-
consumer.on('data', document => {
|
|
118
|
-
expect(document.id).to.be(1);
|
|
119
|
-
setTimeout(done, 10);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('ignores events on other streams', function(done){
|
|
124
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
125
|
-
consumer.on('caught-up', () => {
|
|
126
|
-
storage.write({type: 'Foobar', id: 1});
|
|
127
|
-
storage.write({type: 'Foobar', id: 2});
|
|
128
|
-
storage.write({type: 'Bazinga', id: 3});
|
|
129
|
-
});
|
|
130
|
-
let expected = 0;
|
|
131
|
-
consumer.on('data', document => {
|
|
132
|
-
expect(document.id).to.be(++expected);
|
|
133
|
-
if (document.id === 2) {
|
|
134
|
-
setTimeout(done, 10);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('works with multiple consumers', function(done){
|
|
140
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
141
|
-
consumer.on('caught-up', () => {
|
|
142
|
-
storage.write({type: 'Foobar', id: 1});
|
|
143
|
-
storage.write({type: 'Foobar', id: 2});
|
|
144
|
-
storage.write({type: 'Bazinga', id: 3});
|
|
145
|
-
});
|
|
146
|
-
const consumer2 = new Consumer(storage, 'bazinga', 'consumer2');
|
|
147
|
-
let expected = 0;
|
|
148
|
-
consumer.on('data', document => {
|
|
149
|
-
expect(document.id).to.be(++expected);
|
|
150
|
-
if (document.id === 2) {
|
|
151
|
-
consumer2.on('data', document => {
|
|
152
|
-
expect(document.id).to.be(++expected);
|
|
153
|
-
done();
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('continues from last position after restart', function(done){
|
|
160
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
161
|
-
let expected = 0;
|
|
162
|
-
consumer.on('data', document => {
|
|
163
|
-
expect(document.id).to.be(++expected);
|
|
164
|
-
if (document.id === 3) {
|
|
165
|
-
consumer.stop();
|
|
166
|
-
storage.write({ type: 'Foobar', id: 4 });
|
|
167
|
-
storage.write({ type: 'Foobar', id: 5 }, () => {
|
|
168
|
-
expect(consumer.position).to.be(3);
|
|
169
|
-
consumer.start();
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
if (document.id === 5) {
|
|
173
|
-
done();
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
177
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
178
|
-
storage.write({ type: 'Foobar', id: 3 });
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('will automatically start consuming when registering data listener', function(done){
|
|
182
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
183
|
-
let expected = 0;
|
|
184
|
-
//consumer.stop();
|
|
185
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
186
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
187
|
-
storage.write({ type: 'Foobar', id: 3 }, () => {
|
|
188
|
-
expect(consumer.position).to.be(0);
|
|
189
|
-
|
|
190
|
-
consumer.on('data', document => {
|
|
191
|
-
expect(document.id).to.be(++expected);
|
|
192
|
-
if (document.id === 3) {
|
|
193
|
-
done();
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('can stop during catching up', function(done){
|
|
200
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
201
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
202
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
203
|
-
storage.write({ type: 'Foobar', id: 3 }, () => {
|
|
204
|
-
expect(consumer.position).to.be(0);
|
|
205
|
-
consumer.start();
|
|
206
|
-
consumer.stop();
|
|
207
|
-
|
|
208
|
-
consumer.on('data', document => {
|
|
209
|
-
expect(this).to.be(false);
|
|
210
|
-
});
|
|
211
|
-
setTimeout(done, 10);
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it('stops when push fails during catching up', function(done){
|
|
216
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
217
|
-
const push = consumer.push.bind(consumer);
|
|
218
|
-
consumer.push = (doc) => push(doc) && false;
|
|
219
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
220
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
221
|
-
storage.write({ type: 'Foobar', id: 3 }, () => {
|
|
222
|
-
expect(consumer.position).to.be(0);
|
|
223
|
-
|
|
224
|
-
consumer.on('data', document => {
|
|
225
|
-
expect(document.id).to.be(1);
|
|
226
|
-
setTimeout(done, 10);
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it('starting manually is no-op after registering data listener', function(done){
|
|
232
|
-
consumer = new Consumer(storage, 'foobar', 'consumer1');
|
|
233
|
-
let expected = 0;
|
|
234
|
-
consumer.on('data', document => {
|
|
235
|
-
expect(document.id).to.be(++expected);
|
|
236
|
-
if (document.id === 3) {
|
|
237
|
-
done();
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
consumer.start();
|
|
241
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
242
|
-
storage.write({ type: 'Foobar', id: 2 });
|
|
243
|
-
storage.write({ type: 'Foobar', id: 3 });
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
it('throws when calling setState outside of document handler', function() {
|
|
247
|
-
consumer = new Consumer(storage, 'foobar', 'consumer-1');
|
|
248
|
-
expect(() => consumer.setState({ foo: 'bar' })).to.throwError();
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('restores state after reopening', function(done) {
|
|
252
|
-
const state = { foo: 0, bar: 'baz' };
|
|
253
|
-
consumer = new Consumer(storage, 'foobar', 'consumer-1');
|
|
254
|
-
consumer.on('data', (document) => {
|
|
255
|
-
const newState = {...state, foo: state.foo + 1, lastId: document.id};
|
|
256
|
-
consumer.setState(newState);
|
|
257
|
-
consumer.once('persisted', () => {
|
|
258
|
-
consumer = new Consumer(storage, 'foobar', 'consumer-1');
|
|
259
|
-
expect(consumer.state.foo).to.be(1);
|
|
260
|
-
done();
|
|
261
|
-
});
|
|
262
|
-
consumer.stop();
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
storage.write({ type: 'Foobar', id: 1 });
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
});
|