@seriousme/opifex 1.11.0 → 1.11.2
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/receiver.ts +35 -0
- package/benchmarks/sender.ts +32 -0
- package/benchmarks/utils.ts +9 -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/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +17 -2
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +6 -10
- package/dist/server/handlers/handlePubrel.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/handlers/handlePublish.ts +18 -2
- package/server/handlers/handlePubrel.ts +6 -10
- 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
|
@@ -22,8 +22,6 @@ export interface IMqttConn extends AsyncIterable<AnyPacket> {
|
|
|
22
22
|
readonly isClosed: boolean;
|
|
23
23
|
/** Reason for connection closure if any */
|
|
24
24
|
readonly reason: string | undefined;
|
|
25
|
-
/** Async iterator for receiving packets */
|
|
26
|
-
[Symbol.asyncIterator](): AsyncIterableIterator<AnyPacket>;
|
|
27
25
|
/** Send an MQTT packet */
|
|
28
26
|
send(data: AnyPacket): Promise<void>;
|
|
29
27
|
/** Close the connection */
|
|
@@ -41,6 +39,7 @@ export declare function readPacket(conn: Conn, codecOpts: CodecOpts): Promise<An
|
|
|
41
39
|
* MQTT Connection class implementing IMqttConn interface
|
|
42
40
|
*/
|
|
43
41
|
export declare class MqttConn implements IMqttConn {
|
|
42
|
+
#private;
|
|
44
43
|
/** Underlying connection */
|
|
45
44
|
readonly conn: Conn;
|
|
46
45
|
/** codecOpts */
|
|
@@ -66,11 +65,7 @@ export declare class MqttConn implements IMqttConn {
|
|
|
66
65
|
get reason(): string | undefined;
|
|
67
66
|
/** Get remoteAdress */
|
|
68
67
|
get remoteAddress(): string;
|
|
69
|
-
|
|
70
|
-
* Async iterator for receiving packets
|
|
71
|
-
* @yields MQTT packets
|
|
72
|
-
*/
|
|
73
|
-
[Symbol.asyncIterator](): AsyncIterableIterator<AnyPacket>;
|
|
68
|
+
[Symbol.asyncIterator](): AsyncIterator<AnyPacket>;
|
|
74
69
|
/**
|
|
75
70
|
* Send an MQTT packet
|
|
76
71
|
* @param data Packet to send
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqttConn.d.ts","sourceRoot":"","sources":["../../mqttConn/mqttConn.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EAET,aAAa,EACd,MAAM,sBAAsB,CAAC;AAU9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAIX;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,aAAa,CAAC,SAAS,CAAC;IACzD,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,
|
|
1
|
+
{"version":3,"file":"mqttConn.d.ts","sourceRoot":"","sources":["../../mqttConn/mqttConn.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EAET,aAAa,EACd,MAAM,sBAAsB,CAAC;AAU9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAIX;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,aAAa,CAAC,SAAS,CAAC;IACzD,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,0BAA0B;IAC1B,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,2BAA2B;IAC3B,KAAK,IAAI,IAAI,CAAC;CACf;AAgCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,SAAS,CAAC,CAuBpB;AAED;;GAEG;AACH,qBAAa,QAAS,YAAW,SAAS;;IACxC,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,gBAAgB;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,2CAA2C;IAC3C,OAAO,CAAC,OAAO,CAAiC;IAChD,mCAAmC;IACnC,OAAO,CAAC,SAAS,CAAS;IAE1B;;;;;;;OAOG;gBACS,EACV,IAAI,EACJ,qBAA8C,EAC9C,aAAiC,GAClC,EAAE;QACD,IAAI,EAAE,QAAQ,CAAC;QACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,aAAa,CAAC,EAAE,aAAa,CAAC;KAC/B;IASD,wCAAwC;IACxC,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,uBAAuB;IACvB,IAAI,aAAa,IAAI,MAAM,CAK1B;IA0BM,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC;IAOzD;;;OAGG;IACG,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1C,mCAAmC;IACnC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,2BAA2B;IAC3B,KAAK,IAAI,IAAI;CAUd"}
|
|
@@ -108,25 +108,32 @@ export class MqttConn {
|
|
|
108
108
|
return "unknown";
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
111
|
+
* Returns incoming MQTT packages until the connection is closed. Note that
|
|
112
|
+
* the connection will close automatically upon receiving an invalid packet.
|
|
113
|
+
*
|
|
114
|
+
* @returns a Promise that resolves to AnyPacket if the connection is open
|
|
115
|
+
* and working nominally, undefined otherwise.
|
|
113
116
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
yield await readPacket(this.conn, this.codecOpts);
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
117
|
+
#receive() {
|
|
118
|
+
if (!this._isClosed) {
|
|
119
|
+
return readPacket(this.conn, this.codecOpts).catch((err) => {
|
|
120
120
|
if (err instanceof Error) {
|
|
121
121
|
if (err.name === "PartialReadError") {
|
|
122
122
|
err.message = MqttConnError.UnexpectedEof;
|
|
123
123
|
}
|
|
124
124
|
this._reason = err.message;
|
|
125
125
|
}
|
|
126
|
-
// packet too large, malformed packet or connection closed
|
|
126
|
+
// packet too large, malformed packet or connection closed.
|
|
127
127
|
this.close();
|
|
128
|
-
|
|
129
|
-
}
|
|
128
|
+
return undefined;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return Promise.resolve(undefined);
|
|
132
|
+
}
|
|
133
|
+
async *[Symbol.asyncIterator]() {
|
|
134
|
+
let packet;
|
|
135
|
+
while ((packet = await this.#receive()) !== undefined) {
|
|
136
|
+
yield packet;
|
|
130
137
|
}
|
|
131
138
|
}
|
|
132
139
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqttConn.js","sourceRoot":"","sources":["../../mqttConn/mqttConn.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,EACL,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,aAAa,EAAE,gBAAgB;IAC/B,cAAc,EAAE,kBAAkB;IAClC,aAAa,EAAE,gBAAgB;CACvB,CAAC;AAEX,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"mqttConn.js","sourceRoot":"","sources":["../../mqttConn/mqttConn.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlePublish.d.ts","sourceRoot":"","sources":["../../../server/handlers/handlePublish.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAS,MAAM,YAAY,CAAC;AAkBvD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"handlePublish.d.ts","sourceRoot":"","sources":["../../../server/handlers/handlePublish.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAS,MAAM,YAAY,CAAC;AAkBvD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAiDf"}
|
|
@@ -43,9 +43,24 @@ export async function handlePublish(ctx, packet) {
|
|
|
43
43
|
});
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
/*
|
|
47
|
+
In the QoS 2 delivery protocol, the Receiver
|
|
48
|
+
|
|
49
|
+
- MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH Packet,
|
|
50
|
+
having accepted ownership of the Application Message.
|
|
51
|
+
- Until it has received the corresponding PUBREL packet, the Receiver MUST acknowledge any subsequent
|
|
52
|
+
PUBLISH packet with the same Packet Identifier by sending a PUBREC. It MUST NOT cause duplicate
|
|
53
|
+
messages to be delivered to any onward recipients in this case.
|
|
54
|
+
- MUST respond to a PUBREL packet by sending a PUBCOMP packet containing the same Packet Identifier as the PUBREL.
|
|
55
|
+
- After it has sent a PUBCOMP, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet
|
|
56
|
+
Identifier as being a new publication.
|
|
57
|
+
[MQTT-4.3.3-2].
|
|
58
|
+
*/
|
|
47
59
|
if (ctx.store) {
|
|
48
|
-
ctx.store.pendingIncoming.
|
|
60
|
+
if (!ctx.store.pendingIncoming.has(packet.id)) {
|
|
61
|
+
ctx.store.pendingIncoming.set(packet.id, packet);
|
|
62
|
+
ctx.persistence.publish(packet.topic, packet);
|
|
63
|
+
}
|
|
49
64
|
await ctx.send({
|
|
50
65
|
type: PacketType.pubrec,
|
|
51
66
|
protocolLevel: ctx.protocolLevel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlePublish.js","sourceRoot":"","sources":["../../../server/handlers/handlePublish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,GAAY,EAAE,KAAY;IACrD,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACvC,OAAO,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,MAAqB;IAErB,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5B,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ;QACR,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACd,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,gBAAgB;YACtC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,GAAG,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,EAAE;aACH,CAAC,CAAC;YACH,OAAO;QACT,CAAC;
|
|
1
|
+
{"version":3,"file":"handlePublish.js","sourceRoot":"","sources":["../../../server/handlers/handlePublish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,GAAY,EAAE,KAAY;IACrD,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACvC,OAAO,GAAG,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAY,EACZ,MAAqB;IAErB,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5B,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ;QACR,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACd,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,gBAAgB;YACtC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,MAAM,GAAG,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,EAAE;aACH,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED;;;;;;;;;;;;UAYE;QACF,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9C,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBACjD,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,GAAG,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,EAAE,EAAE,MAAM,CAAC,EAAE;aACd,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlePubrel.d.ts","sourceRoot":"","sources":["../../../server/handlers/handlePubrel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"handlePubrel.d.ts","sourceRoot":"","sources":["../../../server/handlers/handlePubrel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
|
@@ -14,16 +14,12 @@ import { PacketType } from "../deps.js";
|
|
|
14
14
|
export async function handlePubrel(ctx, packet) {
|
|
15
15
|
const id = packet.id;
|
|
16
16
|
if (ctx.store?.pendingIncoming.has(id)) {
|
|
17
|
-
|
|
18
|
-
if (storedPacket) {
|
|
19
|
-
ctx.persistence.publish(storedPacket.topic, storedPacket);
|
|
20
|
-
ctx.store.pendingIncoming.delete(id);
|
|
21
|
-
await ctx.send({
|
|
22
|
-
type: PacketType.pubcomp,
|
|
23
|
-
protocolLevel: ctx.protocolLevel,
|
|
24
|
-
id,
|
|
25
|
-
});
|
|
26
|
-
}
|
|
17
|
+
ctx.store.pendingIncoming.delete(id);
|
|
27
18
|
}
|
|
19
|
+
await ctx.send({
|
|
20
|
+
type: PacketType.pubcomp,
|
|
21
|
+
protocolLevel: ctx.protocolLevel,
|
|
22
|
+
id,
|
|
23
|
+
});
|
|
28
24
|
}
|
|
29
25
|
//# sourceMappingURL=handlePubrel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlePubrel.js","sourceRoot":"","sources":["../../../server/handlers/handlePubrel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAY,EACZ,MAAoB;IAEpB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;IACrB,IAAI,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,
|
|
1
|
+
{"version":3,"file":"handlePubrel.js","sourceRoot":"","sources":["../../../server/handlers/handlePubrel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAY,EACZ,MAAoB;IAEpB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;IACrB,IAAI,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,GAAG,CAAC,IAAI,CAAC;QACb,IAAI,EAAE,UAAU,CAAC,OAAO;QACxB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,EAAE;KACH,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
* }
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
|
-
export declare class
|
|
14
|
+
export declare class BufferedAsyncIterable<T> implements AsyncIterable<T> {
|
|
15
15
|
#private;
|
|
16
|
-
private
|
|
17
|
-
private
|
|
16
|
+
private buffer;
|
|
17
|
+
private bufferSize;
|
|
18
18
|
private done;
|
|
19
|
-
constructor(
|
|
20
|
-
next(): Promise<T>;
|
|
21
|
-
close(reason?: string): void;
|
|
19
|
+
constructor(bufferSize?: number);
|
|
22
20
|
[Symbol.asyncIterator](): AsyncGenerator<Awaited<T>, void, unknown>;
|
|
23
|
-
|
|
21
|
+
next(): T | Promise<T>;
|
|
22
|
+
close(reason?: string): void;
|
|
23
|
+
readonly push: (item: T) => void | Promise<void>;
|
|
24
24
|
get isDone(): boolean;
|
|
25
25
|
}
|
|
26
|
-
//# sourceMappingURL=
|
|
26
|
+
//# sourceMappingURL=BufferedAsyncIterable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BufferedAsyncIterable.d.ts","sourceRoot":"","sources":["../../utils/BufferedAsyncIterable.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAqB,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC;;IAC/D,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,IAAI,CAAS;gBAIT,UAAU,GAAE,MAAa;IAK9B,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;IAM1E,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAYtB,KAAK,CAAC,MAAM,SAAW,GAAG,IAAI;IAO9B,QAAQ,CAAC,IAAI,GAAI,MAAM,CAAC,KAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7C;IAEF,IAAI,MAAM,IAAI,OAAO,CAEpB;CACF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Deferred } from "./deferred.js";
|
|
2
|
+
import { ArrayQueue } from "./queue.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 BufferedAsyncIterable {
|
|
17
|
+
buffer;
|
|
18
|
+
bufferSize;
|
|
19
|
+
done = false;
|
|
20
|
+
#next;
|
|
21
|
+
constructor(bufferSize = 2048) {
|
|
22
|
+
this.buffer = new ArrayQueue();
|
|
23
|
+
this.bufferSize = bufferSize;
|
|
24
|
+
}
|
|
25
|
+
async *[Symbol.asyncIterator]() {
|
|
26
|
+
while (!this.done) {
|
|
27
|
+
yield this.next();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
next() {
|
|
31
|
+
// await nextTick();
|
|
32
|
+
if (this.buffer.size() > 0) {
|
|
33
|
+
return this.buffer.dequeue();
|
|
34
|
+
}
|
|
35
|
+
else if (this.done) {
|
|
36
|
+
throw new Error("Closed");
|
|
37
|
+
}
|
|
38
|
+
else if (!this.#next) {
|
|
39
|
+
this.#next = new Deferred();
|
|
40
|
+
}
|
|
41
|
+
return this.#next.promise;
|
|
42
|
+
}
|
|
43
|
+
close(reason = "closed") {
|
|
44
|
+
this.done = true;
|
|
45
|
+
if (this.#next) {
|
|
46
|
+
this.#next.reject(new Error(reason));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
push = (item) => {
|
|
50
|
+
if (this.#next) {
|
|
51
|
+
this.#next.resolve(item);
|
|
52
|
+
this.#next = undefined;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.buffer.enqueue(item);
|
|
56
|
+
if (this.buffer.size() > this.bufferSize) {
|
|
57
|
+
// If our current buffer has grown greater than the allowed size we adaptively
|
|
58
|
+
// wait for an amount of milliseconds proportional to the size of the buffer.
|
|
59
|
+
// This ensures backpressure is applied to the producer that is pushing items
|
|
60
|
+
// into the queue. Note that this might be an exceedingly simple heuristic,
|
|
61
|
+
// a PID (Proportional-Integral-Derivative) controller could be used to improve
|
|
62
|
+
// the responsiveness of the system.
|
|
63
|
+
return new Promise((resolve) => setTimeout(resolve, this.buffer.size()));
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
get isDone() {
|
|
67
|
+
return this.done;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=BufferedAsyncIterable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BufferedAsyncIterable.js","sourceRoot":"","sources":["../../utils/BufferedAsyncIterable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAqB;IACxB,MAAM,CAAgB;IACtB,UAAU,CAAS;IAEnB,IAAI,GAAG,KAAK,CAAC;IAErB,KAAK,CAAe;IAEpB,YAAY,aAAqB,IAAI;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI;QACF,oBAAoB;QACpB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAG,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC5B,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;IAEQ,IAAI,GAAG,CAAC,IAAO,EAAwB,EAAE;QAChD,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,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACzC,8EAA8E;YAC9E,6EAA6E;YAC7E,6EAA6E;YAC7E,2EAA2E;YAC3E,+EAA+E;YAC/E,oCAAoC;YACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/utils/mod.d.ts
CHANGED
|
@@ -5,6 +5,5 @@
|
|
|
5
5
|
export { assert } from "./assert.ts";
|
|
6
6
|
export { Deferred } from "./deferred.ts";
|
|
7
7
|
export { Logger, logger, LogLevel } from "./logger.ts";
|
|
8
|
-
export {
|
|
9
|
-
export { nextTick } from "./nextTick.ts";
|
|
8
|
+
export { BufferedAsyncIterable } from "./BufferedAsyncIterable.ts";
|
|
10
9
|
//# sourceMappingURL=mod.d.ts.map
|
package/dist/utils/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../utils/mod.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../utils/mod.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/utils/mod.js
CHANGED
|
@@ -5,6 +5,5 @@
|
|
|
5
5
|
export { assert } from "./assert.js";
|
|
6
6
|
export { Deferred } from "./deferred.js";
|
|
7
7
|
export { Logger, logger, LogLevel } from "./logger.js";
|
|
8
|
-
export {
|
|
9
|
-
export { nextTick } from "./nextTick.js";
|
|
8
|
+
export { BufferedAsyncIterable } from "./BufferedAsyncIterable.js";
|
|
10
9
|
//# sourceMappingURL=mod.js.map
|
package/dist/utils/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../utils/mod.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../utils/mod.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
export declare class ArrayQueue<T> {
|
|
19
|
+
private items;
|
|
20
|
+
private headIndex;
|
|
21
|
+
/**
|
|
22
|
+
* size is the difference between the actual array length and the index offset
|
|
23
|
+
* @returns the number of items in the queue
|
|
24
|
+
*/
|
|
25
|
+
size(): number;
|
|
26
|
+
/**
|
|
27
|
+
* isEmpty checks if the queue has no items
|
|
28
|
+
* @returns true if the queue is empty
|
|
29
|
+
*/
|
|
30
|
+
isEmpty(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* enqueue adds an item to the end of the queue
|
|
33
|
+
* O(1) - Push to the end is highly optimized in V8.
|
|
34
|
+
*/
|
|
35
|
+
enqueue(data: T): void;
|
|
36
|
+
/**
|
|
37
|
+
* dequeue removes and returns the item at the front of the queue
|
|
38
|
+
* O(1) - Avoids array shifting by incrementing the index.
|
|
39
|
+
* @returns the item at the front of the queue or undefined if the queue is empty
|
|
40
|
+
*/
|
|
41
|
+
dequeue(): T | undefined;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../utils/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,qBAAa,UAAU,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAa;IAE9B;;;OAGG;IACI,IAAI,IAAI,MAAM;IAGrB;;;OAGG;IACI,OAAO,IAAI,OAAO;IAGzB;;;OAGG;IACI,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAG7B;;;;OAIG;IACI,OAAO,IAAI,CAAC,GAAG,SAAS;CAiBhC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
export class ArrayQueue {
|
|
19
|
+
items = [];
|
|
20
|
+
headIndex = 0; // Tracks the front of the queue
|
|
21
|
+
/**
|
|
22
|
+
* size is the difference between the actual array length and the index offset
|
|
23
|
+
* @returns the number of items in the queue
|
|
24
|
+
*/
|
|
25
|
+
size() {
|
|
26
|
+
return this.items.length - this.headIndex;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* isEmpty checks if the queue has no items
|
|
30
|
+
* @returns true if the queue is empty
|
|
31
|
+
*/
|
|
32
|
+
isEmpty() {
|
|
33
|
+
return this.size() === 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* enqueue adds an item to the end of the queue
|
|
37
|
+
* O(1) - Push to the end is highly optimized in V8.
|
|
38
|
+
*/
|
|
39
|
+
enqueue(data) {
|
|
40
|
+
this.items.push(data);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* dequeue removes and returns the item at the front of the queue
|
|
44
|
+
* O(1) - Avoids array shifting by incrementing the index.
|
|
45
|
+
* @returns the item at the front of the queue or undefined if the queue is empty
|
|
46
|
+
*/
|
|
47
|
+
dequeue() {
|
|
48
|
+
if (this.isEmpty()) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const item = this.items[this.headIndex];
|
|
52
|
+
this.headIndex++; // Move the "front" marker forward
|
|
53
|
+
// Optimization: Periodically "clean up" the dead space
|
|
54
|
+
// when the empty space (headIndex) exceeds a threshold.
|
|
55
|
+
// This amortizes the cost, keeping average time closer to O(1).
|
|
56
|
+
if (this.headIndex > 2000 && this.headIndex > this.items.length / 4) {
|
|
57
|
+
this.items = this.items.slice(this.headIndex);
|
|
58
|
+
this.headIndex = 0;
|
|
59
|
+
}
|
|
60
|
+
return item;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../utils/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,OAAO,UAAU;IACb,KAAK,GAAQ,EAAE,CAAC;IAChB,SAAS,GAAW,CAAC,CAAC,CAAC,gCAAgC;IAE/D;;;OAGG;IACI,IAAI;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;IAC5C,CAAC;IACD;;;OAGG;IACI,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD;;;OAGG;IACI,OAAO,CAAC,IAAO;QACpB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IACD;;;;OAIG;IACI,OAAO;QACZ,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACnB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,kCAAkC;QAEpD,uDAAuD;QACvD,wDAAwD;QACxD,gEAAgE;QAChE,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -56,7 +56,7 @@ test("MqttConn should act as asyncIterator", async () => {
|
|
|
56
56
|
);
|
|
57
57
|
const mqttConn = new MqttConn({ conn, protocolLevel: 4 });
|
|
58
58
|
|
|
59
|
-
const packets = [];
|
|
59
|
+
const packets: AnyPacket[] = [];
|
|
60
60
|
for await (const packet of mqttConn) {
|
|
61
61
|
packets.push(packet);
|
|
62
62
|
}
|
|
@@ -71,7 +71,7 @@ test("MqttConn should close on malformed length", async () => {
|
|
|
71
71
|
const conn = makeDummySockConn([new Uint8Array([1, 175])], new Uint8Array());
|
|
72
72
|
const mqttConn = new MqttConn({ conn });
|
|
73
73
|
|
|
74
|
-
const packets = [];
|
|
74
|
+
const packets: AnyPacket[] = [];
|
|
75
75
|
for await (const packet of mqttConn) {
|
|
76
76
|
packets.push(packet);
|
|
77
77
|
}
|
|
@@ -89,7 +89,7 @@ test("MqttConn should close on failed packets", async () => {
|
|
|
89
89
|
const conn = makeDummySockConn([connect, brokenPublish], new Uint8Array());
|
|
90
90
|
const mqttConn = new MqttConn({ conn });
|
|
91
91
|
|
|
92
|
-
const packets = [];
|
|
92
|
+
const packets: AnyPacket[] = [];
|
|
93
93
|
for await (const packet of mqttConn) {
|
|
94
94
|
packets.push(packet);
|
|
95
95
|
}
|
|
@@ -105,7 +105,8 @@ test("MqttConn should close on packets too large", async () => {
|
|
|
105
105
|
|
|
106
106
|
const conn = makeDummySockConn([connect], new Uint8Array());
|
|
107
107
|
const mqttConn = new MqttConn({ conn, maxIncomingPacketSize: 20 });
|
|
108
|
-
|
|
108
|
+
|
|
109
|
+
const packets: AnyPacket[] = [];
|
|
109
110
|
for await (const packet of mqttConn) {
|
|
110
111
|
packets.push(packet);
|
|
111
112
|
}
|
package/mqttConn/mqttConn.ts
CHANGED
|
@@ -41,8 +41,6 @@ export interface IMqttConn extends AsyncIterable<AnyPacket> {
|
|
|
41
41
|
readonly isClosed: boolean;
|
|
42
42
|
/** Reason for connection closure if any */
|
|
43
43
|
readonly reason: string | undefined;
|
|
44
|
-
/** Async iterator for receiving packets */
|
|
45
|
-
[Symbol.asyncIterator](): AsyncIterableIterator<AnyPacket>;
|
|
46
44
|
/** Send an MQTT packet */
|
|
47
45
|
send(data: AnyPacket): Promise<void>;
|
|
48
46
|
/** Close the connection */
|
|
@@ -166,27 +164,33 @@ export class MqttConn implements IMqttConn {
|
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
167
|
+
* Returns incoming MQTT packages until the connection is closed. Note that
|
|
168
|
+
* the connection will close automatically upon receiving an invalid packet.
|
|
169
|
+
*
|
|
170
|
+
* @returns a Promise that resolves to AnyPacket if the connection is open
|
|
171
|
+
* and working nominally, undefined otherwise.
|
|
171
172
|
*/
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
yield await readPacket(
|
|
176
|
-
this.conn,
|
|
177
|
-
this.codecOpts,
|
|
178
|
-
);
|
|
179
|
-
} catch (err) {
|
|
173
|
+
#receive(): Promise<AnyPacket | undefined> {
|
|
174
|
+
if (!this._isClosed) {
|
|
175
|
+
return readPacket(this.conn, this.codecOpts).catch((err) => {
|
|
180
176
|
if (err instanceof Error) {
|
|
181
177
|
if (err.name === "PartialReadError") {
|
|
182
178
|
err.message = MqttConnError.UnexpectedEof;
|
|
183
179
|
}
|
|
184
180
|
this._reason = err.message;
|
|
185
181
|
}
|
|
186
|
-
// packet too large, malformed packet or connection closed
|
|
182
|
+
// packet too large, malformed packet or connection closed.
|
|
187
183
|
this.close();
|
|
188
|
-
|
|
189
|
-
}
|
|
184
|
+
return undefined;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return Promise.resolve(undefined);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async *[Symbol.asyncIterator](): AsyncIterator<AnyPacket> {
|
|
191
|
+
let packet: AnyPacket | undefined;
|
|
192
|
+
while ((packet = await this.#receive()) !== undefined) {
|
|
193
|
+
yield packet;
|
|
190
194
|
}
|
|
191
195
|
}
|
|
192
196
|
|
package/node/tcpServer.test.ts
CHANGED
package/package.json
CHANGED
|
@@ -52,9 +52,25 @@ export async function handlePublish(
|
|
|
52
52
|
});
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
In the QoS 2 delivery protocol, the Receiver
|
|
58
|
+
|
|
59
|
+
- MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH Packet,
|
|
60
|
+
having accepted ownership of the Application Message.
|
|
61
|
+
- Until it has received the corresponding PUBREL packet, the Receiver MUST acknowledge any subsequent
|
|
62
|
+
PUBLISH packet with the same Packet Identifier by sending a PUBREC. It MUST NOT cause duplicate
|
|
63
|
+
messages to be delivered to any onward recipients in this case.
|
|
64
|
+
- MUST respond to a PUBREL packet by sending a PUBCOMP packet containing the same Packet Identifier as the PUBREL.
|
|
65
|
+
- After it has sent a PUBCOMP, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet
|
|
66
|
+
Identifier as being a new publication.
|
|
67
|
+
[MQTT-4.3.3-2].
|
|
68
|
+
*/
|
|
56
69
|
if (ctx.store) {
|
|
57
|
-
ctx.store.pendingIncoming.
|
|
70
|
+
if (!ctx.store.pendingIncoming.has(packet.id)) {
|
|
71
|
+
ctx.store.pendingIncoming.set(packet.id, packet);
|
|
72
|
+
ctx.persistence.publish(packet.topic, packet);
|
|
73
|
+
}
|
|
58
74
|
await ctx.send({
|
|
59
75
|
type: PacketType.pubrec,
|
|
60
76
|
protocolLevel: ctx.protocolLevel,
|
|
@@ -20,15 +20,11 @@ export async function handlePubrel(
|
|
|
20
20
|
): Promise<void> {
|
|
21
21
|
const id = packet.id;
|
|
22
22
|
if (ctx.store?.pendingIncoming.has(id)) {
|
|
23
|
-
|
|
24
|
-
if (storedPacket) {
|
|
25
|
-
ctx.persistence.publish(storedPacket.topic, storedPacket);
|
|
26
|
-
ctx.store.pendingIncoming.delete(id);
|
|
27
|
-
await ctx.send({
|
|
28
|
-
type: PacketType.pubcomp,
|
|
29
|
-
protocolLevel: ctx.protocolLevel,
|
|
30
|
-
id,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
23
|
+
ctx.store.pendingIncoming.delete(id);
|
|
33
24
|
}
|
|
25
|
+
await ctx.send({
|
|
26
|
+
type: PacketType.pubcomp,
|
|
27
|
+
protocolLevel: ctx.protocolLevel,
|
|
28
|
+
id,
|
|
29
|
+
});
|
|
34
30
|
}
|