mqtt-plus 0.9.8 → 0.9.9
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 +33 -12
- package/dst-stage1/mqtt-plus-base.d.ts +4 -2
- package/dst-stage1/mqtt-plus-base.js +14 -8
- package/dst-stage1/mqtt-plus-event.js +1 -1
- package/dst-stage1/mqtt-plus-info.d.ts +1 -0
- package/dst-stage1/mqtt-plus-meta.d.ts +12 -0
- package/dst-stage1/mqtt-plus-meta.js +43 -0
- package/dst-stage1/mqtt-plus-msg.d.ts +3 -2
- package/dst-stage1/mqtt-plus-msg.js +10 -6
- package/dst-stage1/mqtt-plus-options.js +5 -1
- package/dst-stage1/mqtt-plus-resource.d.ts +14 -4
- package/dst-stage1/mqtt-plus-resource.js +71 -95
- package/dst-stage1/mqtt-plus-service.js +11 -9
- package/dst-stage1/mqtt-plus-util.d.ts +6 -2
- package/dst-stage1/mqtt-plus-util.js +62 -10
- package/dst-stage1/mqtt-plus.d.ts +2 -3
- package/dst-stage1/mqtt-plus.js +1 -3
- package/dst-stage2/mqtt-plus.cjs.js +186 -6126
- package/dst-stage2/mqtt-plus.esm.js +173 -6112
- package/dst-stage2/mqtt-plus.umd.js +14 -14
- package/etc/tsc.tsbuildinfo +1 -1
- package/etc/vite.mts +3 -5
- package/package.json +6 -7
- package/src/mqtt-plus-api.ts +1 -4
- package/src/mqtt-plus-base.ts +19 -10
- package/src/mqtt-plus-event.ts +1 -1
- package/src/mqtt-plus-info.ts +6 -3
- package/src/mqtt-plus-meta.ts +54 -0
- package/src/mqtt-plus-msg.ts +10 -4
- package/src/mqtt-plus-options.ts +5 -1
- package/src/mqtt-plus-resource.ts +189 -145
- package/src/mqtt-plus-service.ts +15 -11
- package/src/mqtt-plus-util.ts +112 -0
- package/src/mqtt-plus.ts +5 -3
- package/tst/mqtt-plus.spec.ts +9 -9
package/README.md
CHANGED
|
@@ -47,9 +47,9 @@ communication patterns with type safety:
|
|
|
47
47
|
Service Call is a *bi-directional* communication pattern.
|
|
48
48
|
A Service is the combination of a service name and optionally zero or more arguments.
|
|
49
49
|
You *register* for a service.
|
|
50
|
-
When a service is *called*, a single particular
|
|
51
|
-
of a directed service call) or one arbitrary
|
|
52
|
-
receives the arguments as the request. The
|
|
50
|
+
When a service is *called*, a single particular registrant (in case
|
|
51
|
+
of a directed service call) or one arbitrary registrant is called and
|
|
52
|
+
receives the arguments as the request. The registrant then has to
|
|
53
53
|
provide the service response.
|
|
54
54
|
|
|
55
55
|
In contrast to the regular uni-directional MQTT message
|
|
@@ -72,7 +72,8 @@ communication patterns with type safety:
|
|
|
72
72
|
|
|
73
73
|
In contrast to the regular MQTT message publish/subscribe, this
|
|
74
74
|
pattern allows to transfer arbitrary amounts of arbitrary data by
|
|
75
|
-
chunking the data via a stream.
|
|
75
|
+
chunking the data via a stream. Additionally, it supports optional
|
|
76
|
+
metadata transfer alongside the resource data.
|
|
76
77
|
|
|
77
78
|

|
|
78
79
|
|
|
@@ -229,7 +230,7 @@ The **MQTT+** API provides the following methods:
|
|
|
229
230
|
The `callback` is called with the `params` passed to a remote `call()`.
|
|
230
231
|
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
231
232
|
|
|
232
|
-
Internally, on the MQTT broker, the topics by
|
|
233
|
+
Internally, on the MQTT broker, the topics generated by
|
|
233
234
|
`topicMake(service, "service-call-request")` (default: `${service}/service-call-request/any` and
|
|
234
235
|
`${service}/service-call-request/${peerId}`) are subscribed. Returns a
|
|
235
236
|
`Registration` object with an `unregister()` method.
|
|
@@ -246,6 +247,7 @@ The **MQTT+** API provides the following methods:
|
|
|
246
247
|
sender: string,
|
|
247
248
|
receiver?: string,
|
|
248
249
|
resource: Buffer | Readable | null,
|
|
250
|
+
meta?: Record<string, any>,
|
|
249
251
|
stream?: Readable,
|
|
250
252
|
buffer?: Promise<Buffer>
|
|
251
253
|
}
|
|
@@ -258,10 +260,12 @@ The **MQTT+** API provides the following methods:
|
|
|
258
260
|
|
|
259
261
|
For **fetch requests**: The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
260
262
|
The `callback` should set `info.resource` to a `Buffer` or `Readable` containing the resource data.
|
|
263
|
+
Optionally, the `callback` can set `info.meta` to a `Record<string, any>` to send metadata back with the response.
|
|
261
264
|
|
|
262
265
|
For **pushed data**: The `callback` is called with the `params` passed to a remote `push()`.
|
|
263
266
|
The `info.stream` provides a Node.js `Readable` stream for consuming the pushed data.
|
|
264
267
|
The `info.buffer` provides a lazy `Promise<Buffer>` that resolves to the complete data once the stream ends.
|
|
268
|
+
The `info.meta` contains optional metadata sent by the pusher via `push()`.
|
|
265
269
|
|
|
266
270
|
Internally, on the MQTT broker, the topics by
|
|
267
271
|
`topicMake(resource, "resource-transfer-request")` and `topicMake(resource, "resource-transfer-response")`
|
|
@@ -319,17 +323,20 @@ The **MQTT+** API provides the following methods:
|
|
|
319
323
|
receiver?: Receiver,
|
|
320
324
|
options?: MQTT::IClientSubscribeOptions,
|
|
321
325
|
...params: any[]
|
|
322
|
-
): Promise<{ stream: Readable, buffer: Promise<Buffer> }>
|
|
326
|
+
): Promise<{ stream: Readable, buffer: Promise<Buffer>, meta: Promise<Record<string, any> | undefined> }>
|
|
323
327
|
|
|
324
328
|
Fetches a resource from any resource provisioner or from a specific provisioner.
|
|
325
329
|
The optional `receiver` directs the call to a specific provisioner only.
|
|
326
330
|
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
327
331
|
|
|
328
|
-
Returns an object with a `stream` (`Readable`) for consuming the transferred data
|
|
329
|
-
|
|
332
|
+
Returns an object with a `stream` (`Readable`) for consuming the transferred data,
|
|
333
|
+
a lazy `buffer` (`Promise<Buffer>`) that resolves to the complete data once the stream ends,
|
|
334
|
+
and a `meta` (`Promise<Record<string, any> | undefined>`) that resolves to optional metadata
|
|
335
|
+
sent by the provisioner when the first chunk arrives.
|
|
330
336
|
|
|
331
337
|
The remote `provision()` `callback` is called with `params` and
|
|
332
338
|
should set `info.resource` to a `Buffer` or `Readable` containing the resource data.
|
|
339
|
+
Optionally, the `callback` can set `info.meta` to send metadata back with the response.
|
|
333
340
|
If the remote `callback` throws an exception, this destroys the stream with the error.
|
|
334
341
|
|
|
335
342
|
Internally, on the MQTT broker, the topic by
|
|
@@ -343,6 +350,7 @@ The **MQTT+** API provides the following methods:
|
|
|
343
350
|
push(
|
|
344
351
|
resource: string,
|
|
345
352
|
streamOrBuffer: Readable | Buffer,
|
|
353
|
+
meta?: Meta,
|
|
346
354
|
receiver?: Receiver,
|
|
347
355
|
options?: MQTT::IClientPublishOptions,
|
|
348
356
|
...params: any[]
|
|
@@ -350,6 +358,8 @@ The **MQTT+** API provides the following methods:
|
|
|
350
358
|
|
|
351
359
|
Pushes a resource to all provisioners or a specific provisioner.
|
|
352
360
|
The `streamOrBuffer` is either a Node.js `Readable` stream or a `Buffer` providing the data to push.
|
|
361
|
+
The optional `meta` (wrapped via `meta()`) sends metadata alongside the resource data,
|
|
362
|
+
which becomes available on the provisioner side via `info.meta`.
|
|
353
363
|
The optional `receiver` directs the push to a specific provisioner only.
|
|
354
364
|
The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
355
365
|
|
|
@@ -359,8 +369,9 @@ The **MQTT+** API provides the following methods:
|
|
|
359
369
|
The returned `Promise` resolves when the entire data has been pushed.
|
|
360
370
|
|
|
361
371
|
The remote `provision()` `callback` is called with `params` and an `info` object
|
|
362
|
-
containing `stream` (`Readable`) for consuming the pushed data
|
|
363
|
-
`buffer` (lazy `Promise<Buffer>`) that resolves to the complete data once the stream ends
|
|
372
|
+
containing `stream` (`Readable`) for consuming the pushed data,
|
|
373
|
+
`buffer` (lazy `Promise<Buffer>`) that resolves to the complete data once the stream ends,
|
|
374
|
+
and `meta` (`Record<string, any> | undefined`) containing the metadata sent by the pusher.
|
|
364
375
|
|
|
365
376
|
Internally, publishes to the MQTT topic by `topicMake(resource, "resource-transfer-response", peerId)`
|
|
366
377
|
(default: `${resource}/resource-transfer-response/any` or `${resource}/resource-transfer-response/${peerId}`).
|
|
@@ -374,6 +385,16 @@ The **MQTT+** API provides the following methods:
|
|
|
374
385
|
Wrap a receiver ID string for use with `emit()`, `call()`, `fetch()` or `push()` to direct the
|
|
375
386
|
message to a specific receiver. Returns a `Receiver` object.
|
|
376
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
|
+
|
|
377
398
|
Internals
|
|
378
399
|
---------
|
|
379
400
|
|
|
@@ -556,9 +577,9 @@ The output will be:
|
|
|
556
577
|
```
|
|
557
578
|
$ node sample.ts
|
|
558
579
|
CONNECT
|
|
559
|
-
RECEIVED example/hello/service-call-request/any {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
580
|
+
RECEIVED example/hello/service-call-request/any {"type":"service-call-request","id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
560
581
|
example/hello: request: world 42 from: 2IBMSk0NPnrz1AeTERoea
|
|
561
|
-
RECEIVED example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
582
|
+
RECEIVED example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea {"type":"service-call-response","id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
562
583
|
example/hello success: world:42
|
|
563
584
|
CLOSE
|
|
564
585
|
```
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { MqttClient, IClientPublishOptions, IClientSubscribeOptions } from "mqtt";
|
|
2
2
|
import { APISchema } from "./mqtt-plus-api";
|
|
3
3
|
import { APIOptions } from "./mqtt-plus-options";
|
|
4
|
-
import {
|
|
5
|
-
export declare class BaseTrait<T extends APISchema = APISchema> extends
|
|
4
|
+
import { MetaTrait } from "./mqtt-plus-meta";
|
|
5
|
+
export declare class BaseTrait<T extends APISchema = APISchema> extends MetaTrait<T> {
|
|
6
6
|
protected mqtt: MqttClient;
|
|
7
|
+
private _messageHandler;
|
|
7
8
|
constructor(mqtt: MqttClient, options?: Partial<APIOptions>);
|
|
8
9
|
destroy(): void;
|
|
9
10
|
protected _subscribeTopic(topic: string, options?: Partial<IClientSubscribeOptions>): Promise<void>;
|
|
10
11
|
protected _unsubscribeTopic(topic: string): Promise<void>;
|
|
11
12
|
private _isIClientPublishOptions;
|
|
12
13
|
protected _parseCallArgs<U extends any[]>(args: any[]): {
|
|
14
|
+
meta?: Record<string, any>;
|
|
13
15
|
receiver?: string;
|
|
14
16
|
options: IClientPublishOptions;
|
|
15
17
|
params: U;
|
|
@@ -21,22 +21,23 @@
|
|
|
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 { MetaTrait } from "./mqtt-plus-meta";
|
|
25
25
|
/* MQTTp Base class with shared infrastructure */
|
|
26
|
-
export class BaseTrait extends
|
|
26
|
+
export class BaseTrait extends MetaTrait {
|
|
27
27
|
/* construct API class */
|
|
28
28
|
constructor(mqtt, options = {}) {
|
|
29
29
|
super(options);
|
|
30
30
|
/* store MQTT client */
|
|
31
31
|
this.mqtt = mqtt;
|
|
32
32
|
/* hook into the MQTT message processing */
|
|
33
|
-
this.
|
|
33
|
+
this._messageHandler = (topic, message, packet) => {
|
|
34
34
|
this._onMessage(topic, message, packet);
|
|
35
|
-
}
|
|
35
|
+
};
|
|
36
|
+
this.mqtt.on("message", this._messageHandler);
|
|
36
37
|
}
|
|
37
38
|
/* destroy API class */
|
|
38
39
|
destroy() {
|
|
39
|
-
this.mqtt.
|
|
40
|
+
this.mqtt.off("message", this._messageHandler);
|
|
40
41
|
}
|
|
41
42
|
/* subscribe to an MQTT topic (Promise-based) */
|
|
42
43
|
async _subscribeTopic(topic, options = {}) {
|
|
@@ -67,8 +68,13 @@ export class BaseTrait extends ReceiverTrait {
|
|
|
67
68
|
const keys = ["qos", "retain", "dup", "properties", "cbStorePut"];
|
|
68
69
|
return Object.keys(arg).every((key) => keys.includes(key));
|
|
69
70
|
}
|
|
70
|
-
/* parse optional
|
|
71
|
+
/* parse optional meta, receiver and options from variadic arguments */
|
|
71
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 */
|
|
72
78
|
let receiver;
|
|
73
79
|
let options = {};
|
|
74
80
|
let params = args;
|
|
@@ -85,11 +91,11 @@ export class BaseTrait extends ReceiverTrait {
|
|
|
85
91
|
options = args[0];
|
|
86
92
|
params = args.slice(1);
|
|
87
93
|
}
|
|
88
|
-
return { receiver, options, params };
|
|
94
|
+
return { meta, receiver, options, params };
|
|
89
95
|
}
|
|
90
96
|
/* handle incoming MQTT message */
|
|
91
97
|
_onMessage(topic, message, packet) {
|
|
92
|
-
/* try to parse
|
|
98
|
+
/* try to parse message as payload */
|
|
93
99
|
let parsed;
|
|
94
100
|
try {
|
|
95
101
|
let input = message;
|
|
@@ -83,7 +83,7 @@ export class EventTrait extends BaseTrait {
|
|
|
83
83
|
/* generate corresponding MQTT topic */
|
|
84
84
|
const topic = this.options.topicMake(event, "event-emission", receiver);
|
|
85
85
|
/* publish message to MQTT topic */
|
|
86
|
-
this.mqtt.publish(topic, message, { qos:
|
|
86
|
+
this.mqtt.publish(topic, message, { qos: 0, ...options });
|
|
87
87
|
}
|
|
88
88
|
/* dispatch message (Event pattern handling) */
|
|
89
89
|
_dispatchMessage(topic, parsed) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { APISchema } from "./mqtt-plus-api";
|
|
2
|
+
import { ReceiverTrait } from "./mqtt-plus-receiver";
|
|
3
|
+
export type Meta = {
|
|
4
|
+
__meta: Record<string, any>;
|
|
5
|
+
};
|
|
6
|
+
export declare class MetaTrait<T extends APISchema = APISchema> extends ReceiverTrait<T> {
|
|
7
|
+
meta(data: Record<string, any>): {
|
|
8
|
+
__meta: Record<string, any>;
|
|
9
|
+
};
|
|
10
|
+
protected _getMeta(obj: Meta): Record<string, any>;
|
|
11
|
+
protected _isMeta(obj: any): obj is Meta;
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
** MQTT+ -- MQTT Communication Patterns
|
|
3
|
+
** Copyright (c) 2018-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
+
**
|
|
5
|
+
** Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
** a copy of this software and associated documentation files (the
|
|
7
|
+
** "Software"), to deal in the Software without restriction, including
|
|
8
|
+
** without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
** distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
** permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
** the following conditions:
|
|
12
|
+
**
|
|
13
|
+
** The above copyright notice and this permission notice shall be included
|
|
14
|
+
** in all copies or substantial portions of the Software.
|
|
15
|
+
**
|
|
16
|
+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
import { ReceiverTrait } from "./mqtt-plus-receiver";
|
|
25
|
+
/* Meta trait */
|
|
26
|
+
export class MetaTrait extends ReceiverTrait {
|
|
27
|
+
/* wrap meta object into wrapper (required for type-safe overloading) */
|
|
28
|
+
meta(data) {
|
|
29
|
+
return { __meta: data };
|
|
30
|
+
}
|
|
31
|
+
/* return meta object from wrapper object */
|
|
32
|
+
_getMeta(obj) {
|
|
33
|
+
return obj.__meta;
|
|
34
|
+
}
|
|
35
|
+
/* detect meta wrapper object */
|
|
36
|
+
_isMeta(obj) {
|
|
37
|
+
return (typeof obj === "object"
|
|
38
|
+
&& obj !== null
|
|
39
|
+
&& "__meta" in obj
|
|
40
|
+
&& typeof obj.__meta === "object"
|
|
41
|
+
&& obj.__meta !== null);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -31,16 +31,17 @@ export declare class ResourceTransferResponse extends Base {
|
|
|
31
31
|
resource?: string | undefined;
|
|
32
32
|
params?: any[] | undefined;
|
|
33
33
|
chunk?: Buffer | undefined;
|
|
34
|
+
meta?: Record<string, any> | undefined;
|
|
34
35
|
error?: string | undefined;
|
|
35
36
|
final?: boolean | undefined;
|
|
36
|
-
constructor(id: string, resource?: string | undefined, params?: any[] | undefined, chunk?: Buffer | undefined, error?: string | undefined, final?: boolean | undefined, sender?: string, receiver?: string);
|
|
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);
|
|
37
38
|
}
|
|
38
39
|
export default class Msg {
|
|
39
40
|
makeEventEmission(id: string, event: string, params?: any[], sender?: string, receiver?: string): EventEmission;
|
|
40
41
|
makeServiceCallRequest(id: string, service: string, params?: any[], sender?: string, receiver?: string): ServiceCallRequest;
|
|
41
42
|
makeServiceCallResponse(id: string, result?: any, error?: string, sender?: string, receiver?: string): ServiceCallResponse;
|
|
42
43
|
makeResourceTransferRequest(id: string, resource: string, params?: any[], sender?: string, receiver?: string): ResourceTransferRequest;
|
|
43
|
-
makeResourceTransferResponse(id: string, resource?: string, params?: any[], chunk?: Buffer, error?: string, final?: boolean, sender?: string, receiver?: string): ResourceTransferResponse;
|
|
44
|
+
makeResourceTransferResponse(id: string, resource?: string, params?: any[], chunk?: Buffer, meta?: Record<string, any>, error?: string, final?: boolean, sender?: string, receiver?: string): ResourceTransferResponse;
|
|
44
45
|
parse(obj: any): EventEmission | ServiceCallRequest | ServiceCallResponse | ResourceTransferRequest | ResourceTransferResponse;
|
|
45
46
|
}
|
|
46
47
|
export declare class MsgTrait<T extends APISchema = APISchema> extends CodecTrait<T> {
|
|
@@ -65,11 +65,12 @@ export class ResourceTransferRequest extends Base {
|
|
|
65
65
|
}
|
|
66
66
|
/* resource response */
|
|
67
67
|
export class ResourceTransferResponse extends Base {
|
|
68
|
-
constructor(id, resource, params, chunk, error, final, sender, receiver) {
|
|
68
|
+
constructor(id, resource, params, chunk, meta, error, final, sender, receiver) {
|
|
69
69
|
super("resource-transfer-response", id, sender, receiver);
|
|
70
70
|
this.resource = resource;
|
|
71
71
|
this.params = params;
|
|
72
72
|
this.chunk = chunk;
|
|
73
|
+
this.meta = meta;
|
|
73
74
|
this.error = error;
|
|
74
75
|
this.final = final;
|
|
75
76
|
}
|
|
@@ -93,8 +94,8 @@ export default class Msg {
|
|
|
93
94
|
return new ResourceTransferRequest(id, resource, params, sender, receiver);
|
|
94
95
|
}
|
|
95
96
|
/* factory for resource response */
|
|
96
|
-
makeResourceTransferResponse(id, resource, params, chunk, error, final, sender, receiver) {
|
|
97
|
-
return new ResourceTransferResponse(id, resource, params, chunk, error, final, sender, receiver);
|
|
97
|
+
makeResourceTransferResponse(id, resource, params, chunk, meta, error, final, sender, receiver) {
|
|
98
|
+
return new ResourceTransferResponse(id, resource, params, chunk, meta, error, final, sender, receiver);
|
|
98
99
|
}
|
|
99
100
|
/* parse any object into typed object */
|
|
100
101
|
parse(obj) {
|
|
@@ -153,21 +154,24 @@ export default class Msg {
|
|
|
153
154
|
throw new Error("invalid ResourceTransferResponse object: \"resource\" field must be a string");
|
|
154
155
|
if (obj.chunk !== undefined && typeof obj.chunk !== "object")
|
|
155
156
|
throw new Error("invalid ResourceTransferResponse object: \"chunk\" field must be an object");
|
|
157
|
+
if (obj.meta !== undefined && (typeof obj.meta !== "object" || obj.meta === null || Array.isArray(obj.meta)))
|
|
158
|
+
throw new Error("invalid ResourceTransferResponse object: \"meta\" field must be an object");
|
|
156
159
|
if (obj.error !== undefined && typeof obj.error !== "string")
|
|
157
160
|
throw new Error("invalid ResourceTransferResponse object: \"error\" field must be a string");
|
|
158
161
|
if (obj.final !== undefined && typeof obj.final !== "boolean")
|
|
159
162
|
throw new Error("invalid ResourceTransferResponse object: \"final\" field must be a boolean");
|
|
160
163
|
if (!validParams(obj))
|
|
161
164
|
throw new Error("invalid ResourceTransferResponse object: \"params\" field must be an array");
|
|
162
|
-
if (anyFieldsExcept(obj, ["type", "id", "resource", "params",
|
|
165
|
+
if (anyFieldsExcept(obj, ["type", "id", "resource", "params",
|
|
166
|
+
"chunk", "meta", "error", "final", "sender", "receiver"]))
|
|
163
167
|
throw new Error("invalid ResourceTransferResponse object: contains unknown fields");
|
|
164
|
-
return this.makeResourceTransferResponse(obj.id, obj.resource, obj.params, obj.chunk, obj.error, obj.final, obj.sender, obj.receiver);
|
|
168
|
+
return this.makeResourceTransferResponse(obj.id, obj.resource, obj.params, obj.chunk, obj.meta, obj.error, obj.final, obj.sender, obj.receiver);
|
|
165
169
|
}
|
|
166
170
|
else
|
|
167
171
|
throw new Error("invalid object: not of any known type");
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
|
-
/*
|
|
174
|
+
/* message trait */
|
|
171
175
|
export class MsgTrait extends CodecTrait {
|
|
172
176
|
constructor() {
|
|
173
177
|
super(...arguments);
|
|
@@ -38,7 +38,11 @@ export class OptionsTrait {
|
|
|
38
38
|
},
|
|
39
39
|
topicMatch: (topic) => {
|
|
40
40
|
const m = topic.match(/^(.+)\/([^/]+)\/([^/]+)$/);
|
|
41
|
-
return m ? {
|
|
41
|
+
return m ? {
|
|
42
|
+
name: m[1],
|
|
43
|
+
operation: m[2],
|
|
44
|
+
peerId: m[3] === "any" ? undefined : m[3]
|
|
45
|
+
} : null;
|
|
42
46
|
},
|
|
43
47
|
...options
|
|
44
48
|
};
|
|
@@ -3,6 +3,7 @@ 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
5
|
import type { Receiver } from "./mqtt-plus-receiver";
|
|
6
|
+
import type { Meta } from "./mqtt-plus-meta";
|
|
6
7
|
import { ServiceTrait } from "./mqtt-plus-service";
|
|
7
8
|
export interface Provisioning {
|
|
8
9
|
unprovision(): Promise<void>;
|
|
@@ -11,12 +12,9 @@ export declare class ResourceTrait<T extends APISchema = APISchema> extends Serv
|
|
|
11
12
|
private provisionings;
|
|
12
13
|
private callbacks;
|
|
13
14
|
private pushStreams;
|
|
15
|
+
private pushTimers;
|
|
14
16
|
provision<K extends ResourceKeys<T> & string>(resource: K, callback: WithInfo<T[K], InfoResource>): Promise<Provisioning>;
|
|
15
17
|
provision<K extends ResourceKeys<T> & string>(resource: K, options: Partial<IClientSubscribeOptions>, callback: WithInfo<T[K], InfoResource>): Promise<Provisioning>;
|
|
16
|
-
private _collectStreamToBuffer;
|
|
17
|
-
private _chunkToBuffer;
|
|
18
|
-
private _sendBufferAsChunks;
|
|
19
|
-
private _sendStreamAsChunks;
|
|
20
18
|
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, ...params: Parameters<T[K]>): Promise<void>;
|
|
21
19
|
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, receiver: Receiver, ...params: Parameters<T[K]>): Promise<void>;
|
|
22
20
|
push<K extends ResourceKeys<T> & string>(resource: K, stream: Readable, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
@@ -25,21 +23,33 @@ export declare class ResourceTrait<T extends APISchema = APISchema> extends Serv
|
|
|
25
23
|
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, receiver: Receiver, ...params: Parameters<T[K]>): Promise<void>;
|
|
26
24
|
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
27
25
|
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, receiver: Receiver, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<void>;
|
|
26
|
+
push<K extends ResourceKeys<T> & string>(resource: K, buffer: Buffer, meta: Meta, ...params: Parameters<T[K]>): Promise<void>;
|
|
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>;
|
|
28
34
|
fetch<K extends ResourceKeys<T> & string>(resource: K, ...params: Parameters<T[K]>): Promise<{
|
|
29
35
|
stream: Readable;
|
|
30
36
|
buffer: Promise<Buffer>;
|
|
37
|
+
meta: Promise<Record<string, any> | undefined>;
|
|
31
38
|
}>;
|
|
32
39
|
fetch<K extends ResourceKeys<T> & string>(resource: K, receiver: Receiver, ...params: Parameters<T[K]>): Promise<{
|
|
33
40
|
stream: Readable;
|
|
34
41
|
buffer: Promise<Buffer>;
|
|
42
|
+
meta: Promise<Record<string, any> | undefined>;
|
|
35
43
|
}>;
|
|
36
44
|
fetch<K extends ResourceKeys<T> & string>(resource: K, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<{
|
|
37
45
|
stream: Readable;
|
|
38
46
|
buffer: Promise<Buffer>;
|
|
47
|
+
meta: Promise<Record<string, any> | undefined>;
|
|
39
48
|
}>;
|
|
40
49
|
fetch<K extends ResourceKeys<T> & string>(resource: K, receiver: Receiver, options: IClientPublishOptions, ...params: Parameters<T[K]>): Promise<{
|
|
41
50
|
stream: Readable;
|
|
42
51
|
buffer: Promise<Buffer>;
|
|
52
|
+
meta: Promise<Record<string, any> | undefined>;
|
|
43
53
|
}>;
|
|
44
54
|
protected _dispatchMessage(topic: string, parsed: any): void;
|
|
45
55
|
}
|