@seriousme/opifex 1.11.0 → 1.11.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 +5 -5
- package/benchmarks/bombing.ts +35 -0
- package/benchmarks/throughputCounter.ts +31 -0
- package/benchmarks/utils.ts +32 -0
- package/client/client.ts +6 -10
- package/client/context.ts +3 -9
- package/client/deps.ts +1 -2
- package/client/handlers/handlePublish.ts +2 -2
- package/client/handlers/handlePubrel.ts +1 -1
- package/deno/tcpServer.test.ts +0 -1
- package/dev_utils/dummyConn.ts +5 -5
- package/dev_utils/mod.ts +1 -0
- package/dev_utils/timers.ts +51 -0
- package/dist/client/client.d.ts +2 -6
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +6 -9
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +2 -3
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +4 -8
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +1 -2
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +1 -2
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handlePublish.js +2 -2
- package/dist/client/handlers/handlePublish.js.map +1 -1
- package/dist/client/handlers/handlePubrel.js +1 -1
- package/dist/client/handlers/handlePubrel.js.map +1 -1
- package/dist/mqttConn/mqttConn.d.ts +2 -7
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +18 -11
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/utils/{asyncQueue.d.ts → BufferedAsyncIterable.d.ts} +8 -8
- package/dist/utils/BufferedAsyncIterable.d.ts.map +1 -0
- package/dist/utils/BufferedAsyncIterable.js +70 -0
- package/dist/utils/BufferedAsyncIterable.js.map +1 -0
- package/dist/utils/mod.d.ts +1 -2
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +1 -2
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/queue.d.ts +43 -0
- package/dist/utils/queue.d.ts.map +1 -0
- package/dist/utils/queue.js +63 -0
- package/dist/utils/queue.js.map +1 -0
- package/examples/tcpServer.test.ts +0 -1
- package/mqttConn/mqttConn.test.ts +5 -4
- package/mqttConn/mqttConn.ts +19 -15
- package/node/tcpServer.test.ts +0 -1
- package/package.json +1 -1
- package/server/test/handleConnect.test.ts +11 -8
- package/utils/BufferedAsyncIterable.ts +76 -0
- package/utils/mod.ts +1 -2
- package/utils/queue.ts +66 -0
- package/dist/utils/asyncQueue.d.ts.map +0 -1
- package/dist/utils/asyncQueue.js +0 -65
- package/dist/utils/asyncQueue.js.map +0 -1
- package/dist/utils/nextTick.d.ts +0 -17
- package/dist/utils/nextTick.d.ts.map +0 -1
- package/dist/utils/nextTick.js +0 -19
- package/dist/utils/nextTick.js.map +0 -1
- package/utils/asyncQueue.ts +0 -71
- package/utils/nextTick.ts +0 -18
package/utils/queue.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simple queue implementation using an array.
|
|
3
|
+
* This implementation optimizes for O(1) enqueue and dequeue operations
|
|
4
|
+
* by avoiding array shifts, which are O(n).
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```ts
|
|
8
|
+
* const queue = new ArrayQueue<number>();
|
|
9
|
+
* queue.enqueue(1);
|
|
10
|
+
* queue.enqueue(2);
|
|
11
|
+
* console.log(queue.dequeue()); // 1
|
|
12
|
+
* console.log(queue.size()); // 1
|
|
13
|
+
* console.log(queue.isEmpty()); // false
|
|
14
|
+
* queue.dequeue();
|
|
15
|
+
* console.log(queue.isEmpty()); // true
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export class ArrayQueue<T> {
|
|
20
|
+
private items: T[] = [];
|
|
21
|
+
private headIndex: number = 0; // Tracks the front of the queue
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* size is the difference between the actual array length and the index offset
|
|
25
|
+
* @returns the number of items in the queue
|
|
26
|
+
*/
|
|
27
|
+
public size(): number {
|
|
28
|
+
return this.items.length - this.headIndex;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* isEmpty checks if the queue has no items
|
|
32
|
+
* @returns true if the queue is empty
|
|
33
|
+
*/
|
|
34
|
+
public isEmpty(): boolean {
|
|
35
|
+
return this.size() === 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* enqueue adds an item to the end of the queue
|
|
39
|
+
* O(1) - Push to the end is highly optimized in V8.
|
|
40
|
+
*/
|
|
41
|
+
public enqueue(data: T): void {
|
|
42
|
+
this.items.push(data);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* dequeue removes and returns the item at the front of the queue
|
|
46
|
+
* O(1) - Avoids array shifting by incrementing the index.
|
|
47
|
+
* @returns the item at the front of the queue or undefined if the queue is empty
|
|
48
|
+
*/
|
|
49
|
+
public dequeue(): T | undefined {
|
|
50
|
+
if (this.isEmpty()) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const item = this.items[this.headIndex];
|
|
55
|
+
this.headIndex++; // Move the "front" marker forward
|
|
56
|
+
|
|
57
|
+
// Optimization: Periodically "clean up" the dead space
|
|
58
|
+
// when the empty space (headIndex) exceeds a threshold.
|
|
59
|
+
// This amortizes the cost, keeping average time closer to O(1).
|
|
60
|
+
if (this.headIndex > 2000 && this.headIndex > this.items.length / 4) {
|
|
61
|
+
this.items = this.items.slice(this.headIndex);
|
|
62
|
+
this.headIndex = 0;
|
|
63
|
+
}
|
|
64
|
+
return item;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asyncQueue.d.ts","sourceRoot":"","sources":["../../utils/asyncQueue.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,qBAAa,UAAU,CAAC,CAAC;;IACvB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,cAAc,CAAY;IAElC,OAAO,CAAC,IAAI,CAAS;gBAIT,cAAc,CAAC,EAAE,MAAM;IAM7B,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC;IAYxB,KAAK,CAAC,MAAM,SAAW,GAAG,IAAI;IAOvB,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;IAM1E,IAAI,CAAC,IAAI,EAAE,CAAC;IAYZ,IAAI,MAAM,IAAI,OAAO,CAEpB;CACF"}
|
package/dist/utils/asyncQueue.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Deferred } from "./deferred.js";
|
|
2
|
-
import { nextTick } from "./nextTick.js";
|
|
3
|
-
/**
|
|
4
|
-
* An Async Queue is a queue that can be used to push items to it and then wait
|
|
5
|
-
* for them to be consumed.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const queue = new AsyncQueue<string>();
|
|
10
|
-
* queue.push("hello");
|
|
11
|
-
* for await (const item of queue) {
|
|
12
|
-
* console.log(item); // "hello"
|
|
13
|
-
* }
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
export class AsyncQueue {
|
|
17
|
-
queue = [];
|
|
18
|
-
maxQueueLength = Infinity;
|
|
19
|
-
done = false;
|
|
20
|
-
#next;
|
|
21
|
-
constructor(maxQueueLength) {
|
|
22
|
-
if (maxQueueLength) {
|
|
23
|
-
this.maxQueueLength = maxQueueLength;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async next() {
|
|
27
|
-
await nextTick();
|
|
28
|
-
if (this.queue.length) {
|
|
29
|
-
return Promise.resolve(this.queue.shift());
|
|
30
|
-
}
|
|
31
|
-
else if (this.done) {
|
|
32
|
-
return Promise.reject("Closed");
|
|
33
|
-
}
|
|
34
|
-
else if (!this.#next) {
|
|
35
|
-
this.#next = new Deferred();
|
|
36
|
-
}
|
|
37
|
-
return this.#next.promise;
|
|
38
|
-
}
|
|
39
|
-
close(reason = "closed") {
|
|
40
|
-
this.done = true;
|
|
41
|
-
if (this.#next) {
|
|
42
|
-
this.#next.reject(new Error(reason));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async *[Symbol.asyncIterator]() {
|
|
46
|
-
while (true) {
|
|
47
|
-
yield await this.next();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
push(item) {
|
|
51
|
-
if (this.#next) {
|
|
52
|
-
this.#next.resolve(item);
|
|
53
|
-
this.#next = undefined;
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (this.queue.length > this.maxQueueLength) {
|
|
57
|
-
this.queue.shift();
|
|
58
|
-
}
|
|
59
|
-
this.queue.push(item);
|
|
60
|
-
}
|
|
61
|
-
get isDone() {
|
|
62
|
-
return this.done;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
//# sourceMappingURL=asyncQueue.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asyncQueue.js","sourceRoot":"","sources":["../../utils/asyncQueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC;;;;;;;;;;;;GAYG;AAEH,MAAM,OAAO,UAAU;IACb,KAAK,GAAQ,EAAE,CAAC;IAChB,cAAc,GAAG,QAAQ,CAAC;IAE1B,IAAI,GAAG,KAAK,CAAC;IAErB,KAAK,CAAe;IAEpB,YAAY,cAAuB;QACjC,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACvC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,QAAQ,EAAE,CAAC;QACjB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,EAAK,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,GAAG,QAAQ;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAO;QACV,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/utils/nextTick.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a promise that resolves on the next tick of the Node.js event loop.
|
|
3
|
-
* This is useful for deferring execution of code until after the current call stack is cleared.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```ts
|
|
7
|
-
* async function example() {
|
|
8
|
-
* console.log('Before nextTick');
|
|
9
|
-
* await nextTick();
|
|
10
|
-
* console.log('After nextTick');
|
|
11
|
-
* }
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* @returns {Promise<void>} A promise that resolves on the next tick of the event loop
|
|
15
|
-
*/
|
|
16
|
-
export declare function nextTick(): Promise<void>;
|
|
17
|
-
//# sourceMappingURL=nextTick.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nextTick.d.ts","sourceRoot":"","sources":["../../utils/nextTick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAExC"}
|
package/dist/utils/nextTick.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a promise that resolves on the next tick of the Node.js event loop.
|
|
3
|
-
* This is useful for deferring execution of code until after the current call stack is cleared.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```ts
|
|
7
|
-
* async function example() {
|
|
8
|
-
* console.log('Before nextTick');
|
|
9
|
-
* await nextTick();
|
|
10
|
-
* console.log('After nextTick');
|
|
11
|
-
* }
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* @returns {Promise<void>} A promise that resolves on the next tick of the event loop
|
|
15
|
-
*/
|
|
16
|
-
export function nextTick() {
|
|
17
|
-
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=nextTick.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nextTick.js","sourceRoot":"","sources":["../../utils/nextTick.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC"}
|
package/utils/asyncQueue.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Deferred } from "./deferred.ts";
|
|
2
|
-
import { nextTick } from "./nextTick.ts";
|
|
3
|
-
/**
|
|
4
|
-
* An Async Queue is a queue that can be used to push items to it and then wait
|
|
5
|
-
* for them to be consumed.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const queue = new AsyncQueue<string>();
|
|
10
|
-
* queue.push("hello");
|
|
11
|
-
* for await (const item of queue) {
|
|
12
|
-
* console.log(item); // "hello"
|
|
13
|
-
* }
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export class AsyncQueue<T> {
|
|
18
|
-
private queue: T[] = [];
|
|
19
|
-
private maxQueueLength = Infinity;
|
|
20
|
-
|
|
21
|
-
private done = false;
|
|
22
|
-
|
|
23
|
-
#next?: Deferred<T>;
|
|
24
|
-
|
|
25
|
-
constructor(maxQueueLength?: number) {
|
|
26
|
-
if (maxQueueLength) {
|
|
27
|
-
this.maxQueueLength = maxQueueLength;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async next(): Promise<T> {
|
|
32
|
-
await nextTick();
|
|
33
|
-
if (this.queue.length) {
|
|
34
|
-
return Promise.resolve(this.queue.shift()!);
|
|
35
|
-
} else if (this.done) {
|
|
36
|
-
return Promise.reject("Closed");
|
|
37
|
-
} else if (!this.#next) {
|
|
38
|
-
this.#next = new Deferred<T>();
|
|
39
|
-
}
|
|
40
|
-
return this.#next.promise;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
close(reason = "closed"): void {
|
|
44
|
-
this.done = true;
|
|
45
|
-
if (this.#next) {
|
|
46
|
-
this.#next.reject(new Error(reason));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async *[Symbol.asyncIterator](): AsyncGenerator<Awaited<T>, void, unknown> {
|
|
51
|
-
while (true) {
|
|
52
|
-
yield await this.next();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
push(item: T) {
|
|
57
|
-
if (this.#next) {
|
|
58
|
-
this.#next.resolve(item);
|
|
59
|
-
this.#next = undefined;
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (this.queue.length > this.maxQueueLength) {
|
|
63
|
-
this.queue.shift();
|
|
64
|
-
}
|
|
65
|
-
this.queue.push(item);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
get isDone(): boolean {
|
|
69
|
-
return this.done;
|
|
70
|
-
}
|
|
71
|
-
}
|
package/utils/nextTick.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a promise that resolves on the next tick of the Node.js event loop.
|
|
3
|
-
* This is useful for deferring execution of code until after the current call stack is cleared.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```ts
|
|
7
|
-
* async function example() {
|
|
8
|
-
* console.log('Before nextTick');
|
|
9
|
-
* await nextTick();
|
|
10
|
-
* console.log('After nextTick');
|
|
11
|
-
* }
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* @returns {Promise<void>} A promise that resolves on the next tick of the event loop
|
|
15
|
-
*/
|
|
16
|
-
export function nextTick(): Promise<void> {
|
|
17
|
-
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
18
|
-
}
|