mqtt-plus 1.4.11 → 1.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/AGENTS.md +8 -8
  2. package/CHANGELOG.md +21 -0
  3. package/README.md +2 -2
  4. package/doc/mqtt-plus-api.md +5 -5
  5. package/doc/mqtt-plus-broker-setup.md +0 -14
  6. package/doc/mqtt-plus-comm-sink-push.d2 +4 -5
  7. package/doc/mqtt-plus-comm-sink-push.svg +90 -91
  8. package/doc/mqtt-plus-comm-source-fetch.d2 +4 -6
  9. package/doc/mqtt-plus-comm-source-fetch.svg +89 -91
  10. package/doc/mqtt-plus-internals.md +17 -15
  11. package/dst-stage1/mqtt-plus-base.d.ts +0 -1
  12. package/dst-stage1/mqtt-plus-base.js +3 -8
  13. package/dst-stage1/mqtt-plus-error.js +1 -1
  14. package/dst-stage1/mqtt-plus-event.js +11 -11
  15. package/dst-stage1/mqtt-plus-msg.js +1 -1
  16. package/dst-stage1/mqtt-plus-service.js +10 -3
  17. package/dst-stage1/mqtt-plus-sink.js +69 -49
  18. package/dst-stage1/mqtt-plus-source.js +64 -47
  19. package/dst-stage1/mqtt-plus-subscription.d.ts +2 -0
  20. package/dst-stage1/mqtt-plus-subscription.js +7 -0
  21. package/dst-stage1/mqtt-plus-util.js +14 -4
  22. package/dst-stage2/mqtt-plus.cjs.js +165 -114
  23. package/dst-stage2/mqtt-plus.esm.js +165 -114
  24. package/dst-stage2/mqtt-plus.umd.js +12 -12
  25. package/package.json +12 -12
  26. package/src/mqtt-plus-base.ts +3 -14
  27. package/src/mqtt-plus-codec.ts +0 -1
  28. package/src/mqtt-plus-encode.ts +0 -1
  29. package/src/mqtt-plus-error.ts +1 -2
  30. package/src/mqtt-plus-event.ts +12 -12
  31. package/src/mqtt-plus-msg.ts +1 -1
  32. package/src/mqtt-plus-service.ts +11 -5
  33. package/src/mqtt-plus-sink.ts +108 -92
  34. package/src/mqtt-plus-source.ts +72 -54
  35. package/src/mqtt-plus-subscription.ts +13 -0
  36. package/src/mqtt-plus-trace.ts +0 -1
  37. package/src/mqtt-plus-util.ts +14 -4
  38. package/tst/mqtt-plus-0-broker-mosquitto.ts +0 -14
  39. package/tst/mqtt-plus-4-sink.spec.ts +144 -0
  40. package/tst/mqtt-plus-5-source.spec.ts +133 -0
package/AGENTS.md CHANGED
@@ -65,10 +65,10 @@ each extending the previous. The final exported class `MQTTp` sits at
65
65
  the bottom of this chain:
66
66
 
67
67
  ```
68
- OptionsTrait — configuration (id, codec, timeout, chunkSize, chunkCredit, topicMake/topicMatch)
68
+ OptionsTrait — configuration (id, codec, timeout, share, chunkSize, chunkCredit, topicMake/topicMatch)
69
69
  ↓ CodecTrait — CBOR/JSON codec handling
70
- ↓ EncodeTrait — message encoding/validation (valibot schemas)
71
- ↓ MsgTrait — message class definitions and parsing
70
+ ↓ EncodeTrait — string/buffer conversion utilities (str2buf, buf2str)
71
+ ↓ MsgTrait — message class definitions, valibot schemas, and parsing
72
72
  ↓ TraceTrait — EventEmitter + structured logging
73
73
  ↓ BaseTrait — MQTT client hookup, subscription management, message routing
74
74
  ↓ SubscriptionTrait — ref-counted MQTT topic subscription management
@@ -92,15 +92,15 @@ Each trait lives in its own file: `src/mqtt-plus-<trait>.ts`.
92
92
  | `src/mqtt-plus-api.ts` | Branded endpoint type definitions (Event, Service, Source, Sink) and APISchema generic |
93
93
  | `src/mqtt-plus-info.ts` | Info/context object types passed to pattern callbacks (sender metadata, etc.) |
94
94
  | `src/mqtt-plus-error.ts` | Spool (resource cleanup) and run (error handling) utilities |
95
- | `src/mqtt-plus-util.ts` | Stream/buffer conversion, RefCountedSubscription, and CreditGate flow control |
95
+ | `src/mqtt-plus-util.ts` | PLazy, CreditGate flow control, and stream/buffer collection utilities |
96
96
  | `src/mqtt-plus-version.ts` | Version utility for converting version strings to numeric format |
97
- | `src/mqtt-plus-options.ts` | OptionsTrait — configuration (id, codec, timeout, chunkSize, chunkCredit, topicMake/topicMatch) |
97
+ | `src/mqtt-plus-options.ts` | OptionsTrait — configuration (id, codec, timeout, share, chunkSize, chunkCredit, topicMake/topicMatch) |
98
98
  | `src/mqtt-plus-codec.ts` | CodecTrait — CBOR and JSON codec encoding/decoding |
99
- | `src/mqtt-plus-encode.ts` | EncodeTrait — message validation and encoding via valibot schemas |
100
- | `src/mqtt-plus-msg.ts` | MsgTrait — message class definitions and parsing logic |
99
+ | `src/mqtt-plus-encode.ts` | EncodeTrait — string/buffer conversion utilities (str2buf, buf2str) |
100
+ | `src/mqtt-plus-msg.ts` | MsgTrait — message class definitions, valibot schemas, and parsing logic |
101
101
  | `src/mqtt-plus-trace.ts` | TraceTrait — EventEmitter and structured logging |
102
102
  | `src/mqtt-plus-base.ts` | BaseTrait — MQTT client connection, subscription management, message routing |
103
- | `src/mqtt-plus-subscription.ts` | SubscriptionTrait — ref-counted MQTT topic subscription management |
103
+ | `src/mqtt-plus-subscription.ts` | SubscriptionTrait — RefCountedSubscription class and ref-counted MQTT topic subscription management |
104
104
  | `src/mqtt-plus-timer.ts` | TimerTrait — named timer management (refresh/clear) |
105
105
  | `src/mqtt-plus-meta.ts` | MetaTrait — instance and per-request metadata management |
106
106
  | `src/mqtt-plus-auth.ts` | AuthTrait — JWT authentication (jose) and role-based access control |
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
  ChangeLog
3
3
  =========
4
4
 
5
+ 1.4.13 (2026-03-10)
6
+ -------------------
7
+
8
+ - IMPROVEMENT: improve error handling in sink pattern
9
+ - IMPROVEMENT: add test cases for large buffer/stream and interrupted data transfer via sink/source
10
+ - IMPROVEMENT: use a single response topic for each of event/service/sink/source
11
+ - BUGFIX: fix error handling in sink pattern
12
+ - BUGFIX: prevent unhandled promise rejections
13
+ - BUGFIX: fix await unrolling in message handling
14
+ - BUGFIX: fix acknowledgement handling
15
+ - UPDATE: upgrade NPM dependencies
16
+ - CLEANUP: various minor code cleanups (naming, alignment, formatting, comments, variable reuse)
17
+
18
+ 1.4.12 (2026-03-05)
19
+ -------------------
20
+
21
+ - IMPROVEMENT: make all subscriptions ref-counted and spooled
22
+ - UPDATE: update documentation
23
+ - UPDATE: upgrade NPM dependencies
24
+ - CLEANUP: cleanup code
25
+
5
26
  1.4.11 (2026-03-05)
6
27
  -------------------
7
28
 
package/README.md CHANGED
@@ -91,7 +91,7 @@ const Server = async (api: MQTTp<API>, log: (msg: string, ...args: any[]) => voi
91
91
  const input = new Readable()
92
92
  input.push(api.str2buf(`the ${filename} content`))
93
93
  input.push(null)
94
- info.stream = readable
94
+ info.stream = input
95
95
  })
96
96
  await api.sink("example/upload", async (filename, info) => {
97
97
  log("example/upload: SERVER:", filename)
@@ -176,7 +176,7 @@ Notice
176
176
 
177
177
  > [!Note]
178
178
  > **MQTT+** and its peer dependency **MQTT.js** provide a powerful
179
- > functionality, but are not small in size. **MQTT+** is 3.500 LoC
179
+ > functionality, but are not small in size. **MQTT+** is 4.000 LoC
180
180
  > and 75 KB in size (ESM and CJS format). When bundled with all its
181
181
  > dependencies, it is 220 KB in size (UMD format). Its peer dependency
182
182
  > **MQTT.js** is 370 KB (ESM and CJS format) and 860 KB (UMD format) in
@@ -113,7 +113,7 @@ Authentication
113
113
  credential(credential: string): void
114
114
 
115
115
  /* issue client-side token on server-side */
116
- issue(payload: { roles: string[], id?: string }): Promise<string>
116
+ issue(payload: { roles: string[], id?: string, exp?: number }): Promise<string>
117
117
 
118
118
  /* add/remove client-side token (client-side) */
119
119
  authenticate(token: string): void
@@ -437,8 +437,8 @@ Sink Registration
437
437
  receiver?: string,
438
438
  authenticated?: boolean,
439
439
  meta?: Record<string, any>,
440
- stream?: Readable,
441
- buffer?: Promise<Uint8Array>
440
+ stream: Readable,
441
+ buffer: Promise<Uint8Array>
442
442
  }
443
443
  ) => void | Promise<void>
444
444
  ): Promise<Registration>
@@ -451,8 +451,8 @@ Sink Registration
451
451
  receiver?: string,
452
452
  authenticated?: boolean,
453
453
  meta?: Record<string, any>,
454
- stream?: Readable,
455
- buffer?: Promise<Uint8Array>
454
+ stream: Readable,
455
+ buffer: Promise<Uint8Array>
456
456
  }
457
457
  ) => void | Promise<void>,
458
458
  options?: MQTT::IClientSubscribeOptions,
@@ -75,25 +75,19 @@ pattern write example/client/+/service-call-response/%c
75
75
 
76
76
  topic write example/server/+/source-fetch-request/+
77
77
  pattern read example/server/+/source-fetch-response/%c
78
- pattern read example/server/+/source-fetch-chunk/%c
79
- topic write example/server/+/source-fetch-credit/+
80
78
 
81
79
  topic read example/client/+/source-fetch-request/any
82
80
  pattern read example/client/+/source-fetch-request/%c
83
81
  topic write example/client/+/source-fetch-response/+
84
- topic write example/client/+/source-fetch-chunk/+
85
82
 
86
83
  # ---- sink push ----
87
84
 
88
85
  topic write example/server/+/sink-push-request/+
89
86
  pattern read example/server/+/sink-push-response/%c
90
- topic write example/server/+/sink-push-chunk/+
91
87
 
92
88
  topic read example/client/+/sink-push-request/any
93
89
  pattern read example/client/+/sink-push-request/%c
94
90
  pattern write example/client/+/sink-push-response/%c
95
- pattern read example/client/+/sink-push-chunk/%c
96
- pattern read example/client/+/sink-push-credit/%c
97
91
 
98
92
  # ==== server/authenticated ACL ====
99
93
 
@@ -126,13 +120,9 @@ topic read $share/server/example/server/+/source-fetch-request/any
126
120
  pattern read example/server/+/source-fetch-request/%c
127
121
  pattern read $share/server/example/server/+/source-fetch-request/%c
128
122
  topic write example/server/+/source-fetch-response/+
129
- topic write example/server/+/source-fetch-chunk/+
130
- pattern read example/server/+/source-fetch-credit/%c
131
- pattern read $share/server/example/server/+/source-fetch-credit/%c
132
123
 
133
124
  topic write example/client/+/source-fetch-request/+
134
125
  pattern read example/client/+/source-fetch-response/%c
135
- pattern read example/client/+/source-fetch-chunk/%c
136
126
 
137
127
  # ---- sink push ----
138
128
 
@@ -141,13 +131,9 @@ topic read $share/server/example/server/+/sink-push-request/any
141
131
  pattern read example/server/+/sink-push-request/%c
142
132
  pattern read $share/server/example/server/+/sink-push-request/%c
143
133
  topic write example/server/+/sink-push-response/+
144
- pattern read example/server/+/sink-push-chunk/%c
145
- pattern read $share/server/example/server/+/sink-push-chunk/%c
146
134
 
147
135
  topic write example/client/+/sink-push-request/+
148
136
  pattern read example/client/+/sink-push-response/%c
149
- topic write example/client/+/sink-push-credit/+
150
- topic write example/client/+/sink-push-chunk/+
151
137
  ```
152
138
 
153
139
  ...and an `example` user (with password `example`) in `mosquitto-pwd.txt` like:
@@ -8,7 +8,6 @@ broker.class: brown
8
8
 
9
9
  sink("foo/bar") {
10
10
  server -> broker: "op: subscribe\ntopic: foo/bar/sink-push-request/any"
11
- server -> broker: "op: subscribe\ntopic: foo/bar/sink-push-chunk/YYY"
12
11
  }
13
12
 
14
13
  push("foo/bar") {
@@ -17,9 +16,9 @@ push("foo/bar") {
17
16
  broker -> server: "op: publish\ntopic: foo/bar/sink-push-request/any\ndata: Sink-Push-Request"
18
17
  broker <- server: "op: publish\ntopic: foo/bar/sink-push-response/XXX\ndata: Sink-Push-Response"
19
18
  client <- broker: "op: publish\ntopic: foo/bar/sink-push-response/XXX\ndata: Sink-Push-Response"
20
- client -> broker: "op: publish\ntopic: foo/bar/sink-push-chunk/YYY\ndata: Sink-Push-Chunk #1 (first)"
21
- broker -> server: "op: publish\ntopic: foo/bar/sink-push-chunk/YYY\ndata: Sink-Push-Chunk #1 (first)"
22
- client -> broker: "op: publish\ntopic: foo/bar/sink-push-chunk/YYY\ndata: Sink-Push-Chunk #N (final)"
23
- broker -> server: "op: publish\ntopic: foo/bar/sink-push-chunk/YYY\ndata: Sink-Push-Chunk #N (final)"
19
+ client -> broker: "op: publish\ntopic: foo/bar/sink-push-request/YYY\ndata: Sink-Push-Chunk #1 (first)"
20
+ broker -> server: "op: publish\ntopic: foo/bar/sink-push-request/YYY\ndata: Sink-Push-Chunk #1 (first)"
21
+ client -> broker: "op: publish\ntopic: foo/bar/sink-push-request/YYY\ndata: Sink-Push-Chunk #N (final)"
22
+ broker -> server: "op: publish\ntopic: foo/bar/sink-push-request/YYY\ndata: Sink-Push-Chunk #N (final)"
24
23
  client -> broker: "op: unsubscribe\ntopic: foo/bar/sink-push-response/XXX"
25
24
  }
@@ -1,16 +1,16 @@
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 726 1582"><svg class="d2-1059530002 d2-svg" width="726" height="1582" viewBox="11 51 726 1582"><rect x="11.000000" y="51.000000" width="726.000000" height="1582.000000" rx="0.000000" fill="#ffffff" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
2
- .d2-1059530002 .text {
3
- font-family: "d2-1059530002-font-regular";
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 726 1476"><svg class="d2-1888860115 d2-svg" width="726" height="1476" viewBox="11 51 726 1476"><rect x="11.000000" y="51.000000" width="726.000000" height="1476.000000" rx="0.000000" fill="#ffffff" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
2
+ .d2-1888860115 .text {
3
+ font-family: "d2-1888860115-font-regular";
4
4
  }
5
5
  @font-face {
6
- font-family: d2-1059530002-font-regular;
6
+ font-family: d2-1888860115-font-regular;
7
7
  src: url("data:application/font-woff;base64,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");
8
8
  }
9
- .d2-1059530002 .text-italic {
10
- font-family: "d2-1059530002-font-italic";
9
+ .d2-1888860115 .text-italic {
10
+ font-family: "d2-1888860115-font-italic";
11
11
  }
12
12
  @font-face {
13
- font-family: d2-1059530002-font-italic;
13
+ font-family: d2-1888860115-font-italic;
14
14
  src: url("data:application/font-woff;base64,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");
15
15
  }]]></style><style type="text/css"><![CDATA[.shape {
16
16
  shape-rendering: geometricPrecision;
@@ -25,89 +25,88 @@
25
25
  opacity: 0.5;
26
26
  }
27
27
 
28
- .d2-1059530002 .fill-N1{fill:#303030;}
29
- .d2-1059530002 .fill-N2{fill:#606060;}
30
- .d2-1059530002 .fill-N3{fill:#909090;}
31
- .d2-1059530002 .fill-N4{fill:#c0c0c0;}
32
- .d2-1059530002 .fill-N5{fill:#e0e0e0;}
33
- .d2-1059530002 .fill-N6{fill:#f0f0f0;}
34
- .d2-1059530002 .fill-N7{fill:#ffffff;}
35
- .d2-1059530002 .fill-B1{fill:#336699;}
36
- .d2-1059530002 .fill-B2{fill:#6699cc;}
37
- .d2-1059530002 .fill-B3{fill:#99ccff;}
38
- .d2-1059530002 .fill-B4{fill:#c0d0ff;}
39
- .d2-1059530002 .fill-B5{fill:#e0f0ff;}
40
- .d2-1059530002 .fill-B6{fill:#f0f8ff;}
41
- .d2-1059530002 .fill-AA2{fill:#cfb098;}
42
- .d2-1059530002 .fill-AA4{fill:#efd0b8;}
43
- .d2-1059530002 .fill-AA5{fill:#ffe0c8;}
44
- .d2-1059530002 .fill-AB4{fill:#efd0b8;}
45
- .d2-1059530002 .fill-AB5{fill:#ffe0c8;}
46
- .d2-1059530002 .stroke-N1{stroke:#303030;}
47
- .d2-1059530002 .stroke-N2{stroke:#606060;}
48
- .d2-1059530002 .stroke-N3{stroke:#909090;}
49
- .d2-1059530002 .stroke-N4{stroke:#c0c0c0;}
50
- .d2-1059530002 .stroke-N5{stroke:#e0e0e0;}
51
- .d2-1059530002 .stroke-N6{stroke:#f0f0f0;}
52
- .d2-1059530002 .stroke-N7{stroke:#ffffff;}
53
- .d2-1059530002 .stroke-B1{stroke:#336699;}
54
- .d2-1059530002 .stroke-B2{stroke:#6699cc;}
55
- .d2-1059530002 .stroke-B3{stroke:#99ccff;}
56
- .d2-1059530002 .stroke-B4{stroke:#c0d0ff;}
57
- .d2-1059530002 .stroke-B5{stroke:#e0f0ff;}
58
- .d2-1059530002 .stroke-B6{stroke:#f0f8ff;}
59
- .d2-1059530002 .stroke-AA2{stroke:#cfb098;}
60
- .d2-1059530002 .stroke-AA4{stroke:#efd0b8;}
61
- .d2-1059530002 .stroke-AA5{stroke:#ffe0c8;}
62
- .d2-1059530002 .stroke-AB4{stroke:#efd0b8;}
63
- .d2-1059530002 .stroke-AB5{stroke:#ffe0c8;}
64
- .d2-1059530002 .background-color-N1{background-color:#303030;}
65
- .d2-1059530002 .background-color-N2{background-color:#606060;}
66
- .d2-1059530002 .background-color-N3{background-color:#909090;}
67
- .d2-1059530002 .background-color-N4{background-color:#c0c0c0;}
68
- .d2-1059530002 .background-color-N5{background-color:#e0e0e0;}
69
- .d2-1059530002 .background-color-N6{background-color:#f0f0f0;}
70
- .d2-1059530002 .background-color-N7{background-color:#ffffff;}
71
- .d2-1059530002 .background-color-B1{background-color:#336699;}
72
- .d2-1059530002 .background-color-B2{background-color:#6699cc;}
73
- .d2-1059530002 .background-color-B3{background-color:#99ccff;}
74
- .d2-1059530002 .background-color-B4{background-color:#c0d0ff;}
75
- .d2-1059530002 .background-color-B5{background-color:#e0f0ff;}
76
- .d2-1059530002 .background-color-B6{background-color:#f0f8ff;}
77
- .d2-1059530002 .background-color-AA2{background-color:#cfb098;}
78
- .d2-1059530002 .background-color-AA4{background-color:#efd0b8;}
79
- .d2-1059530002 .background-color-AA5{background-color:#ffe0c8;}
80
- .d2-1059530002 .background-color-AB4{background-color:#efd0b8;}
81
- .d2-1059530002 .background-color-AB5{background-color:#ffe0c8;}
82
- .d2-1059530002 .color-N1{color:#303030;}
83
- .d2-1059530002 .color-N2{color:#606060;}
84
- .d2-1059530002 .color-N3{color:#909090;}
85
- .d2-1059530002 .color-N4{color:#c0c0c0;}
86
- .d2-1059530002 .color-N5{color:#e0e0e0;}
87
- .d2-1059530002 .color-N6{color:#f0f0f0;}
88
- .d2-1059530002 .color-N7{color:#ffffff;}
89
- .d2-1059530002 .color-B1{color:#336699;}
90
- .d2-1059530002 .color-B2{color:#6699cc;}
91
- .d2-1059530002 .color-B3{color:#99ccff;}
92
- .d2-1059530002 .color-B4{color:#c0d0ff;}
93
- .d2-1059530002 .color-B5{color:#e0f0ff;}
94
- .d2-1059530002 .color-B6{color:#f0f8ff;}
95
- .d2-1059530002 .color-AA2{color:#cfb098;}
96
- .d2-1059530002 .color-AA4{color:#efd0b8;}
97
- .d2-1059530002 .color-AA5{color:#ffe0c8;}
98
- .d2-1059530002 .color-AB4{color:#efd0b8;}
99
- .d2-1059530002 .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-1059530002);mix-blend-mode:overlay}.sketch-overlay-B2{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-B3{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-B4{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1059530002);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1059530002);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-AA4{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1059530002);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1059530002);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1059530002);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1059530002);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-normal-d2-1059530002);mix-blend-mode:color-burn}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1059530002);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1059530002);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="324.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#cfb098" fill="#ffe0c9" style="stroke-width:2;" /></g><text x="374.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="636.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="686.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 1631.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1059530002)" /></g><g class="KGJyb2tlciAtLSApWzBd"><path d="M 374.000000 120.000000 L 374.000000 1631.000000" stroke="#cfb098" fill="none" class="connection" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1059530002)" /></g><g class="KHNlcnZlciAtLSApWzBd"><path d="M 686.000000 120.000000 L 686.000000 1631.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1059530002)" /></g><g class="JiMzOTtzaW5rKCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="334.000000" y="175.000000" width="392.000000" height="198.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="339.000000" y="180.000000" width="100.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="389.000000" y="196.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">sink(&#34;foo/bar&#34;)</text></g><g class="JiMzOTtwdXNoKCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="22.000000" y="418.000000" width="704.000000" height="1174.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="27.000000" y="423.000000" width="105.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="79.500000" y="439.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">push(&#34;foo/bar&#34;)</text></g><g class="KHNlcnZlciAtJmd0OyBicm9rZXIpWzBd"><marker id="mk-d2-1059530002-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 684.000000 237.000000 L 378.000000 237.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="530.000000" y="235.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: subscribe</tspan><tspan x="530.000000" dy="18.500000">topic: foo/bar/sink-push-request/any</tspan></text></g><g class="KHNlcnZlciAtJmd0OyBicm9rZXIpWzFd"><path d="M 684.000000 343.000000 L 378.000000 343.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="530.500000" y="341.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.500000" dy="0.000000">op: subscribe</tspan><tspan x="530.500000" dy="18.500000">topic: foo/bar/sink-push-chunk/YYY</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzBd"><path d="M 64.000000 480.000000 L 370.000000 480.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="218.000000" y="478.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: subscribe</tspan><tspan x="218.000000" dy="18.500000">topic: foo/bar/sink-push-response/XXX</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzFd"><path d="M 64.000000 594.000000 L 370.000000 594.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="218.000000" y="584.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: publish</tspan><tspan x="218.000000" dy="17.666667">topic: foo/bar/sink-push-request/any</tspan><tspan x="218.000000" dy="17.666667">data: Sink-Push-Request</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzBd"><path d="M 376.000000 716.000000 L 682.000000 716.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="530.000000" y="706.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: publish</tspan><tspan x="530.000000" dy="17.666667">topic: foo/bar/sink-push-request/any</tspan><tspan x="530.000000" dy="17.666667">data: Sink-Push-Request</tspan></text></g><g class="KGJyb2tlciAmbHQ7LSBzZXJ2ZXIpWzBd"><marker id="mk-d2-1059530002-2451250203" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" fill="#336699" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 378.000000 838.000000 L 684.000000 838.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-start="url(#mk-d2-1059530002-2451250203)" mask="url(#d2-1059530002)" /><text x="530.000000" y="828.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: publish</tspan><tspan x="530.000000" dy="17.666667">topic: foo/bar/sink-push-response/XXX</tspan><tspan x="530.000000" dy="17.666667">data: Sink-Push-Response</tspan></text></g><g class="KGNsaWVudCAmbHQ7LSBicm9rZXIpWzBd"><path d="M 66.000000 960.000000 L 372.000000 960.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-start="url(#mk-d2-1059530002-2451250203)" mask="url(#d2-1059530002)" /><text x="218.000000" y="950.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: publish</tspan><tspan x="218.000000" dy="17.666667">topic: foo/bar/sink-push-response/XXX</tspan><tspan x="218.000000" dy="17.666667">data: Sink-Push-Response</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzJd"><path d="M 64.000000 1082.000000 L 370.000000 1082.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="218.500000" y="1072.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.500000" dy="0.000000">op: publish</tspan><tspan x="218.500000" dy="17.666667">topic: foo/bar/sink-push-chunk/YYY</tspan><tspan x="218.500000" dy="17.666667">data: Sink-Push-Chunk #1 (first)</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzFd"><path d="M 376.000000 1204.000000 L 682.000000 1204.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="530.500000" y="1194.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.500000" dy="0.000000">op: publish</tspan><tspan x="530.500000" dy="17.666667">topic: foo/bar/sink-push-chunk/YYY</tspan><tspan x="530.500000" dy="17.666667">data: Sink-Push-Chunk #1 (first)</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzNd"><path d="M 64.000000 1326.000000 L 370.000000 1326.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="218.500000" y="1316.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.500000" dy="0.000000">op: publish</tspan><tspan x="218.500000" dy="17.666667">topic: foo/bar/sink-push-chunk/YYY</tspan><tspan x="218.500000" dy="17.666667">data: Sink-Push-Chunk #N (final)</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzJd"><path d="M 376.000000 1448.000000 L 682.000000 1448.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="530.500000" y="1438.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.500000" dy="0.000000">op: publish</tspan><tspan x="530.500000" dy="17.666667">topic: foo/bar/sink-push-chunk/YYY</tspan><tspan x="530.500000" dy="17.666667">data: Sink-Push-Chunk #N (final)</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzRd"><path d="M 64.000000 1562.000000 L 370.000000 1562.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1059530002-3488378134)" mask="url(#d2-1059530002)" /><text x="218.000000" y="1560.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: unsubscribe</tspan><tspan x="218.000000" dy="18.500000">topic: foo/bar/sink-push-response/XXX</tspan></text></g><mask id="d2-1059530002" maskUnits="userSpaceOnUse" x="11" y="51" width="726" height="1582">
100
- <rect x="11" y="51" width="726" height="1582" fill="white"></rect>
28
+ .d2-1888860115 .fill-N1{fill:#303030;}
29
+ .d2-1888860115 .fill-N2{fill:#606060;}
30
+ .d2-1888860115 .fill-N3{fill:#909090;}
31
+ .d2-1888860115 .fill-N4{fill:#c0c0c0;}
32
+ .d2-1888860115 .fill-N5{fill:#e0e0e0;}
33
+ .d2-1888860115 .fill-N6{fill:#f0f0f0;}
34
+ .d2-1888860115 .fill-N7{fill:#ffffff;}
35
+ .d2-1888860115 .fill-B1{fill:#336699;}
36
+ .d2-1888860115 .fill-B2{fill:#6699cc;}
37
+ .d2-1888860115 .fill-B3{fill:#99ccff;}
38
+ .d2-1888860115 .fill-B4{fill:#c0d0ff;}
39
+ .d2-1888860115 .fill-B5{fill:#e0f0ff;}
40
+ .d2-1888860115 .fill-B6{fill:#f0f8ff;}
41
+ .d2-1888860115 .fill-AA2{fill:#cfb098;}
42
+ .d2-1888860115 .fill-AA4{fill:#efd0b8;}
43
+ .d2-1888860115 .fill-AA5{fill:#ffe0c8;}
44
+ .d2-1888860115 .fill-AB4{fill:#efd0b8;}
45
+ .d2-1888860115 .fill-AB5{fill:#ffe0c8;}
46
+ .d2-1888860115 .stroke-N1{stroke:#303030;}
47
+ .d2-1888860115 .stroke-N2{stroke:#606060;}
48
+ .d2-1888860115 .stroke-N3{stroke:#909090;}
49
+ .d2-1888860115 .stroke-N4{stroke:#c0c0c0;}
50
+ .d2-1888860115 .stroke-N5{stroke:#e0e0e0;}
51
+ .d2-1888860115 .stroke-N6{stroke:#f0f0f0;}
52
+ .d2-1888860115 .stroke-N7{stroke:#ffffff;}
53
+ .d2-1888860115 .stroke-B1{stroke:#336699;}
54
+ .d2-1888860115 .stroke-B2{stroke:#6699cc;}
55
+ .d2-1888860115 .stroke-B3{stroke:#99ccff;}
56
+ .d2-1888860115 .stroke-B4{stroke:#c0d0ff;}
57
+ .d2-1888860115 .stroke-B5{stroke:#e0f0ff;}
58
+ .d2-1888860115 .stroke-B6{stroke:#f0f8ff;}
59
+ .d2-1888860115 .stroke-AA2{stroke:#cfb098;}
60
+ .d2-1888860115 .stroke-AA4{stroke:#efd0b8;}
61
+ .d2-1888860115 .stroke-AA5{stroke:#ffe0c8;}
62
+ .d2-1888860115 .stroke-AB4{stroke:#efd0b8;}
63
+ .d2-1888860115 .stroke-AB5{stroke:#ffe0c8;}
64
+ .d2-1888860115 .background-color-N1{background-color:#303030;}
65
+ .d2-1888860115 .background-color-N2{background-color:#606060;}
66
+ .d2-1888860115 .background-color-N3{background-color:#909090;}
67
+ .d2-1888860115 .background-color-N4{background-color:#c0c0c0;}
68
+ .d2-1888860115 .background-color-N5{background-color:#e0e0e0;}
69
+ .d2-1888860115 .background-color-N6{background-color:#f0f0f0;}
70
+ .d2-1888860115 .background-color-N7{background-color:#ffffff;}
71
+ .d2-1888860115 .background-color-B1{background-color:#336699;}
72
+ .d2-1888860115 .background-color-B2{background-color:#6699cc;}
73
+ .d2-1888860115 .background-color-B3{background-color:#99ccff;}
74
+ .d2-1888860115 .background-color-B4{background-color:#c0d0ff;}
75
+ .d2-1888860115 .background-color-B5{background-color:#e0f0ff;}
76
+ .d2-1888860115 .background-color-B6{background-color:#f0f8ff;}
77
+ .d2-1888860115 .background-color-AA2{background-color:#cfb098;}
78
+ .d2-1888860115 .background-color-AA4{background-color:#efd0b8;}
79
+ .d2-1888860115 .background-color-AA5{background-color:#ffe0c8;}
80
+ .d2-1888860115 .background-color-AB4{background-color:#efd0b8;}
81
+ .d2-1888860115 .background-color-AB5{background-color:#ffe0c8;}
82
+ .d2-1888860115 .color-N1{color:#303030;}
83
+ .d2-1888860115 .color-N2{color:#606060;}
84
+ .d2-1888860115 .color-N3{color:#909090;}
85
+ .d2-1888860115 .color-N4{color:#c0c0c0;}
86
+ .d2-1888860115 .color-N5{color:#e0e0e0;}
87
+ .d2-1888860115 .color-N6{color:#f0f0f0;}
88
+ .d2-1888860115 .color-N7{color:#ffffff;}
89
+ .d2-1888860115 .color-B1{color:#336699;}
90
+ .d2-1888860115 .color-B2{color:#6699cc;}
91
+ .d2-1888860115 .color-B3{color:#99ccff;}
92
+ .d2-1888860115 .color-B4{color:#c0d0ff;}
93
+ .d2-1888860115 .color-B5{color:#e0f0ff;}
94
+ .d2-1888860115 .color-B6{color:#f0f8ff;}
95
+ .d2-1888860115 .color-AA2{color:#cfb098;}
96
+ .d2-1888860115 .color-AA4{color:#efd0b8;}
97
+ .d2-1888860115 .color-AA5{color:#ffe0c8;}
98
+ .d2-1888860115 .color-AB4{color:#efd0b8;}
99
+ .d2-1888860115 .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-1888860115);mix-blend-mode:overlay}.sketch-overlay-B2{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-B3{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-B4{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1888860115);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1888860115);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-AA4{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1888860115);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1888860115);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1888860115);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1888860115);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-normal-d2-1888860115);mix-blend-mode:color-burn}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1888860115);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1888860115);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="324.000000" y="52.000000" width="100.000000" height="66.000000" stroke="#cfb098" fill="#ffe0c9" style="stroke-width:2;" /></g><text x="374.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="636.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="686.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 1525.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1888860115)" /></g><g class="KGJyb2tlciAtLSApWzBd"><path d="M 374.000000 120.000000 L 374.000000 1525.000000" stroke="#cfb098" fill="none" class="connection" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1888860115)" /></g><g class="KHNlcnZlciAtLSApWzBd"><path d="M 686.000000 120.000000 L 686.000000 1525.000000" stroke="#6699cc" fill="none" class="connection stroke-B2" style="stroke-width:2;stroke-dasharray:12.000000,11.838767;" mask="url(#d2-1888860115)" /></g><g class="JiMzOTtzaW5rKCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="334.000000" y="175.000000" width="392.000000" height="92.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="339.000000" y="180.000000" width="100.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="389.000000" y="196.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">sink(&#34;foo/bar&#34;)</text></g><g class="JiMzOTtwdXNoKCYjMzQ7Zm9vL2JhciYjMzQ7KSYjMzk7"><g class="shape blend" ><rect x="22.000000" y="312.000000" width="704.000000" height="1174.000000" stroke="#336699" fill="#e0e0e0" class=" stroke-B1 fill-N5" style="stroke-width:0;" /></g><rect x="27.000000" y="317.000000" width="105.000000" height="21.000000" fill="#e0e0e0" class=" fill-N5" /><text x="79.500000" y="333.000000" fill="#303030" class="text fill-N1" style="text-anchor:middle;font-size:16px">push(&#34;foo/bar&#34;)</text></g><g class="KHNlcnZlciAtJmd0OyBicm9rZXIpWzBd"><marker id="mk-d2-1888860115-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 684.000000 237.000000 L 378.000000 237.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="530.000000" y="235.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: subscribe</tspan><tspan x="530.000000" dy="18.500000">topic: foo/bar/sink-push-request/any</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzBd"><path d="M 64.000000 374.000000 L 370.000000 374.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="218.000000" y="372.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: subscribe</tspan><tspan x="218.000000" dy="18.500000">topic: foo/bar/sink-push-response/XXX</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzFd"><path d="M 64.000000 488.000000 L 370.000000 488.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="218.000000" y="478.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: publish</tspan><tspan x="218.000000" dy="17.666667">topic: foo/bar/sink-push-request/any</tspan><tspan x="218.000000" dy="17.666667">data: Sink-Push-Request</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzBd"><path d="M 376.000000 610.000000 L 682.000000 610.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="530.000000" y="600.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: publish</tspan><tspan x="530.000000" dy="17.666667">topic: foo/bar/sink-push-request/any</tspan><tspan x="530.000000" dy="17.666667">data: Sink-Push-Request</tspan></text></g><g class="KGJyb2tlciAmbHQ7LSBzZXJ2ZXIpWzBd"><marker id="mk-d2-1888860115-2451250203" markerWidth="10.000000" markerHeight="12.000000" refX="3.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="10.000000,0.000000 0.000000,6.000000 10.000000,12.000000" fill="#336699" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 378.000000 732.000000 L 684.000000 732.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-start="url(#mk-d2-1888860115-2451250203)" mask="url(#d2-1888860115)" /><text x="530.000000" y="722.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.000000" dy="0.000000">op: publish</tspan><tspan x="530.000000" dy="17.666667">topic: foo/bar/sink-push-response/XXX</tspan><tspan x="530.000000" dy="17.666667">data: Sink-Push-Response</tspan></text></g><g class="KGNsaWVudCAmbHQ7LSBicm9rZXIpWzBd"><path d="M 66.000000 854.000000 L 372.000000 854.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-start="url(#mk-d2-1888860115-2451250203)" mask="url(#d2-1888860115)" /><text x="218.000000" y="844.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: publish</tspan><tspan x="218.000000" dy="17.666667">topic: foo/bar/sink-push-response/XXX</tspan><tspan x="218.000000" dy="17.666667">data: Sink-Push-Response</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzJd"><path d="M 64.000000 976.000000 L 370.000000 976.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="218.500000" y="966.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.500000" dy="0.000000">op: publish</tspan><tspan x="218.500000" dy="17.666667">topic: foo/bar/sink-push-request/YYY</tspan><tspan x="218.500000" dy="17.666667">data: Sink-Push-Chunk #1 (first)</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzFd"><path d="M 376.000000 1098.000000 L 682.000000 1098.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="530.500000" y="1088.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.500000" dy="0.000000">op: publish</tspan><tspan x="530.500000" dy="17.666667">topic: foo/bar/sink-push-request/YYY</tspan><tspan x="530.500000" dy="17.666667">data: Sink-Push-Chunk #1 (first)</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzNd"><path d="M 64.000000 1220.000000 L 370.000000 1220.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="218.500000" y="1210.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.500000" dy="0.000000">op: publish</tspan><tspan x="218.500000" dy="17.666667">topic: foo/bar/sink-push-request/YYY</tspan><tspan x="218.500000" dy="17.666667">data: Sink-Push-Chunk #N (final)</tspan></text></g><g class="KGJyb2tlciAtJmd0OyBzZXJ2ZXIpWzJd"><path d="M 376.000000 1342.000000 L 682.000000 1342.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="530.500000" y="1332.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="530.500000" dy="0.000000">op: publish</tspan><tspan x="530.500000" dy="17.666667">topic: foo/bar/sink-push-request/YYY</tspan><tspan x="530.500000" dy="17.666667">data: Sink-Push-Chunk #N (final)</tspan></text></g><g class="KGNsaWVudCAtJmd0OyBicm9rZXIpWzRd"><path d="M 64.000000 1456.000000 L 370.000000 1456.000000" stroke="#336699" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-d2-1888860115-3488378134)" mask="url(#d2-1888860115)" /><text x="218.000000" y="1454.000000" fill="#606060" class="text-italic fill-N2" style="text-anchor:middle;font-size:16px"><tspan x="218.000000" dy="0.000000">op: unsubscribe</tspan><tspan x="218.000000" dy="18.500000">topic: foo/bar/sink-push-response/XXX</tspan></text></g><mask id="d2-1888860115" maskUnits="userSpaceOnUse" x="11" y="51" width="726" height="1476">
100
+ <rect x="11" y="51" width="726" height="1476" fill="white"></rect>
101
101
  <rect x="407.000000" y="219.000000" width="246" height="37" fill="black"></rect>
102
- <rect x="413.000000" y="325.000000" width="235" height="37" fill="black"></rect>
103
- <rect x="90.000000" y="462.000000" width="256" height="37" fill="black"></rect>
104
- <rect x="95.000000" y="568.000000" width="246" height="53" fill="black"></rect>
105
- <rect x="407.000000" y="690.000000" width="246" height="53" fill="black"></rect>
106
- <rect x="402.000000" y="812.000000" width="256" height="53" fill="black"></rect>
107
- <rect x="90.000000" y="934.000000" width="256" height="53" fill="black"></rect>
108
- <rect x="101.000000" y="1056.000000" width="235" height="53" fill="black"></rect>
109
- <rect x="413.000000" y="1178.000000" width="235" height="53" fill="black"></rect>
110
- <rect x="101.000000" y="1300.000000" width="235" height="53" fill="black"></rect>
111
- <rect x="413.000000" y="1422.000000" width="235" height="53" fill="black"></rect>
112
- <rect x="90.000000" y="1544.000000" width="256" height="37" fill="black"></rect>
102
+ <rect x="90.000000" y="356.000000" width="256" height="37" fill="black"></rect>
103
+ <rect x="95.000000" y="462.000000" width="246" height="53" fill="black"></rect>
104
+ <rect x="407.000000" y="584.000000" width="246" height="53" fill="black"></rect>
105
+ <rect x="402.000000" y="706.000000" width="256" height="53" fill="black"></rect>
106
+ <rect x="90.000000" y="828.000000" width="256" height="53" fill="black"></rect>
107
+ <rect x="96.000000" y="950.000000" width="245" height="53" fill="black"></rect>
108
+ <rect x="408.000000" y="1072.000000" width="245" height="53" fill="black"></rect>
109
+ <rect x="96.000000" y="1194.000000" width="245" height="53" fill="black"></rect>
110
+ <rect x="408.000000" y="1316.000000" width="245" height="53" fill="black"></rect>
111
+ <rect x="90.000000" y="1438.000000" width="256" height="37" fill="black"></rect>
113
112
  </mask></svg></svg>
@@ -12,15 +12,13 @@ source("foo/bar") {
12
12
 
13
13
  fetch("foo/bar") {
14
14
  client -> broker: "op: subscribe\ntopic: foo/bar/source-fetch-response/XXX"
15
- client -> broker: "op: subscribe\ntopic: foo/bar/source-fetch-chunk/XXX"
16
15
  client -> broker: "op: publish\ntopic: foo/bar/source-fetch-request/any\ndata: Source-Fetch-Request"
17
16
  broker -> server: "op: publish\ntopic: foo/bar/source-fetch-request/any\ndata: Source-Fetch-Request"
18
17
  broker <- server: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Response"
19
18
  client <- broker: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Response"
20
- broker <- server: "op: publish\ntopic: foo/bar/source-fetch-chunk/XXX\ndata: Source-Fetch-Chunk #1 (first)"
21
- client <- broker: "op: publish\ntopic: foo/bar/source-fetch-chunk/XXX\ndata: Source-Fetch-Chunk #1 (first)"
22
- broker <- server: "op: publish\ntopic: foo/bar/source-fetch-chunk/XXX\ndata: Source-Fetch-Chunk #N (final)"
23
- client <- broker: "op: publish\ntopic: foo/bar/source-fetch-chunk/XXX\ndata: Source-Fetch-Chunk #N (final)"
19
+ broker <- server: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Chunk #1 (first)"
20
+ client <- broker: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Chunk #1 (first)"
21
+ broker <- server: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Chunk #N (final)"
22
+ client <- broker: "op: publish\ntopic: foo/bar/source-fetch-response/XXX\ndata: Source-Fetch-Chunk #N (final)"
24
23
  client -> broker: "op: unsubscribe\ntopic: foo/bar/source-fetch-response/XXX"
25
- client -> broker: "op: unsubscribe\ntopic: foo/bar/source-fetch-chunk/XXX"
26
24
  }