mqtt-plus 1.4.0 → 1.4.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/AGENTS.md +55 -44
- package/CHANGELOG.md +14 -0
- package/README.md +4 -3
- package/doc/mqtt-plus-api.md +693 -680
- package/doc/mqtt-plus-architecture.d2 +139 -0
- package/doc/mqtt-plus-architecture.md +10 -0
- package/doc/mqtt-plus-architecture.svg +95 -0
- package/doc/mqtt-plus-broker-setup.md +9 -3
- package/doc/mqtt-plus-comm.md +73 -0
- package/doc/mqtt-plus-internals.md +3 -3
- package/dst-stage1/mqtt-plus-base.d.ts +3 -2
- package/dst-stage1/mqtt-plus-base.js +53 -22
- package/dst-stage1/mqtt-plus-event.d.ts +0 -2
- package/dst-stage1/mqtt-plus-event.js +6 -26
- 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 +2 -0
- package/dst-stage1/mqtt-plus-msg.js +17 -0
- package/dst-stage1/mqtt-plus-service.d.ts +0 -5
- package/dst-stage1/mqtt-plus-service.js +12 -48
- package/dst-stage1/mqtt-plus-sink.d.ts +0 -10
- package/dst-stage1/mqtt-plus-sink.js +25 -92
- package/dst-stage1/mqtt-plus-source.d.ts +0 -10
- package/dst-stage1/mqtt-plus-source.js +23 -88
- package/dst-stage1/mqtt-plus-subscription.d.ts +20 -0
- package/dst-stage1/mqtt-plus-subscription.js +126 -0
- package/dst-stage1/mqtt-plus-timer.d.ts +8 -0
- package/dst-stage1/mqtt-plus-timer.js +57 -0
- package/dst-stage1/mqtt-plus-topic.d.ts +20 -0
- package/dst-stage1/mqtt-plus-topic.js +112 -0
- package/dst-stage1/mqtt-plus-trace.js +2 -0
- package/dst-stage1/mqtt-plus-util.d.ts +0 -13
- package/dst-stage1/mqtt-plus-util.js +1 -77
- package/dst-stage1/mqtt-plus-version.d.ts +0 -1
- package/dst-stage1/mqtt-plus-version.js +0 -6
- package/dst-stage1/tsc.tsbuildinfo +1 -1
- package/dst-stage2/mqtt-plus.cjs.js +242 -292
- package/dst-stage2/mqtt-plus.esm.js +240 -290
- package/dst-stage2/mqtt-plus.umd.js +12 -12
- package/etc/knip.jsonc +1 -1
- package/etc/stx.conf +6 -4
- package/package.json +1 -1
- package/src/mqtt-plus-base.ts +56 -26
- package/src/mqtt-plus-event.ts +8 -24
- package/src/mqtt-plus-meta.ts +3 -3
- package/src/mqtt-plus-msg.ts +28 -0
- package/src/mqtt-plus-service.ts +12 -50
- package/src/mqtt-plus-sink.ts +32 -105
- package/src/mqtt-plus-source.ts +29 -99
- package/src/mqtt-plus-subscription.ts +141 -0
- package/src/mqtt-plus-timer.ts +61 -0
- package/src/mqtt-plus-trace.ts +4 -0
- package/src/mqtt-plus-util.ts +1 -81
- package/src/mqtt-plus-version.ts +0 -7
- package/tst/mqtt-plus-0-fixture.ts +2 -2
- package/tst/mqtt-plus-0-mosquitto.ts +5 -0
- package/tst/mqtt-plus-1-api.spec.ts +1 -1
- package/tst/mqtt-plus-2-event.spec.ts +0 -6
- package/tst/mqtt-plus-3-service.spec.ts +3 -7
- package/tst/mqtt-plus-4-sink.spec.ts +14 -9
- package/tst/mqtt-plus-5-source.spec.ts +11 -5
- package/tst/mqtt-plus-6-misc.spec.ts +23 -23
- package/tst/tsc.json +1 -1
- package/doc/mqtt-plus-communication.md +0 -68
- /package/doc/{mqtt-plus-1-event-emission.d2 → mqtt-plus-comm-event-emission.d2} +0 -0
- /package/doc/{mqtt-plus-1-event-emission.svg → mqtt-plus-comm-event-emission.svg} +0 -0
- /package/doc/{mqtt-plus-2-service-call.d2 → mqtt-plus-comm-service-call.d2} +0 -0
- /package/doc/{mqtt-plus-2-service-call.svg → mqtt-plus-comm-service-call.svg} +0 -0
- /package/doc/{mqtt-plus-3-sink-push.d2 → mqtt-plus-comm-sink-push.d2} +0 -0
- /package/doc/{mqtt-plus-3-sink-push.svg → mqtt-plus-comm-sink-push.svg} +0 -0
- /package/doc/{mqtt-plus-4-source-fetch.d2 → mqtt-plus-comm-source-fetch.d2} +0 -0
- /package/doc/{mqtt-plus-4-source-fetch.svg → mqtt-plus-comm-source-fetch.svg} +0 -0
- /package/{doc/theme.d2 → etc/d2.theme.d2} +0 -0
package/doc/mqtt-plus-api.md
CHANGED
|
@@ -1,682 +1,695 @@
|
|
|
1
1
|
|
|
2
|
-
Application Programming Interface
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
2
|
+
MQTT+ Application Programming Interface
|
|
3
|
+
=======================================
|
|
4
|
+
|
|
5
|
+
Construction
|
|
6
|
+
------------
|
|
7
|
+
|
|
8
|
+
/* (simplified TypeScript API method signature) */
|
|
9
|
+
constructor<API extends Record<string,
|
|
10
|
+
Event< (...args: any[]) => void | Promise<void>> |
|
|
11
|
+
Service< (...args: any[]) => any | Promise<any> > |
|
|
12
|
+
Source< (...args: any[]) => void | Promise<void>> |
|
|
13
|
+
Sink< (...args: any[]) => void | Promise<void>>
|
|
14
|
+
>>(
|
|
15
|
+
mqtt: MqttClient | null,
|
|
16
|
+
options?: {
|
|
17
|
+
id: string
|
|
18
|
+
codec: "cbor" | "json"
|
|
19
|
+
timeout: number
|
|
20
|
+
chunkSize: number
|
|
21
|
+
chunkCredit: number
|
|
22
|
+
topicMake: (name: string, operation: string, peerId?: string) => string
|
|
23
|
+
topicMatch: (topic: string) => { name: string, operation: string, peerId?: string } | null
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
The `API` is a TypeScript type,
|
|
28
|
+
describing the available events, services, sources, and sinks.
|
|
29
|
+
|
|
30
|
+
- The `mqtt` is the [MQTT.js](https://www.npmjs.com/package/mqtt) instance,
|
|
31
|
+
which has to be established separately. A `null` MQTT instance can be
|
|
32
|
+
used for performing dry-runs (see *Dry-Run Publishing for MQTT Last-Will* under
|
|
33
|
+
**Event Emission** below).
|
|
34
|
+
|
|
35
|
+
- The optional `options` object supports the following fields:
|
|
36
|
+
- `id`: Custom MQTT peer identifier (default: auto-generated NanoID).
|
|
37
|
+
- `codec`: Encoding format, either `cbor` or `json` (default: `cbor`).
|
|
38
|
+
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
39
|
+
- `chunkSize`: Chunk size in bytes for source/sink transfers (default: `16384`).
|
|
40
|
+
- `chunkCredit`: Number of credit units for flow control in source/sink
|
|
41
|
+
chunked transfers (default: `4`). Controls how many chunks can be
|
|
42
|
+
in-flight before the receiver must grant additional credit.
|
|
43
|
+
- `topicMake`: Custom topic generation function.
|
|
44
|
+
The `operation` parameter is one of: `event-emission`,
|
|
45
|
+
`service-call-request`, `service-call-response`,
|
|
46
|
+
`source-fetch-request`, `source-fetch-response`,
|
|
47
|
+
`source-fetch-chunk`, `source-fetch-credit`,
|
|
48
|
+
`sink-push-request`, `sink-push-response`,
|
|
49
|
+
`sink-push-chunk`, `sink-push-credit`. (default: `` (name, operation, peerId) =>
|
|
50
|
+
`${name}/${operation}/${peerId ?? "any"}` ``)
|
|
51
|
+
- `topicMatch`: Custom topic matching function.
|
|
52
|
+
Returns `{ name: string, operation: string, peerId?: string }` or `null` if no match.
|
|
53
|
+
The `peerId` is `undefined` for broadcast topics (those ending with `/any`).
|
|
54
|
+
(default: `` (topic) => { const m = topic.match(/^(.+)\/([^/]+)\/([^/]+)$/); return m ? { name: m[1], operation: m[2], peerId: m[3] === "any" ? undefined : m[3] } : null } ``)
|
|
55
|
+
|
|
56
|
+
Destruction
|
|
57
|
+
-----------
|
|
58
|
+
|
|
59
|
+
destroy(): void
|
|
60
|
+
|
|
61
|
+
Clean up the MQTT+ instance by removing all event listeners.
|
|
62
|
+
Call this method when the instance is no longer needed.
|
|
63
|
+
The companion MQTT.js instance has to be destroyed separately.
|
|
64
|
+
|
|
65
|
+
Event Handling
|
|
66
|
+
--------------
|
|
67
|
+
|
|
68
|
+
/* listen for error or log events */
|
|
69
|
+
on(event: "error", callback: (error: Error) => void): void
|
|
70
|
+
on(event: "log", callback: (log: LogEvent) => void): void
|
|
71
|
+
|
|
72
|
+
/* remove error or log event listener */
|
|
73
|
+
off(event: "error", callback: (error: Error) => void): void
|
|
74
|
+
off(event: "log", callback: (log: LogEvent) => void): void
|
|
75
|
+
|
|
76
|
+
MQTT+ emits `error` and `log` events for monitoring and debugging.
|
|
77
|
+
|
|
78
|
+
- The `on()` method registers an event listener.
|
|
79
|
+
The `"error"` event is emitted when an error occurs during
|
|
80
|
+
message processing, subscription, or publishing.
|
|
81
|
+
The `"log"` event is emitted for informational and debug-level
|
|
82
|
+
messages with a `LogEvent` object containing `timestamp`, `level`,
|
|
83
|
+
`msg`, and optional `data` fields.
|
|
84
|
+
|
|
85
|
+
- The `off()` method removes a previously registered event listener.
|
|
86
|
+
|
|
87
|
+
- The `LogEvent` object provides `resolve()` for resolving lazy
|
|
88
|
+
promise-based fields and `toString()` for rendering log entries
|
|
89
|
+
as formatted strings.
|
|
90
|
+
|
|
91
|
+
Example:
|
|
92
|
+
|
|
93
|
+
mqttp.on("error", (err) => {
|
|
94
|
+
console.error("MQTT+ error:", err.message)
|
|
95
|
+
})
|
|
96
|
+
mqttp.on("log", (log) => {
|
|
97
|
+
console.log(log.toString())
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
Authentication
|
|
101
|
+
--------------
|
|
102
|
+
|
|
103
|
+
/* store server-side secret credential */
|
|
104
|
+
credential(credential: string): void
|
|
105
|
+
|
|
106
|
+
/* issue client-side token on server-side */
|
|
107
|
+
issue(payload: { roles: string[], id?: string }): Promise<string>
|
|
108
|
+
|
|
109
|
+
/* add/remove client-side token (client-side) */
|
|
110
|
+
authenticate(token: string): void
|
|
111
|
+
authenticate(token: string, remove: boolean): void
|
|
112
|
+
|
|
113
|
+
MQTT+ provides JWT-based authentication for securing events, services,
|
|
114
|
+
sources, and sinks. Authentication works by issuing tokens on the
|
|
115
|
+
server-side and validating them when messages are received.
|
|
116
|
+
|
|
117
|
+
- The `credential()` method sets the secret key used for signing and
|
|
118
|
+
verifying JWT tokens. This must be called before `issue()` can be
|
|
119
|
+
used.
|
|
120
|
+
|
|
121
|
+
- The `issue()` method creates a new JWT token with the specified `roles` array.
|
|
122
|
+
The optional `id` field can bind the token to a specific client identifier.
|
|
123
|
+
|
|
124
|
+
- The `authenticate()` method manages client-side tokens:
|
|
125
|
+
called with a token, adds the token to the set of active tokens;
|
|
126
|
+
called with a token and `true`, removes the token from the set.
|
|
127
|
+
|
|
128
|
+
- When a client has tokens set via `authenticate()`, they are automatically
|
|
129
|
+
included in outgoing `emit()`, `call()`, `push()`, and `fetch()` requests.
|
|
130
|
+
|
|
131
|
+
Example:
|
|
132
|
+
|
|
133
|
+
/* server: set credential and issue token */
|
|
134
|
+
mqttp.credential("my-secret-key")
|
|
135
|
+
const token = await mqttp.issue({ roles: [ "admin", "user" ] })
|
|
136
|
+
|
|
137
|
+
/* client: add token for authentication */
|
|
138
|
+
mqttp.authenticate(token)
|
|
139
|
+
|
|
140
|
+
Meta Information
|
|
141
|
+
----------------
|
|
142
|
+
|
|
143
|
+
/* set meta information by key */
|
|
144
|
+
meta(key: string, value: any): void
|
|
145
|
+
|
|
146
|
+
/* retrieve meta information by key */
|
|
147
|
+
meta(key: string): any
|
|
148
|
+
|
|
149
|
+
/* delete meta information by key */
|
|
150
|
+
meta(key: string, value: null): void
|
|
151
|
+
|
|
152
|
+
MQTT+ allows attaching persistent meta-data to an instance that is
|
|
153
|
+
automatically included in all outgoing messages. This is useful for
|
|
154
|
+
adding context information like client version, environment, or user
|
|
155
|
+
identity to every request.
|
|
156
|
+
|
|
157
|
+
- The `meta()` method manages instance-level meta-data:
|
|
158
|
+
called with a key only, retrieves the meta-data entry for that key;
|
|
159
|
+
called with a key and non-null value, sets the meta-data entry;
|
|
160
|
+
called with a key and `null`, deletes the meta-data entry.
|
|
161
|
+
|
|
162
|
+
- Instance-level meta-data set via `meta()` is merged with any per-request
|
|
163
|
+
`meta` option passed to `emit()`, `call()`, `push()`, or `fetch()`.
|
|
164
|
+
Per-request meta-data takes precedence over instance-level metadata.
|
|
165
|
+
|
|
166
|
+
- On the receiving side, meta-data is available via the `info.meta`
|
|
167
|
+
field in callbacks for `event()`, `service()`, `source()`, and `sink()`.
|
|
168
|
+
For `fetch()`, the returned `meta` promise resolves to the meta-data
|
|
169
|
+
sent by the source.
|
|
170
|
+
|
|
171
|
+
Example:
|
|
172
|
+
|
|
173
|
+
/* client: set instance-level metadata */
|
|
174
|
+
mqttp.meta("clientVersion", "1.0.0")
|
|
175
|
+
mqttp.meta("environment", "production")
|
|
176
|
+
|
|
177
|
+
/* client: retrieve a metadata entry */
|
|
178
|
+
const environment = mqttp.meta("environment")
|
|
179
|
+
|
|
180
|
+
/* client: delete a metadata entry */
|
|
181
|
+
mqttp.meta("environment", null)
|
|
182
|
+
|
|
183
|
+
/* client: per-request metadata (merged with instance-level) */
|
|
184
|
+
mqttp.call({ name: "example/hello", params: [ "world" ], meta: { requestId: "123" } })
|
|
185
|
+
|
|
186
|
+
/* server: access meta-data in callback */
|
|
187
|
+
await mqttp.service("example/hello", (arg, info) => {
|
|
188
|
+
console.log(info.meta?.clientVersion) /* "1.0.0" */
|
|
189
|
+
console.log(info.meta?.requestId) /* "123" */
|
|
190
|
+
return `hello ${arg}`
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
Event Registration
|
|
194
|
+
------------------
|
|
195
|
+
|
|
196
|
+
/* (simplified TypeScript API method signature) */
|
|
197
|
+
event(
|
|
198
|
+
name: string,
|
|
199
|
+
callback: (
|
|
200
|
+
...params: any[],
|
|
201
|
+
info: {
|
|
202
|
+
sender: string,
|
|
203
|
+
receiver?: string,
|
|
204
|
+
authenticated?: boolean,
|
|
205
|
+
meta?: Record<string, any>
|
|
206
|
+
}
|
|
207
|
+
) => void | Promise<void>
|
|
208
|
+
): Promise<Registration>
|
|
209
|
+
event({
|
|
210
|
+
name: string,
|
|
211
|
+
callback: (
|
|
212
|
+
...params: any[],
|
|
213
|
+
info: {
|
|
214
|
+
sender: string,
|
|
215
|
+
receiver?: string,
|
|
216
|
+
authenticated?: boolean,
|
|
217
|
+
meta?: Record<string, any>
|
|
218
|
+
}
|
|
219
|
+
) => void | Promise<void>,
|
|
220
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
221
|
+
share?: string,
|
|
222
|
+
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
223
|
+
}): Promise<Registration>
|
|
224
|
+
|
|
225
|
+
Register for an event.
|
|
226
|
+
|
|
227
|
+
- The `name` has to be a valid MQTT topic name.
|
|
228
|
+
|
|
229
|
+
- The `callback` is called with the `params` passed to a remote `emit()`.
|
|
230
|
+
There is no return value of `callback`.
|
|
231
|
+
|
|
232
|
+
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
233
|
+
|
|
234
|
+
- The optional `share` enables
|
|
235
|
+
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
236
|
+
(MQTT 5.0) for load-balancing messages across multiple registrations
|
|
237
|
+
by specifying a group name. This internally prefixes the event with
|
|
238
|
+
`$share/<share>/`.
|
|
239
|
+
|
|
240
|
+
- The optional `auth` enables authentication validation on incoming events.
|
|
241
|
+
When set to a role name string (e.g., `"admin"`), authentication is required
|
|
242
|
+
and the token must include that role. When set to an object `{ mode, roles }`,
|
|
243
|
+
the mode can be `"require"` (reject unauthenticated) or `"optional"` (accept all
|
|
244
|
+
but reflect validation result in `info.authenticated`), and roles specifies
|
|
245
|
+
the required role names.
|
|
246
|
+
|
|
247
|
+
- Internally, on the MQTT broker, the topics generated by
|
|
248
|
+
`topicMake(name, "event-emission")` (default: `${name}/event-emission/any` and
|
|
249
|
+
`${name}/event-emission/${peerId}`) are subscribed.
|
|
250
|
+
|
|
251
|
+
- Returns a `Registration` object with a `destroy()` method.
|
|
252
|
+
|
|
253
|
+
Event Emission
|
|
254
|
+
--------------
|
|
255
|
+
|
|
256
|
+
/* (simplified TypeScript API method signature) */
|
|
257
|
+
emit(
|
|
258
|
+
event: string,
|
|
259
|
+
...params: any[]
|
|
260
|
+
): void
|
|
261
|
+
emit({
|
|
262
|
+
event: string,
|
|
263
|
+
params: any[],
|
|
264
|
+
receiver?: string,
|
|
265
|
+
options?: MQTT::IClientPublishOptions,
|
|
266
|
+
meta?: Record<string, any>
|
|
267
|
+
}): void
|
|
268
|
+
emit({
|
|
269
|
+
event: string,
|
|
270
|
+
params: any[],
|
|
271
|
+
receiver?: string,
|
|
272
|
+
options?: MQTT::IClientPublishOptions,
|
|
273
|
+
meta?: Record<string, any>,
|
|
274
|
+
dry: true
|
|
275
|
+
}): { topic: string, payload: string | Uint8Array, options: IClientPublishOptions }
|
|
276
|
+
|
|
277
|
+
Emit an event to all subscribers or a specific subscriber ("fire and forget").
|
|
278
|
+
|
|
279
|
+
- The optional `receiver` directs the event to a specific subscriber only.
|
|
280
|
+
|
|
281
|
+
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
282
|
+
|
|
283
|
+
- The optional `meta` sends additional metadata alongside the event,
|
|
284
|
+
which is merged with instance-level metadata set via `meta()`.
|
|
285
|
+
|
|
286
|
+
- The optional `dry` flag, when set to `true`, returns the publish information
|
|
287
|
+
(`topic`, `payload`, `options`) instead of actually publishing to the MQTT broker.
|
|
288
|
+
This is useful for generating MQTT "last will" messages (see example below).
|
|
289
|
+
|
|
290
|
+
- The remote `event()` `callback` is called with `params` and its
|
|
291
|
+
return value is silently ignored.
|
|
292
|
+
|
|
293
|
+
- Internally, publishes to the MQTT topic by `topicMake(event, "event-emission", peerId)`
|
|
294
|
+
(default: `${event}/event-emission/any` or `${event}/event-emission/${peerId}`).
|
|
295
|
+
|
|
296
|
+
- *Dry-Run Publishing for MQTT Last-Will:*
|
|
297
|
+
When you need to set up an MQTT "last will" message (automatically published
|
|
298
|
+
by the broker when a client disconnects *unexpectedly*), you can use `dry: true`
|
|
299
|
+
together with a `null` MQTT client:
|
|
300
|
+
|
|
301
|
+
type API = {
|
|
302
|
+
"example/connection": Event<(state: "open" | "close") => void>
|
|
303
|
+
[...]
|
|
304
|
+
}
|
|
305
|
+
const mqttpDry = new MQTTp<API>(null, { id: "my-client" })
|
|
306
|
+
const will = mqttpDry.emit({
|
|
307
|
+
dry: true,
|
|
308
|
+
event: "example/connection",
|
|
309
|
+
params: [ "close" ],
|
|
310
|
+
[...]
|
|
311
|
+
})
|
|
312
|
+
mqttpDry.destroy()
|
|
313
|
+
const mqtt = MQTT.connect("[...]", {
|
|
314
|
+
will: {
|
|
315
|
+
topic: will.topic,
|
|
316
|
+
payload: will.payload,
|
|
317
|
+
qos: will.options.qos
|
|
318
|
+
},
|
|
319
|
+
[...]
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
Service Registration
|
|
323
|
+
--------------------
|
|
324
|
+
|
|
325
|
+
/* (simplified TypeScript API method signature) */
|
|
326
|
+
service(
|
|
327
|
+
name: string,
|
|
328
|
+
callback: (
|
|
329
|
+
...params: any[],
|
|
330
|
+
info: {
|
|
331
|
+
sender: string,
|
|
332
|
+
receiver?: string,
|
|
333
|
+
authenticated?: boolean,
|
|
334
|
+
meta?: Record<string, any>
|
|
335
|
+
}
|
|
336
|
+
) => any | Promise<any>
|
|
337
|
+
): Promise<Registration>
|
|
338
|
+
service({
|
|
339
|
+
name: string,
|
|
340
|
+
callback: (
|
|
341
|
+
...params: any[],
|
|
342
|
+
info: {
|
|
343
|
+
sender: string,
|
|
344
|
+
receiver?: string,
|
|
345
|
+
authenticated?: boolean,
|
|
346
|
+
meta?: Record<string, any>
|
|
347
|
+
}
|
|
348
|
+
) => any | Promise<any>,
|
|
349
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
350
|
+
share?: string,
|
|
351
|
+
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
352
|
+
}): Promise<Registration>
|
|
353
|
+
|
|
354
|
+
Register a service.
|
|
355
|
+
|
|
356
|
+
- The `name` has to be a valid MQTT topic name.
|
|
357
|
+
|
|
358
|
+
- The `callback` is called with the `params` passed to a remote `call()`.
|
|
359
|
+
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
360
|
+
|
|
361
|
+
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
362
|
+
|
|
363
|
+
- The optional `share` enables
|
|
364
|
+
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
365
|
+
(MQTT 5.0) for load-balancing service calls across multiple services
|
|
366
|
+
by specifying a group name. This internally prefixes the service
|
|
367
|
+
with `$share/<share>/`. By default a share named `default` is used.
|
|
368
|
+
|
|
369
|
+
- The optional `auth` enables authentication validation on incoming service calls.
|
|
370
|
+
When set to a role name string (e.g., `"admin"`), authentication is required
|
|
371
|
+
and the token must include that role. When set to an object `{ mode, roles }`,
|
|
372
|
+
the mode can be `"require"` (reject unauthenticated with error response) or
|
|
373
|
+
`"optional"` (accept all but reflect validation result in `info.authenticated`),
|
|
374
|
+
and roles specifies the required role names.
|
|
375
|
+
|
|
376
|
+
- Internally, on the MQTT broker, the topics generated by
|
|
377
|
+
`topicMake(name, "service-call-request")` (default: `${name}/service-call-request/any` and
|
|
378
|
+
`${name}/service-call-request/${peerId}`) are subscribed.
|
|
379
|
+
|
|
380
|
+
- Returns a `Registration` object with a `destroy()` method.
|
|
381
|
+
|
|
382
|
+
Service Call
|
|
383
|
+
------------
|
|
384
|
+
|
|
385
|
+
/* (simplified TypeScript API method signature) */
|
|
386
|
+
call(
|
|
387
|
+
name: string,
|
|
388
|
+
...params: any[]
|
|
389
|
+
): Promise<any>
|
|
390
|
+
call({
|
|
391
|
+
name: string,
|
|
392
|
+
params: any[],
|
|
393
|
+
receiver?: string,
|
|
394
|
+
options?: MQTT::IClientPublishOptions,
|
|
395
|
+
meta?: Record<string, any>
|
|
396
|
+
}): Promise<any>
|
|
397
|
+
|
|
398
|
+
Call a service on all registrants or on a specific registrant ("request and response").
|
|
399
|
+
|
|
400
|
+
- The optional `receiver` directs the call to a specific registrant only.
|
|
401
|
+
|
|
402
|
+
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
403
|
+
|
|
404
|
+
- The optional `meta` sends additional metadata alongside the service call,
|
|
405
|
+
which is merged with instance-level metadata set via `meta()`.
|
|
406
|
+
|
|
407
|
+
- The remote `service()` `callback` is called with `params` and its
|
|
408
|
+
return value resolves the returned `Promise`. If the remote `callback`
|
|
409
|
+
throws an exception, this rejects the returned `Promise`.
|
|
410
|
+
|
|
411
|
+
- Internally, on the MQTT broker, the topic by
|
|
412
|
+
`topicMake(service, "service-call-response", peerId)` (default:
|
|
413
|
+
`${service}/service-call-response/${peerId}`) is temporarily
|
|
414
|
+
subscribed for receiving the response.
|
|
415
|
+
|
|
416
|
+
Sink Registration
|
|
417
|
+
-----------------
|
|
418
|
+
|
|
419
|
+
/* (simplified TypeScript API method signature) */
|
|
420
|
+
sink(
|
|
421
|
+
name: string,
|
|
422
|
+
callback: (
|
|
423
|
+
...params: any[],
|
|
424
|
+
info: {
|
|
425
|
+
sender: string,
|
|
426
|
+
receiver?: string,
|
|
427
|
+
authenticated?: boolean,
|
|
428
|
+
meta?: Record<string, any>,
|
|
429
|
+
stream?: Readable,
|
|
430
|
+
buffer?: Promise<Uint8Array>
|
|
431
|
+
}
|
|
432
|
+
) => void | Promise<void>
|
|
433
|
+
): Promise<Registration>
|
|
434
|
+
sink({
|
|
435
|
+
name: string,
|
|
436
|
+
callback: (
|
|
437
|
+
...params: any[],
|
|
438
|
+
info: {
|
|
439
|
+
sender: string,
|
|
440
|
+
receiver?: string,
|
|
441
|
+
authenticated?: boolean,
|
|
442
|
+
meta?: Record<string, any>,
|
|
443
|
+
stream?: Readable,
|
|
444
|
+
buffer?: Promise<Uint8Array>
|
|
445
|
+
}
|
|
446
|
+
) => void | Promise<void>,
|
|
447
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
448
|
+
share?: string,
|
|
449
|
+
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
450
|
+
}): Promise<Registration>
|
|
451
|
+
|
|
452
|
+
Register a sink for receiving data.
|
|
453
|
+
|
|
454
|
+
- The `name` has to be a valid MQTT topic name.
|
|
455
|
+
|
|
456
|
+
- The `callback` is called with the `params` passed to a remote `push()`.
|
|
457
|
+
The `info.stream` provides a Node.js `Readable` stream for consuming the pushed data.
|
|
458
|
+
The `info.buffer` provides a lazy `Promise<Uint8Array>` that resolves to the complete data once the stream ends.
|
|
459
|
+
The `info.meta` contains optional metadata sent by the pusher via `push()`.
|
|
460
|
+
|
|
461
|
+
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
462
|
+
|
|
463
|
+
- The optional `share` enables
|
|
464
|
+
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
465
|
+
(MQTT 5.0) for load-balancing sink pushes across multiple sink
|
|
466
|
+
handlers by specifying a group name. This internally prefixes the
|
|
467
|
+
sink with `$share/<share>/`. By default a share named `default` is
|
|
468
|
+
used.
|
|
469
|
+
|
|
470
|
+
- The optional `auth` enables authentication validation on incoming sink pushes.
|
|
471
|
+
When set to a role name string (e.g., `"admin"`), authentication
|
|
472
|
+
is required and the token must include that role. When set to an
|
|
473
|
+
object `{ mode, roles }`, the mode can be `"require"` (reject
|
|
474
|
+
unauthenticated) or `"optional"` (accept all but reflect validation
|
|
475
|
+
result in `info.authenticated`), and roles specifies the required
|
|
476
|
+
role names.
|
|
477
|
+
|
|
478
|
+
- Internally, on the MQTT broker, the topics generated by
|
|
479
|
+
`topicMake(name, "sink-push-request")`
|
|
480
|
+
(default: `${name}/sink-push-request/any` and
|
|
481
|
+
`${name}/sink-push-request/${peerId}`) and
|
|
482
|
+
`topicMake(name, "sink-push-chunk", peerId)`
|
|
483
|
+
(default: `${name}/sink-push-chunk/${peerId}`) are subscribed.
|
|
484
|
+
|
|
485
|
+
- Returns a `Registration` object with a `destroy()` method.
|
|
486
|
+
|
|
487
|
+
Sink Push
|
|
488
|
+
---------
|
|
489
|
+
|
|
490
|
+
/* (simplified TypeScript API method signature) */
|
|
491
|
+
push(
|
|
492
|
+
name: string,
|
|
493
|
+
data: Readable | Uint8Array,
|
|
494
|
+
...params: any[]
|
|
495
|
+
): Promise<void>
|
|
496
|
+
push({
|
|
497
|
+
name: string,
|
|
498
|
+
data: Readable | Uint8Array,
|
|
499
|
+
params: any[]
|
|
500
|
+
meta?: Record<string, any>,
|
|
501
|
+
receiver?: string,
|
|
502
|
+
options?: MQTT::IClientPublishOptions
|
|
503
|
+
}): Promise<void>
|
|
504
|
+
|
|
505
|
+
Pushes data to all established sinks or a specific sink handler.
|
|
506
|
+
|
|
507
|
+
- The `data` is either a Node.js `Readable` stream or a `Uint8Array` providing the data to push.
|
|
508
|
+
|
|
509
|
+
- The optional `meta` sends metadata alongside the data,
|
|
510
|
+
which becomes available on the sink handler side via `info.meta`.
|
|
511
|
+
|
|
512
|
+
- The optional `receiver` directs the push to a specific sink handler only.
|
|
513
|
+
|
|
514
|
+
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
515
|
+
|
|
516
|
+
- The data is read from `data` in chunks (default: 16KB,
|
|
517
|
+
configurable via `chunkSize` option) and sent over MQTT until the
|
|
518
|
+
stream is closed or the buffer is fully transferred.
|
|
519
|
+
The returned `Promise` resolves when the entire data has been pushed.
|
|
520
|
+
|
|
521
|
+
- The remote `sink()` `callback` is called with `params` and an `info` object
|
|
522
|
+
containing `stream` (`Readable`) for consuming the pushed data,
|
|
523
|
+
`buffer` (lazy `Promise<Uint8Array>`) that resolves to the complete
|
|
524
|
+
data once the stream ends, and `meta` (`Record<string, any> |
|
|
525
|
+
undefined`) containing the metadata sent by the pusher.
|
|
526
|
+
|
|
527
|
+
- Internally, on the MQTT broker, the topic by
|
|
528
|
+
`topicMake(name, "sink-push-response", peerId)` (default:
|
|
529
|
+
`${name}/sink-push-response/${peerId}`) is temporarily
|
|
530
|
+
subscribed for receiving the ack/nak response,
|
|
531
|
+
then publishes to the MQTT topic by `topicMake(name, "sink-push-request", peerId)`
|
|
532
|
+
(default: `${name}/sink-push-request/any` or `${name}/sink-push-request/${peerId}`)
|
|
533
|
+
for the initial request, `topicMake(name, "sink-push-chunk", peerId)`
|
|
534
|
+
(default: `${name}/sink-push-chunk/${peerId}`) for the data chunks,
|
|
535
|
+
and optionally `topicMake(name, "sink-push-credit", peerId)`
|
|
536
|
+
(default: `${name}/sink-push-credit/${peerId}`) for credit-based flow control.
|
|
537
|
+
|
|
538
|
+
Source Registration
|
|
539
|
+
-------------------
|
|
540
|
+
|
|
541
|
+
/* (simplified TypeScript API method signature) */
|
|
542
|
+
source(
|
|
543
|
+
name: string,
|
|
544
|
+
callback: (
|
|
545
|
+
...params: any[],
|
|
546
|
+
info: {
|
|
547
|
+
sender: string,
|
|
548
|
+
receiver?: string,
|
|
549
|
+
authenticated?: boolean,
|
|
550
|
+
meta?: Record<string, any>,
|
|
551
|
+
stream?: Readable,
|
|
552
|
+
buffer?: Promise<Uint8Array>
|
|
553
|
+
}
|
|
554
|
+
) => void | Promise<void>
|
|
555
|
+
): Promise<Registration>
|
|
556
|
+
source({
|
|
557
|
+
name: string,
|
|
558
|
+
callback: (
|
|
559
|
+
...params: any[],
|
|
560
|
+
info: {
|
|
561
|
+
sender: string,
|
|
562
|
+
receiver?: string,
|
|
563
|
+
authenticated?: boolean,
|
|
564
|
+
meta?: Record<string, any>,
|
|
565
|
+
stream?: Readable,
|
|
566
|
+
buffer?: Promise<Uint8Array>
|
|
567
|
+
}
|
|
568
|
+
) => void | Promise<void>,
|
|
569
|
+
options?: MQTT::IClientSubscribeOptions,
|
|
570
|
+
share?: string,
|
|
571
|
+
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
572
|
+
}): Promise<Registration>
|
|
573
|
+
|
|
574
|
+
Register a source for sending data.
|
|
575
|
+
|
|
576
|
+
- The `name` has to be a valid MQTT topic name.
|
|
577
|
+
|
|
578
|
+
- The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
579
|
+
The `callback` should set `info.stream` to a `Readable` or
|
|
580
|
+
`info.buffer` to a `Promise<Uint8Array>` containing the data.
|
|
581
|
+
Optionally, the `callback` can set `info.meta` to a `Record<string,
|
|
582
|
+
any>` to send metadata back with the response.
|
|
583
|
+
|
|
584
|
+
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
585
|
+
|
|
586
|
+
- The optional `share` enables
|
|
587
|
+
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
588
|
+
(MQTT 5.0) for load-balancing source requests across multiple
|
|
589
|
+
sources by specifying a group name. This internally prefixes the
|
|
590
|
+
source with `$share/<share>/`. By default a share named `default` is
|
|
591
|
+
used.
|
|
592
|
+
|
|
593
|
+
- The optional `auth` enables authentication validation on incoming source fetches.
|
|
594
|
+
When set to a role name string (e.g., `"admin"`), authentication
|
|
595
|
+
is required and the token must include that role. When set to an
|
|
596
|
+
object `{ mode, roles }`, the mode can be `"require"` (reject
|
|
597
|
+
unauthenticated) or `"optional"` (accept all but reflect validation
|
|
598
|
+
result in `info.authenticated`), and roles specifies the required
|
|
599
|
+
role names.
|
|
600
|
+
|
|
601
|
+
- Internally, on the MQTT broker, the topics generated by
|
|
602
|
+
`topicMake(name, "source-fetch-request")`
|
|
603
|
+
(default: `${name}/source-fetch-request/any` and
|
|
604
|
+
`${name}/source-fetch-request/${peerId}`) and
|
|
605
|
+
`topicMake(name, "source-fetch-credit", peerId)`
|
|
606
|
+
(default: `${name}/source-fetch-credit/${peerId}`) are subscribed.
|
|
607
|
+
|
|
608
|
+
- Returns a `Registration` object with a `destroy()` method.
|
|
609
|
+
|
|
610
|
+
Source Fetch
|
|
611
|
+
------------
|
|
612
|
+
|
|
613
|
+
/* (simplified TypeScript API method signature) */
|
|
614
|
+
fetch(
|
|
615
|
+
name: string,
|
|
616
|
+
...params: any[]
|
|
617
|
+
): Promise<{
|
|
618
|
+
stream: Readable,
|
|
619
|
+
buffer: Promise<Uint8Array>,
|
|
620
|
+
meta: Promise<Record<string, any> | undefined>
|
|
621
|
+
}>
|
|
622
|
+
fetch({
|
|
623
|
+
name: string,
|
|
624
|
+
params: any[],
|
|
625
|
+
receiver?: string,
|
|
626
|
+
options?: MQTT::IClientPublishOptions,
|
|
627
|
+
meta?: Record<string, any>
|
|
628
|
+
}): Promise<{
|
|
629
|
+
stream: Readable,
|
|
630
|
+
buffer: Promise<Uint8Array>,
|
|
631
|
+
meta: Promise<Record<string, any> | undefined>
|
|
632
|
+
}>
|
|
633
|
+
|
|
634
|
+
Fetches data from any source or from a specific source.
|
|
635
|
+
|
|
636
|
+
- The optional `receiver` directs the call to a specific source only.
|
|
637
|
+
|
|
638
|
+
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
639
|
+
|
|
640
|
+
- The optional `meta` sends additional metadata alongside the fetch request,
|
|
641
|
+
which is merged with instance-level metadata set via `meta()`.
|
|
642
|
+
|
|
643
|
+
- Returns an object with a `stream` (`Readable`) for consuming the transferred data,
|
|
644
|
+
a lazy `buffer` (`Promise<Uint8Array>`) that resolves
|
|
645
|
+
to the complete data once the stream ends, and a `meta`
|
|
646
|
+
(`Promise<Record<string, any> | undefined>`) that resolves to
|
|
647
|
+
optional metadata sent by the source when the first chunk arrives.
|
|
648
|
+
|
|
649
|
+
- The remote `source()` `callback` is called with `params` and
|
|
650
|
+
should set `info.stream` to a `Readable` or `info.buffer` to
|
|
651
|
+
a `Promise<Uint8Array>` containing the data. Optionally, the
|
|
652
|
+
`callback` can set `info.meta` to send metadata back with the
|
|
653
|
+
response. If the remote `callback` throws an exception, this
|
|
654
|
+
destroys the stream with the error.
|
|
655
|
+
|
|
656
|
+
- Internally, on the MQTT broker, the topics by
|
|
657
|
+
`topicMake(name, "source-fetch-response", peerId)`
|
|
658
|
+
and `topicMake(name, "source-fetch-chunk", peerId)`
|
|
659
|
+
(default: `${name}/source-fetch-response/${peerId}` and
|
|
660
|
+
`${name}/source-fetch-chunk/${peerId}`) are temporarily subscribed
|
|
661
|
+
for receiving the response and data chunks.
|
|
662
|
+
|
|
663
|
+
Data Type Conversion Utilities
|
|
664
|
+
------------------------------
|
|
665
|
+
|
|
666
|
+
/* convert character string to buffer */
|
|
667
|
+
str2buf(data: string): Uint8Array
|
|
668
|
+
|
|
669
|
+
/* convert buffer to character string */
|
|
670
|
+
buf2str(data: Uint8Array): string
|
|
671
|
+
|
|
672
|
+
/* convert byte-based typed array to buffer */
|
|
673
|
+
arr2buf(data: Buffer | Uint8Array | Int8Array): Uint8Array
|
|
674
|
+
|
|
675
|
+
/* convert buffer to byte-based typed array */
|
|
676
|
+
buf2arr(data: Uint8Array, type: typeof Buffer): Buffer
|
|
677
|
+
buf2arr(data: Uint8Array, type: typeof Uint8Array): Uint8Array
|
|
678
|
+
buf2arr(data: Uint8Array, type: typeof Int8Array): Int8Array
|
|
679
|
+
|
|
680
|
+
MQTT+ provides utility methods for converting between strings,
|
|
681
|
+
buffers, and typed arrays. These are useful when working with binary
|
|
682
|
+
data in source/sink transfers or when interfacing with API methods that
|
|
683
|
+
expect specific data types.
|
|
684
|
+
|
|
685
|
+
Example:
|
|
686
|
+
|
|
687
|
+
/* string to buffer conversion */
|
|
688
|
+
const buffer = mqttp.str2buf("Hello, World!")
|
|
689
|
+
const text = mqttp.buf2str(buffer)
|
|
690
|
+
|
|
691
|
+
/* typed array conversions */
|
|
692
|
+
const ui8a = mqttp.arr2buf(buffer)
|
|
693
|
+
const buffer = mqttp.buf2arr(ui8a, Buffer)
|
|
694
|
+
const i8a = mqttp.buf2arr(ui8a, Int8Array)
|
|
153
695
|
|
|
154
|
-
- The `meta()` method manages instance-level meta-data:
|
|
155
|
-
called with a key only, retrieves the meta-data entry for that key;
|
|
156
|
-
called with a key and non-null value, sets the meta-data entry;
|
|
157
|
-
called with a key and `null`, deletes the meta-data entry.
|
|
158
|
-
|
|
159
|
-
- Instance-level meta-data set via `meta()` is merged with any per-request
|
|
160
|
-
`meta` option passed to `emit()`, `call()`, `push()`, or `fetch()`.
|
|
161
|
-
Per-request meta-data takes precedence over instance-level metadata.
|
|
162
|
-
|
|
163
|
-
- On the receiving side, meta-data is available via the `info.meta`
|
|
164
|
-
field in callbacks for `event()`, `service()`, `source()`, and `sink()`.
|
|
165
|
-
For `fetch()`, the returned `meta` promise resolves to the meta-data
|
|
166
|
-
sent by the source.
|
|
167
|
-
|
|
168
|
-
Example:
|
|
169
|
-
|
|
170
|
-
/* client: set instance-level metadata */
|
|
171
|
-
mqttp.meta("clientVersion", "1.0.0")
|
|
172
|
-
mqttp.meta("environment", "production")
|
|
173
|
-
|
|
174
|
-
/* client: retrieve a metadata entry */
|
|
175
|
-
const environment = mqttp.meta("environment")
|
|
176
|
-
|
|
177
|
-
/* client: delete a metadata entry */
|
|
178
|
-
mqttp.meta("environment", null)
|
|
179
|
-
|
|
180
|
-
/* client: per-request metadata (merged with instance-level) */
|
|
181
|
-
mqttp.call({ name: "example/hello", params: [ "world" ], meta: { requestId: "123" } })
|
|
182
|
-
|
|
183
|
-
/* server: access meta-data in callback */
|
|
184
|
-
await mqttp.service("example/hello", (arg, info) => {
|
|
185
|
-
console.log(info.meta?.clientVersion) /* "1.0.0" */
|
|
186
|
-
console.log(info.meta?.requestId) /* "123" */
|
|
187
|
-
return `hello ${arg}`
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
- **Event Registration**:<br/>
|
|
191
|
-
|
|
192
|
-
/* (simplified TypeScript API method signature) */
|
|
193
|
-
event(
|
|
194
|
-
name: string,
|
|
195
|
-
callback: (
|
|
196
|
-
...params: any[],
|
|
197
|
-
info: {
|
|
198
|
-
sender: string,
|
|
199
|
-
receiver?: string,
|
|
200
|
-
authenticated?: boolean,
|
|
201
|
-
meta?: Record<string, any>
|
|
202
|
-
}
|
|
203
|
-
) => void | Promise<void>
|
|
204
|
-
): Promise<Registration>
|
|
205
|
-
event({
|
|
206
|
-
name: string,
|
|
207
|
-
callback: (
|
|
208
|
-
...params: any[],
|
|
209
|
-
info: {
|
|
210
|
-
sender: string,
|
|
211
|
-
receiver?: string,
|
|
212
|
-
authenticated?: boolean,
|
|
213
|
-
meta?: Record<string, any>
|
|
214
|
-
}
|
|
215
|
-
) => void | Promise<void>,
|
|
216
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
217
|
-
share?: string,
|
|
218
|
-
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
219
|
-
}): Promise<Registration>
|
|
220
|
-
|
|
221
|
-
Register for an event.
|
|
222
|
-
|
|
223
|
-
- The `name` has to be a valid MQTT topic name.
|
|
224
|
-
|
|
225
|
-
- The `callback` is called with the `params` passed to a remote `emit()`.
|
|
226
|
-
There is no return value of `callback`.
|
|
227
|
-
|
|
228
|
-
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
229
|
-
|
|
230
|
-
- The optional `share` enables
|
|
231
|
-
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
232
|
-
(MQTT 5.0) for load-balancing messages across multiple registrations
|
|
233
|
-
by specifying a group name. This internally prefixes the event with
|
|
234
|
-
`$share/<share>/`.
|
|
235
|
-
|
|
236
|
-
- The optional `auth` enables authentication validation on incoming events.
|
|
237
|
-
When set to a role name string (e.g., `"admin"`), authentication is required
|
|
238
|
-
and the token must include that role. When set to an object `{ mode, roles }`,
|
|
239
|
-
the mode can be `"require"` (reject unauthenticated) or `"optional"` (accept all
|
|
240
|
-
but reflect validation result in `info.authenticated`), and roles specifies
|
|
241
|
-
the required role names.
|
|
242
|
-
|
|
243
|
-
- Internally, on the MQTT broker, the topics generated by
|
|
244
|
-
`topicMake(name, "event-emission")` (default: `${name}/event-emission/any` and
|
|
245
|
-
`${name}/event-emission/${peerId}`) are subscribed.
|
|
246
|
-
|
|
247
|
-
- Returns a `Registration` object with a `destroy()` method.
|
|
248
|
-
|
|
249
|
-
- **Service Registration**:<br/>
|
|
250
|
-
|
|
251
|
-
/* (simplified TypeScript API method signature) */
|
|
252
|
-
service(
|
|
253
|
-
name: string,
|
|
254
|
-
callback: (
|
|
255
|
-
...params: any[],
|
|
256
|
-
info: {
|
|
257
|
-
sender: string,
|
|
258
|
-
receiver?: string,
|
|
259
|
-
authenticated?: boolean,
|
|
260
|
-
meta?: Record<string, any>
|
|
261
|
-
}
|
|
262
|
-
) => any | Promise<any>
|
|
263
|
-
): Promise<Registration>
|
|
264
|
-
service({
|
|
265
|
-
name: string,
|
|
266
|
-
callback: (
|
|
267
|
-
...params: any[],
|
|
268
|
-
info: {
|
|
269
|
-
sender: string,
|
|
270
|
-
receiver?: string,
|
|
271
|
-
authenticated?: boolean,
|
|
272
|
-
meta?: Record<string, any>
|
|
273
|
-
}
|
|
274
|
-
) => any | Promise<any>,
|
|
275
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
276
|
-
share?: string,
|
|
277
|
-
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
278
|
-
}): Promise<Registration>
|
|
279
|
-
|
|
280
|
-
Register a service.
|
|
281
|
-
|
|
282
|
-
- The `name` has to be a valid MQTT topic name.
|
|
283
|
-
|
|
284
|
-
- The `callback` is called with the `params` passed to a remote `call()`.
|
|
285
|
-
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
286
|
-
|
|
287
|
-
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
288
|
-
|
|
289
|
-
- The optional `share` enables
|
|
290
|
-
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
291
|
-
(MQTT 5.0) for load-balancing service calls across multiple services
|
|
292
|
-
by specifying a group name. This internally prefixes the service
|
|
293
|
-
with `$share/<share>/`. By default a share named `default` is used.
|
|
294
|
-
|
|
295
|
-
- The optional `auth` enables authentication validation on incoming service calls.
|
|
296
|
-
When set to a role name string (e.g., `"admin"`), authentication is required
|
|
297
|
-
and the token must include that role. When set to an object `{ mode, roles }`,
|
|
298
|
-
the mode can be `"require"` (reject unauthenticated with error response) or
|
|
299
|
-
`"optional"` (accept all but reflect validation result in `info.authenticated`),
|
|
300
|
-
and roles specifies the required role names.
|
|
301
|
-
|
|
302
|
-
- Internally, on the MQTT broker, the topics generated by
|
|
303
|
-
`topicMake(name, "service-call-request")` (default: `${name}/service-call-request/any` and
|
|
304
|
-
`${name}/service-call-request/${peerId}`) are subscribed
|
|
305
|
-
|
|
306
|
-
- Returns a `Registration` object with a `destroy()` method.
|
|
307
|
-
|
|
308
|
-
- **Source Registration**:<br/>
|
|
309
|
-
|
|
310
|
-
/* (simplified TypeScript API method signature) */
|
|
311
|
-
source(
|
|
312
|
-
name: string,
|
|
313
|
-
callback: (
|
|
314
|
-
...params: any[],
|
|
315
|
-
info: {
|
|
316
|
-
sender: string,
|
|
317
|
-
receiver?: string,
|
|
318
|
-
authenticated?: boolean,
|
|
319
|
-
meta?: Record<string, any>,
|
|
320
|
-
stream?: Readable,
|
|
321
|
-
buffer?: Promise<Uint8Array>
|
|
322
|
-
}
|
|
323
|
-
) => void | Promise<void>
|
|
324
|
-
): Promise<Registration>
|
|
325
|
-
source({
|
|
326
|
-
name: string,
|
|
327
|
-
callback: (
|
|
328
|
-
...params: any[],
|
|
329
|
-
info: {
|
|
330
|
-
sender: string,
|
|
331
|
-
receiver?: string,
|
|
332
|
-
authenticated?: boolean,
|
|
333
|
-
meta?: Record<string, any>,
|
|
334
|
-
stream?: Readable,
|
|
335
|
-
buffer?: Promise<Uint8Array>
|
|
336
|
-
}
|
|
337
|
-
) => void | Promise<void>,
|
|
338
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
339
|
-
share?: string,
|
|
340
|
-
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
341
|
-
}): Promise<Registration>
|
|
342
|
-
|
|
343
|
-
Register a source for sending data.
|
|
344
|
-
|
|
345
|
-
- The `name` has to be a valid MQTT topic name.
|
|
346
|
-
|
|
347
|
-
- The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
348
|
-
The `callback` should set `info.stream` to a `Readable` or
|
|
349
|
-
`info.buffer` to a `Promise<Uint8Array>` containing the data.
|
|
350
|
-
Optionally, the `callback` can set `info.meta` to a `Record<string,
|
|
351
|
-
any>` to send metadata back with the response.
|
|
352
|
-
|
|
353
|
-
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
354
|
-
|
|
355
|
-
- The optional `share` enables
|
|
356
|
-
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
357
|
-
(MQTT 5.0) for load-balancing source requests across multiple
|
|
358
|
-
sources by specifying a group name. This internally prefixes the
|
|
359
|
-
source with `$share/<share>/`. By default a share named `default` is
|
|
360
|
-
used.
|
|
361
|
-
|
|
362
|
-
- The optional `auth` enables authentication validation on incoming source fetches.
|
|
363
|
-
When set to a role name string (e.g., `"admin"`), authentication
|
|
364
|
-
is required and the token must include that role. When set to an
|
|
365
|
-
object `{ mode, roles }`, the mode can be `"require"` (reject
|
|
366
|
-
unauthenticated) or `"optional"` (accept all but reflect validation
|
|
367
|
-
result in `info.authenticated`), and roles specifies the required
|
|
368
|
-
role names.
|
|
369
|
-
|
|
370
|
-
- Internally, on the MQTT broker, the topics by
|
|
371
|
-
`topicMake(name, "source-fetch-request")`
|
|
372
|
-
(default: `${name}/source-fetch-request/any` and
|
|
373
|
-
`${name}/source-fetch-request/${peerId}`) and
|
|
374
|
-
`topicMake(name, "source-fetch-credit", peerId)`
|
|
375
|
-
(default: `${name}/source-fetch-credit/${peerId}`) are subscribed.
|
|
376
|
-
|
|
377
|
-
- Returns a `Registration` object with a `destroy()` method.
|
|
378
|
-
|
|
379
|
-
- **Sink Registration**:<br/>
|
|
380
|
-
|
|
381
|
-
/* (simplified TypeScript API method signature) */
|
|
382
|
-
sink(
|
|
383
|
-
name: string,
|
|
384
|
-
callback: (
|
|
385
|
-
...params: any[],
|
|
386
|
-
info: {
|
|
387
|
-
sender: string,
|
|
388
|
-
receiver?: string,
|
|
389
|
-
authenticated?: boolean,
|
|
390
|
-
meta?: Record<string, any>,
|
|
391
|
-
stream?: Readable,
|
|
392
|
-
buffer?: Promise<Uint8Array>
|
|
393
|
-
}
|
|
394
|
-
) => void | Promise<void>
|
|
395
|
-
): Promise<Registration>
|
|
396
|
-
sink({
|
|
397
|
-
name: string,
|
|
398
|
-
callback: (
|
|
399
|
-
...params: any[],
|
|
400
|
-
info: {
|
|
401
|
-
sender: string,
|
|
402
|
-
receiver?: string,
|
|
403
|
-
authenticated?: boolean,
|
|
404
|
-
meta?: Record<string, any>,
|
|
405
|
-
stream?: Readable,
|
|
406
|
-
buffer?: Promise<Uint8Array>
|
|
407
|
-
}
|
|
408
|
-
) => void | Promise<void>,
|
|
409
|
-
options?: MQTT::IClientSubscribeOptions,
|
|
410
|
-
share?: string,
|
|
411
|
-
auth?: string | { mode: "require" | "optional", roles: string[] }
|
|
412
|
-
}): Promise<Registration>
|
|
413
|
-
|
|
414
|
-
Register a sink for receiving data.
|
|
415
|
-
|
|
416
|
-
- The `name` has to be a valid MQTT topic name.
|
|
417
|
-
|
|
418
|
-
- The `callback` is called with the `params` passed to a remote `push()`.
|
|
419
|
-
The `info.stream` provides a Node.js `Readable` stream for consuming the pushed data.
|
|
420
|
-
The `info.buffer` provides a lazy `Promise<Uint8Array>` that resolves to the complete data once the stream ends.
|
|
421
|
-
The `info.meta` contains optional metadata sent by the pusher via `push()`.
|
|
422
|
-
|
|
423
|
-
- The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
424
|
-
|
|
425
|
-
- The optional `share` enables
|
|
426
|
-
[MQTT Shared Subscriptions](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250)
|
|
427
|
-
(MQTT 5.0) for load-balancing sink pushes across multiple sink
|
|
428
|
-
handlers by specifying a group name. This internally prefixes the
|
|
429
|
-
sink with `$share/<share>/`. By default a share named `default` is
|
|
430
|
-
used.
|
|
431
|
-
|
|
432
|
-
- The optional `auth` enables authentication validation on incoming sink pushes.
|
|
433
|
-
When set to a role name string (e.g., `"admin"`), authentication
|
|
434
|
-
is required and the token must include that role. When set to an
|
|
435
|
-
object `{ mode, roles }`, the mode can be `"require"` (reject
|
|
436
|
-
unauthenticated) or `"optional"` (accept all but reflect validation
|
|
437
|
-
result in `info.authenticated`), and roles specifies the required
|
|
438
|
-
role names.
|
|
439
|
-
|
|
440
|
-
- Internally, on the MQTT broker, the topics by
|
|
441
|
-
`topicMake(name, "sink-push-request")`
|
|
442
|
-
(default: `${name}/sink-push-request/any` and
|
|
443
|
-
`${name}/sink-push-request/${peerId}`) and
|
|
444
|
-
`topicMake(name, "sink-push-chunk", peerId)`
|
|
445
|
-
(default: `${name}/sink-push-chunk/${peerId}`) are subscribed.
|
|
446
|
-
|
|
447
|
-
- Returns a `Registration` object with a `destroy()` method.
|
|
448
|
-
|
|
449
|
-
- **Event Emission**:<br/>
|
|
450
|
-
|
|
451
|
-
/* (simplified TypeScript API method signature) */
|
|
452
|
-
emit(
|
|
453
|
-
event: string,
|
|
454
|
-
...params: any[]
|
|
455
|
-
): void
|
|
456
|
-
emit({
|
|
457
|
-
event: string,
|
|
458
|
-
params: any[],
|
|
459
|
-
receiver?: string,
|
|
460
|
-
options?: MQTT::IClientPublishOptions,
|
|
461
|
-
meta?: Record<string, any>
|
|
462
|
-
}): void
|
|
463
|
-
emit({
|
|
464
|
-
event: string,
|
|
465
|
-
params: any[],
|
|
466
|
-
receiver?: string,
|
|
467
|
-
options?: MQTT::IClientPublishOptions,
|
|
468
|
-
meta?: Record<string, any>,
|
|
469
|
-
dry: true
|
|
470
|
-
}): { topic: string, payload: string | Uint8Array, options: IClientPublishOptions }
|
|
471
|
-
|
|
472
|
-
Emit an event to all subscribers or a specific subscriber ("fire and forget").
|
|
473
|
-
|
|
474
|
-
- The optional `receiver` directs the event to a specific subscriber only.
|
|
475
|
-
|
|
476
|
-
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
477
|
-
|
|
478
|
-
- The optional `meta` sends additional metadata alongside the event,
|
|
479
|
-
which is merged with instance-level metadata set via `meta()`.
|
|
480
|
-
|
|
481
|
-
- The optional `dry` flag, when set to `true`, returns the publish information
|
|
482
|
-
(`topic`, `payload`, `options`) instead of actually publishing to the MQTT broker.
|
|
483
|
-
This is useful for generating MQTT "last will" messages (see example below).
|
|
484
|
-
|
|
485
|
-
- The remote `event()` `callback` is called with `params` and its
|
|
486
|
-
return value is silently ignored.
|
|
487
|
-
|
|
488
|
-
- Internally, publishes to the MQTT topic by `topicMake(event, "event-emission", peerId)`
|
|
489
|
-
(default: `${event}/event-emission/any` or `${event}/event-emission/${peerId}`).
|
|
490
|
-
|
|
491
|
-
- *Dry-Run Publishing for MQTT Last-Will:*
|
|
492
|
-
When you need to set up an MQTT "last will" message (automatically published
|
|
493
|
-
by the broker when a client disconnects *unexpectedly*), you can use `dry: true`
|
|
494
|
-
together with a `null` MQTT client:
|
|
495
|
-
|
|
496
|
-
type API = {
|
|
497
|
-
"example/connection": Event<(state: "open" | "close") => void>
|
|
498
|
-
[...]
|
|
499
|
-
}
|
|
500
|
-
const mqttpDry = new MQTTp<API>(null, { id: "my-client" })
|
|
501
|
-
const will = mqttpDry.emit({
|
|
502
|
-
dry: true,
|
|
503
|
-
event: "example/connection",
|
|
504
|
-
params: [ "close" ],
|
|
505
|
-
[...]
|
|
506
|
-
})
|
|
507
|
-
mqttpDry.destroy()
|
|
508
|
-
const mqtt = MQTT.connect("[...]", {
|
|
509
|
-
will: {
|
|
510
|
-
topic: will.topic,
|
|
511
|
-
payload: will.payload,
|
|
512
|
-
qos: will.options.qos
|
|
513
|
-
},
|
|
514
|
-
[...]
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
- **Service Call**:<br/>
|
|
518
|
-
|
|
519
|
-
/* (simplified TypeScript API method signature) */
|
|
520
|
-
call(
|
|
521
|
-
name: string,
|
|
522
|
-
...params: any[]
|
|
523
|
-
): Promise<any>
|
|
524
|
-
call({
|
|
525
|
-
name: string,
|
|
526
|
-
params: any[],
|
|
527
|
-
receiver?: string,
|
|
528
|
-
options?: MQTT::IClientPublishOptions,
|
|
529
|
-
meta?: Record<string, any>
|
|
530
|
-
}): Promise<any>
|
|
531
|
-
|
|
532
|
-
Call a service on all registrants or on a specific registrant ("request and response").
|
|
533
|
-
|
|
534
|
-
- The optional `receiver` directs the call to a specific registrant only.
|
|
535
|
-
|
|
536
|
-
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
537
|
-
|
|
538
|
-
- The optional `meta` sends additional metadata alongside the service call,
|
|
539
|
-
which is merged with instance-level metadata set via `meta()`.
|
|
540
|
-
|
|
541
|
-
- The remote `service()` `callback` is called with `params` and its
|
|
542
|
-
return value resolves the returned `Promise`. If the remote `callback`
|
|
543
|
-
throws an exception, this rejects the returned `Promise`.
|
|
544
|
-
|
|
545
|
-
- Internally, on the MQTT broker, the topic by
|
|
546
|
-
`topicMake(service, "service-call-response", peerId)` (default:
|
|
547
|
-
`${service}/service-call-response/${peerId}`) is temporarily
|
|
548
|
-
subscribed for receiving the response.
|
|
549
|
-
|
|
550
|
-
- **Source Fetch**:<br/>
|
|
551
|
-
|
|
552
|
-
/* (simplified TypeScript API method signature) */
|
|
553
|
-
fetch(
|
|
554
|
-
name: string,
|
|
555
|
-
...params: any[]
|
|
556
|
-
): Promise<{
|
|
557
|
-
stream: Readable,
|
|
558
|
-
buffer: Promise<Uint8Array>,
|
|
559
|
-
meta: Promise<Record<string, any> | undefined>
|
|
560
|
-
}>
|
|
561
|
-
fetch({
|
|
562
|
-
name: string,
|
|
563
|
-
params: any[],
|
|
564
|
-
receiver?: string,
|
|
565
|
-
options?: MQTT::IClientPublishOptions,
|
|
566
|
-
meta?: Record<string, any>
|
|
567
|
-
}): Promise<{
|
|
568
|
-
stream: Readable,
|
|
569
|
-
buffer: Promise<Uint8Array>,
|
|
570
|
-
meta: Promise<Record<string, any> | undefined>
|
|
571
|
-
}>
|
|
572
|
-
|
|
573
|
-
Fetches data from any source or from a specific source.
|
|
574
|
-
|
|
575
|
-
- The optional `receiver` directs the call to a specific source only.
|
|
576
|
-
|
|
577
|
-
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
578
|
-
|
|
579
|
-
- The optional `meta` sends additional metadata alongside the fetch request,
|
|
580
|
-
which is merged with instance-level metadata set via `meta()`.
|
|
581
|
-
|
|
582
|
-
- Returns an object with a `stream` (`Readable`) for consuming the transferred data,
|
|
583
|
-
a lazy `buffer` (`Promise<Uint8Array>`) that resolves
|
|
584
|
-
to the complete data once the stream ends, and a `meta`
|
|
585
|
-
(`Promise<Record<string, any> | undefined>`) that resolves to
|
|
586
|
-
optional metadata sent by the source when the first chunk arrives.
|
|
587
|
-
|
|
588
|
-
- The remote `source()` `callback` is called with `params` and
|
|
589
|
-
should set `info.stream` to a `Readable` or `info.buffer` to
|
|
590
|
-
a `Promise<Uint8Array>` containing the data. Optionally, the
|
|
591
|
-
`callback` can set `info.meta` to send metadata back with the
|
|
592
|
-
response. If the remote `callback` throws an exception, this
|
|
593
|
-
destroys the stream with the error.
|
|
594
|
-
|
|
595
|
-
- Internally, on the MQTT broker, the topics by
|
|
596
|
-
`topicMake(name, "source-fetch-response", peerId)`
|
|
597
|
-
and `topicMake(name, "source-fetch-chunk", peerId)`
|
|
598
|
-
(default: `${name}/source-fetch-response/${peerId}` and
|
|
599
|
-
`${name}/source-fetch-chunk/${peerId}`) are temporarily subscribed
|
|
600
|
-
for receiving the response and data chunks.
|
|
601
|
-
|
|
602
|
-
- **Sink Push**:<br/>
|
|
603
|
-
|
|
604
|
-
/* (simplified TypeScript API method signature) */
|
|
605
|
-
push(
|
|
606
|
-
name: string,
|
|
607
|
-
data: Readable | Uint8Array,
|
|
608
|
-
...params: any[]
|
|
609
|
-
): Promise<void>
|
|
610
|
-
push({
|
|
611
|
-
name: string,
|
|
612
|
-
data: Readable | Uint8Array,
|
|
613
|
-
params: any[]
|
|
614
|
-
meta?: Record<string, any>,
|
|
615
|
-
receiver?: string,
|
|
616
|
-
options?: MQTT::IClientPublishOptions
|
|
617
|
-
}): Promise<void>
|
|
618
|
-
|
|
619
|
-
Pushes data to all established sinks or a specific sink handler.
|
|
620
|
-
|
|
621
|
-
- The `data` is either a Node.js `Readable` stream or a `Uint8Array` providing the data to push.
|
|
622
|
-
|
|
623
|
-
- The optional `meta` sends metadata alongside the data,
|
|
624
|
-
which becomes available on the sink handler side via `info.meta`.
|
|
625
|
-
|
|
626
|
-
- The optional `receiver` directs the push to a specific sink handler only.
|
|
627
|
-
|
|
628
|
-
- The optional `options` allows setting MQTT.js `publish()` options like `qos` or `retain`.
|
|
629
|
-
|
|
630
|
-
- The data is read from `data` in chunks (default: 16KB,
|
|
631
|
-
configurable via `chunkSize` option) and sent over MQTT until the
|
|
632
|
-
stream is closed or the buffer is fully transferred.
|
|
633
|
-
The returned `Promise` resolves when the entire data has been pushed.
|
|
634
|
-
|
|
635
|
-
- The remote `sink()` `callback` is called with `params` and an `info` object
|
|
636
|
-
containing `stream` (`Readable`) for consuming the pushed data,
|
|
637
|
-
`buffer` (lazy `Promise<Uint8Array>`) that resolves to the complete
|
|
638
|
-
data once the stream ends, and `meta` (`Record<string, any> |
|
|
639
|
-
undefined`) containing the metadata sent by the pusher.
|
|
640
|
-
|
|
641
|
-
- Internally, on the MQTT broker, the topic by
|
|
642
|
-
`topicMake(name, "sink-push-response", peerId)` (default:
|
|
643
|
-
`${name}/sink-push-response/${peerId}`) is temporarily
|
|
644
|
-
subscribed for receiving the ack/nak response,
|
|
645
|
-
then publishes to the MQTT topic by `topicMake(name, "sink-push-request", peerId)`
|
|
646
|
-
(default: `${name}/sink-push-request/any` or `${name}/sink-push-request/${peerId}`)
|
|
647
|
-
for the initial request, `topicMake(name, "sink-push-chunk", peerId)`
|
|
648
|
-
(default: `${name}/sink-push-chunk/${peerId}`) for the data chunks,
|
|
649
|
-
and optionally `topicMake(name, "sink-push-credit", peerId)`
|
|
650
|
-
(default: `${name}/sink-push-credit/${peerId}`) for credit-based flow control.
|
|
651
|
-
|
|
652
|
-
- **Data Type Conversion Utilities**:<br/>
|
|
653
|
-
|
|
654
|
-
/* convert character string to buffer */
|
|
655
|
-
str2buf(data: string): Uint8Array
|
|
656
|
-
|
|
657
|
-
/* convert buffer to character string */
|
|
658
|
-
buf2str(data: Uint8Array): string
|
|
659
|
-
|
|
660
|
-
/* convert byte-based typed array to buffer */
|
|
661
|
-
arr2buf(data: Buffer | Uint8Array | Int8Array): Uint8Array
|
|
662
|
-
|
|
663
|
-
/* convert buffer to byte-based typed array */
|
|
664
|
-
buf2arr(data: Uint8Array, type: typeof Buffer): Buffer
|
|
665
|
-
buf2arr(data: Uint8Array, type: typeof Uint8Array): Uint8Array
|
|
666
|
-
buf2arr(data: Uint8Array, type: typeof Int8Array): Int8Array
|
|
667
|
-
|
|
668
|
-
MQTT+ provides utility methods for converting between strings,
|
|
669
|
-
buffers, and typed arrays. These are useful when working with binary
|
|
670
|
-
data in source/sink transfers or when interfacing with API methods that
|
|
671
|
-
expect specific data types.
|
|
672
|
-
|
|
673
|
-
Example:
|
|
674
|
-
|
|
675
|
-
/* string to buffer conversion */
|
|
676
|
-
const buffer = mqttp.str2buf("Hello, World!")
|
|
677
|
-
const text = mqttp.buf2str(buffer)
|
|
678
|
-
|
|
679
|
-
/* typed array conversions */
|
|
680
|
-
const ui8a = mqttp.arr2buf(buffer)
|
|
681
|
-
const buffer = mqttp.buf2arr(ui8a, Buffer)
|
|
682
|
-
const i8a = mqttp.buf2arr(ui8a, Int8Array)
|