tapeworm 0.5.0 → 0.6.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +22 -22
  3. package/README.md +332 -332
  4. package/biome.json +58 -0
  5. package/dist/index.d.ts +5 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +20 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/src/dispatch/dispatch_service.d.ts +8 -0
  10. package/dist/src/dispatch/dispatch_service.d.ts.map +1 -0
  11. package/dist/src/dispatch/dispatch_service.js +9 -0
  12. package/dist/src/dispatch/dispatch_service.js.map +1 -0
  13. package/dist/src/event.d.ts +10 -0
  14. package/dist/src/event.d.ts.map +1 -0
  15. package/dist/src/event.js +12 -0
  16. package/dist/src/event.js.map +1 -0
  17. package/dist/src/event_store.d.ts +29 -0
  18. package/dist/src/event_store.d.ts.map +1 -0
  19. package/dist/src/event_store.js +71 -0
  20. package/dist/src/event_store.js.map +1 -0
  21. package/dist/src/event_store_partition.d.ts +28 -0
  22. package/dist/src/event_store_partition.d.ts.map +1 -0
  23. package/dist/src/event_store_partition.js +130 -0
  24. package/dist/src/event_store_partition.js.map +1 -0
  25. package/dist/src/event_stream.d.ts +32 -0
  26. package/dist/src/event_stream.d.ts.map +1 -0
  27. package/dist/src/event_stream.js +142 -0
  28. package/dist/src/event_stream.js.map +1 -0
  29. package/dist/src/persistence/commit.d.ts +4 -0
  30. package/dist/src/persistence/commit.d.ts.map +1 -0
  31. package/dist/src/persistence/commit.js +11 -0
  32. package/dist/src/persistence/commit.js.map +1 -0
  33. package/dist/src/persistence/concurrency_error.d.ts +6 -0
  34. package/dist/src/persistence/concurrency_error.d.ts.map +1 -0
  35. package/dist/src/persistence/concurrency_error.js +13 -0
  36. package/dist/src/persistence/concurrency_error.js.map +1 -0
  37. package/dist/src/persistence/duplicate_commit_error.d.ts +6 -0
  38. package/dist/src/persistence/duplicate_commit_error.d.ts.map +1 -0
  39. package/dist/src/persistence/duplicate_commit_error.js +13 -0
  40. package/dist/src/persistence/duplicate_commit_error.js.map +1 -0
  41. package/dist/src/persistence/inmemory/inmemory_partition.d.ts +23 -0
  42. package/dist/src/persistence/inmemory/inmemory_partition.d.ts.map +1 -0
  43. package/dist/src/persistence/inmemory/inmemory_partition.js +138 -0
  44. package/dist/src/persistence/inmemory/inmemory_partition.js.map +1 -0
  45. package/dist/src/persistence/inmemory/inmemory_persistence.d.ts +13 -0
  46. package/dist/src/persistence/inmemory/inmemory_persistence.d.ts.map +1 -0
  47. package/dist/src/persistence/inmemory/inmemory_persistence.js +26 -0
  48. package/dist/src/persistence/inmemory/inmemory_persistence.js.map +1 -0
  49. package/dist/src/persistence/persistence_partition.d.ts +12 -0
  50. package/dist/src/persistence/persistence_partition.d.ts.map +1 -0
  51. package/dist/src/persistence/persistence_partition.js +21 -0
  52. package/dist/src/persistence/persistence_partition.js.map +1 -0
  53. package/dist/src/persistence/persistence_provider_template.d.ts +10 -0
  54. package/dist/src/persistence/persistence_provider_template.d.ts.map +1 -0
  55. package/dist/src/persistence/persistence_provider_template.js +11 -0
  56. package/dist/src/persistence/persistence_provider_template.js.map +1 -0
  57. package/dist/src/replication/master_replication_service.d.ts +7 -0
  58. package/dist/src/replication/master_replication_service.d.ts.map +1 -0
  59. package/dist/src/replication/master_replication_service.js +9 -0
  60. package/dist/src/replication/master_replication_service.js.map +1 -0
  61. package/dist/src/types.d.ts +68 -0
  62. package/dist/src/types.d.ts.map +1 -0
  63. package/dist/src/types.js +3 -0
  64. package/dist/src/types.js.map +1 -0
  65. package/index.ts +21 -0
  66. package/package.json +44 -46
  67. package/scripts/postbuild.js +27 -0
  68. package/src/dispatch/dispatch_service.ts +14 -0
  69. package/src/event.ts +24 -0
  70. package/src/event_store.ts +82 -0
  71. package/src/event_store_partition.ts +270 -0
  72. package/src/event_stream.ts +184 -0
  73. package/src/persistence/commit.ts +24 -0
  74. package/src/persistence/concurrency_error.ts +16 -0
  75. package/src/persistence/duplicate_commit_error.ts +16 -0
  76. package/src/persistence/inmemory/inmemory_partition.ts +194 -0
  77. package/src/persistence/inmemory/inmemory_persistence.ts +35 -0
  78. package/src/persistence/persistence_partition.ts +34 -0
  79. package/src/persistence/persistence_provider_template.ts +20 -0
  80. package/src/replication/master_replication_service.ts +12 -0
  81. package/src/types.ts +128 -0
  82. package/test/event_partition.ts +151 -0
  83. package/test/event_store.ts +25 -0
  84. package/test/event_stream.ts +160 -0
  85. package/test/persistence/inmemory.ts +139 -0
  86. package/tsconfig.json +13 -0
  87. package/vitest.config.ts +13 -0
  88. package/.eslintrc +0 -4
  89. package/.travis.yml +0 -4
  90. package/checkstyle-result.xml +0 -1
  91. package/index.js +0 -1
  92. package/lib/dispatch/dispatch_service.js +0 -7
  93. package/lib/event.js +0 -10
  94. package/lib/event_store.js +0 -53
  95. package/lib/event_store_partition.js +0 -148
  96. package/lib/event_stream.js +0 -150
  97. package/lib/persistence/commit.js +0 -12
  98. package/lib/persistence/concurrency_error.js +0 -10
  99. package/lib/persistence/duplicate_commit_error.js +0 -10
  100. package/lib/persistence/inmemory/inmemory_partition.js +0 -146
  101. package/lib/persistence/inmemory/inmemory_persistence.js +0 -25
  102. package/lib/persistence/persistence_partition.js +0 -23
  103. package/lib/persistence/persistence_provider_template.js +0 -17
  104. package/lib/replication/master_replication_service.js +0 -7
  105. package/test/event_partition.js +0 -232
  106. package/test/event_store.js +0 -36
  107. package/test/event_stream.js +0 -214
  108. package/test/persistence/inmemory.js +0 -162
@@ -0,0 +1,160 @@
1
+ import Promise from "bluebird";
2
+ import { v4 as uuid } from "uuid";
3
+ import { describe, expect, it } from "vitest";
4
+ import EventStore from "..";
5
+ import EventStream from "../src/event_stream";
6
+
7
+ describe("event_stream", () => {
8
+ describe("#openStream", () => {
9
+ it("should return 0 commits for new stream", async () => {
10
+ const es = new EventStore();
11
+ const stream = await es.openPartition("location").call("openStream", "1");
12
+ expect(stream.getCommittedEvents()).toHaveLength(0);
13
+ });
14
+ });
15
+
16
+ describe("#commit", () => {
17
+ it("should do nothing if nothing has been appended", async () => {
18
+ const es = new EventStore();
19
+ const stream = await es.openPartition("location").call("openStream", "1");
20
+ stream.commit(uuid());
21
+ expect(stream.getCommittedEvents()).toHaveLength(0);
22
+ });
23
+
24
+ it("should call commit on partition", () => {
25
+ let called = false;
26
+ const mockPartition = {
27
+ append: (commit, callback) => {
28
+ called = true;
29
+ return Promise.resolve().nodeify(callback);
30
+ },
31
+ _queryStream: (streamId, callback) => {
32
+ return Promise.resolve([]).nodeify(callback);
33
+ },
34
+ };
35
+
36
+ const stream = new EventStream(mockPartition, "11");
37
+ stream.append({ event: "123" });
38
+ stream.commit(uuid());
39
+
40
+ expect(called).toBe(true);
41
+ });
42
+
43
+ it("should keep track of uncommitted events", async () => {
44
+ const es = new EventStore();
45
+ const stream = await es.openPartition("location").call("openStream", "1");
46
+
47
+ stream.append({ event: "123" });
48
+ expect(stream.getUncommittedEvents()).toHaveLength(1);
49
+ });
50
+
51
+ it("should move uncommitted events to committed on commit", async () => {
52
+ const es = new EventStore();
53
+ const stream = await es.openPartition("location").call("openStream", "1");
54
+
55
+ stream.append({ event: "123" });
56
+ await stream.commit(uuid());
57
+
58
+ expect(stream.getUncommittedEvents()).toHaveLength(0);
59
+ expect(stream.getCommittedEvents()).toHaveLength(1);
60
+ });
61
+
62
+ it("two events becomes one commit", async () => {
63
+ const es = new EventStore();
64
+ const stream = await es.openPartition("location").call("openStream", "1");
65
+
66
+ stream.append({ event: "123" });
67
+ stream.append({ event: "999" });
68
+ await stream.commit(uuid());
69
+
70
+ expect(stream.getCommittedEvents()).toHaveLength(2);
71
+ expect(stream._commitSequence).toBe(0);
72
+ });
73
+
74
+ it("two commits gets increasing commit sequence", async () => {
75
+ const es = new EventStore();
76
+ const stream = await es.openPartition("location").call("openStream", "1");
77
+
78
+ stream.append({ event: "123" });
79
+ stream.append({ event: "999" });
80
+ await stream.commit(uuid());
81
+
82
+ stream.append({ event: "666" });
83
+ stream.append({ event: "777" });
84
+ await stream.commit(uuid());
85
+
86
+ expect(stream.getCommittedEvents()).toHaveLength(4);
87
+ expect(stream._commitSequence).toBe(1);
88
+ });
89
+
90
+ it("event stream writeOnly", async () => {
91
+ const es = new EventStore();
92
+ const partition = await es.openPartition("location");
93
+ const stream = await partition.openStream("1", true);
94
+
95
+ stream.append({ event: "123" });
96
+ await stream.commit(uuid());
97
+
98
+ expect(stream._commitSequence).toBe(0);
99
+ stream.append({ event: "666" });
100
+ stream.append({ event: "777" });
101
+ await stream.commit(uuid());
102
+
103
+ expect(stream._commitSequence).toBe(1);
104
+ });
105
+
106
+ it("committed events should have increasing version", async () => {
107
+ const es = new EventStore();
108
+ const stream = await es.openPartition("location").call("openStream", "1");
109
+
110
+ stream.append({ event: "123" });
111
+ stream.append({ event: "999" });
112
+ await stream.commit(uuid());
113
+
114
+ stream.append({ event: "666" });
115
+ stream.append({ event: "777" });
116
+ await stream.commit(uuid());
117
+
118
+ expect(stream.getCommittedEvents()[3].version).toBe(3);
119
+ expect(stream._version).toBe(4);
120
+ });
121
+
122
+ it("committed events should have increasing version (writeOnly)", async () => {
123
+ const es = new EventStore();
124
+ const partition = await es.openPartition("location");
125
+ const stream = await partition.openStream("1", true);
126
+
127
+ stream.append({ event: "123" });
128
+ stream.append({ event: "999" });
129
+ await stream.commit(uuid());
130
+
131
+ stream.append({ event: "666" });
132
+ stream.append({ event: "777" });
133
+ await stream.commit(uuid());
134
+
135
+ expect(stream._version).toBe(4);
136
+ });
137
+
138
+ it("published events should have increasing version", async () => {
139
+ let commitCount = 0;
140
+
141
+ const es = new EventStore(null, (commit) => {
142
+ expect(commit.events[0]).toHaveProperty("version");
143
+ commitCount++;
144
+ });
145
+
146
+ const stream = await es.openPartition("location").call("openStream", "1");
147
+
148
+ stream.append({ event: "123" });
149
+ stream.append({ event: "999" });
150
+ await stream.commit(uuid());
151
+
152
+ stream.append({ event: "666" });
153
+ stream.append({ event: "777" });
154
+ await stream.commit(uuid());
155
+
156
+ expect(stream.getCommittedEvents()[1].version).toBe(1);
157
+ expect(commitCount).toBe(2);
158
+ });
159
+ });
160
+ });
@@ -0,0 +1,139 @@
1
+ import Promise from "bluebird";
2
+ import { v4 as uuid } from "uuid";
3
+ import { describe, expect, it } from "vitest";
4
+ import Event from "../../src/event";
5
+ import Commit from "../../src/persistence/commit";
6
+ import Store from "../../src/persistence/inmemory/inmemory_persistence";
7
+
8
+ describe("inmemory_persistence", () => {
9
+ describe("#commit", () => {
10
+ it("should accept a commit and store it", async () => {
11
+ const store = new Store();
12
+ const partition = await store.openPartition("1");
13
+ const events = [new Event(uuid(), "type1", { test: 11 })];
14
+ const commit = new Commit(uuid(), "master", "1", 0, events);
15
+
16
+ await partition.append(commit);
17
+ const x = await partition.queryAll();
18
+ expect(x).toHaveLength(1);
19
+ });
20
+
21
+ it("commit in one stream is not visible in other", async () => {
22
+ const store = new Store();
23
+ const partition = await store.openPartition("1");
24
+
25
+ let events = [new Event(uuid(), "type1", { test: 11 })];
26
+ let commit = new Commit(uuid(), "master", "1", 0, events);
27
+ partition.append(commit);
28
+
29
+ events = [new Event(uuid(), "type2", { test: 22 })];
30
+ commit = new Commit(uuid(), "master", "2", 0, events);
31
+ partition.append(commit);
32
+
33
+ const [r1, r2] = await Promise.all([partition.queryStream("1"), partition.queryStream("2")]);
34
+
35
+ expect(r1).toHaveLength(1);
36
+ expect(r2).toHaveLength(1);
37
+ });
38
+
39
+ it("two commits in one stream are visible", async () => {
40
+ const store = new Store();
41
+ const partition = await store.openPartition("1");
42
+
43
+ let events = [new Event(uuid(), "type1", { test: 11 })];
44
+ let commit = new Commit(uuid(), "master", "1", 0, events);
45
+ partition.append(commit);
46
+
47
+ events = [new Event(uuid(), "type2", { test: 22 })];
48
+ commit = new Commit(uuid(), "master", "1", 1, events);
49
+ partition.append(commit);
50
+
51
+ const res = await partition.queryAll();
52
+ expect(res).toHaveLength(2);
53
+ });
54
+
55
+ it("should skip events", async () => {
56
+ const store = new Store();
57
+ const partition = await store.openPartition("1");
58
+
59
+ let events = [new Event(uuid(), "type1", { test: 11 }), new Event(uuid(), "type1", { test: 12 })];
60
+ let commit = new Commit(uuid(), "master", "1", 0, events);
61
+ partition.append(commit);
62
+
63
+ events = [new Event(uuid(), "type2", { test: 22 })];
64
+ commit = new Commit(uuid(), "master", "1", 1, events);
65
+ partition.append(commit);
66
+
67
+ const res = await partition.queryStream("1", 2);
68
+ expect(res).toHaveLength(1);
69
+ });
70
+
71
+ it("should skip events and split commit if inbetween", async () => {
72
+ const store = new Store();
73
+ const partition = await store.openPartition("1");
74
+
75
+ let events = [new Event(uuid(), "type1", { test: 11 }), new Event(uuid(), "type1", { test: 12 })];
76
+ let commit = new Commit(uuid(), "master", "1", 0, events);
77
+ partition.append(commit);
78
+
79
+ events = [new Event(uuid(), "type2", { test: 22 })];
80
+ commit = new Commit(uuid(), "master", "1", 1, events);
81
+ partition.append(commit);
82
+
83
+ const res = await partition.queryStream("1", 1);
84
+ expect(res).toHaveLength(2);
85
+ expect(res[0].events).toHaveLength(1);
86
+ });
87
+ });
88
+ describe("#concurrency", () => {
89
+ it("same commit sequence twice should throw", async () => {
90
+ const store = new Store();
91
+ const partition = await store.openPartition("1");
92
+
93
+ const events = [new Event(uuid(), "type1", { test: 11 })];
94
+ const commit = new Commit(uuid(), "master", "1", 0, events);
95
+ const commit2 = new Commit(uuid(), "master", "1", 0, events);
96
+
97
+ await expect(async () => await Promise.all(partition.append(commit), partition.append(commit2))).rejects.toThrow("Concurrency error on stream 1");
98
+ });
99
+ });
100
+
101
+ describe("#duplicateEvents", () => {
102
+ it("same commit twice should throw", async () => {
103
+ const store = new Store();
104
+ const partition = await store.openPartition("1");
105
+
106
+ const events = [new Event(uuid(), "type1", { test: 11 })];
107
+ const commit = new Commit(uuid(), "master", "1", 0, events);
108
+
109
+ await partition.append(commit);
110
+ await expect(async () => partition.append(commit)).rejects.toThrow(`Duplicate commit of ${commit.id}`);
111
+ });
112
+ });
113
+
114
+ describe("#partition", () => {
115
+ it("getting the same partition twice should return same instance", async () => {
116
+ const store = new Store();
117
+ const [p1, p2] = await Promise.all([store.openPartition("1"), store.openPartition("1")]);
118
+ expect(p1).toBe(p2);
119
+ });
120
+
121
+ it("not indicating partition name should give master partition", async () => {
122
+ const store = new Store();
123
+ const [p1, p2] = await Promise.all([store.openPartition(), store.openPartition("master")]);
124
+ expect(p1).toBe(p2);
125
+ });
126
+ });
127
+
128
+ describe("#storeSnapshot", () => {
129
+ it("should return previously stored snapshot", async () => {
130
+ const store = new Store();
131
+ const part = await store.openPartition("1");
132
+
133
+ const snapshot = await part.storeSnapshot("stream1", { iAmSnapshot: true }, 10);
134
+ const newSnapshot = await part.loadSnapshot("stream1");
135
+
136
+ expect(newSnapshot).toBe(snapshot);
137
+ });
138
+ });
139
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": ".",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "ignoreDeprecations": "6.0",
9
+ "types": ["node"]
10
+ },
11
+ "include": ["src/**/*", "index.ts"],
12
+ "exclude": ["test/**/*", "dist/**/*"]
13
+ }
@@ -0,0 +1,13 @@
1
+ import { defineConfig } from "vitest/config";
2
+ import path from "node:path";
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ include: ["**/*.{test,spec}.?[jt]s", "test/**/*.[jt]s"],
7
+ },
8
+ resolve: {
9
+ alias: {
10
+ tapeworm: path.resolve(__dirname, "index.ts"),
11
+ },
12
+ },
13
+ });
package/.eslintrc DELETED
@@ -1,4 +0,0 @@
1
- {
2
-
3
- "extends": "airbnb-es5"
4
- }
package/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - "0.11"
4
- - "0.10"