mqtt-plus 0.9.4 → 0.9.6
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 +77 -62
- 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 +23 -0
- package/doc/mqtt-plus-4-resource-transfer.svg +109 -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 +14 -13
- package/dst-stage1/mqtt-plus-msg.js +55 -51
- package/dst-stage1/mqtt-plus-resource.d.ts +4 -4
- package/dst-stage1/mqtt-plus-resource.js +23 -23
- 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 +90 -85
- package/dst-stage2/mqtt-plus.esm.js +90 -85
- package/dst-stage2/mqtt-plus.umd.js +10 -10
- package/etc/d2.mts +21 -0
- package/etc/eslint.mts +1 -1
- package/etc/stx.conf +6 -0
- package/package.json +3 -1
- package/src/mqtt-plus-api.ts +3 -3
- 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 +69 -63
- package/src/mqtt-plus-resource.ts +33 -37
- 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,7 @@ 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
|
|
|
81
|
-
|
|
82
|
-
> **MQTT+** is similar to and derived from
|
|
83
|
-
> [MQTT-JSON-RPC](https://github.com/rse/mqtt-json-rpc) of the same
|
|
84
|
-
> author, but instead of just JSON, MQTT+ encodes packets as JSON
|
|
85
|
-
> or CBOR (default), uses an own packet format (allowing sender and
|
|
86
|
-
> receiver information), uses shorter NanoIDs instead of longer UUIDs
|
|
87
|
-
> for identification of sender, receiver and requests, and has
|
|
88
|
-
> no support for stream transfers.
|
|
87
|
+

|
|
89
88
|
|
|
90
89
|
Usage
|
|
91
90
|
-----
|
|
@@ -100,9 +99,10 @@ pattern of each endpoint:
|
|
|
100
99
|
import type * as MQTTpt from "mqtt-plus"
|
|
101
100
|
|
|
102
101
|
export type API = {
|
|
103
|
-
"example/sample":
|
|
104
|
-
"example/upload":
|
|
105
|
-
"example/hello":
|
|
102
|
+
"example/sample": MQTTpt.Event<(a1: string, a2: number) => void>
|
|
103
|
+
"example/upload": MQTTpt.Stream<(name: string) => void>
|
|
104
|
+
"example/hello": MQTTpt.Service<(a1: string, a2: number) => string>
|
|
105
|
+
"example/resource": MQTTpt.Resource<(filename: string) => void>
|
|
106
106
|
}
|
|
107
107
|
```
|
|
108
108
|
|
|
@@ -122,11 +122,11 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
122
122
|
const mqttp = new MQTTp<API>(mqtt)
|
|
123
123
|
|
|
124
124
|
mqtt.on("connect", async () => {
|
|
125
|
-
mqttp.subscribe("example/sample", (a1, a2) => {
|
|
126
|
-
console.log("example/sample:
|
|
125
|
+
await mqttp.subscribe("example/sample", (a1, a2, info) => {
|
|
126
|
+
console.log("example/sample:", a1, a2, "from:", info.sender)
|
|
127
127
|
})
|
|
128
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
129
|
-
console.log("example/hello:
|
|
128
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
129
|
+
console.log("example/hello:", a1, a2, "from:", info.sender)
|
|
130
130
|
return `${a1}:${a2}`
|
|
131
131
|
})
|
|
132
132
|
})
|
|
@@ -143,9 +143,9 @@ const mqtt = MQTT.connect("wss://127.0.0.1:8883", { ... })
|
|
|
143
143
|
const mqttp = new MQTTp<API>(mqtt)
|
|
144
144
|
|
|
145
145
|
mqtt.on("connect", () => {
|
|
146
|
-
mqttp.emit("example/sample", "
|
|
146
|
+
mqttp.emit("example/sample", "world", 42)
|
|
147
147
|
mqttp.call("example/hello", "world", 42).then((response) => {
|
|
148
|
-
console.log("example/hello response:
|
|
148
|
+
console.log("example/hello response:", response)
|
|
149
149
|
mqtt.end()
|
|
150
150
|
})
|
|
151
151
|
})
|
|
@@ -184,7 +184,7 @@ The **MQTT+** API provides the following methods:
|
|
|
184
184
|
- `timeout`: Communication timeout in milliseconds (default: `10000`).
|
|
185
185
|
- `chunkSize`: Chunk size in bytes for stream transfers (default: `16384`).
|
|
186
186
|
- `topicMake`: Custom topic generation function.
|
|
187
|
-
The `operation` parameter is one of: `event-
|
|
187
|
+
The `operation` parameter is one of: `event-emission`, `stream-transfer`, `service-call-request`, `service-call-response`, `resource-transfer-request`, `resource-transfer-response`.
|
|
188
188
|
(default: `` (name, operation, peerId) => `${name}/${operation}` + (peerId ? `/${peerId}` : "/any") ``)
|
|
189
189
|
- `topicMatch`: Custom topic matching function.
|
|
190
190
|
Returns `{ name, operation, peerId? }` or `null` if no match. The `peerId` is `undefined` for broadcast topics (ending with `/any`).
|
|
@@ -209,8 +209,8 @@ The **MQTT+** API provides the following methods:
|
|
|
209
209
|
There is no return value of `callback`.
|
|
210
210
|
|
|
211
211
|
Internally, on the MQTT broker, the topics generated by
|
|
212
|
-
`topicMake(event, "event-
|
|
213
|
-
`${event}/event-
|
|
212
|
+
`topicMake(event, "event-emission")` (default: `${event}/event-emission/any` and
|
|
213
|
+
`${event}/event-emission/${peerId}`) are subscribed. Returns a
|
|
214
214
|
`Subscription` object with an `unsubscribe()` method.
|
|
215
215
|
|
|
216
216
|
- **Stream Attachment**:<br/>
|
|
@@ -233,8 +233,8 @@ The **MQTT+** API provides the following methods:
|
|
|
233
233
|
There is no return value of `callback`.
|
|
234
234
|
|
|
235
235
|
Internally, on the MQTT broker, the topics generated by
|
|
236
|
-
`topicMake(stream, "stream-
|
|
237
|
-
`${stream}/stream-
|
|
236
|
+
`topicMake(stream, "stream-transfer")` (default: `${stream}/stream-transfer/any` and
|
|
237
|
+
`${stream}/stream-transfer/${peerId}`) are subscribed. Returns an
|
|
238
238
|
`Attachment` object with an `unattach()` method.
|
|
239
239
|
|
|
240
240
|
- **Service Registration**:<br/>
|
|
@@ -256,8 +256,8 @@ The **MQTT+** API provides the following methods:
|
|
|
256
256
|
The return value of `callback` will resolve the `Promise` returned by the remote `call()`.
|
|
257
257
|
|
|
258
258
|
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
|
|
259
|
+
`topicMake(service, "service-call-request")` (default: `${service}/service-call-request/any` and
|
|
260
|
+
`${service}/service-call-request/${peerId}`) are subscribed. Returns a
|
|
261
261
|
`Registration` object with an `unregister()` method.
|
|
262
262
|
|
|
263
263
|
- **Resource Provisioning**:<br/>
|
|
@@ -268,19 +268,19 @@ The **MQTT+** API provides the following methods:
|
|
|
268
268
|
options?: MQTT::IClientSubscribeOptions
|
|
269
269
|
callback: (
|
|
270
270
|
...params: any[],
|
|
271
|
-
info: { sender: string, receiver?: string }
|
|
272
|
-
) =>
|
|
271
|
+
info: { sender: string, receiver?: string, resource: Buffer | null }
|
|
272
|
+
) => void
|
|
273
273
|
): Promise<Provisioning>
|
|
274
274
|
|
|
275
275
|
Provision a resource.
|
|
276
276
|
The `resource` has to be a valid MQTT topic name.
|
|
277
277
|
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
|
|
278
|
+
The `callback` is called with the `params` passed to a remote `fetch()`.
|
|
279
|
+
The `callback` should set `info.resource` to a `Buffer` containing the resource data.
|
|
280
280
|
|
|
281
281
|
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
|
|
282
|
+
`topicMake(resource, "resource-transfer-request")` (default: `${resource}/resource-transfer-request/any` and
|
|
283
|
+
`${resource}/resource-transfer-request/${peerId}`) are subscribed. Returns a
|
|
284
284
|
`Provisioning` object with an `unprovision()` method.
|
|
285
285
|
|
|
286
286
|
- **Event Emission**:<br/>
|
|
@@ -300,8 +300,8 @@ The **MQTT+** API provides the following methods:
|
|
|
300
300
|
The remote `subscribe()` `callback` is called with `params` and its
|
|
301
301
|
return value is silently ignored.
|
|
302
302
|
|
|
303
|
-
Internally, publishes to the MQTT topic by `topicMake(event, "event-
|
|
304
|
-
(default: `${event}/event-
|
|
303
|
+
Internally, publishes to the MQTT topic by `topicMake(event, "event-emission", peerId)`
|
|
304
|
+
(default: `${event}/event-emission/any` or `${event}/event-emission/${peerId}`).
|
|
305
305
|
|
|
306
306
|
- **Stream Transfer**:<br/>
|
|
307
307
|
|
|
@@ -327,8 +327,8 @@ The **MQTT+** API provides the following methods:
|
|
|
327
327
|
The remote `attach()` `callback` is called with `params` and an `info` object
|
|
328
328
|
containing a `stream.Readable` for consuming the transferred data.
|
|
329
329
|
|
|
330
|
-
Internally, publishes to the MQTT topic by `topicMake(stream, "stream-
|
|
331
|
-
(default: `${stream}/stream-
|
|
330
|
+
Internally, publishes to the MQTT topic by `topicMake(stream, "stream-transfer", peerId)`
|
|
331
|
+
(default: `${stream}/stream-transfer/any` or `${stream}/stream-transfer/${peerId}`).
|
|
332
332
|
|
|
333
333
|
- **Service Call**:<br/>
|
|
334
334
|
|
|
@@ -348,8 +348,8 @@ The **MQTT+** API provides the following methods:
|
|
|
348
348
|
return value resolves the returned `Promise`. If the remote `callback`
|
|
349
349
|
throws an exception, this rejects the returned `Promise`.
|
|
350
350
|
|
|
351
|
-
Internally, on the MQTT broker, the topic by `topicMake(service, "service-call", peerId)`
|
|
352
|
-
(default: `${service}/service-call/${peerId}`) is temporarily subscribed
|
|
351
|
+
Internally, on the MQTT broker, the topic by `topicMake(service, "service-call-response", peerId)`
|
|
352
|
+
(default: `${service}/service-call-response/${peerId}`) is temporarily subscribed
|
|
353
353
|
for receiving the response.
|
|
354
354
|
|
|
355
355
|
- **Resource Transfer**:<br/>
|
|
@@ -371,8 +371,8 @@ The **MQTT+** API provides the following methods:
|
|
|
371
371
|
throws an exception, this rejects the returned `Promise`.
|
|
372
372
|
|
|
373
373
|
Internally, on the MQTT broker, the topic by
|
|
374
|
-
`topicMake(resource, "resource-transfer", peerId)` (default:
|
|
375
|
-
`${resource}/resource-transfer/${peerId}`) is temporarily subscribed
|
|
374
|
+
`topicMake(resource, "resource-transfer-response", peerId)` (default:
|
|
375
|
+
`${resource}/resource-transfer-response/${peerId}`) is temporarily subscribed
|
|
376
376
|
for receiving the response.
|
|
377
377
|
|
|
378
378
|
- **Receiver Wrapping**:<br/>
|
|
@@ -407,15 +407,16 @@ mqttp.call("example/hello", "world", 42).then((result) => {
|
|
|
407
407
|
```
|
|
408
408
|
|
|
409
409
|
...the following message is sent to the permanent MQTT topic
|
|
410
|
-
`example/hello/service-call/any` (the shown NanoIDs are just
|
|
411
|
-
ones):
|
|
410
|
+
`example/hello/service-call-request/any` (the shown NanoIDs are just
|
|
411
|
+
pseudo ones):
|
|
412
412
|
|
|
413
413
|
```json
|
|
414
414
|
{
|
|
415
|
+
"type": "service-call-request",
|
|
415
416
|
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
416
|
-
"
|
|
417
|
-
"
|
|
418
|
-
"
|
|
417
|
+
"service": "example/hello",
|
|
418
|
+
"params": [ "world", 42 ],
|
|
419
|
+
"sender": "2IBMSk0NPnrz1AeTERoea"
|
|
419
420
|
}
|
|
420
421
|
```
|
|
421
422
|
|
|
@@ -430,13 +431,15 @@ mqttp.register("example/hello", (a1, a2) => {
|
|
|
430
431
|
...and then its result, in the above `mqttp.call()` example `"world:42"`, is then
|
|
431
432
|
sent back as the following success response
|
|
432
433
|
message to the temporary (client-specific) MQTT topic
|
|
433
|
-
`example/hello/service-call/2IBMSk0NPnrz1AeTERoea`:
|
|
434
|
+
`example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea`:
|
|
434
435
|
|
|
435
436
|
```json
|
|
436
437
|
{
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"result":
|
|
438
|
+
"type": "service-call-response",
|
|
439
|
+
"id": "vwLzfQDu2uEeOdOfIlT42",
|
|
440
|
+
"result": "world:42",
|
|
441
|
+
"sender": "2IBMSk0NPnrz1AeTERoea",
|
|
442
|
+
"receiver": "2IBMSk0NPnrz1AeTERoea"
|
|
440
443
|
}
|
|
441
444
|
```
|
|
442
445
|
|
|
@@ -542,18 +545,18 @@ mqtt.on("close", () => { console.log("CLOSE") })
|
|
|
542
545
|
mqtt.on("reconnect", () => { console.log("RECONNECT") })
|
|
543
546
|
mqtt.on("message", (topic, message) => { console.log("RECEIVED", topic, message.toString()) })
|
|
544
547
|
|
|
545
|
-
mqtt.on("connect", () => {
|
|
548
|
+
mqtt.on("connect", async () => {
|
|
546
549
|
console.log("CONNECT")
|
|
547
|
-
mqttp.register("example/hello", (a1, a2) => {
|
|
548
|
-
console.log("example/hello: request:
|
|
550
|
+
await mqttp.register("example/hello", (a1, a2, info) => {
|
|
551
|
+
console.log("example/hello: request:", a1, a2, "from:", info.sender)
|
|
549
552
|
return `${a1}:${a2}`
|
|
550
553
|
})
|
|
551
|
-
mqttp.call("example/hello", "world", 42).then((result) => {
|
|
552
|
-
console.log("example/hello success:
|
|
554
|
+
mqttp.call("example/hello", "world", 42).then(async (result) => {
|
|
555
|
+
console.log("example/hello success:", result)
|
|
553
556
|
mqtt.end()
|
|
554
557
|
await mosquitto.stop()
|
|
555
558
|
}).catch((err) => {
|
|
556
|
-
console.log("example/hello error:
|
|
559
|
+
console.log("example/hello error:", err)
|
|
557
560
|
})
|
|
558
561
|
})
|
|
559
562
|
```
|
|
@@ -563,17 +566,29 @@ The output will be:
|
|
|
563
566
|
```
|
|
564
567
|
$ node sample.ts
|
|
565
568
|
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:
|
|
569
|
+
RECEIVED example/hello/service-call-request/any {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","service":"example/hello","params":["world",42]}
|
|
570
|
+
example/hello: request: world 42 from: 2IBMSk0NPnrz1AeTERoea
|
|
571
|
+
RECEIVED example/hello/service-call-response/2IBMSk0NPnrz1AeTERoea {"id":"vwLzfQDu2uEeOdOfIlT42","sender":"2IBMSk0NPnrz1AeTERoea","receiver":"2IBMSk0NPnrz1AeTERoea","result":"world:42"}
|
|
572
|
+
example/hello success: world:42
|
|
570
573
|
CLOSE
|
|
571
574
|
```
|
|
572
575
|
|
|
576
|
+
Notice
|
|
577
|
+
------
|
|
578
|
+
|
|
579
|
+
> [!Note]
|
|
580
|
+
> **MQTT+** is somewhat similar to and originally derived from
|
|
581
|
+
> [MQTT-JSON-RPC](https://github.com/rse/mqtt-json-rpc) of the same
|
|
582
|
+
> author, but instead of just JSON, MQTT+ encodes packets as JSON
|
|
583
|
+
> or CBOR (default), uses an own packet format (allowing sender and
|
|
584
|
+
> receiver information), uses shorter NanoIDs instead of longer UUIDs
|
|
585
|
+
> for identification of sender, receiver and requests, and additionally
|
|
586
|
+
> provides stream transfer and resource transfer support.
|
|
587
|
+
|
|
573
588
|
License
|
|
574
589
|
-------
|
|
575
590
|
|
|
576
|
-
Copyright (c) 2018-
|
|
591
|
+
Copyright (c) 2018-2026 Dr. Ralf S. Engelschall (http://engelschall.com/)
|
|
577
592
|
|
|
578
593
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
579
594
|
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
|
+
|