cojson 0.12.0 → 0.12.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/PriorityBasedMessageQueue.d.ts +16 -0
- package/dist/PriorityBasedMessageQueue.d.ts.map +1 -1
- package/dist/PriorityBasedMessageQueue.js +50 -1
- package/dist/PriorityBasedMessageQueue.js.map +1 -1
- package/dist/tests/LinkedList.test.d.ts +2 -0
- package/dist/tests/LinkedList.test.d.ts.map +1 -0
- package/dist/tests/LinkedList.test.js +84 -0
- package/dist/tests/LinkedList.test.js.map +1 -0
- package/package.json +1 -1
- package/src/PriorityBasedMessageQueue.ts +62 -2
- package/src/tests/LinkedList.test.ts +96 -0
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,21 @@ export type QueueEntry = {
|
|
|
6
6
|
resolve: () => void;
|
|
7
7
|
reject: (_: unknown) => void;
|
|
8
8
|
};
|
|
9
|
+
type LinkedListNode<T> = {
|
|
10
|
+
value: T;
|
|
11
|
+
next: LinkedListNode<T> | undefined;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Using a linked list to make the shift operation O(1) instead of O(n)
|
|
15
|
+
* as our queues can grow very large when the system is under pressure.
|
|
16
|
+
*/
|
|
17
|
+
export declare class LinkedList<T> {
|
|
18
|
+
head: LinkedListNode<T> | undefined;
|
|
19
|
+
tail: LinkedListNode<T> | undefined;
|
|
20
|
+
length: number;
|
|
21
|
+
push(value: T): void;
|
|
22
|
+
shift(): T | undefined;
|
|
23
|
+
}
|
|
9
24
|
export declare class PriorityBasedMessageQueue {
|
|
10
25
|
private defaultPriority;
|
|
11
26
|
private queues;
|
|
@@ -15,4 +30,5 @@ export declare class PriorityBasedMessageQueue {
|
|
|
15
30
|
push(msg: SyncMessage): Promise<void>;
|
|
16
31
|
pull(): QueueEntry | undefined;
|
|
17
32
|
}
|
|
33
|
+
export {};
|
|
18
34
|
//# sourceMappingURL=PriorityBasedMessageQueue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PriorityBasedMessageQueue.d.ts","sourceRoot":"","sources":["../src/PriorityBasedMessageQueue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAkB7C,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"PriorityBasedMessageQueue.d.ts","sourceRoot":"","sources":["../src/PriorityBasedMessageQueue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAkB7C,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,WAAW,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9B,CAAC;AAaF,KAAK,cAAc,CAAC,CAAC,IAAI;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,qBAAa,UAAU,CAAC,CAAC;IACvB,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CAAa;IAChD,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CAAa;IAChD,MAAM,SAAK;IAEX,IAAI,CAAC,KAAK,EAAE,CAAC;IAgBb,KAAK;CAkBN;AAED,qBAAa,yBAAyB;IAuBxB,OAAO,CAAC,eAAe;IAtBnC,OAAO,CAAC,MAAM,CASZ;IACF,gBAAgB,sFAMX;IAEL,OAAO,CAAC,QAAQ;gBAII,eAAe,EAAE,eAAe;IAE7C,IAAI,CAAC,GAAG,EAAE,WAAW;IAerB,IAAI;CAaZ"}
|
|
@@ -12,13 +12,62 @@ function promiseWithResolvers() {
|
|
|
12
12
|
reject,
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Using a linked list to make the shift operation O(1) instead of O(n)
|
|
17
|
+
* as our queues can grow very large when the system is under pressure.
|
|
18
|
+
*/
|
|
19
|
+
export class LinkedList {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.head = undefined;
|
|
22
|
+
this.tail = undefined;
|
|
23
|
+
this.length = 0;
|
|
24
|
+
}
|
|
25
|
+
push(value) {
|
|
26
|
+
const node = { value, next: undefined };
|
|
27
|
+
if (this.head === undefined) {
|
|
28
|
+
this.head = node;
|
|
29
|
+
this.tail = node;
|
|
30
|
+
}
|
|
31
|
+
else if (this.tail) {
|
|
32
|
+
this.tail.next = node;
|
|
33
|
+
this.tail = node;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw new Error("LinkedList is corrupted");
|
|
37
|
+
}
|
|
38
|
+
this.length++;
|
|
39
|
+
}
|
|
40
|
+
shift() {
|
|
41
|
+
if (!this.head) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const node = this.head;
|
|
45
|
+
const value = node.value;
|
|
46
|
+
this.head = node.next;
|
|
47
|
+
node.next = undefined;
|
|
48
|
+
if (this.head === undefined) {
|
|
49
|
+
this.tail = undefined;
|
|
50
|
+
}
|
|
51
|
+
this.length--;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
15
55
|
export class PriorityBasedMessageQueue {
|
|
16
56
|
getQueue(priority) {
|
|
17
57
|
return this.queues[priority];
|
|
18
58
|
}
|
|
19
59
|
constructor(defaultPriority) {
|
|
20
60
|
this.defaultPriority = defaultPriority;
|
|
21
|
-
this.queues = [
|
|
61
|
+
this.queues = [
|
|
62
|
+
new LinkedList(),
|
|
63
|
+
new LinkedList(),
|
|
64
|
+
new LinkedList(),
|
|
65
|
+
new LinkedList(),
|
|
66
|
+
new LinkedList(),
|
|
67
|
+
new LinkedList(),
|
|
68
|
+
new LinkedList(),
|
|
69
|
+
new LinkedList(),
|
|
70
|
+
];
|
|
22
71
|
this.queueSizeCounter = metrics
|
|
23
72
|
.getMeter("cojson")
|
|
24
73
|
.createUpDownCounter("jazz.messagequeue.size", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PriorityBasedMessageQueue.js","sourceRoot":"","sources":["../src/PriorityBasedMessageQueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIxD,SAAS,oBAAoB;IAC3B,IAAI,OAAO,GAAG,CAAC,CAAI,EAAE,EAAE,GAAE,CAAC,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,CAAU,EAAE,EAAE,GAAE,CAAC,CAAC;IAEhC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;QACnD,OAAO,GAAG,QAAQ,CAAC;QACnB,MAAM,GAAG,OAAO,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,OAAO;QACP,MAAM;KACP,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"PriorityBasedMessageQueue.js","sourceRoot":"","sources":["../src/PriorityBasedMessageQueue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkedList.test.d.ts","sourceRoot":"","sources":["../../src/tests/LinkedList.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { LinkedList } from "../PriorityBasedMessageQueue";
|
|
3
|
+
describe("LinkedList", () => {
|
|
4
|
+
let list;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
list = new LinkedList();
|
|
7
|
+
});
|
|
8
|
+
describe("initialization", () => {
|
|
9
|
+
it("should create an empty list", () => {
|
|
10
|
+
expect(list.length).toBe(0);
|
|
11
|
+
expect(list.head).toBeUndefined();
|
|
12
|
+
expect(list.tail).toBeUndefined();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe("push", () => {
|
|
16
|
+
it("should add an element to an empty list", () => {
|
|
17
|
+
list.push(1);
|
|
18
|
+
expect(list.length).toBe(1);
|
|
19
|
+
expect(list.head?.value).toBe(1);
|
|
20
|
+
expect(list.tail?.value).toBe(1);
|
|
21
|
+
});
|
|
22
|
+
it("should add multiple elements in sequence", () => {
|
|
23
|
+
list.push(1);
|
|
24
|
+
list.push(2);
|
|
25
|
+
list.push(3);
|
|
26
|
+
expect(list.length).toBe(3);
|
|
27
|
+
expect(list.head?.value).toBe(1);
|
|
28
|
+
expect(list.tail?.value).toBe(3);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe("shift", () => {
|
|
32
|
+
it("should return undefined for empty list", () => {
|
|
33
|
+
expect(list.shift()).toBeUndefined();
|
|
34
|
+
expect(list.length).toBe(0);
|
|
35
|
+
expect(list.head).toBeUndefined();
|
|
36
|
+
expect(list.tail).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
it("should remove and return the first element", () => {
|
|
39
|
+
list.push(1);
|
|
40
|
+
list.push(2);
|
|
41
|
+
const shifted = list.shift();
|
|
42
|
+
expect(shifted).toBe(1);
|
|
43
|
+
expect(list.length).toBe(1);
|
|
44
|
+
expect(list.head?.value).toBe(2);
|
|
45
|
+
expect(list.tail?.value).toBe(2);
|
|
46
|
+
});
|
|
47
|
+
it("should maintain correct order when shifting multiple times", () => {
|
|
48
|
+
list.push(1);
|
|
49
|
+
list.push(2);
|
|
50
|
+
list.push(3);
|
|
51
|
+
expect(list.shift()).toBe(1);
|
|
52
|
+
expect(list.shift()).toBe(2);
|
|
53
|
+
expect(list.shift()).toBe(3);
|
|
54
|
+
expect(list.length).toBe(0);
|
|
55
|
+
expect(list.head).toBeUndefined();
|
|
56
|
+
expect(list.tail).toBeUndefined();
|
|
57
|
+
});
|
|
58
|
+
it("should handle shift after last element is removed", () => {
|
|
59
|
+
list.push(1);
|
|
60
|
+
list.shift();
|
|
61
|
+
expect(list.shift()).toBeUndefined();
|
|
62
|
+
expect(list.length).toBe(0);
|
|
63
|
+
expect(list.head).toBeUndefined();
|
|
64
|
+
expect(list.tail).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe("edge cases", () => {
|
|
68
|
+
it("should handle push after all elements have been shifted", () => {
|
|
69
|
+
list.push(1);
|
|
70
|
+
list.shift();
|
|
71
|
+
list.push(2);
|
|
72
|
+
expect(list.length).toBe(1);
|
|
73
|
+
expect(list.shift()).toBe(2);
|
|
74
|
+
});
|
|
75
|
+
it("should handle alternating push and shift operations", () => {
|
|
76
|
+
list.push(1);
|
|
77
|
+
expect(list.shift()).toBe(1);
|
|
78
|
+
list.push(2);
|
|
79
|
+
expect(list.shift()).toBe(2);
|
|
80
|
+
expect(list.length).toBe(0);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=LinkedList.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkedList.test.js","sourceRoot":"","sources":["../../src/tests/LinkedList.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -33,10 +33,70 @@ type Tuple<T, N extends number, A extends unknown[] = []> = A extends {
|
|
|
33
33
|
}
|
|
34
34
|
? A
|
|
35
35
|
: Tuple<T, N, [...A, T]>;
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
type QueueTuple = Tuple<LinkedList<QueueEntry>, 8>;
|
|
38
|
+
|
|
39
|
+
type LinkedListNode<T> = {
|
|
40
|
+
value: T;
|
|
41
|
+
next: LinkedListNode<T> | undefined;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Using a linked list to make the shift operation O(1) instead of O(n)
|
|
46
|
+
* as our queues can grow very large when the system is under pressure.
|
|
47
|
+
*/
|
|
48
|
+
export class LinkedList<T> {
|
|
49
|
+
head: LinkedListNode<T> | undefined = undefined;
|
|
50
|
+
tail: LinkedListNode<T> | undefined = undefined;
|
|
51
|
+
length = 0;
|
|
52
|
+
|
|
53
|
+
push(value: T) {
|
|
54
|
+
const node = { value, next: undefined };
|
|
55
|
+
|
|
56
|
+
if (this.head === undefined) {
|
|
57
|
+
this.head = node;
|
|
58
|
+
this.tail = node;
|
|
59
|
+
} else if (this.tail) {
|
|
60
|
+
this.tail.next = node;
|
|
61
|
+
this.tail = node;
|
|
62
|
+
} else {
|
|
63
|
+
throw new Error("LinkedList is corrupted");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.length++;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
shift() {
|
|
70
|
+
if (!this.head) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const node = this.head;
|
|
75
|
+
const value = node.value;
|
|
76
|
+
this.head = node.next;
|
|
77
|
+
node.next = undefined;
|
|
78
|
+
|
|
79
|
+
if (this.head === undefined) {
|
|
80
|
+
this.tail = undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.length--;
|
|
84
|
+
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
37
88
|
|
|
38
89
|
export class PriorityBasedMessageQueue {
|
|
39
|
-
private queues: QueueTuple = [
|
|
90
|
+
private queues: QueueTuple = [
|
|
91
|
+
new LinkedList<QueueEntry>(),
|
|
92
|
+
new LinkedList<QueueEntry>(),
|
|
93
|
+
new LinkedList<QueueEntry>(),
|
|
94
|
+
new LinkedList<QueueEntry>(),
|
|
95
|
+
new LinkedList<QueueEntry>(),
|
|
96
|
+
new LinkedList<QueueEntry>(),
|
|
97
|
+
new LinkedList<QueueEntry>(),
|
|
98
|
+
new LinkedList<QueueEntry>(),
|
|
99
|
+
];
|
|
40
100
|
queueSizeCounter = metrics
|
|
41
101
|
.getMeter("cojson")
|
|
42
102
|
.createUpDownCounter("jazz.messagequeue.size", {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { LinkedList } from "../PriorityBasedMessageQueue";
|
|
3
|
+
|
|
4
|
+
describe("LinkedList", () => {
|
|
5
|
+
let list: LinkedList<number>;
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
list = new LinkedList<number>();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe("initialization", () => {
|
|
12
|
+
it("should create an empty list", () => {
|
|
13
|
+
expect(list.length).toBe(0);
|
|
14
|
+
expect(list.head).toBeUndefined();
|
|
15
|
+
expect(list.tail).toBeUndefined();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe("push", () => {
|
|
20
|
+
it("should add an element to an empty list", () => {
|
|
21
|
+
list.push(1);
|
|
22
|
+
expect(list.length).toBe(1);
|
|
23
|
+
expect(list.head?.value).toBe(1);
|
|
24
|
+
expect(list.tail?.value).toBe(1);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should add multiple elements in sequence", () => {
|
|
28
|
+
list.push(1);
|
|
29
|
+
list.push(2);
|
|
30
|
+
list.push(3);
|
|
31
|
+
expect(list.length).toBe(3);
|
|
32
|
+
expect(list.head?.value).toBe(1);
|
|
33
|
+
expect(list.tail?.value).toBe(3);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("shift", () => {
|
|
38
|
+
it("should return undefined for empty list", () => {
|
|
39
|
+
expect(list.shift()).toBeUndefined();
|
|
40
|
+
expect(list.length).toBe(0);
|
|
41
|
+
expect(list.head).toBeUndefined();
|
|
42
|
+
expect(list.tail).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should remove and return the first element", () => {
|
|
46
|
+
list.push(1);
|
|
47
|
+
list.push(2);
|
|
48
|
+
|
|
49
|
+
const shifted = list.shift();
|
|
50
|
+
expect(shifted).toBe(1);
|
|
51
|
+
expect(list.length).toBe(1);
|
|
52
|
+
expect(list.head?.value).toBe(2);
|
|
53
|
+
expect(list.tail?.value).toBe(2);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should maintain correct order when shifting multiple times", () => {
|
|
57
|
+
list.push(1);
|
|
58
|
+
list.push(2);
|
|
59
|
+
list.push(3);
|
|
60
|
+
|
|
61
|
+
expect(list.shift()).toBe(1);
|
|
62
|
+
expect(list.shift()).toBe(2);
|
|
63
|
+
expect(list.shift()).toBe(3);
|
|
64
|
+
expect(list.length).toBe(0);
|
|
65
|
+
expect(list.head).toBeUndefined();
|
|
66
|
+
expect(list.tail).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should handle shift after last element is removed", () => {
|
|
70
|
+
list.push(1);
|
|
71
|
+
list.shift();
|
|
72
|
+
expect(list.shift()).toBeUndefined();
|
|
73
|
+
expect(list.length).toBe(0);
|
|
74
|
+
expect(list.head).toBeUndefined();
|
|
75
|
+
expect(list.tail).toBeUndefined();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("edge cases", () => {
|
|
80
|
+
it("should handle push after all elements have been shifted", () => {
|
|
81
|
+
list.push(1);
|
|
82
|
+
list.shift();
|
|
83
|
+
list.push(2);
|
|
84
|
+
expect(list.length).toBe(1);
|
|
85
|
+
expect(list.shift()).toBe(2);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("should handle alternating push and shift operations", () => {
|
|
89
|
+
list.push(1);
|
|
90
|
+
expect(list.shift()).toBe(1);
|
|
91
|
+
list.push(2);
|
|
92
|
+
expect(list.shift()).toBe(2);
|
|
93
|
+
expect(list.length).toBe(0);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|