mqtt-plus 0.9.11 → 0.9.13
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 +85 -55
- package/dst-stage1/mqtt-plus-base.d.ts +3 -10
- package/dst-stage1/mqtt-plus-base.js +2 -34
- package/dst-stage1/mqtt-plus-codec.js +13 -2
- package/dst-stage1/mqtt-plus-event.d.ts +6 -4
- package/dst-stage1/mqtt-plus-event.js +17 -2
- package/dst-stage1/mqtt-plus-info.d.ts +0 -1
- package/dst-stage1/mqtt-plus-meta.d.ts +2 -2
- package/dst-stage1/mqtt-plus-meta.js +2 -2
- package/dst-stage1/mqtt-plus-msg.d.ts +3 -2
- package/dst-stage1/mqtt-plus-msg.js +4 -3
- package/dst-stage1/mqtt-plus-options.d.ts +4 -3
- package/dst-stage1/mqtt-plus-resource.d.ts +15 -29
- package/dst-stage1/mqtt-plus-resource.js +54 -16
- package/dst-stage1/mqtt-plus-service.d.ts +6 -4
- package/dst-stage1/mqtt-plus-service.js +17 -2
- package/dst-stage1/mqtt-plus-util.d.ts +0 -1
- package/dst-stage1/mqtt-plus-util.js +1 -1
- package/dst-stage2/mqtt-plus.cjs.js +1608 -84
- package/dst-stage2/mqtt-plus.esm.js +1608 -84
- package/dst-stage2/mqtt-plus.umd.js +20 -17
- package/{src/mqtt-plus-receiver.ts → etc/knip.jsonc} +19 -27
- package/etc/stx.conf +2 -1
- package/etc/tsc.tsbuildinfo +1 -1
- package/package.json +7 -9
- package/src/mqtt-plus-base.ts +3 -45
- package/src/mqtt-plus-codec.ts +14 -2
- package/src/mqtt-plus-event.ts +31 -20
- package/src/mqtt-plus-info.ts +2 -3
- package/src/mqtt-plus-msg.ts +5 -3
- package/src/mqtt-plus-options.ts +1 -1
- package/src/mqtt-plus-resource.ts +106 -164
- package/src/mqtt-plus-service.ts +34 -26
- package/src/mqtt-plus-util.ts +1 -1
- package/tst/mqtt-plus.spec.ts +1 -3
- package/src/mqtt-plus-meta.ts +0 -54
package/README.md
CHANGED
|
@@ -87,12 +87,12 @@ The API type defines the available endpoints. Use the marker types
|
|
|
87
87
|
pattern of each endpoint:
|
|
88
88
|
|
|
89
89
|
```ts
|
|
90
|
-
import type
|
|
90
|
+
import type { Event, Service, Resource } from "mqtt-plus"
|
|
91
91
|
|
|
92
92
|
export type API = {
|
|
93
|
-
"example/sample":
|
|
94
|
-
"example/hello":
|
|
95
|
-
"example/resource":
|
|
93
|
+
"example/sample": Event<(a1: string, a2: number) => void>
|
|
94
|
+
"example/hello": Service<(a1: string, a2: number) => string>
|
|
95
|
+
"example/resource": Resource<(filename: string) => void>
|
|
96
96
|
}
|
|
97
97
|
```
|
|
98
98
|
|
|
@@ -108,7 +108,7 @@ import MQTT from "mqtt"
|
|
|
108
108
|
import MQTTp from "mqtt-plus"
|
|
109
109
|
import type { API } from [...]
|
|
110
110
|
|
|
111
|
-
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
111
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { [...] })
|
|
112
112
|
const mqttp = new MQTTp<API>(mqtt)
|
|
113
113
|
|
|
114
114
|
mqtt.on("connect", async () => {
|
|
@@ -129,7 +129,7 @@ import MQTT from "mqtt"
|
|
|
129
129
|
import MQTTp from "mqtt-plus"
|
|
130
130
|
import type { API } from [...]
|
|
131
131
|
|
|
132
|
-
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
132
|
+
const mqtt = MQTT.connect("wss://127.0.0.1:8883", { [...] })
|
|
133
133
|
const mqttp = new MQTTp<API>(mqtt)
|
|
134
134
|
|
|
135
135
|
mqtt.on("connect", () => {
|
|
@@ -179,7 +179,8 @@ The **MQTT+** API provides the following methods:
|
|
|
179
179
|
The `operation` parameter is one of: `event-emission`, `service-call-request`, `service-call-response`, `resource-transfer-request`, `resource-transfer-response`.
|
|
180
180
|
(default: `` (name, operation, peerId) => `${name}/${protocol}/${peerId ?? "any"}` ``)
|
|
181
181
|
- `topicMatch`: Custom topic matching function.
|
|
182
|
-
Returns `{ name, operation, peerId? }` or `null` if no match.
|
|
182
|
+
Returns `{ name, operation, peerId? }` or `null` if no match.
|
|
183
|
+
The `peerId` is `undefined` for broadcast topics (ending with `/any`).
|
|
183
184
|
(default: `` (topic) => { const m = topic.match(/^(.+)\/([^/]+)\/([^/]+)$/); return m ? { name: m[1], operation: m[2], peerId: m[3] === "any" ? undefined : m[3] } : null } ``)
|
|
184
185
|
|
|
185
186
|
- **Destruction**:<br/>
|
|
@@ -246,7 +247,6 @@ The **MQTT+** API provides the following methods:
|
|
|
246
247
|
info: {
|
|
247
248
|
sender: string,
|
|
248
249
|
receiver?: string,
|
|
249
|
-
resource: Buffer | Readable | null,
|
|
250
250
|
meta?: Record<string, any>,
|
|
251
251
|
stream?: Readable,
|
|
252
252
|
buffer?: Promise<Buffer>
|
|
@@ -259,7 +259,7 @@ The **MQTT+** API provides the following methods:
|
|
|
259
259
|
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
260
260
|
|
|
261
261
|
For **fetch requests**: The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
262
|
-
The `callback` should set `info.
|
|
262
|
+
The `callback` should set `info.stream` to a `Readable` or `info.buffer` to a `Promise<Buffer>` containing the resource data.
|
|
263
263
|
Optionally, the `callback` can set `info.meta` to a `Record<string, any>` to send metadata back with the response.
|
|
264
264
|
|
|
265
265
|
For **pushed data**: The `callback` is called with the `params` passed to a remote `push()`.
|
|
@@ -278,10 +278,14 @@ The **MQTT+** API provides the following methods:
|
|
|
278
278
|
/* (simplified TypeScript API method signature) */
|
|
279
279
|
emit(
|
|
280
280
|
event: string,
|
|
281
|
-
receiver?: Receiver,
|
|
282
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
283
281
|
...params: any[]
|
|
284
282
|
): void
|
|
283
|
+
emit({
|
|
284
|
+
event: string,
|
|
285
|
+
params: any[],
|
|
286
|
+
receiver?: string,
|
|
287
|
+
options?: MQTT::IClientSubscribeOptions
|
|
288
|
+
}): void
|
|
285
289
|
|
|
286
290
|
Emit an event to all subscribers or a specific subscriber ("fire and forget").
|
|
287
291
|
The optional `receiver` directs the event to a specific subscriber only.
|
|
@@ -298,10 +302,14 @@ The **MQTT+** API provides the following methods:
|
|
|
298
302
|
/* (simplified TypeScript API method signature) */
|
|
299
303
|
call(
|
|
300
304
|
service: string,
|
|
301
|
-
receiver?: Receiver,
|
|
302
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
303
305
|
...params: any[]
|
|
304
306
|
): Promise<any>
|
|
307
|
+
call({
|
|
308
|
+
service: string,
|
|
309
|
+
params: any[],
|
|
310
|
+
receiver?: string,
|
|
311
|
+
options?: MQTT::IClientPublishOptions
|
|
312
|
+
}): Promise<any>
|
|
305
313
|
|
|
306
314
|
Call a service on all registrants or on a specific registrant ("request and response").
|
|
307
315
|
The optional `receiver` directs the call to a specific registrant only.
|
|
@@ -320,10 +328,22 @@ The **MQTT+** API provides the following methods:
|
|
|
320
328
|
/* (simplified TypeScript API method signature) */
|
|
321
329
|
fetch(
|
|
322
330
|
resource: string,
|
|
323
|
-
receiver?: Receiver,
|
|
324
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
325
331
|
...params: any[]
|
|
326
|
-
): Promise<{
|
|
332
|
+
): Promise<{
|
|
333
|
+
stream: Readable,
|
|
334
|
+
buffer: Promise<Buffer>,
|
|
335
|
+
meta: Promise<Record<string, any> | undefined>
|
|
336
|
+
}>
|
|
337
|
+
fetch({
|
|
338
|
+
resource: string,
|
|
339
|
+
params: any[],
|
|
340
|
+
receiver?: string,
|
|
341
|
+
options?: MQTT::IClientSubscribeOptions
|
|
342
|
+
}): Promise<{
|
|
343
|
+
stream: Readable,
|
|
344
|
+
buffer: Promise<Buffer>,
|
|
345
|
+
meta: Promise<Record<string, any> | undefined>
|
|
346
|
+
}>
|
|
327
347
|
|
|
328
348
|
Fetches a resource from any resource provisioner or from a specific provisioner.
|
|
329
349
|
The optional `receiver` directs the call to a specific provisioner only.
|
|
@@ -335,7 +355,7 @@ The **MQTT+** API provides the following methods:
|
|
|
335
355
|
sent by the provisioner when the first chunk arrives.
|
|
336
356
|
|
|
337
357
|
The remote `provision()` `callback` is called with `params` and
|
|
338
|
-
should set `info.
|
|
358
|
+
should set `info.stream` to a `Readable` or `info.buffer` to a `Promise<Buffer>` containing the resource data.
|
|
339
359
|
Optionally, the `callback` can set `info.meta` to send metadata back with the response.
|
|
340
360
|
If the remote `callback` throws an exception, this destroys the stream with the error.
|
|
341
361
|
|
|
@@ -350,15 +370,20 @@ The **MQTT+** API provides the following methods:
|
|
|
350
370
|
push(
|
|
351
371
|
resource: string,
|
|
352
372
|
streamOrBuffer: Readable | Buffer,
|
|
353
|
-
meta?: Meta,
|
|
354
|
-
receiver?: Receiver,
|
|
355
|
-
options?: MQTT::IClientPublishOptions,
|
|
356
373
|
...params: any[]
|
|
357
374
|
): Promise<void>
|
|
375
|
+
push({
|
|
376
|
+
resource: string,
|
|
377
|
+
streamOrBuffer: Readable | Buffer,
|
|
378
|
+
params: any[]
|
|
379
|
+
meta?: Record<string, any>,
|
|
380
|
+
receiver?: string,
|
|
381
|
+
options?: MQTT::IClientPublishOptions
|
|
382
|
+
}): Promise<void>
|
|
358
383
|
|
|
359
384
|
Pushes a resource to all provisioners or a specific provisioner.
|
|
360
385
|
The `streamOrBuffer` is either a Node.js `Readable` stream or a `Buffer` providing the data to push.
|
|
361
|
-
The optional `meta`
|
|
386
|
+
The optional `meta` sends metadata alongside the resource data,
|
|
362
387
|
which becomes available on the provisioner side via `info.meta`.
|
|
363
388
|
The optional `receiver` directs the push to a specific provisioner only.
|
|
364
389
|
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
@@ -376,25 +401,6 @@ The **MQTT+** API provides the following methods:
|
|
|
376
401
|
Internally, publishes to the MQTT topic by `topicMake(resource, "resource-transfer-response", peerId)`
|
|
377
402
|
(default: `${resource}/resource-transfer-response/any` or `${resource}/resource-transfer-response/${peerId}`).
|
|
378
403
|
|
|
379
|
-
- **Receiver Wrapping**:<br/>
|
|
380
|
-
|
|
381
|
-
receiver(
|
|
382
|
-
id: string
|
|
383
|
-
): Receiver
|
|
384
|
-
|
|
385
|
-
Wrap a receiver ID string for use with `emit()`, `call()`, `fetch()` or `push()` to direct the
|
|
386
|
-
message to a specific receiver. Returns a `Receiver` object.
|
|
387
|
-
|
|
388
|
-
- **Meta Wrapping**:<br/>
|
|
389
|
-
|
|
390
|
-
meta(
|
|
391
|
-
data: Record<string, any>
|
|
392
|
-
): Meta
|
|
393
|
-
|
|
394
|
-
Wrap a metadata object for use with `push()` to send metadata alongside the resource data.
|
|
395
|
-
The metadata is transferred with the first chunk and becomes available on the provisioner
|
|
396
|
-
side via `info.meta`. Returns a `Meta` object.
|
|
397
|
-
|
|
398
404
|
Internals
|
|
399
405
|
---------
|
|
400
406
|
|
|
@@ -542,14 +548,13 @@ const mqtt = MQTT.connect("mqtt://127.0.0.1:1883", {
|
|
|
542
548
|
})
|
|
543
549
|
|
|
544
550
|
type API = {
|
|
545
|
-
"example/sample":
|
|
546
|
-
"example/hello":
|
|
551
|
+
"example/sample": MQTTpt.Event<(a1: string, a2: number) => void>
|
|
552
|
+
"example/hello": MQTTpt.Service<(a1: string, a2: number) => string>
|
|
553
|
+
"example/resource": MQTTpt.Resource<(filename: string) => void>
|
|
547
554
|
}
|
|
548
555
|
|
|
549
556
|
const mqttp = new MQTTp<API>(mqtt, { codec: "json" })
|
|
550
557
|
|
|
551
|
-
type Sample = (a: string, b: number) => string
|
|
552
|
-
|
|
553
558
|
mqtt.on("error", (err) => { console.log("ERROR", err) })
|
|
554
559
|
mqtt.on("offline", () => { console.log("OFFLINE") })
|
|
555
560
|
mqtt.on("close", () => { console.log("CLOSE") })
|
|
@@ -558,17 +563,36 @@ mqtt.on("message", (topic, message) => { console.log("RECEIVED", topic, messag
|
|
|
558
563
|
|
|
559
564
|
mqtt.on("connect", async () => {
|
|
560
565
|
console.log("CONNECT")
|
|
561
|
-
|
|
566
|
+
|
|
567
|
+
/* event emission example */
|
|
568
|
+
const sub = await mqttp.subscribe("example/sample", (a1, a2, info) => {
|
|
569
|
+
console.log("example/sample: received:", a1, a2, "from:", info.sender)
|
|
570
|
+
})
|
|
571
|
+
mqttp.emit("example/sample", "world", 42)
|
|
572
|
+
await new Promise((resolve) => { setTimeout(resolve, 100) })
|
|
573
|
+
await sub.unsubscribe()
|
|
574
|
+
|
|
575
|
+
/* service call example */
|
|
576
|
+
const reg = await mqttp.register("example/hello", (a1, a2, info) => {
|
|
562
577
|
console.log("example/hello: request:", a1, a2, "from:", info.sender)
|
|
563
578
|
return `${a1}:${a2}`
|
|
564
579
|
})
|
|
565
|
-
mqttp.call("example/hello", "world", 42)
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
580
|
+
const result = await mqttp.call("example/hello", "world", 42)
|
|
581
|
+
console.log("example/hello: success:", result)
|
|
582
|
+
await reg.unregister()
|
|
583
|
+
|
|
584
|
+
/* resource fetch example */
|
|
585
|
+
const prov = await mqttp.provision("example/resource", async (filename, info) => {
|
|
586
|
+
console.log("example/resource: request:", filename, "from:", info.sender)
|
|
587
|
+
info.buffer = Promise.resolve(Buffer.from(`the ${filename} content`))
|
|
571
588
|
})
|
|
589
|
+
const res = await mqttp.fetch("example/resource", "foo")
|
|
590
|
+
const data = await res.buffer
|
|
591
|
+
console.log("example/resource: result:", data.toString())
|
|
592
|
+
await prov.unprovision()
|
|
593
|
+
|
|
594
|
+
mqtt.end()
|
|
595
|
+
await mosquitto.stop()
|
|
572
596
|
})
|
|
573
597
|
```
|
|
574
598
|
|
|
@@ -577,10 +601,16 @@ The output will be:
|
|
|
577
601
|
```
|
|
578
602
|
$ node sample.ts
|
|
579
603
|
CONNECT
|
|
580
|
-
RECEIVED example/
|
|
581
|
-
example/
|
|
582
|
-
RECEIVED example/hello/service-call-
|
|
583
|
-
example/hello
|
|
604
|
+
RECEIVED example/sample/event-emission/any {"type":"event-emission","id":"...","sender":"...","event":"example/sample","params":["world",42]}
|
|
605
|
+
example/sample: received: world 42 from: ...
|
|
606
|
+
RECEIVED example/hello/service-call-request/any {"type":"service-call-request","id":"...","sender":"...","service":"example/hello","params":["world",42]}
|
|
607
|
+
example/hello: request: world 42 from: ...
|
|
608
|
+
RECEIVED example/hello/service-call-response/... {"type":"service-call-response","id":"...","sender":"...","receiver":"...","result":"world:42"}
|
|
609
|
+
example/hello: success: world:42
|
|
610
|
+
RECEIVED example/resource/resource-transfer-request/any {"type":"resource-transfer-request","id":"...","sender":"...","resource":"example/resource","params":["foo"]}
|
|
611
|
+
example/resource: request: foo from: ...
|
|
612
|
+
RECEIVED example/resource/resource-transfer-response/... {"type":"resource-transfer-response","id":"...","sender":"...","receiver":"...","chunk":...,"final":true}
|
|
613
|
+
example/resource: result: the foo content
|
|
584
614
|
CLOSE
|
|
585
615
|
```
|
|
586
616
|
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
import { MqttClient,
|
|
1
|
+
import { MqttClient, IClientSubscribeOptions } from "mqtt";
|
|
2
2
|
import { APISchema } from "./mqtt-plus-api";
|
|
3
|
+
import { MsgTrait } from "./mqtt-plus-msg";
|
|
3
4
|
import { APIOptions } from "./mqtt-plus-options";
|
|
4
|
-
|
|
5
|
-
export declare class BaseTrait<T extends APISchema = APISchema> extends MetaTrait<T> {
|
|
5
|
+
export declare class BaseTrait<T extends APISchema = APISchema> extends MsgTrait<T> {
|
|
6
6
|
protected mqtt: MqttClient;
|
|
7
7
|
private _messageHandler;
|
|
8
8
|
constructor(mqtt: MqttClient, options?: Partial<APIOptions>);
|
|
9
9
|
destroy(): void;
|
|
10
10
|
protected _subscribeTopic(topic: string, options?: Partial<IClientSubscribeOptions>): Promise<void>;
|
|
11
11
|
protected _unsubscribeTopic(topic: string): Promise<void>;
|
|
12
|
-
private _isIClientPublishOptions;
|
|
13
|
-
protected _parseCallArgs<U extends any[]>(args: any[]): {
|
|
14
|
-
meta?: Record<string, any>;
|
|
15
|
-
receiver?: string;
|
|
16
|
-
options: IClientPublishOptions;
|
|
17
|
-
params: U;
|
|
18
|
-
};
|
|
19
12
|
private _onMessage;
|
|
20
13
|
protected _dispatchMessage(_topic: string, _parsed: any): void;
|
|
21
14
|
}
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
22
|
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
24
|
+
import { MsgTrait } from "./mqtt-plus-msg";
|
|
25
25
|
/* MQTTp Base class with shared infrastructure */
|
|
26
|
-
export class BaseTrait extends
|
|
26
|
+
export class BaseTrait extends MsgTrait {
|
|
27
27
|
/* construct API class */
|
|
28
28
|
constructor(mqtt, options = {}) {
|
|
29
29
|
super(options);
|
|
@@ -61,38 +61,6 @@ export class BaseTrait extends MetaTrait {
|
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
/* check whether argument has structure of interface IClientPublishOptions */
|
|
65
|
-
_isIClientPublishOptions(arg) {
|
|
66
|
-
if (typeof arg !== "object")
|
|
67
|
-
return false;
|
|
68
|
-
const keys = ["qos", "retain", "dup", "properties", "cbStorePut"];
|
|
69
|
-
return Object.keys(arg).every((key) => keys.includes(key));
|
|
70
|
-
}
|
|
71
|
-
/* parse optional meta, receiver and options from variadic arguments */
|
|
72
|
-
_parseCallArgs(args) {
|
|
73
|
-
/* extract optional meta from arguments */
|
|
74
|
-
let meta;
|
|
75
|
-
if (args.length > 0 && this._isMeta(args[0]))
|
|
76
|
-
meta = this._getMeta(args.shift());
|
|
77
|
-
/* extract optional receiver and options from arguments */
|
|
78
|
-
let receiver;
|
|
79
|
-
let options = {};
|
|
80
|
-
let params = args;
|
|
81
|
-
if (args.length >= 2 && this._isReceiver(args[0]) && this._isIClientPublishOptions(args[1])) {
|
|
82
|
-
receiver = this._getReceiver(args[0]);
|
|
83
|
-
options = args[1];
|
|
84
|
-
params = args.slice(2);
|
|
85
|
-
}
|
|
86
|
-
else if (args.length >= 1 && this._isReceiver(args[0])) {
|
|
87
|
-
receiver = this._getReceiver(args[0]);
|
|
88
|
-
params = args.slice(1);
|
|
89
|
-
}
|
|
90
|
-
else if (args.length >= 1 && this._isIClientPublishOptions(args[0])) {
|
|
91
|
-
options = args[0];
|
|
92
|
-
params = args.slice(1);
|
|
93
|
-
}
|
|
94
|
-
return { meta, receiver, options, params };
|
|
95
|
-
}
|
|
96
64
|
/* handle incoming MQTT message */
|
|
97
65
|
_onMessage(topic, message, packet) {
|
|
98
66
|
/* try to parse message as payload */
|
|
@@ -22,8 +22,19 @@
|
|
|
22
22
|
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
/* external requirements */
|
|
25
|
-
import CBOR from "
|
|
25
|
+
import * as CBOR from "cbor2";
|
|
26
|
+
import { registerEncoder } from "cbor2/encoder";
|
|
27
|
+
import { Tag } from "cbor2/tag";
|
|
26
28
|
import { OptionsTrait } from "./mqtt-plus-options";
|
|
29
|
+
/* directly support Buffer type for CBOR */
|
|
30
|
+
registerEncoder(Buffer, (buffer) => [
|
|
31
|
+
64000,
|
|
32
|
+
new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)
|
|
33
|
+
]);
|
|
34
|
+
Tag.registerDecoder(64000, (tag) => {
|
|
35
|
+
const array = tag.contents;
|
|
36
|
+
return Buffer.copyBytesFrom(array);
|
|
37
|
+
});
|
|
27
38
|
/* the encoder/decoder abstraction */
|
|
28
39
|
export default class Codec {
|
|
29
40
|
constructor(type) {
|
|
@@ -33,7 +44,7 @@ export default class Codec {
|
|
|
33
44
|
let result;
|
|
34
45
|
if (this.type === "cbor") {
|
|
35
46
|
try {
|
|
36
|
-
result = CBOR.encode(data);
|
|
47
|
+
result = Buffer.from(CBOR.encode(data));
|
|
37
48
|
}
|
|
38
49
|
catch (_ex) {
|
|
39
50
|
throw new Error("failed to encode CBOR format");
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { IClientPublishOptions, IClientSubscribeOptions } from "mqtt";
|
|
2
2
|
import { APISchema, EventKeys } from "./mqtt-plus-api";
|
|
3
3
|
import type { WithInfo, InfoEvent } from "./mqtt-plus-info";
|
|
4
|
-
import type { Receiver } from "./mqtt-plus-receiver";
|
|
5
4
|
import { BaseTrait } from "./mqtt-plus-base";
|
|
6
5
|
export interface Subscription {
|
|
7
6
|
unsubscribe(): Promise<void>;
|
|
@@ -11,8 +10,11 @@ export declare class EventTrait<T extends APISchema = APISchema> extends BaseTra
|
|
|
11
10
|
subscribe<K extends EventKeys<T> & string>(event: K, callback: WithInfo<T[K], InfoEvent>): Promise<Subscription>;
|
|
12
11
|
subscribe<K extends EventKeys<T> & string>(event: K, options: Partial<IClientSubscribeOptions>, callback: WithInfo<T[K], InfoEvent>): Promise<Subscription>;
|
|
13
12
|
emit<K extends EventKeys<T> & string>(event: K, ...params: Parameters<T[K]>): void;
|
|
14
|
-
emit<K extends EventKeys<T> & string>(
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
emit<K extends EventKeys<T> & string>(config: {
|
|
14
|
+
event: K;
|
|
15
|
+
params: Parameters<T[K]>;
|
|
16
|
+
receiver?: string;
|
|
17
|
+
options?: IClientPublishOptions;
|
|
18
|
+
}): void;
|
|
17
19
|
protected _dispatchMessage(topic: string, parsed: any): void;
|
|
18
20
|
}
|
|
@@ -72,9 +72,24 @@ export class EventTrait extends BaseTrait {
|
|
|
72
72
|
};
|
|
73
73
|
return subscription;
|
|
74
74
|
}
|
|
75
|
-
emit(
|
|
75
|
+
emit(eventOrConfig, ...args) {
|
|
76
76
|
/* determine actual parameters */
|
|
77
|
-
|
|
77
|
+
let event;
|
|
78
|
+
let params;
|
|
79
|
+
let receiver;
|
|
80
|
+
let options = {};
|
|
81
|
+
if (typeof eventOrConfig === "object" && eventOrConfig !== null) {
|
|
82
|
+
/* object-based API */
|
|
83
|
+
event = eventOrConfig.event;
|
|
84
|
+
params = eventOrConfig.params;
|
|
85
|
+
receiver = eventOrConfig.receiver;
|
|
86
|
+
options = eventOrConfig.options ?? {};
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
/* positional API */
|
|
90
|
+
event = eventOrConfig;
|
|
91
|
+
params = args;
|
|
92
|
+
}
|
|
78
93
|
/* generate unique request id */
|
|
79
94
|
const rid = nanoid();
|
|
80
95
|
/* generate encoded message */
|
|
@@ -8,7 +8,6 @@ export interface InfoEvent extends InfoBase {
|
|
|
8
8
|
export interface InfoService extends InfoBase {
|
|
9
9
|
}
|
|
10
10
|
export interface InfoResource extends InfoBase {
|
|
11
|
-
resource: Buffer | Readable | null;
|
|
12
11
|
meta?: Record<string, any>;
|
|
13
12
|
stream?: Readable;
|
|
14
13
|
buffer?: Promise<Buffer>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { APISchema } from "./mqtt-plus-api";
|
|
2
|
-
import {
|
|
2
|
+
import { MsgTrait } from "./mqtt-plus-msg";
|
|
3
3
|
export type Meta = {
|
|
4
4
|
__meta: Record<string, any>;
|
|
5
5
|
};
|
|
6
|
-
export declare class MetaTrait<T extends APISchema = APISchema> extends
|
|
6
|
+
export declare class MetaTrait<T extends APISchema = APISchema> extends MsgTrait<T> {
|
|
7
7
|
meta(data: Record<string, any>): {
|
|
8
8
|
__meta: Record<string, any>;
|
|
9
9
|
};
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
22
|
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
|
-
import {
|
|
24
|
+
import { MsgTrait } from "./mqtt-plus-msg";
|
|
25
25
|
/* Meta trait */
|
|
26
|
-
export class MetaTrait extends
|
|
26
|
+
export class MetaTrait extends MsgTrait {
|
|
27
27
|
/* wrap meta object into wrapper (required for type-safe overloading) */
|
|
28
28
|
meta(data) {
|
|
29
29
|
return { __meta: data };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APISchema } from "./mqtt-plus-api";
|
|
2
2
|
import { CodecTrait } from "./mqtt-plus-codec";
|
|
3
|
-
|
|
3
|
+
declare class Base {
|
|
4
4
|
type: string;
|
|
5
5
|
id: string;
|
|
6
6
|
sender?: string | undefined;
|
|
@@ -36,7 +36,7 @@ export declare class ResourceTransferResponse extends Base {
|
|
|
36
36
|
final?: boolean | undefined;
|
|
37
37
|
constructor(id: string, resource?: string | undefined, params?: any[] | undefined, chunk?: Buffer | undefined, meta?: Record<string, any> | undefined, error?: string | undefined, final?: boolean | undefined, sender?: string, receiver?: string);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
declare class Msg {
|
|
40
40
|
makeEventEmission(id: string, event: string, params?: any[], sender?: string, receiver?: string): EventEmission;
|
|
41
41
|
makeServiceCallRequest(id: string, service: string, params?: any[], sender?: string, receiver?: string): ServiceCallRequest;
|
|
42
42
|
makeServiceCallResponse(id: string, result?: any, error?: string, sender?: string, receiver?: string): ServiceCallResponse;
|
|
@@ -47,3 +47,4 @@ export default class Msg {
|
|
|
47
47
|
export declare class MsgTrait<T extends APISchema = APISchema> extends CodecTrait<T> {
|
|
48
48
|
protected msg: Msg;
|
|
49
49
|
}
|
|
50
|
+
export {};
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { CodecTrait } from "./mqtt-plus-codec";
|
|
25
25
|
/* base class */
|
|
26
|
-
|
|
26
|
+
class Base {
|
|
27
27
|
constructor(type, id, sender, receiver) {
|
|
28
28
|
this.type = type;
|
|
29
29
|
this.id = id;
|
|
@@ -76,7 +76,7 @@ export class ResourceTransferResponse extends Base {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
/* utility class */
|
|
79
|
-
|
|
79
|
+
class Msg {
|
|
80
80
|
/* factory for event emission */
|
|
81
81
|
makeEventEmission(id, event, params, sender, receiver) {
|
|
82
82
|
return new EventEmission(id, event, params, sender, receiver);
|
|
@@ -110,9 +110,10 @@ export default class Msg {
|
|
|
110
110
|
throw new Error("invalid object: invalid \"sender\" field");
|
|
111
111
|
if ("receiver" in obj && obj.receiver !== undefined && typeof obj.receiver !== "string")
|
|
112
112
|
throw new Error("invalid object: invalid \"receiver\" field");
|
|
113
|
-
/*
|
|
113
|
+
/* utility predicates for validation */
|
|
114
114
|
const anyFieldsExcept = (obj, allowed) => Object.keys(obj).some((key) => !allowed.includes(key));
|
|
115
115
|
const validParams = (obj) => obj.params === undefined || (typeof obj.params === "object" && Array.isArray(obj.params));
|
|
116
|
+
/* dispatch according to type indication by field */
|
|
116
117
|
if (obj.type === "event-emission") {
|
|
117
118
|
/* detect and parse event emission */
|
|
118
119
|
if (typeof obj.event !== "string")
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { APISchema } from "./mqtt-plus-api";
|
|
2
|
-
|
|
3
|
-
export type TopicMatch = (topic: string) => TopicMatching | null;
|
|
4
|
-
export type TopicMatching = {
|
|
2
|
+
type TopicMatching = {
|
|
5
3
|
name: string;
|
|
6
4
|
operation: string;
|
|
7
5
|
peerId?: string;
|
|
8
6
|
};
|
|
7
|
+
export type TopicMake = (name: string, operation: string, peerId?: string) => string;
|
|
8
|
+
export type TopicMatch = (topic: string) => TopicMatching | null;
|
|
9
9
|
export interface APIOptions {
|
|
10
10
|
id: string;
|
|
11
11
|
codec: "cbor" | "json";
|
|
@@ -18,3 +18,4 @@ export declare class OptionsTrait<T extends APISchema = APISchema> {
|
|
|
18
18
|
protected options: APIOptions;
|
|
19
19
|
constructor(options?: Partial<APIOptions>);
|
|
20
20
|
}
|
|
21
|
+
export {};
|
|
@@ -2,8 +2,6 @@ import { Readable } from "stream";
|
|
|
2
2
|
import { IClientPublishOptions, IClientSubscribeOptions } from "mqtt";
|
|
3
3
|
import { APISchema, ResourceKeys } from "./mqtt-plus-api";
|
|
4
4
|
import type { WithInfo, InfoResource } from "./mqtt-plus-info";
|
|
5
|
-
import type { Receiver } from "./mqtt-plus-receiver";
|
|
6
|
-
import type { Meta } from "./mqtt-plus-meta";
|
|
7
5
|
import { ServiceTrait } from "./mqtt-plus-service";
|
|
8
6
|
export interface Provisioning {
|
|
9
7
|
unprovision(): Promise<void>;
|
|
@@ -15,38 +13,26 @@ export declare class ResourceTrait<T extends APISchema = APISchema> extends Serv
|
|
|
15
13
|
private pushTimers;
|
|
16
14
|
provision<K extends ResourceKeys<T> & string>(resource: K, callback: WithInfo<T[K], InfoResource>): Promise<Provisioning>;
|
|
17
15
|
provision<K extends ResourceKeys<T> & string>(resource: K, options: Partial<IClientSubscribeOptions>, callback: WithInfo<T[K], InfoResource>): Promise<Provisioning>;
|
|
18
|
-
push<K extends ResourceKeys<T> & string>(resource: K,
|
|
19
|
-
push<K extends ResourceKeys<T> & string>(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, meta: Meta, receiver: Receiver, ...params: Parameters<T[K]>): Promise<void>;
|
|
28
|
-
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, meta: Meta, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
29
|
-
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, meta: Meta, receiver: Receiver, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
30
|
-
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, meta: Meta, ...params: Parameters<T[K]>): Promise<void>;
|
|
31
|
-
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, meta: Meta, receiver: Receiver, ...params: Parameters<T[K]>): Promise<void>;
|
|
32
|
-
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, meta: Meta, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
33
|
-
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, meta: Meta, receiver: Receiver, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
16
|
+
push<K extends ResourceKeys<T> & string>(resource: K, data: Readable | Buffer, ...params: Parameters<T[K]>): Promise<void>;
|
|
17
|
+
push<K extends ResourceKeys<T> & string>(config: {
|
|
18
|
+
resource: K;
|
|
19
|
+
data: Readable | Buffer;
|
|
20
|
+
params: Parameters<T[K]>;
|
|
21
|
+
meta?: Record<string, any>;
|
|
22
|
+
receiver?: string;
|
|
23
|
+
options?: IClientPublishOptions;
|
|
24
|
+
}): Promise<void>;
|
|
34
25
|
fetch<K extends ResourceKeys<T> & string>(resource: K, ...params: Parameters<T[K]>): Promise<{
|
|
35
26
|
stream: Readable;
|
|
36
27
|
buffer: Promise<Buffer>;
|
|
37
28
|
meta: Promise<Record<string, any> | undefined>;
|
|
38
29
|
}>;
|
|
39
|
-
fetch<K extends ResourceKeys<T> & string>(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
stream: Readable;
|
|
46
|
-
buffer: Promise<Buffer>;
|
|
47
|
-
meta: Promise<Record<string, any> | undefined>;
|
|
48
|
-
}>;
|
|
49
|
-
fetch<K extends ResourceKeys<T> & string>(resource: K, receiver: Receiver, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<{
|
|
30
|
+
fetch<K extends ResourceKeys<T> & string>(config: {
|
|
31
|
+
resource: K;
|
|
32
|
+
params: Parameters<T[K]>;
|
|
33
|
+
receiver?: string;
|
|
34
|
+
options?: IClientPublishOptions;
|
|
35
|
+
}): Promise<{
|
|
50
36
|
stream: Readable;
|
|
51
37
|
buffer: Promise<Buffer>;
|
|
52
38
|
meta: Promise<Record<string, any> | undefined>;
|