mqtt-plus 1.4.11 → 1.4.12
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/AGENTS.md +8 -8
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/dst-stage1/mqtt-plus-base.d.ts +0 -1
- package/dst-stage1/mqtt-plus-base.js +1 -6
- package/dst-stage1/mqtt-plus-service.js +1 -2
- package/dst-stage1/mqtt-plus-sink.js +5 -7
- package/dst-stage1/mqtt-plus-source.js +2 -4
- package/dst-stage1/mqtt-plus-subscription.d.ts +2 -0
- package/dst-stage1/mqtt-plus-subscription.js +6 -0
- package/dst-stage2/mqtt-plus.cjs.js +12 -18
- package/dst-stage2/mqtt-plus.esm.js +12 -18
- package/dst-stage2/mqtt-plus.umd.js +11 -11
- package/package.json +3 -3
- package/src/mqtt-plus-base.ts +1 -12
- package/src/mqtt-plus-service.ts +1 -3
- package/src/mqtt-plus-sink.ts +37 -42
- package/src/mqtt-plus-source.ts +2 -6
- package/src/mqtt-plus-subscription.ts +12 -0
package/AGENTS.md
CHANGED
|
@@ -65,10 +65,10 @@ each extending the previous. The final exported class `MQTTp` sits at
|
|
|
65
65
|
the bottom of this chain:
|
|
66
66
|
|
|
67
67
|
```
|
|
68
|
-
OptionsTrait — configuration (id, codec, timeout, chunkSize, chunkCredit, topicMake/topicMatch)
|
|
68
|
+
OptionsTrait — configuration (id, codec, timeout, share, chunkSize, chunkCredit, topicMake/topicMatch)
|
|
69
69
|
↓ CodecTrait — CBOR/JSON codec handling
|
|
70
|
-
↓ EncodeTrait —
|
|
71
|
-
↓ MsgTrait — message class definitions and parsing
|
|
70
|
+
↓ EncodeTrait — string/buffer conversion utilities (str2buf, buf2str)
|
|
71
|
+
↓ MsgTrait — message class definitions, valibot schemas, and parsing
|
|
72
72
|
↓ TraceTrait — EventEmitter + structured logging
|
|
73
73
|
↓ BaseTrait — MQTT client hookup, subscription management, message routing
|
|
74
74
|
↓ SubscriptionTrait — ref-counted MQTT topic subscription management
|
|
@@ -92,15 +92,15 @@ Each trait lives in its own file: `src/mqtt-plus-<trait>.ts`.
|
|
|
92
92
|
| `src/mqtt-plus-api.ts` | Branded endpoint type definitions (Event, Service, Source, Sink) and APISchema generic |
|
|
93
93
|
| `src/mqtt-plus-info.ts` | Info/context object types passed to pattern callbacks (sender metadata, etc.) |
|
|
94
94
|
| `src/mqtt-plus-error.ts` | Spool (resource cleanup) and run (error handling) utilities |
|
|
95
|
-
| `src/mqtt-plus-util.ts` |
|
|
95
|
+
| `src/mqtt-plus-util.ts` | PLazy, CreditGate flow control, and stream/buffer collection utilities |
|
|
96
96
|
| `src/mqtt-plus-version.ts` | Version utility for converting version strings to numeric format |
|
|
97
|
-
| `src/mqtt-plus-options.ts` | OptionsTrait — configuration (id, codec, timeout, chunkSize, chunkCredit, topicMake/topicMatch) |
|
|
97
|
+
| `src/mqtt-plus-options.ts` | OptionsTrait — configuration (id, codec, timeout, share, chunkSize, chunkCredit, topicMake/topicMatch) |
|
|
98
98
|
| `src/mqtt-plus-codec.ts` | CodecTrait — CBOR and JSON codec encoding/decoding |
|
|
99
|
-
| `src/mqtt-plus-encode.ts` | EncodeTrait —
|
|
100
|
-
| `src/mqtt-plus-msg.ts` | MsgTrait — message class definitions and parsing logic |
|
|
99
|
+
| `src/mqtt-plus-encode.ts` | EncodeTrait — string/buffer conversion utilities (str2buf, buf2str) |
|
|
100
|
+
| `src/mqtt-plus-msg.ts` | MsgTrait — message class definitions, valibot schemas, and parsing logic |
|
|
101
101
|
| `src/mqtt-plus-trace.ts` | TraceTrait — EventEmitter and structured logging |
|
|
102
102
|
| `src/mqtt-plus-base.ts` | BaseTrait — MQTT client connection, subscription management, message routing |
|
|
103
|
-
| `src/mqtt-plus-subscription.ts` | SubscriptionTrait — ref-counted MQTT topic subscription management |
|
|
103
|
+
| `src/mqtt-plus-subscription.ts` | SubscriptionTrait — RefCountedSubscription class and ref-counted MQTT topic subscription management |
|
|
104
104
|
| `src/mqtt-plus-timer.ts` | TimerTrait — named timer management (refresh/clear) |
|
|
105
105
|
| `src/mqtt-plus-meta.ts` | MetaTrait — instance and per-request metadata management |
|
|
106
106
|
| `src/mqtt-plus-auth.ts` | AuthTrait — JWT authentication (jose) and role-based access control |
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
ChangeLog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
1.4.12 (2026-03-05)
|
|
6
|
+
-------------------
|
|
7
|
+
|
|
8
|
+
- IMPROVEMENT: make all subscriptions ref-counted and spooled
|
|
9
|
+
- UPDATE: update documentation
|
|
10
|
+
- UPDATE: upgrade NPM dependencies
|
|
11
|
+
- CLEANUP: cleanup code
|
|
12
|
+
|
|
5
13
|
1.4.11 (2026-03-05)
|
|
6
14
|
-------------------
|
|
7
15
|
|
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ Notice
|
|
|
176
176
|
|
|
177
177
|
> [!Note]
|
|
178
178
|
> **MQTT+** and its peer dependency **MQTT.js** provide a powerful
|
|
179
|
-
> functionality, but are not small in size. **MQTT+** is 3.
|
|
179
|
+
> functionality, but are not small in size. **MQTT+** is 3.900 LoC
|
|
180
180
|
> and 75 KB in size (ESM and CJS format). When bundled with all its
|
|
181
181
|
> dependencies, it is 220 KB in size (UMD format). Its peer dependency
|
|
182
182
|
> **MQTT.js** is 370 KB (ESM and CJS format) and 860 KB (UMD format) in
|
|
@@ -11,7 +11,6 @@ export declare class BaseTrait<T extends APISchema = APISchema> extends TraceTra
|
|
|
11
11
|
constructor(mqtt: MqttClient | null, options?: Partial<APIOptions>);
|
|
12
12
|
destroy(): Promise<void>;
|
|
13
13
|
protected makeRegistration(spool: Spool, kind: string, name: string, key: string): Registration;
|
|
14
|
-
protected subscribeTopicAndSpool(spool: Spool, topic: string, options?: Partial<IClientSubscribeOptions>): Promise<void>;
|
|
15
14
|
protected subscribeTopic(topic: string, options?: Partial<IClientSubscribeOptions>): Promise<void>;
|
|
16
15
|
protected unsubscribeTopic(topic: string): Promise<void>;
|
|
17
16
|
protected publishToTopic(topic: string, message: string | Uint8Array, options?: IClientPublishOptions): Promise<void>;
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
import { TraceTrait } from "./mqtt-plus-trace";
|
|
25
|
-
import {
|
|
25
|
+
import { ensureError } from "./mqtt-plus-error";
|
|
26
26
|
import { PLazy } from "./mqtt-plus-util";
|
|
27
27
|
/* MQTTp Base class with shared infrastructure */
|
|
28
28
|
export class BaseTrait extends TraceTrait {
|
|
@@ -94,11 +94,6 @@ export class BaseTrait extends TraceTrait {
|
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
/* subscribe to an MQTT topic and spool the unsubscription */
|
|
98
|
-
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
99
|
-
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscribeTopic(topic, { qos: 2, ...options }));
|
|
100
|
-
spool.roll(() => this.unsubscribeTopic(topic).catch(() => { }));
|
|
101
|
-
}
|
|
102
97
|
/* subscribe to an MQTT topic (Promise-based) */
|
|
103
98
|
async subscribeTopic(topic, options = {}) {
|
|
104
99
|
this.log("info", `subscribing to MQTT topic "${topic}"`);
|
|
@@ -137,8 +137,7 @@ export class ServiceTrait extends EventTrait {
|
|
|
137
137
|
requestId = nanoid();
|
|
138
138
|
/* subscribe to MQTT response topic */
|
|
139
139
|
const responseTopic = this.options.topicMake(name, "service-call-response", this.options.id);
|
|
140
|
-
await
|
|
141
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
140
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
142
141
|
/* create promise for MQTT response handling */
|
|
143
142
|
const timerId = `service-call:${requestId}`;
|
|
144
143
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -36,13 +36,13 @@ export class SinkTrait extends SourceTrait {
|
|
|
36
36
|
this.pushStreams = new Map();
|
|
37
37
|
this.pushSpools = new Map();
|
|
38
38
|
}
|
|
39
|
-
/* destroy
|
|
39
|
+
/* destroy trait */
|
|
40
40
|
async destroy() {
|
|
41
41
|
for (const stream of this.pushStreams.values())
|
|
42
42
|
stream.destroy(new Error("sink destroyed"));
|
|
43
|
+
this.pushStreams.clear();
|
|
43
44
|
for (const spool of this.pushSpools.values())
|
|
44
45
|
await spool.unroll();
|
|
45
|
-
this.pushStreams.clear();
|
|
46
46
|
this.pushSpools.clear();
|
|
47
47
|
await super.destroy();
|
|
48
48
|
}
|
|
@@ -76,7 +76,7 @@ export class SinkTrait extends SourceTrait {
|
|
|
76
76
|
const topicReqB = this.options.topicMake(topicS, "sink-push-request");
|
|
77
77
|
const topicReqD = this.options.topicMake(name, "sink-push-request", this.options.id);
|
|
78
78
|
const topicChunkD = this.options.topicMake(name, "sink-push-chunk", this.options.id);
|
|
79
|
-
/*
|
|
79
|
+
/* react on sink push request */
|
|
80
80
|
this.onRequest.set(`sink-push-request:${name}`, async (request, topicName) => {
|
|
81
81
|
/* determine information */
|
|
82
82
|
const requestId = request.id;
|
|
@@ -258,8 +258,7 @@ export class SinkTrait extends SourceTrait {
|
|
|
258
258
|
requestId = nanoid();
|
|
259
259
|
/* subscribe to response topic (for ack/nak) */
|
|
260
260
|
const responseTopic = this.options.topicMake(name, "sink-push-response", this.options.id);
|
|
261
|
-
await
|
|
262
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
261
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
263
262
|
/* define abort controller and signal */
|
|
264
263
|
const abortController = new AbortController();
|
|
265
264
|
const abortSignal = abortController.signal;
|
|
@@ -326,8 +325,7 @@ export class SinkTrait extends SourceTrait {
|
|
|
326
325
|
/* subscribe to credit topic if flow control is active */
|
|
327
326
|
if (creditGate) {
|
|
328
327
|
const creditTopic = this.options.topicMake(name, "sink-push-credit", this.options.id);
|
|
329
|
-
await
|
|
330
|
-
spool.roll(() => this.subscriptions.unsubscribe(creditTopic));
|
|
328
|
+
await this.subscribeTopicAndSpool(spool, creditTopic, { qos: options.qos ?? 2 });
|
|
331
329
|
const gate = creditGate;
|
|
332
330
|
spool.roll(() => { gate.abort(); });
|
|
333
331
|
/* update credit callback to include gate replenish */
|
|
@@ -230,10 +230,8 @@ export class SourceTrait extends ServiceTrait {
|
|
|
230
230
|
/* subscribe to response topic (for ack/nak) and chunk topic (for data) */
|
|
231
231
|
const responseTopic = this.options.topicMake(name, "source-fetch-response", this.options.id);
|
|
232
232
|
const chunkTopic = this.options.topicMake(name, "source-fetch-chunk", this.options.id);
|
|
233
|
-
await
|
|
234
|
-
|
|
235
|
-
await run(`subscribe to MQTT topic "${chunkTopic}"`, spool, () => this.subscriptions.subscribe(chunkTopic, { qos: options.qos ?? 2 }));
|
|
236
|
-
spool.roll(() => this.subscriptions.unsubscribe(chunkTopic));
|
|
233
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
234
|
+
await this.subscribeTopicAndSpool(spool, chunkTopic, { qos: options.qos ?? 2 });
|
|
237
235
|
/* credit-based flow control state */
|
|
238
236
|
const chunkCredit = this.options.chunkCredit;
|
|
239
237
|
let chunksReceived = 0;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { IClientSubscribeOptions } from "mqtt";
|
|
2
2
|
import type { APISchema } from "./mqtt-plus-api";
|
|
3
3
|
import { BaseTrait } from "./mqtt-plus-base";
|
|
4
|
+
import { Spool } from "./mqtt-plus-error";
|
|
4
5
|
declare class RefCountedSubscription {
|
|
5
6
|
private subscribeFn;
|
|
6
7
|
private unsubscribeFn;
|
|
@@ -18,6 +19,7 @@ declare class RefCountedSubscription {
|
|
|
18
19
|
}
|
|
19
20
|
export declare class SubscriptionTrait<T extends APISchema = APISchema> extends BaseTrait<T> {
|
|
20
21
|
protected subscriptions: RefCountedSubscription;
|
|
22
|
+
protected subscribeTopicAndSpool(spool: Spool, topic: string, options?: Partial<IClientSubscribeOptions>): Promise<void>;
|
|
21
23
|
destroy(): Promise<void>;
|
|
22
24
|
}
|
|
23
25
|
export {};
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
import { BaseTrait } from "./mqtt-plus-base";
|
|
25
|
+
import { run } from "./mqtt-plus-error";
|
|
25
26
|
/* reference-counted subscription helper */
|
|
26
27
|
class RefCountedSubscription {
|
|
27
28
|
/* initial construction with configuration */
|
|
@@ -162,6 +163,11 @@ export class SubscriptionTrait extends BaseTrait {
|
|
|
162
163
|
super(...arguments);
|
|
163
164
|
this.subscriptions = new RefCountedSubscription((topic, options) => this.subscribeTopic(topic, options), (topic) => this.unsubscribeTopic(topic));
|
|
164
165
|
}
|
|
166
|
+
/* subscribe to an MQTT topic (reference-counted) and spool the unsubscription */
|
|
167
|
+
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
168
|
+
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscriptions.subscribe(topic, { qos: 2, ...options }));
|
|
169
|
+
spool.roll(() => this.subscriptions.unsubscribe(topic));
|
|
170
|
+
}
|
|
165
171
|
/* destroy subscription trait */
|
|
166
172
|
async destroy() {
|
|
167
173
|
await this.subscriptions.flush();
|
|
@@ -972,12 +972,6 @@ class BaseTrait extends TraceTrait {
|
|
|
972
972
|
}
|
|
973
973
|
};
|
|
974
974
|
}
|
|
975
|
-
/* subscribe to an MQTT topic and spool the unsubscription */
|
|
976
|
-
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
977
|
-
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscribeTopic(topic, { qos: 2, ...options }));
|
|
978
|
-
spool.roll(() => this.unsubscribeTopic(topic).catch(() => {
|
|
979
|
-
}));
|
|
980
|
-
}
|
|
981
975
|
/* subscribe to an MQTT topic (Promise-based) */
|
|
982
976
|
async subscribeTopic(topic, options = {}) {
|
|
983
977
|
this.log("info", `subscribing to MQTT topic "${topic}"`);
|
|
@@ -1191,6 +1185,11 @@ class SubscriptionTrait extends BaseTrait {
|
|
|
1191
1185
|
super(...arguments);
|
|
1192
1186
|
this.subscriptions = new RefCountedSubscription((topic, options) => this.subscribeTopic(topic, options), (topic) => this.unsubscribeTopic(topic));
|
|
1193
1187
|
}
|
|
1188
|
+
/* subscribe to an MQTT topic (reference-counted) and spool the unsubscription */
|
|
1189
|
+
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
1190
|
+
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscriptions.subscribe(topic, { qos: 2, ...options }));
|
|
1191
|
+
spool.roll(() => this.subscriptions.unsubscribe(topic));
|
|
1192
|
+
}
|
|
1194
1193
|
/* destroy subscription trait */
|
|
1195
1194
|
async destroy() {
|
|
1196
1195
|
await this.subscriptions.flush();
|
|
@@ -1522,8 +1521,7 @@ class ServiceTrait extends EventTrait {
|
|
|
1522
1521
|
while (this.onResponse.has(`service-call-response:${requestId}`))
|
|
1523
1522
|
requestId = nanoid.nanoid();
|
|
1524
1523
|
const responseTopic = this.options.topicMake(name, "service-call-response", this.options.id);
|
|
1525
|
-
await
|
|
1526
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
1524
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
1527
1525
|
const timerId = `service-call:${requestId}`;
|
|
1528
1526
|
const promise = new Promise((resolve, reject) => {
|
|
1529
1527
|
this.timerRefresh(timerId, async () => {
|
|
@@ -1719,10 +1717,8 @@ class SourceTrait extends ServiceTrait {
|
|
|
1719
1717
|
requestId = nanoid.nanoid();
|
|
1720
1718
|
const responseTopic = this.options.topicMake(name, "source-fetch-response", this.options.id);
|
|
1721
1719
|
const chunkTopic = this.options.topicMake(name, "source-fetch-chunk", this.options.id);
|
|
1722
|
-
await
|
|
1723
|
-
|
|
1724
|
-
await run(`subscribe to MQTT topic "${chunkTopic}"`, spool, () => this.subscriptions.subscribe(chunkTopic, { qos: options.qos ?? 2 }));
|
|
1725
|
-
spool.roll(() => this.subscriptions.unsubscribe(chunkTopic));
|
|
1720
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
1721
|
+
await this.subscribeTopicAndSpool(spool, chunkTopic, { qos: options.qos ?? 2 });
|
|
1726
1722
|
const chunkCredit = this.options.chunkCredit;
|
|
1727
1723
|
let chunksReceived = 0;
|
|
1728
1724
|
let creditGranted = chunkCredit;
|
|
@@ -1835,13 +1831,13 @@ class SinkTrait extends SourceTrait {
|
|
|
1835
1831
|
this.pushStreams = /* @__PURE__ */ new Map();
|
|
1836
1832
|
this.pushSpools = /* @__PURE__ */ new Map();
|
|
1837
1833
|
}
|
|
1838
|
-
/* destroy
|
|
1834
|
+
/* destroy trait */
|
|
1839
1835
|
async destroy() {
|
|
1840
1836
|
for (const stream of this.pushStreams.values())
|
|
1841
1837
|
stream.destroy(new Error("sink destroyed"));
|
|
1838
|
+
this.pushStreams.clear();
|
|
1842
1839
|
for (const spool of this.pushSpools.values())
|
|
1843
1840
|
await spool.unroll();
|
|
1844
|
-
this.pushStreams.clear();
|
|
1845
1841
|
this.pushSpools.clear();
|
|
1846
1842
|
await super.destroy();
|
|
1847
1843
|
}
|
|
@@ -2033,8 +2029,7 @@ class SinkTrait extends SourceTrait {
|
|
|
2033
2029
|
while (this.onResponse.has(`sink-push-response:${requestId}`) || this.onResponse.has(`sink-push-credit:${requestId}`))
|
|
2034
2030
|
requestId = nanoid.nanoid();
|
|
2035
2031
|
const responseTopic = this.options.topicMake(name, "sink-push-response", this.options.id);
|
|
2036
|
-
await
|
|
2037
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
2032
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
2038
2033
|
const abortController = new AbortController();
|
|
2039
2034
|
const abortSignal = abortController.signal;
|
|
2040
2035
|
if (data instanceof node_stream.Readable) {
|
|
@@ -2098,8 +2093,7 @@ class SinkTrait extends SourceTrait {
|
|
|
2098
2093
|
creditGate = new CreditGate(initialCredit);
|
|
2099
2094
|
if (creditGate) {
|
|
2100
2095
|
const creditTopic = this.options.topicMake(name, "sink-push-credit", this.options.id);
|
|
2101
|
-
await
|
|
2102
|
-
spool.roll(() => this.subscriptions.unsubscribe(creditTopic));
|
|
2096
|
+
await this.subscribeTopicAndSpool(spool, creditTopic, { qos: options.qos ?? 2 });
|
|
2103
2097
|
const gate = creditGate;
|
|
2104
2098
|
spool.roll(() => {
|
|
2105
2099
|
gate.abort();
|
|
@@ -951,12 +951,6 @@ class BaseTrait extends TraceTrait {
|
|
|
951
951
|
}
|
|
952
952
|
};
|
|
953
953
|
}
|
|
954
|
-
/* subscribe to an MQTT topic and spool the unsubscription */
|
|
955
|
-
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
956
|
-
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscribeTopic(topic, { qos: 2, ...options }));
|
|
957
|
-
spool.roll(() => this.unsubscribeTopic(topic).catch(() => {
|
|
958
|
-
}));
|
|
959
|
-
}
|
|
960
954
|
/* subscribe to an MQTT topic (Promise-based) */
|
|
961
955
|
async subscribeTopic(topic, options = {}) {
|
|
962
956
|
this.log("info", `subscribing to MQTT topic "${topic}"`);
|
|
@@ -1170,6 +1164,11 @@ class SubscriptionTrait extends BaseTrait {
|
|
|
1170
1164
|
super(...arguments);
|
|
1171
1165
|
this.subscriptions = new RefCountedSubscription((topic, options) => this.subscribeTopic(topic, options), (topic) => this.unsubscribeTopic(topic));
|
|
1172
1166
|
}
|
|
1167
|
+
/* subscribe to an MQTT topic (reference-counted) and spool the unsubscription */
|
|
1168
|
+
async subscribeTopicAndSpool(spool, topic, options = {}) {
|
|
1169
|
+
await run(`subscribe to MQTT topic "${topic}"`, spool, () => this.subscriptions.subscribe(topic, { qos: 2, ...options }));
|
|
1170
|
+
spool.roll(() => this.subscriptions.unsubscribe(topic));
|
|
1171
|
+
}
|
|
1173
1172
|
/* destroy subscription trait */
|
|
1174
1173
|
async destroy() {
|
|
1175
1174
|
await this.subscriptions.flush();
|
|
@@ -1501,8 +1500,7 @@ class ServiceTrait extends EventTrait {
|
|
|
1501
1500
|
while (this.onResponse.has(`service-call-response:${requestId}`))
|
|
1502
1501
|
requestId = nanoid();
|
|
1503
1502
|
const responseTopic = this.options.topicMake(name, "service-call-response", this.options.id);
|
|
1504
|
-
await
|
|
1505
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
1503
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
1506
1504
|
const timerId = `service-call:${requestId}`;
|
|
1507
1505
|
const promise = new Promise((resolve, reject) => {
|
|
1508
1506
|
this.timerRefresh(timerId, async () => {
|
|
@@ -1698,10 +1696,8 @@ class SourceTrait extends ServiceTrait {
|
|
|
1698
1696
|
requestId = nanoid();
|
|
1699
1697
|
const responseTopic = this.options.topicMake(name, "source-fetch-response", this.options.id);
|
|
1700
1698
|
const chunkTopic = this.options.topicMake(name, "source-fetch-chunk", this.options.id);
|
|
1701
|
-
await
|
|
1702
|
-
|
|
1703
|
-
await run(`subscribe to MQTT topic "${chunkTopic}"`, spool, () => this.subscriptions.subscribe(chunkTopic, { qos: options.qos ?? 2 }));
|
|
1704
|
-
spool.roll(() => this.subscriptions.unsubscribe(chunkTopic));
|
|
1699
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
1700
|
+
await this.subscribeTopicAndSpool(spool, chunkTopic, { qos: options.qos ?? 2 });
|
|
1705
1701
|
const chunkCredit = this.options.chunkCredit;
|
|
1706
1702
|
let chunksReceived = 0;
|
|
1707
1703
|
let creditGranted = chunkCredit;
|
|
@@ -1814,13 +1810,13 @@ class SinkTrait extends SourceTrait {
|
|
|
1814
1810
|
this.pushStreams = /* @__PURE__ */ new Map();
|
|
1815
1811
|
this.pushSpools = /* @__PURE__ */ new Map();
|
|
1816
1812
|
}
|
|
1817
|
-
/* destroy
|
|
1813
|
+
/* destroy trait */
|
|
1818
1814
|
async destroy() {
|
|
1819
1815
|
for (const stream of this.pushStreams.values())
|
|
1820
1816
|
stream.destroy(new Error("sink destroyed"));
|
|
1817
|
+
this.pushStreams.clear();
|
|
1821
1818
|
for (const spool of this.pushSpools.values())
|
|
1822
1819
|
await spool.unroll();
|
|
1823
|
-
this.pushStreams.clear();
|
|
1824
1820
|
this.pushSpools.clear();
|
|
1825
1821
|
await super.destroy();
|
|
1826
1822
|
}
|
|
@@ -2012,8 +2008,7 @@ class SinkTrait extends SourceTrait {
|
|
|
2012
2008
|
while (this.onResponse.has(`sink-push-response:${requestId}`) || this.onResponse.has(`sink-push-credit:${requestId}`))
|
|
2013
2009
|
requestId = nanoid();
|
|
2014
2010
|
const responseTopic = this.options.topicMake(name, "sink-push-response", this.options.id);
|
|
2015
|
-
await
|
|
2016
|
-
spool.roll(() => this.subscriptions.unsubscribe(responseTopic));
|
|
2011
|
+
await this.subscribeTopicAndSpool(spool, responseTopic, { qos: options.qos ?? 2 });
|
|
2017
2012
|
const abortController = new AbortController();
|
|
2018
2013
|
const abortSignal = abortController.signal;
|
|
2019
2014
|
if (data instanceof Readable) {
|
|
@@ -2077,8 +2072,7 @@ class SinkTrait extends SourceTrait {
|
|
|
2077
2072
|
creditGate = new CreditGate(initialCredit);
|
|
2078
2073
|
if (creditGate) {
|
|
2079
2074
|
const creditTopic = this.options.topicMake(name, "sink-push-credit", this.options.id);
|
|
2080
|
-
await
|
|
2081
|
-
spool.roll(() => this.subscriptions.unsubscribe(creditTopic));
|
|
2075
|
+
await this.subscribeTopicAndSpool(spool, creditTopic, { qos: options.qos ?? 2 });
|
|
2082
2076
|
const gate = creditGate;
|
|
2083
2077
|
spool.roll(() => {
|
|
2084
2078
|
gate.abort();
|