@eleven-am/pondsocket 0.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.
Files changed (64) hide show
  1. package/.eslintrc.js +28 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/pondsocket.iml +12 -0
  4. package/LICENSE +674 -0
  5. package/base.d.ts +1 -0
  6. package/base.js +17 -0
  7. package/client.d.ts +1 -0
  8. package/client.js +17 -0
  9. package/index.d.ts +1 -0
  10. package/index.js +17 -0
  11. package/jest.config.js +11 -0
  12. package/package.json +48 -0
  13. package/pondBase/baseClass.d.ts +37 -0
  14. package/pondBase/baseClass.js +111 -0
  15. package/pondBase/baseClass.test.js +73 -0
  16. package/pondBase/enums.d.ts +9 -0
  17. package/pondBase/enums.js +14 -0
  18. package/pondBase/index.d.ts +6 -0
  19. package/pondBase/index.js +22 -0
  20. package/pondBase/pondBase.d.ts +41 -0
  21. package/pondBase/pondBase.js +60 -0
  22. package/pondBase/pondBase.test.js +101 -0
  23. package/pondBase/pubSub.d.ts +73 -0
  24. package/pondBase/pubSub.js +138 -0
  25. package/pondBase/pubSub.test.js +309 -0
  26. package/pondBase/simpleBase.d.ts +131 -0
  27. package/pondBase/simpleBase.js +211 -0
  28. package/pondBase/simpleBase.test.js +153 -0
  29. package/pondBase/types.d.ts +2 -0
  30. package/pondBase/types.js +2 -0
  31. package/pondClient/channel.d.ts +66 -0
  32. package/pondClient/channel.js +152 -0
  33. package/pondClient/index.d.ts +2 -0
  34. package/pondClient/index.js +18 -0
  35. package/pondClient/socket.d.ts +42 -0
  36. package/pondClient/socket.js +116 -0
  37. package/pondSocket/channel.d.ts +134 -0
  38. package/pondSocket/channel.js +287 -0
  39. package/pondSocket/channel.test.js +377 -0
  40. package/pondSocket/channelMiddleWare.d.ts +26 -0
  41. package/pondSocket/channelMiddleWare.js +36 -0
  42. package/pondSocket/endpoint.d.ts +90 -0
  43. package/pondSocket/endpoint.js +323 -0
  44. package/pondSocket/endpoint.test.js +513 -0
  45. package/pondSocket/enums.d.ts +19 -0
  46. package/pondSocket/enums.js +25 -0
  47. package/pondSocket/index.d.ts +7 -0
  48. package/pondSocket/index.js +23 -0
  49. package/pondSocket/pondChannel.d.ts +79 -0
  50. package/pondSocket/pondChannel.js +219 -0
  51. package/pondSocket/pondChannel.test.js +430 -0
  52. package/pondSocket/pondResponse.d.ts +25 -0
  53. package/pondSocket/pondResponse.js +120 -0
  54. package/pondSocket/pondSocket.d.ts +47 -0
  55. package/pondSocket/pondSocket.js +94 -0
  56. package/pondSocket/server.test.js +136 -0
  57. package/pondSocket/socketMiddleWare.d.ts +6 -0
  58. package/pondSocket/socketMiddleWare.js +32 -0
  59. package/pondSocket/types.d.ts +74 -0
  60. package/pondSocket/types.js +2 -0
  61. package/socket.d.ts +1 -0
  62. package/socket.js +17 -0
  63. package/tsconfig.eslint.json +5 -0
  64. package/tsconfig.json +90 -0
@@ -0,0 +1,73 @@
1
+ export declare class Subscription {
2
+ unsubscribe(): void;
3
+ }
4
+
5
+ export declare class Broadcast<T, A> {
6
+
7
+ /**
8
+ * @desc Subscribe to the broadcast
9
+ * @param handler - The handler to call when the broadcast is published
10
+ */
11
+ subscribe(handler: (data: T) => A): Subscription;
12
+
13
+ /**
14
+ * @desc Publish to the broadcast
15
+ * @param data - The data to publish
16
+ */
17
+ publish(data: T): A | undefined;
18
+ }
19
+
20
+ export declare class Subject<T, A> extends Broadcast<T, A> {
21
+ constructor(value: T);
22
+
23
+ /**
24
+ * @desc Get the current value of the subject
25
+ */
26
+ get value(): T;
27
+
28
+ /**
29
+ * @desc Subscribe to the subject
30
+ * @param handler - The handler to call when the subject is published
31
+ */
32
+ subscribe(handler: (data: T) => A): Subscription;
33
+
34
+ /**
35
+ * @desc Publish to the subject
36
+ * @param data - The data to publish
37
+ */
38
+ publish(data: T): A | undefined;
39
+ }
40
+
41
+ export declare class EventPubSub<T, A> {
42
+
43
+ /**
44
+ * @desc Subscribe to the event subject
45
+ * @param event - The event to subscribe to
46
+ * @param handler - The handler to call when the event subject is published
47
+ */
48
+ subscribe(event: string, handler: (data: T) => A): Subscription;
49
+
50
+ /**
51
+ * @desc Publish to the event subject
52
+ * @param event - The event to publish
53
+ * @param data - The data to publish
54
+ */
55
+ publish(event: string, data: T): void;
56
+
57
+ /**
58
+ * @desc Subscribe to all events
59
+ * @param handler - The handler to call when the event subject is published
60
+ */
61
+ subscribeAll(handler: (event: T) => A): Subscription;
62
+
63
+ /**
64
+ * @desc Complete the event subject
65
+ */
66
+ complete(): void;
67
+
68
+ /**
69
+ * @desc Subscribe to the event subject completion
70
+ * @param handler - The handler to call when the event subject is completed
71
+ */
72
+ onComplete(handler: () => void): void;
73
+ }
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventPubSub = exports.Subject = exports.Broadcast = void 0;
4
+ class Broadcast {
5
+ constructor() {
6
+ this._subscribers = new Set();
7
+ }
8
+ /**
9
+ * @desc Subscribe to the broadcast
10
+ * @param handler - The handler to call when the broadcast is published
11
+ */
12
+ subscribe(handler) {
13
+ this._subscribers.add(handler);
14
+ return {
15
+ /**
16
+ * @desc Unsubscribe from the broadcast
17
+ */
18
+ unsubscribe: () => {
19
+ this._subscribers.delete(handler);
20
+ }
21
+ };
22
+ }
23
+ /**
24
+ * @desc Publish to the broadcast
25
+ * @param data - The data to publish
26
+ */
27
+ publish(data) {
28
+ let result;
29
+ for (const subscriber of this._subscribers) {
30
+ result = subscriber(data);
31
+ if (result)
32
+ break;
33
+ }
34
+ return result;
35
+ }
36
+ }
37
+ exports.Broadcast = Broadcast;
38
+ class Subject extends Broadcast {
39
+ constructor(value) {
40
+ super();
41
+ this._value = value;
42
+ }
43
+ /**
44
+ * @desc Get the current value of the subject
45
+ */
46
+ get value() {
47
+ return this._value;
48
+ }
49
+ /**
50
+ * @desc Subscribe to the subject
51
+ * @param handler - The handler to call when the subject is published
52
+ */
53
+ subscribe(handler) {
54
+ void handler(this._value);
55
+ return super.subscribe(handler);
56
+ }
57
+ /**
58
+ * @desc Publish to the subject
59
+ * @param data - The data to publish
60
+ */
61
+ publish(data) {
62
+ if (this._value !== data) {
63
+ this._value = data;
64
+ return super.publish(data);
65
+ }
66
+ }
67
+ }
68
+ exports.Subject = Subject;
69
+ class EventPubSub {
70
+ constructor() {
71
+ this._subscribers = new Set();
72
+ }
73
+ /**
74
+ * @desc Subscribe to the event subject
75
+ * @param event - The event to subscribe to
76
+ * @param handler - The handler to call when the event subject is published
77
+ */
78
+ subscribe(event, handler) {
79
+ const subscriber = (eventData) => {
80
+ if (eventData.type === event)
81
+ return handler(eventData.data);
82
+ return undefined;
83
+ };
84
+ this._subscribers.add(subscriber);
85
+ return {
86
+ /**
87
+ * @desc Unsubscribe from the event subject
88
+ */
89
+ unsubscribe: () => {
90
+ this._subscribers.delete(subscriber);
91
+ }
92
+ };
93
+ }
94
+ /**
95
+ * @desc Publish to the event subject
96
+ * @param event - The event to publish
97
+ * @param data - The data to publish
98
+ */
99
+ publish(event, data) {
100
+ for (const subscriber of this._subscribers) {
101
+ void subscriber({ type: event, data });
102
+ }
103
+ }
104
+ /**
105
+ * @desc Subscribe to all events
106
+ * @param handler - The handler to call when the event subject is published
107
+ */
108
+ subscribeAll(handler) {
109
+ const subscriber = (eventData) => {
110
+ return handler(eventData.data);
111
+ };
112
+ this._subscribers.add(subscriber);
113
+ return {
114
+ /**
115
+ * @desc Unsubscribe from the event subject
116
+ */
117
+ unsubscribe: () => {
118
+ this._subscribers.delete(subscriber);
119
+ }
120
+ };
121
+ }
122
+ /**
123
+ * @desc Complete the event subject
124
+ */
125
+ complete() {
126
+ this._subscribers.clear();
127
+ if (this._onComplete)
128
+ this._onComplete();
129
+ }
130
+ /**
131
+ * @desc Subscribe to the event subject completion
132
+ * @param handler - The handler to call when the event subject is completed
133
+ */
134
+ onComplete(handler) {
135
+ this._onComplete = handler;
136
+ }
137
+ }
138
+ exports.EventPubSub = EventPubSub;
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const pubSub_1 = require("./pubSub");
4
+ describe('Broadcast', () => {
5
+ it('should be defined', () => {
6
+ expect(pubSub_1.Broadcast).toBeDefined();
7
+ });
8
+ it('should be a class', () => {
9
+ expect(pubSub_1.Broadcast).toBeInstanceOf(Function);
10
+ });
11
+ // Functionality tests
12
+ it('should publish a message to all subscribers', () => {
13
+ const broadcast = new pubSub_1.Broadcast();
14
+ const subscriber = jest.fn();
15
+ broadcast.subscribe(subscriber); // test with one subscriber
16
+ broadcast.publish('Hello');
17
+ expect(subscriber).toHaveBeenCalledWith('Hello');
18
+ });
19
+ it('should publish a message to all subscribers', () => {
20
+ const broadcast = new pubSub_1.Broadcast();
21
+ const subscriber1 = jest.fn();
22
+ const subscriber2 = jest.fn();
23
+ broadcast.subscribe(subscriber1); // test with two subscribers
24
+ broadcast.subscribe(subscriber2);
25
+ broadcast.publish('Hello');
26
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
27
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
28
+ });
29
+ it('should publish a message to all subscribers', () => {
30
+ // including subscribers that subscribe after the first message is published
31
+ const broadcast = new pubSub_1.Broadcast();
32
+ const subscriber1 = jest.fn();
33
+ const subscriber2 = jest.fn();
34
+ broadcast.subscribe(subscriber1);
35
+ broadcast.publish('Hello');
36
+ broadcast.subscribe(subscriber2);
37
+ broadcast.publish('Hello Again');
38
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
39
+ expect(subscriber1).toHaveBeenCalledWith('Hello Again');
40
+ expect(subscriber2).toHaveBeenCalledWith('Hello Again');
41
+ });
42
+ it('should unsubscribe a subscriber and thus not receive new message', () => {
43
+ const broadcast = new pubSub_1.Broadcast();
44
+ const subscriber1 = jest.fn();
45
+ const subscriber2 = jest.fn();
46
+ broadcast.subscribe(subscriber1);
47
+ broadcast.subscribe(subscriber2);
48
+ broadcast.publish('Hello');
49
+ const subscription = broadcast.subscribe(subscriber2);
50
+ subscription.unsubscribe();
51
+ broadcast.publish('Hello Again');
52
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
53
+ expect(subscriber1).toHaveBeenCalledWith('Hello Again');
54
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
55
+ expect(subscriber2).not.toHaveBeenCalledWith('Hello Again');
56
+ });
57
+ it('should stop the broadcast midway if a subscription returns a value', () => {
58
+ const broadcast = new pubSub_1.Broadcast();
59
+ const subscriber1 = jest.fn();
60
+ const subscriber2 = jest.fn(() => true);
61
+ const subscriber3 = jest.fn();
62
+ broadcast.subscribe(subscriber1);
63
+ broadcast.subscribe(subscriber2);
64
+ broadcast.subscribe(subscriber3);
65
+ broadcast.publish('Hello');
66
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
67
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
68
+ expect(subscriber3).not.toHaveBeenCalled();
69
+ });
70
+ it('should throw an error if one of its subscribers throws an error', () => {
71
+ const broadcast = new pubSub_1.Broadcast();
72
+ const subscriber1 = jest.fn();
73
+ const subscriber2 = jest.fn(() => {
74
+ throw new Error('Something went wrong');
75
+ });
76
+ const subscriber3 = jest.fn();
77
+ broadcast.subscribe(subscriber1);
78
+ broadcast.subscribe(subscriber2);
79
+ broadcast.subscribe(subscriber3);
80
+ expect(() => broadcast.publish('Hello')).toThrowError('Something went wrong');
81
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
82
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
83
+ expect(subscriber3).not.toHaveBeenCalled();
84
+ });
85
+ });
86
+ describe('Subject', () => {
87
+ it('should be defined', () => {
88
+ expect(pubSub_1.Subject).toBeDefined();
89
+ });
90
+ it('should be a class', () => {
91
+ expect(pubSub_1.Subject).toBeInstanceOf(Function);
92
+ });
93
+ // Functionality tests
94
+ it('should publish a message to all subscribers', () => {
95
+ const subject = new pubSub_1.Subject('hi');
96
+ const subscriber = jest.fn();
97
+ subject.subscribe(subscriber); // test with one subscriber
98
+ subject.publish('Hello');
99
+ expect(subscriber).toHaveBeenCalledWith('Hello');
100
+ });
101
+ it('should publish a message to all subscribers', () => {
102
+ const subject = new pubSub_1.Subject('hi');
103
+ const subscriber1 = jest.fn();
104
+ const subscriber2 = jest.fn();
105
+ subject.subscribe(subscriber1); // test with two subscribers
106
+ subject.subscribe(subscriber2);
107
+ subject.publish('Hello');
108
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
109
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
110
+ });
111
+ it('should provide the initial value to new subscribers', () => {
112
+ const subject = new pubSub_1.Subject('hi');
113
+ const subscriber = jest.fn();
114
+ subject.subscribe(subscriber); // test with one subscriber
115
+ expect(subscriber).toHaveBeenCalledWith('hi');
116
+ });
117
+ it('should publish a message to all subscribers', () => {
118
+ // including subscribers that subscribe after the first message is published
119
+ const subject = new pubSub_1.Subject('hi');
120
+ const subscriber1 = jest.fn();
121
+ const subscriber2 = jest.fn();
122
+ subject.subscribe(subscriber1);
123
+ subject.publish('Hello');
124
+ subject.subscribe(subscriber2);
125
+ subject.publish('Hello Again');
126
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
127
+ expect(subscriber1).toHaveBeenCalledWith('Hello Again');
128
+ expect(subscriber2).toHaveBeenCalledWith('Hello Again');
129
+ });
130
+ it('should return the current value when the getter is called', () => {
131
+ const subject = new pubSub_1.Subject('hi');
132
+ expect(subject.value).toEqual('hi');
133
+ });
134
+ it('should throw an error if one of its subscribers throws an error', () => {
135
+ const subject = new pubSub_1.Subject('hi');
136
+ const subscriber1 = jest.fn();
137
+ const subscriber2 = jest.fn(() => {
138
+ throw new Error('Something went wrong');
139
+ });
140
+ const subscriber3 = jest.fn();
141
+ subject.subscribe(subscriber1);
142
+ // because the subject immediately calls the subscriber with the initial value
143
+ expect(() => subject.subscribe(subscriber2)).toThrowError('Something went wrong');
144
+ subscriber2.mockClear();
145
+ subject.subscribe(subscriber3);
146
+ // since ths subscriber throws an error, the subject should not call it
147
+ subject.publish('Hello'); // this should not call subscriber2 and should not throw an error
148
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
149
+ expect(subscriber3).toHaveBeenCalledWith('Hello');
150
+ expect(subscriber2).not.toHaveBeenCalled();
151
+ });
152
+ });
153
+ describe('EventSubject', () => {
154
+ it('should be defined', () => {
155
+ expect(pubSub_1.EventPubSub).toBeDefined();
156
+ });
157
+ it('should be a class', () => {
158
+ expect(pubSub_1.EventPubSub).toBeInstanceOf(Function);
159
+ });
160
+ // Functionality tests
161
+ it('should publish a message to all subscribers', () => {
162
+ const subject = new pubSub_1.EventPubSub();
163
+ const subscriber = jest.fn();
164
+ subject.subscribe('test', subscriber); // test with one subscriber
165
+ subject.publish('test', 'Hello');
166
+ expect(subscriber).toHaveBeenCalledWith('Hello');
167
+ });
168
+ it('should publish a message to all subscribers', () => {
169
+ const subject = new pubSub_1.EventPubSub();
170
+ const subscriber1 = jest.fn();
171
+ const subscriber2 = jest.fn();
172
+ subject.subscribe('test', subscriber1); // test with two subscribers
173
+ subject.subscribe('test', subscriber2);
174
+ subject.publish('test', 'Hello');
175
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
176
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
177
+ });
178
+ it('should publish a message to all subscribers', () => {
179
+ // including subscribers that subscribe after the first message is published
180
+ const subject = new pubSub_1.EventPubSub();
181
+ const subscriber1 = jest.fn();
182
+ const subscriber2 = jest.fn();
183
+ subject.subscribe('test', subscriber1);
184
+ subject.publish('test', 'Hello');
185
+ subject.subscribe('test', subscriber2);
186
+ subject.publish('test', 'Hello Again');
187
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
188
+ expect(subscriber1).toHaveBeenCalledWith('Hello Again');
189
+ expect(subscriber2).toHaveBeenCalledWith('Hello Again');
190
+ });
191
+ it('should not call a function if the event name does not match', () => {
192
+ const subject = new pubSub_1.EventPubSub();
193
+ const subscriber = jest.fn();
194
+ subject.subscribe('test', subscriber);
195
+ subject.publish('test2', 'Hello');
196
+ expect(subscriber).not.toHaveBeenCalled();
197
+ });
198
+ it('should not call a function if the event name does not match', () => {
199
+ // including subscribers that subscribe after the first message is published
200
+ const subject = new pubSub_1.EventPubSub();
201
+ const subscriber1 = jest.fn();
202
+ const subscriber2 = jest.fn();
203
+ subject.subscribe('test', subscriber1);
204
+ subject.publish('test', 'Hello');
205
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
206
+ expect(subscriber2).not.toHaveBeenCalled();
207
+ subscriber1.mockClear();
208
+ subscriber2.mockClear();
209
+ subject.subscribe('test2', subscriber2);
210
+ subject.publish('test2', 'Hello Again');
211
+ expect(subscriber1).not.toHaveBeenCalled();
212
+ expect(subscriber2).toHaveBeenCalledWith('Hello Again');
213
+ });
214
+ it('should accept a generic subscriber', () => {
215
+ const subject = new pubSub_1.EventPubSub();
216
+ const subscriber = jest.fn();
217
+ subject.subscribeAll(subscriber);
218
+ subject.publish('test', 'Hello');
219
+ expect(subscriber).toHaveBeenCalledWith('Hello');
220
+ });
221
+ it('should accept a generic subscriber', () => {
222
+ const subject = new pubSub_1.EventPubSub();
223
+ const subscriber = jest.fn();
224
+ subject.subscribeAll(subscriber);
225
+ subject.publish('test', 'Hello');
226
+ subject.publish('test2', 'Hello Again');
227
+ expect(subscriber).toHaveBeenCalledWith('Hello');
228
+ expect(subscriber).toHaveBeenCalledWith('Hello Again');
229
+ });
230
+ it('should be able to unsubscribe from a specific event', () => {
231
+ const subject = new pubSub_1.EventPubSub();
232
+ const subscriber = jest.fn();
233
+ const sub = subject.subscribe('test', subscriber);
234
+ subject.publish('test', 'Hello');
235
+ expect(subscriber).toHaveBeenCalledWith('Hello');
236
+ subscriber.mockClear();
237
+ sub.unsubscribe();
238
+ subject.publish('test', 'Hello Again');
239
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
240
+ });
241
+ it('should complete the subscription when unsubscribed', () => {
242
+ const subject = new pubSub_1.EventPubSub();
243
+ const subscriber = jest.fn();
244
+ const subscriber2 = jest.fn();
245
+ const subscriber3 = jest.fn();
246
+ subject.subscribe('test', subscriber);
247
+ subject.subscribe('test1', subscriber2);
248
+ subject.subscribe('test2', subscriber3);
249
+ subject.publish('test', 'Hello');
250
+ expect(subscriber).toHaveBeenCalledWith('Hello');
251
+ subscriber.mockClear();
252
+ subject.publish('test1', 'Hello Again');
253
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
254
+ expect(subscriber2).toHaveBeenCalledWith('Hello Again');
255
+ subscriber2.mockClear();
256
+ subject.publish('test2', 'Hello Again');
257
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
258
+ expect(subscriber2).not.toHaveBeenCalledWith('Hello Again');
259
+ expect(subscriber3).toHaveBeenCalledWith('Hello Again');
260
+ subscriber3.mockClear();
261
+ subject.complete(); // complete all subscriptions
262
+ subject.publish('test', 'Hello Again');
263
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
264
+ subject.publish('test1', 'Hello Again');
265
+ expect(subscriber2).not.toHaveBeenCalledWith('Hello Again');
266
+ subject.publish('test2', 'Hello Again');
267
+ expect(subscriber3).not.toHaveBeenCalledWith('Hello Again');
268
+ });
269
+ it('should throw an error if one of its subscribers throw an error', () => {
270
+ const subject = new pubSub_1.EventPubSub();
271
+ const subscriber1 = jest.fn();
272
+ const subscriber2 = jest.fn(() => {
273
+ throw new Error('Something went wrong');
274
+ });
275
+ const subscriber3 = jest.fn();
276
+ subject.subscribeAll(subscriber1);
277
+ subject.subscribeAll(subscriber2);
278
+ subject.subscribe('event', subscriber3);
279
+ expect(() => subject.publish('event', 'Hello')).toThrowError('Something went wrong');
280
+ expect(subscriber1).toHaveBeenCalledWith('Hello');
281
+ expect(subscriber2).toHaveBeenCalledWith('Hello');
282
+ expect(subscriber3).not.toHaveBeenCalled();
283
+ });
284
+ it('should be possible to unsubscribe from a generic subscriber', () => {
285
+ const subject = new pubSub_1.EventPubSub();
286
+ const subscriber = jest.fn();
287
+ const sub = subject.subscribeAll(subscriber);
288
+ subject.publish('test', 'Hello');
289
+ expect(subscriber).toHaveBeenCalledWith('Hello');
290
+ subscriber.mockClear();
291
+ sub.unsubscribe();
292
+ subject.publish('test', 'Hello Again');
293
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
294
+ });
295
+ it('should be able to add an oncomplete callback', () => {
296
+ const subject = new pubSub_1.EventPubSub();
297
+ const subscriber = jest.fn();
298
+ const subscriber2 = jest.fn();
299
+ subject.onComplete(subscriber2);
300
+ subject.subscribe('test', subscriber);
301
+ subject.publish('test', 'Hello');
302
+ expect(subscriber).toHaveBeenCalledWith('Hello');
303
+ subscriber.mockClear();
304
+ subject.complete();
305
+ expect(subscriber2).toHaveBeenCalled();
306
+ subject.publish('test', 'Hello Again');
307
+ expect(subscriber).not.toHaveBeenCalledWith('Hello Again');
308
+ });
309
+ });
@@ -0,0 +1,131 @@
1
+ export declare class PondDocument<T> {
2
+ private readonly _id;
3
+ private readonly _getDoc;
4
+ private readonly _removeDoc;
5
+ private readonly _updateDoc;
6
+
7
+ constructor(id: string, removeDoc: () => void, updateDoc: (value: T) => PondDocument<T>, getDoc: () => T);
8
+
9
+ get id(): string;
10
+
11
+ get doc(): T;
12
+
13
+ /**
14
+ * @desc Removes the document from the collection
15
+ */
16
+ removeDoc(): T;
17
+
18
+ /**
19
+ * @desc Updates the document in the collection
20
+ * @param value - the new value of the document
21
+ */
22
+ updateDoc(value: T): this;
23
+ }
24
+
25
+ declare type UpdateCallback<T> = (data: {
26
+ oldValue: T | null; currentValue: T | null;
27
+ }) => void;
28
+
29
+ export declare class SimpleBase<T> {
30
+ constructor(callbacks?: UpdateCallback<T>);
31
+
32
+ /**
33
+ * @desc Get the number of documents
34
+ */
35
+ get size(): number;
36
+
37
+ /**
38
+ * @desc Get all the documents in the database
39
+ */
40
+ get all(): PondDocument<T>[];
41
+
42
+ /**
43
+ * @desc Gets all the keys of the database
44
+ */
45
+ get keys(): string[];
46
+
47
+ /**
48
+ * @desc Gets all the values of the database
49
+ */
50
+ get values(): T[];
51
+
52
+ /**
53
+ * @desc Makes the database iterable
54
+ */
55
+ [Symbol.iterator](): IterableIterator<PondDocument<T>>;
56
+
57
+ /**
58
+ * @desc Create a generator for the pond
59
+ */
60
+ generator(): Generator<PondDocument<T>>;
61
+
62
+ /**
63
+ * @desc Get a document by key
64
+ * @param key - The key of the document
65
+ */
66
+ get(key: string): PondDocument<T> | null;
67
+
68
+ /**
69
+ * @desc getOrCreate a document in the database
70
+ * @param key - The key of the document
71
+ * @param creator - The function to create the document
72
+ */
73
+ getOrCreate(key: string, creator: (doc: Readonly<PondDocument<T>>) => T): PondDocument<T>;
74
+
75
+ /**
76
+ * @desc Upsert a document in the database
77
+ * @param key - The key of the document
78
+ * @param value - The value of the document
79
+ */
80
+ upsert(key: string, value: T): PondDocument<T>;
81
+
82
+ /**
83
+ * @desc checks if a document exists
84
+ * @param key - The key of the document
85
+ */
86
+ has(key: string): boolean;
87
+
88
+ /**
89
+ * @desc Set a document to the database
90
+ * @param key - The key of the document
91
+ * @param value - The value of the document
92
+ */
93
+ set(key: string, value: T): PondDocument<T>;
94
+
95
+ /**
96
+ * @desc Find a document by a query function
97
+ * @param query - The query function
98
+ */
99
+ find(query: (doc: T, id: string) => boolean): PondDocument<T> | null;
100
+
101
+ /**
102
+ * @desc Map the pond to a new array
103
+ * @param mapper - The mapper function
104
+ */
105
+ map<U>(mapper: (doc: T, id: string) => U): U[];
106
+
107
+ /**
108
+ * @desc Filters the pond using a query function
109
+ * @param query - The query function
110
+ */
111
+ filter(query: (doc: T, id: string) => boolean): PondDocument<T>[];
112
+
113
+ /**
114
+ * @desc Reduce the pond to a single value
115
+ * @param reducer - The reducer function
116
+ * @param initialValue - The initial value of the reducer
117
+ */
118
+ reduce<U>(reducer: (accumulator: U, currentValue: T) => U, initialValue: U): U;
119
+
120
+ /**
121
+ * @desc Generate a generic pond document
122
+ * @param id - The id of the document
123
+ */
124
+ createGenericDocument(id?: string): PondDocument<T>;
125
+
126
+ /**
127
+ * @desc Gets the raw database
128
+ * @protected
129
+ */
130
+ protected _getDB(): Record<string, T>;
131
+ }