mqtt-plus 0.9.4 → 0.9.5
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 +68 -56
- package/doc/mqtt-plus-1-event-emission.d2 +18 -0
- package/doc/mqtt-plus-1-event-emission.svg +104 -0
- package/doc/mqtt-plus-2-stream-transfer.d2 +22 -0
- package/doc/mqtt-plus-2-stream-transfer.svg +108 -0
- package/doc/mqtt-plus-3-service-call.d2 +21 -0
- package/doc/mqtt-plus-3-service-call.svg +107 -0
- package/doc/mqtt-plus-4-resource-transfer.d2 +25 -0
- package/doc/mqtt-plus-4-resource-transfer.svg +111 -0
- package/doc/theme.d2 +40 -0
- package/dst-stage1/mqtt-plus-api.d.ts +2 -2
- package/dst-stage1/mqtt-plus-info.d.ts +1 -0
- package/dst-stage1/mqtt-plus-msg.d.ts +11 -11
- package/dst-stage1/mqtt-plus-msg.js +44 -44
- package/dst-stage1/mqtt-plus-resource.d.ts +4 -4
- package/dst-stage1/mqtt-plus-resource.js +16 -14
- package/dst-stage1/mqtt-plus-service.d.ts +4 -4
- package/dst-stage1/mqtt-plus-service.js +6 -6
- package/dst-stage1/mqtt-plus-stream.js +8 -8
- package/dst-stage2/mqtt-plus.cjs.js +70 -68
- package/dst-stage2/mqtt-plus.esm.js +70 -68
- package/dst-stage2/mqtt-plus.umd.js +9 -9
- package/etc/d2.mts +21 -0
- package/etc/stx.conf +6 -0
- package/package.json +3 -1
- package/src/mqtt-plus-api.ts +2 -2
- package/src/mqtt-plus-base.ts +12 -11
- package/src/mqtt-plus-event.ts +1 -1
- package/src/mqtt-plus-info.ts +1 -1
- package/src/mqtt-plus-msg.ts +55 -55
- package/src/mqtt-plus-resource.ts +25 -26
- package/src/mqtt-plus-service.ts +13 -13
- package/src/mqtt-plus-stream.ts +8 -8
- package/tst/mqtt-plus.spec.ts +40 -7
package/README.md
CHANGED
|
@@ -22,10 +22,10 @@ $ npm install mqtt mqtt-plus
|
|
|
22
22
|
About
|
|
23
23
|
-----
|
|
24
24
|
|
|
25
|
-
This is **MQTT+**,
|
|
25
|
+
This is **MQTT+**, a companion addon API for the excellent
|
|
26
26
|
[MQTT](http://mqtt.org/) client TypeScript/JavaScript API
|
|
27
|
-
[MQTT.js](https://www.npmjs.com/package/mqtt),
|
|
28
|
-
communication patterns with
|
|
27
|
+
[MQTT.js](https://www.npmjs.com/package/mqtt), providing additional
|
|
28
|
+
communication patterns with type safety:
|
|
29
29
|
|
|
30
30
|
- **Event Emission**:
|
|
31
31
|
|
|
@@ -38,7 +38,9 @@ communication patterns with optional type safety:
|
|
|
38
38
|
|
|
39
39
|
In contrast to the regular MQTT message publish/subscribe, this
|
|
40
40
|
pattern allows to direct the event to particular subscribers and
|
|
41
|
-
provides optional information about the sender to subscribers.
|
|
41
|
+
provides optional information about the sender and receiver to subscribers.
|
|
42
|
+
|
|
43
|
+

|
|
42
44
|
|
|
43
45
|
- **Stream Transfer**:
|
|
44
46
|
|
|
@@ -54,6 +56,8 @@ communication patterns with optional type safety:
|
|
|
54
56
|
pattern allows to transfer arbitrary amounts of arbitrary data by
|
|
55
57
|
chunking the data via a stream.
|
|
56
58
|
|
|
59
|
+

|
|
60
|
+
|
|
57
61
|
- **Service Call**:
|
|
58
62
|
|
|
59
63
|
Service Call is a *bi-directional* communication pattern.
|
|
@@ -69,6 +73,8 @@ communication patterns with optional type safety:
|
|
|
69
73
|
Procedure Call](https://en.wikipedia.org/wiki/Remote_procedure_call)
|
|
70
74
|
(RPC) style communication.
|
|
71
75
|
|
|
76
|
+

|
|
77
|
+
|
|
72
78
|
- **Resource Transfer**:
|
|
73
79
|
|
|
74
80
|
Resource Transfer is a *bi-directional* communication pattern.
|
|
@@ -78,14 +84,16 @@ communication patterns with optional type safety:
|
|
|
78
84
|
of a directed resource transfer) or one arbitrary provisioner is called and
|
|
79
85
|
sends or receives the resource and its arguments.
|
|
80
86
|
|
|
87
|
+

|
|
88
|
+
|
|
81
89
|
> [!Note]
|
|
82
90
|
> **MQTT+** is similar to and derived from
|
|
83
91
|
> [MQTT-JSON-RPC](https://github.com/rse/mqtt-json-rpc) of the same
|
|
84
92
|
> author, but instead of just JSON, MQTT+ encodes packets as JSON
|
|
85
93
|
> or CBOR (default), uses an own packet format (allowing sender and
|
|
86
94
|
> receiver information), uses shorter NanoIDs instead of longer UUIDs
|
|
87
|
-
> for identification of sender, receiver and requests, and
|
|
88
|
-
>
|
|
95
|
+
> for identification of sender, receiver and requests, and additionally
|
|
96
|
+
> provides stream transfer and resource transfer support.
|
|
89
97
|
|
|
90
98
|
Usage
|
|
91
99
|
-----
|
|
@@ -100,9 +108,10 @@ pattern of each endpoint:
|
|
|
100
108
|
import type * as MQTTpt from "mqtt-plus"
|
|
101
109
|
|
|
102
110
|
export type API = {
|
|
103
|
-
"example/sample":
|
|
104
|
-
"example/upload":
|
|
105
|
-
"example/hello":
|
|
111
|
+
"example/sample": MQTTpt.Event<(a1: string, a2: number) => void>
|
|
112
|
+
"example/upload": MQTTpt.Stream<(name: string) => void>
|
|
113
|
+
"example/hello": MQTTpt.Service<(a1: string, a2: number) => string>
|
|
114
|
+
"example/resource": MQTTpt.Resource<(filename: string) => void>
|
|
106
115
|
}
|
|
107
116
|
```
|
|
108
117
|
|
|
@@ -122,11 +131,11 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
122
131
|
const mqttp = new MQTTp<API>(mqtt)
|
|
123
132
|
|
|
124
133
|
mqtt.on("connect", async () => {
|
|
125
|
-
mqttp.subscribe("example/sample", (a1, a2) => {
|
|
126
|
-
console.log("example/sample:
|
|
134
|
+
await mqttp.subscribe("example/sample", (a1, a2, info) => {
|
|
135
|
+
console.log("example/sample:", a1, a2, "from:", info.sender)
|
|
127
136
|
})
|
|
128
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
129
|
-
console.log("example/hello:
|
|
137
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
138
|
+
console.log("example/hello:", a1, a2, "from:", info.sender)
|
|
130
139
|
return `${a1}:${a2}`
|
|
131
140
|
})
|
|
132
141
|
})
|
|
@@ -143,9 +152,9 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
143
152
|
const mqttp = new MQTTp<API>(mqtt)
|
|
144
153
|
|
|
145
154
|
mqtt.on("connect", () => {
|
|
146
|
-
mqttp.emit("example/sample", "
|
|
155
|
+
mqttp.emit("example/sample", "world", 42)
|
|
147
156
|
mqttp.call("example/hello", "world", 42).then((response) => {
|
|
148
|
-
console.log("example/hello response:
|
|
157
|
+
console.log("example/hello response:", response)
|
|
149
158
|
mqtt.end()
|
|
150
159
|
})
|
|
151
160
|
})
|
|
@@ -184,7 +193,7 @@ The **MQTT+** API provides the following methods:
|
|
|
184
193
|
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
185
194
|
- `chunkSize`: Chunk size in bytes for stream transfers (default: `16384`).
|
|
186
195
|
- `topicMake`: Custom topic generation function.
|
|
187
|
-
The `operation` parameter is one of: `event-
|
|
196
|
+
The `operation` parameter is one of: `event-emission`, `stream-transfer`, `service-call-request`, `service-call-response`, `resource-transfer-request`, `resource-transfer-response`.
|
|
188
197
|
(default: `` (name, operation, peerId) => `${name}/${operation}` + (peerId ? `/${peerId}` : "/any") ``)
|
|
189
198
|
- `topicMatch`: Custom topic matching function.
|
|
190
199
|
Returns `{ name, operation, peerId? }` or `null` if no match. The `peerId` is `undefined` for broadcast topics (ending with `/any`).
|
|
@@ -209,8 +218,8 @@ The **MQTT+** API provides the following methods:
|
|
|
209
218
|
There is no return value of `callback`.
|
|
210
219
|
|
|
211
220
|
Internally, on the MQTT broker, the topics generated by
|
|
212
|
-
`topicMake(event, "event-
|
|
213
|
-
`${event}/event-
|
|
221
|
+
`topicMake(event, "event-emission")` (default: `${event}/event-emission/any` and
|
|
222
|
+
`${event}/event-emission/${peerId}`) are subscribed. Returns a
|
|
214
223
|
`Subscription` object with an `unsubscribe()` method.
|
|
215
224
|
|
|
216
225
|
- **Stream Attachment**:<br/>
|
|
@@ -233,8 +242,8 @@ The **MQTT+** API provides the following methods:
|
|
|
233
242
|
There is no return value of `callback`.
|
|
234
243
|
|
|
235
244
|
Internally, on the MQTT broker, the topics generated by
|
|
236
|
-
`topicMake(stream, "stream-
|
|
237
|
-
`${stream}/stream-
|
|
245
|
+
`topicMake(stream, "stream-transfer")` (default: `${stream}/stream-transfer/any` and
|
|
246
|
+
`${stream}/stream-transfer/${peerId}`) are subscribed. Returns an
|
|
238
247
|
`Attachment` object with an `unattach()` method.
|
|
239
248
|
|
|
240
249
|
- **Service Registration**:<br/>
|
|
@@ -256,8 +265,8 @@ The **MQTT+** API provides the following methods:
|
|
|
256
265
|
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
257
266
|
|
|
258
267
|
Internally, on the MQTT broker, the topics by
|
|
259
|
-
`topicMake(service, "service-call")` (default: `${service}/service-call/any` and
|
|
260
|
-
`${service}/service-call/${peerId}`) are subscribed. Returns a
|
|
268
|
+
`topicMake(service, "service-call-request")` (default: `${service}/service-call-request/any` and
|
|
269
|
+
`${service}/service-call-request/${peerId}`) are subscribed. Returns a
|
|
261
270
|
`Registration` object with an `unregister()` method.
|
|
262
271
|
|
|
263
272
|
- **Resource Provisioning**:<br/>
|
|
@@ -268,19 +277,19 @@ The **MQTT+** API provides the following methods:
|
|
|
268
277
|
options?: MQTT::IClientSubscribeOptions
|
|
269
278
|
callback: (
|
|
270
279
|
...params: any[],
|
|
271
|
-
info: { sender: string, receiver?: string }
|
|
272
|
-
) =>
|
|
280
|
+
info: { sender: string, receiver?: string, resource: Buffer | null }
|
|
281
|
+
) => void
|
|
273
282
|
): Promise<Provisioning>
|
|
274
283
|
|
|
275
284
|
Provision a resource.
|
|
276
285
|
The `resource` has to be a valid MQTT topic name.
|
|
277
286
|
The optional `options` allows setting MQTT.js `subscribe()` options like `qos`.
|
|
278
|
-
The `callback` is called with the `params` passed to a remote `
|
|
279
|
-
The
|
|
287
|
+
The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
288
|
+
The `callback` should set `info.resource` to a `Buffer` containing the resource data.
|
|
280
289
|
|
|
281
290
|
Internally, on the MQTT broker, the topics by
|
|
282
|
-
`topicMake(resource, "resource-transfer")` (default: `${resource}/resource-transfer/any` and
|
|
283
|
-
`${resource}/resource-transfer/${peerId}`) are subscribed. Returns a
|
|
291
|
+
`topicMake(resource, "resource-transfer-request")` (default: `${resource}/resource-transfer-request/any` and
|
|
292
|
+
`${resource}/resource-transfer-request/${peerId}`) are subscribed. Returns a
|
|
284
293
|
`Provisioning` object with an `unprovision()` method.
|
|
285
294
|
|
|
286
295
|
- **Event Emission**:<br/>
|
|
@@ -300,8 +309,8 @@ The **MQTT+** API provides the following methods:
|
|
|
300
309
|
The remote `subscribe()` `callback` is called with `params` and its
|
|
301
310
|
return value is silently ignored.
|
|
302
311
|
|
|
303
|
-
Internally, publishes to the MQTT topic by `topicMake(event, "event-
|
|
304
|
-
(default: `${event}/event-
|
|
312
|
+
Internally, publishes to the MQTT topic by `topicMake(event, "event-emission", peerId)`
|
|
313
|
+
(default: `${event}/event-emission/any` or `${event}/event-emission/${peerId}`).
|
|
305
314
|
|
|
306
315
|
- **Stream Transfer**:<br/>
|
|
307
316
|
|
|
@@ -327,8 +336,8 @@ The **MQTT+** API provides the following methods:
|
|
|
327
336
|
The remote `attach()` `callback` is called with `params` and an `info` object
|
|
328
337
|
containing a `stream.Readable` for consuming the transferred data.
|
|
329
338
|
|
|
330
|
-
Internally, publishes to the MQTT topic by `topicMake(stream, "stream-
|
|
331
|
-
(default: `${stream}/stream-
|
|
339
|
+
Internally, publishes to the MQTT topic by `topicMake(stream, "stream-transfer", peerId)`
|
|
340
|
+
(default: `${stream}/stream-transfer/any` or `${stream}/stream-transfer/${peerId}`).
|
|
332
341
|
|
|
333
342
|
- **Service Call**:<br/>
|
|
334
343
|
|
|
@@ -348,8 +357,8 @@ The **MQTT+** API provides the following methods:
|
|
|
348
357
|
return value resolves the returned `Promise`. If the remote `callback`
|
|
349
358
|
throws an exception, this rejects the returned `Promise`.
|
|
350
359
|
|
|
351
|
-
Internally, on the MQTT broker, the topic by `topicMake(service, "service-call", peerId)`
|
|
352
|
-
(default: `${service}/service-call/${peerId}`) is temporarily subscribed
|
|
360
|
+
Internally, on the MQTT broker, the topic by `topicMake(service, "service-call-response", peerId)`
|
|
361
|
+
(default: `${service}/service-call-response/${peerId}`) is temporarily subscribed
|
|
353
362
|
for receiving the response.
|
|
354
363
|
|
|
355
364
|
- **Resource Transfer**:<br/>
|
|
@@ -371,8 +380,8 @@ The **MQTT+** API provides the following methods:
|
|
|
371
380
|
throws an exception, this rejects the returned `Promise`.
|
|
372
381
|
|
|
373
382
|
Internally, on the MQTT broker, the topic by
|
|
374
|
-
`topicMake(resource, "resource-transfer", peerId)` (default:
|
|
375
|
-
`${resource}/resource-transfer/${peerId}`) is temporarily subscribed
|
|
383
|
+
`topicMake(resource, "resource-transfer-response", peerId)` (default:
|
|
384
|
+
`${resource}/resource-transfer-response/${peerId}`) is temporarily subscribed
|
|
376
385
|
for receiving the response.
|
|
377
386
|
|
|
378
387
|
- **Receiver Wrapping**:<br/>
|
|
@@ -407,15 +416,16 @@ mqttp.call("example/hello", "world", 42).then((result) => {
|
|
|
407
416
|
```
|
|
408
417
|
|
|
409
418
|
...the following message is sent to the permanent MQTT topic
|
|
410
|
-
`example/hello/service-call/any` (the shown NanoIDs are just
|
|
411
|
-
ones):
|
|
419
|
+
`example/hello/service-call-request/any` (the shown NanoIDs are just
|
|
420
|
+
pseudo ones):
|
|
412
421
|
|
|
413
422
|
```json
|
|
414
423
|
{
|
|
424
|
+
"type": "service-call-request",
|
|
415
425
|
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
416
|
-
"
|
|
417
|
-
"
|
|
418
|
-
"
|
|
426
|
+
"service": "example/hello",
|
|
427
|
+
"params": [ "world", 42 ],
|
|
428
|
+
"sender": "2IBMSk0NPnrz1AeTERoea"
|
|
419
429
|
}
|
|
420
430
|
```
|
|
421
431
|
|
|
@@ -430,13 +440,15 @@ mqttp.register("example/hello", (a1, a2) => {
|
|
|
430
440
|
...and then its result, in the above `mqttp.call()` example `"world:42"`, is then
|
|
431
441
|
sent back as the following success response
|
|
432
442
|
message to the temporary (client-specific) MQTT topic
|
|
433
|
-
`example/hello/service-call/2IBMSk0NPnrz1AeTERoea`:
|
|
443
|
+
`example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea`:
|
|
434
444
|
|
|
435
445
|
```json
|
|
436
446
|
{
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"result":
|
|
447
|
+
"type": "service-call-response",
|
|
448
|
+
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
449
|
+
"result": "world:42",
|
|
450
|
+
"sender": "2IBMSk0NPnrz1AeTERoea",
|
|
451
|
+
"receiver": "2IBMSk0NPnrz1AeTERoea"
|
|
440
452
|
}
|
|
441
453
|
```
|
|
442
454
|
|
|
@@ -542,18 +554,18 @@ mqtt.on("close", () => { console.log("CLOSE") })
|
|
|
542
554
|
mqtt.on("reconnect", () => { console.log("RECONNECT") })
|
|
543
555
|
mqtt.on("message", (topic, message) => { console.log("RECEIVED", topic, message.toString()) })
|
|
544
556
|
|
|
545
|
-
mqtt.on("connect", () => {
|
|
557
|
+
mqtt.on("connect", async () => {
|
|
546
558
|
console.log("CONNECT")
|
|
547
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
548
|
-
console.log("example/hello: request:
|
|
559
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
560
|
+
console.log("example/hello: request:", a1, a2, "from:", info.sender)
|
|
549
561
|
return `${a1}:${a2}`
|
|
550
562
|
})
|
|
551
|
-
mqttp.call("example/hello", "world", 42).then((result) => {
|
|
552
|
-
console.log("example/hello success:
|
|
563
|
+
mqttp.call("example/hello", "world", 42).then(async (result) => {
|
|
564
|
+
console.log("example/hello success:", result)
|
|
553
565
|
mqtt.end()
|
|
554
566
|
await mosquitto.stop()
|
|
555
567
|
}).catch((err) => {
|
|
556
|
-
console.log("example/hello error:
|
|
568
|
+
console.log("example/hello error:", err)
|
|
557
569
|
})
|
|
558
570
|
})
|
|
559
571
|
```
|
|
@@ -563,17 +575,17 @@ The output will be:
|
|
|
563
575
|
```
|
|
564
576
|
$ node sample.ts
|
|
565
577
|
CONNECT
|
|
566
|
-
RECEIVED example/hello/service-call/any {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
567
|
-
example/hello: request:
|
|
568
|
-
RECEIVED example/hello/service-call/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
569
|
-
example/hello success:
|
|
578
|
+
RECEIVED example/hello/service-call-request/any {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
579
|
+
example/hello: request: world 42 from: 2IBMSk0NPnrz1AeTERoea
|
|
580
|
+
RECEIVED example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
581
|
+
example/hello success: world:42
|
|
570
582
|
CLOSE
|
|
571
583
|
```
|
|
572
584
|
|
|
573
585
|
License
|
|
574
586
|
-------
|
|
575
587
|
|
|
576
|
-
Copyright (c) 2018-
|
|
588
|
+
Copyright (c) 2018-2026 Dr. Ralf S. Engelschall (http://engelschall.com/)
|
|
577
589
|
|
|
578
590
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
579
591
|
a copy of this software and associated documentation files (the
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
shape: sequence_diagram
|
|
3
|
+
|
|
4
|
+
client: "Client"
|
|
5
|
+
broker: "Broker"
|
|
6
|
+
server: "Server"
|
|
7
|
+
|
|
8
|
+
broker.class: brown
|
|
9
|
+
|
|
10
|
+
"subscribe(\"foo/bar\")": {
|
|
11
|
+
server -> broker: "op: subscribe\ntopic: foo/bar/event-emission/any"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
"emit(\"foo/bar\")": {
|
|
15
|
+
client -> broker: "op: publish\ntopic: foo/bar/event-emission/any\ndata: Event-Emission"
|
|
16
|
+
broker -> server: "op: publish\ntopic: foo/bar/event-emission/any\ndata: Event-Emission"
|
|
17
|
+
}
|
|
18
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.0-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 670 524"><svg class="d2-1243767131 d2-svg" width="670" height="524" viewBox="11 51 670 524"><rect x="11.000000" y="51.000000" width="670.000000" height="524.000000" rx="0.000000" fill="#ffffff" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
|
|
2
|
+
.d2-1243767131 .text {
|
|
3
|
+
font-family: "d2-1243767131-font-regular";
|
|
4
|
+
}
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: d2-1243767131-font-regular;
|
|
7
|
+
src: url("data:application/font-woff;base64,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");
|
|
8
|
+
}
|
|
9
|
+
.d2-1243767131 .text-italic {
|
|
10
|
+
font-family: "d2-1243767131-font-italic";
|
|
11
|
+
}
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: d2-1243767131-font-italic;
|
|
14
|
+
src: url("data:application/font-woff;base64,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");
|
|
15
|
+
}]]></style><style type="text/css"><![CDATA[.shape {
|
|
16
|
+
shape-rendering: geometricPrecision;
|
|
17
|
+
stroke-linejoin: round;
|
|
18
|
+
}
|
|
19
|
+
.connection {
|
|
20
|
+
stroke-linecap: round;
|
|
21
|
+
stroke-linejoin: round;
|
|
22
|
+
}
|
|
23
|
+
.blend {
|
|
24
|
+
mix-blend-mode: multiply;
|
|
25
|
+
opacity: 0.5;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.d2-1243767131 .fill-N1{fill:#303030;}
|
|
29
|
+
.d2-1243767131 .fill-N2{fill:#606060;}
|
|
30
|
+
.d2-1243767131 .fill-N3{fill:#909090;}
|
|
31
|
+
.d2-1243767131 .fill-N4{fill:#c0c0c0;}
|
|
32
|
+
.d2-1243767131 .fill-N5{fill:#e0e0e0;}
|
|
33
|
+
.d2-1243767131 .fill-N6{fill:#f0f0f0;}
|
|
34
|
+
.d2-1243767131 .fill-N7{fill:#ffffff;}
|
|
35
|
+
.d2-1243767131 .fill-B1{fill:#336699;}
|
|
36
|
+
.d2-1243767131 .fill-B2{fill:#6699cc;}
|
|
37
|
+
.d2-1243767131 .fill-B3{fill:#99ccff;}
|
|
38
|
+
.d2-1243767131 .fill-B4{fill:#c0d0ff;}
|
|
39
|
+
.d2-1243767131 .fill-B5{fill:#e0f0ff;}
|
|
40
|
+
.d2-1243767131 .fill-B6{fill:#f0f8ff;}
|
|
41
|
+
.d2-1243767131 .fill-AA2{fill:#cfb098;}
|
|
42
|
+
.d2-1243767131 .fill-AA4{fill:#efd0b8;}
|
|
43
|
+
.d2-1243767131 .fill-AA5{fill:#ffe0c8;}
|
|
44
|
+
.d2-1243767131 .fill-AB4{fill:#efd0b8;}
|
|
45
|
+
.d2-1243767131 .fill-AB5{fill:#ffe0c8;}
|
|
46
|
+
.d2-1243767131 .stroke-N1{stroke:#303030;}
|
|
47
|
+
.d2-1243767131 .stroke-N2{stroke:#606060;}
|
|
48
|
+
.d2-1243767131 .stroke-N3{stroke:#909090;}
|
|
49
|
+
.d2-1243767131 .stroke-N4{stroke:#c0c0c0;}
|
|
50
|
+
.d2-1243767131 .stroke-N5{stroke:#e0e0e0;}
|
|
51
|
+
.d2-1243767131 .stroke-N6{stroke:#f0f0f0;}
|
|
52
|
+
.d2-1243767131 .stroke-N7{stroke:#ffffff;}
|
|
53
|
+
.d2-1243767131 .stroke-B1{stroke:#336699;}
|
|
54
|
+
.d2-1243767131 .stroke-B2{stroke:#6699cc;}
|
|
55
|
+
.d2-1243767131 .stroke-B3{stroke:#99ccff;}
|
|
56
|
+
.d2-1243767131 .stroke-B4{stroke:#c0d0ff;}
|
|
57
|
+
.d2-1243767131 .stroke-B5{stroke:#e0f0ff;}
|
|
58
|
+
.d2-1243767131 .stroke-B6{stroke:#f0f8ff;}
|
|
59
|
+
.d2-1243767131 .stroke-AA2{stroke:#cfb098;}
|
|
60
|
+
.d2-1243767131 .stroke-AA4{stroke:#efd0b8;}
|
|
61
|
+
.d2-1243767131 .stroke-AA5{stroke:#ffe0c8;}
|
|
62
|
+
.d2-1243767131 .stroke-AB4{stroke:#efd0b8;}
|
|
63
|
+
.d2-1243767131 .stroke-AB5{stroke:#ffe0c8;}
|
|
64
|
+
.d2-1243767131 .background-color-N1{background-color:#303030;}
|
|
65
|
+
.d2-1243767131 .background-color-N2{background-color:#606060;}
|
|
66
|
+
.d2-1243767131 .background-color-N3{background-color:#909090;}
|
|
67
|
+
.d2-1243767131 .background-color-N4{background-color:#c0c0c0;}
|
|
68
|
+
.d2-1243767131 .background-color-N5{background-color:#e0e0e0;}
|
|
69
|
+
.d2-1243767131 .background-color-N6{background-color:#f0f0f0;}
|
|
70
|
+
.d2-1243767131 .background-color-N7{background-color:#ffffff;}
|
|
71
|
+
.d2-1243767131 .background-color-B1{background-color:#336699;}
|
|
72
|
+
.d2-1243767131 .background-color-B2{background-color:#6699cc;}
|
|
73
|
+
.d2-1243767131 .background-color-B3{background-color:#99ccff;}
|
|
74
|
+
.d2-1243767131 .background-color-B4{background-color:#c0d0ff;}
|
|
75
|
+
.d2-1243767131 .background-color-B5{background-color:#e0f0ff;}
|
|
76
|
+
.d2-1243767131 .background-color-B6{background-color:#f0f8ff;}
|
|
77
|
+
.d2-1243767131 .background-color-AA2{background-color:#cfb098;}
|
|
78
|
+
.d2-1243767131 .background-color-AA4{background-color:#efd0b8;}
|
|
79
|
+
.d2-1243767131 .background-color-AA5{background-color:#ffe0c8;}
|
|
80
|
+
.d2-1243767131 .background-color-AB4{background-color:#efd0b8;}
|
|
81
|
+
.d2-1243767131 .background-color-AB5{background-color:#ffe0c8;}
|
|
82
|
+
.d2-1243767131 .color-N1{color:#303030;}
|
|
83
|
+
.d2-1243767131 .color-N2{color:#606060;}
|
|
84
|
+
.d2-1243767131 .color-N3{color:#909090;}
|
|
85
|
+
.d2-1243767131 .color-N4{color:#c0c0c0;}
|
|
86
|
+
.d2-1243767131 .color-N5{color:#e0e0e0;}
|
|
87
|
+
.d2-1243767131 .color-N6{color:#f0f0f0;}
|
|
88
|
+
.d2-1243767131 .color-N7{color:#ffffff;}
|
|
89
|
+
.d2-1243767131 .color-B1{color:#336699;}
|
|
90
|
+
.d2-1243767131 .color-B2{color:#6699cc;}
|
|
91
|
+
.d2-1243767131 .color-B3{color:#99ccff;}
|
|
92
|
+
.d2-1243767131 .color-B4{color:#c0d0ff;}
|
|
93
|
+
.d2-1243767131 .color-B5{color:#e0f0ff;}
|
|
94
|
+
.d2-1243767131 .color-B6{color:#f0f8ff;}
|
|
95
|
+
.d2-1243767131 .color-AA2{color:#cfb098;}
|
|
96
|
+
.d2-1243767131 .color-AA4{color:#efd0b8;}
|
|
97
|
+
.d2-1243767131 .color-AA5{color:#ffe0c8;}
|
|
98
|
+
.d2-1243767131 .color-AB4{color:#efd0b8;}
|
|
99
|
+
.d2-1243767131 .color-AB5{color:#ffe0c8;}.appendix text.text{fill:#303030}.md{--color-fg-default:#303030;--color-fg-muted:#606060;--color-fg-subtle:#909090;--color-canvas-default:#ffffff;--color-canvas-subtle:#f0f0f0;--color-border-default:#336699;--color-border-muted:#6699cc;--color-neutral-muted:#f0f0f0;--color-accent-fg:#6699cc;--color-accent-emphasis:#6699cc;--color-attention-subtle:#606060;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-dark-d2-1243767131);mix-blend-mode:overlay}.sketch-overlay-B2{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B3{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AA4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1243767131);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1243767131);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-normal-d2-1243767131);mix-blend-mode:color-burn}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1243767131);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><g class="Y2xpZW50"><g class="shape" ><rect x="12.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#336699" fill="#e0f0ff" class=" stroke-B1 fill-B5" style="stroke-width:2;" /></g><text x="62.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Client</text></g><g class="YnJva2Vy brown"><g class="shape" ><rect x="296.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#cfb098" fill="#ffe0c9" style="stroke-width:2;" /></g><text x="346.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Broker</text></g><g class="c2VydmVy"><g class="shape" ><rect x="580.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#336699" fill="#e0f0ff" class=" stroke-B1 fill-B5" style="stroke-width:2;" /></g><text x="630.000000" y="90.500000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">Server</text></g><g class="KGNsaWVudCAtLSApWzBd"><path d="M 62.000000 120.000000 L 62.000000 573.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="KGJyb2tlciAtLSApWzBd"><path d="M 346.000000 120.000000 L 346.000000 573.000000" stroke="#cfb098" fill="none" class="connection" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="KHNlcnZlciAtLSApWzBd"><path d="M 630.000000 120.000000 L 630.000000 573.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1243767131)" /></g><g class="JiMzOTtzdWJzY3JpYmUoJiMzNDtmb28vYmFyJiMzNDspJiMzOTs="><g class="shape blend" ><rect x="306.000000" y="175.000000" width="364.000000" height="92.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="311.000000" y="180.000000" width="138.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="380.000000" y="196.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">subscribe("foo/bar")</text></g><g class="JiMzOTtlbWl0KCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="22.000000" y="312.000000" width="648.000000" height="230.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="27.000000" y="317.000000" width="104.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="79.000000" y="333.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">emit("foo/bar")</text></g><g class="KHNlcnZlciAtJmd0OyBicm9rZXIpWzBd"><marker id="mk-d2-1243767131-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" fill="#336699" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 628.000000 237.000000 L 350.000000 237.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="488.000000" y="235.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="488.000000" dy="0.000000">op: subscribe</tspan><tspan x="488.000000" dy="18.500000">topic: foo/bar/event-emission/any</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzBd"><path d="M 64.000000 382.000000 L 342.000000 382.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="204.000000" y="372.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="204.000000" dy="0.000000">op: publish</tspan><tspan x="204.000000" dy="17.666667">topic: foo/bar/event-emission/any</tspan><tspan x="204.000000" dy="17.666667">data: Event-Emission</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzBd"><path d="M 348.000000 504.000000 L 626.000000 504.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1243767131-3488378134)" mask="url(#d2-1243767131)" /><text x="488.000000" y="494.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="488.000000" dy="0.000000">op: publish</tspan><tspan x="488.000000" dy="17.666667">topic: foo/bar/event-emission/any</tspan><tspan x="488.000000" dy="17.666667">data: Event-Emission</tspan></text></g><mask id="d2-1243767131" maskUnits="userSpaceOnUse" x="11" y="51" width="670" height="524">
|
|
100
|
+
<rect x="11" y="51" width="670" height="524" fill="white"></rect>
|
|
101
|
+
<rect x="374.000000" y="219.000000" width="228" height="37" fill="black"></rect>
|
|
102
|
+
<rect x="90.000000" y="356.000000" width="228" height="53" fill="black"></rect>
|
|
103
|
+
<rect x="374.000000" y="478.000000" width="228" height="53" fill="black"></rect>
|
|
104
|
+
</mask></svg></svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
shape: sequence_diagram
|
|
3
|
+
|
|
4
|
+
client: "Client"
|
|
5
|
+
broker: "Broker"
|
|
6
|
+
server: "Server"
|
|
7
|
+
|
|
8
|
+
broker.class: brown
|
|
9
|
+
|
|
10
|
+
attach("foo/bar") {
|
|
11
|
+
server -> broker: "op: subscribe\ntopic: foo/bar/stream-transfer"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fetch("foo/bar") {
|
|
15
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #1"
|
|
16
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #1"
|
|
17
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #N"
|
|
18
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer #N"
|
|
19
|
+
client -> broker: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer EoS"
|
|
20
|
+
broker -> server: "op: publish\ntopic: foo/bar/stream-transfer/any\ndata: Stream-Transfer EoS"
|
|
21
|
+
}
|
|
22
|
+
|