@thalesrc/hermes 7.5.2 → 7.5.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 +33 -17
- package/docs/images/broadcast-communication.svg +87 -0
- package/docs/images/chrome-extension-communication.svg +110 -0
- package/docs/images/core-architecture.svg +59 -0
- package/docs/images/iframe-communication.svg +74 -0
- package/docs/images/worker-communication.svg +75 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@thalesrc/hermes)
|
|
4
4
|
[](https://www.npmjs.com/package/@thalesrc/hermes)
|
|
5
|
+
[](https://codecov.io/gh/thalesrc/thalesrc?flag=hermes)
|
|
5
6
|
[](https://www.typescriptlang.org/)
|
|
6
7
|
[](https://opensource.org/licenses/MIT)
|
|
7
8
|
|
|
@@ -38,6 +39,8 @@ The library uses two main abstractions:
|
|
|
38
39
|
- **`MessageHost`**: Listens for requests and sends responses (uses `@Listen` decorator)
|
|
39
40
|
- **`MessageService`**: Combines both client and host (bidirectional communication)
|
|
40
41
|
|
|
42
|
+

|
|
43
|
+
|
|
41
44
|
### Decorators
|
|
42
45
|
|
|
43
46
|
- **`@Request(path)`**: Marks a method as a message sender
|
|
@@ -49,6 +52,8 @@ The library uses two main abstractions:
|
|
|
49
52
|
|
|
50
53
|
Send and receive messages between iframes and parent windows.
|
|
51
54
|
|
|
55
|
+

|
|
56
|
+
|
|
52
57
|
#### Client-Only (Iframe)
|
|
53
58
|
|
|
54
59
|
```typescript
|
|
@@ -149,6 +154,8 @@ const iframeService = new IframeBidirectional('my-channel');
|
|
|
149
154
|
|
|
150
155
|
Communicate across extension contexts (background, content scripts, popups).
|
|
151
156
|
|
|
157
|
+

|
|
158
|
+
|
|
152
159
|
#### Content Script
|
|
153
160
|
|
|
154
161
|
```typescript
|
|
@@ -203,6 +210,8 @@ const background = new BackgroundScript();
|
|
|
203
210
|
|
|
204
211
|
Communicate between main thread and web workers.
|
|
205
212
|
|
|
213
|
+

|
|
214
|
+
|
|
206
215
|
#### Main Thread
|
|
207
216
|
|
|
208
217
|
```typescript
|
|
@@ -318,6 +327,8 @@ const workerService = new WorkerThread();
|
|
|
318
327
|
|
|
319
328
|
Communicate between different tabs/windows of the same origin.
|
|
320
329
|
|
|
330
|
+

|
|
331
|
+
|
|
321
332
|
#### Tab 1
|
|
322
333
|
|
|
323
334
|
```typescript
|
|
@@ -537,24 +548,28 @@ const client = new ChromeMessageClient('extension-port');
|
|
|
537
548
|
|
|
538
549
|
### Testing
|
|
539
550
|
|
|
540
|
-
Hermes uses
|
|
551
|
+
Hermes uses a modular testing structure with separate configurations for each submodule:
|
|
541
552
|
|
|
542
553
|
```bash
|
|
543
|
-
# Run all tests (
|
|
544
|
-
pnpm nx
|
|
554
|
+
# Run all tests (all submodules in parallel)
|
|
555
|
+
pnpm nx run hermes:test
|
|
556
|
+
|
|
557
|
+
# Run specific submodule tests
|
|
558
|
+
pnpm nx run hermes:test/core # Core functionality (Node.js)
|
|
559
|
+
pnpm nx run hermes:test/worker # Web Worker tests (Browser)
|
|
560
|
+
pnpm nx run hermes:test/chrome # Chrome extension tests (Browser)
|
|
561
|
+
pnpm nx run hermes:test/broadcast # Broadcast Channel tests (Browser)
|
|
562
|
+
pnpm nx run hermes:test/iframe # Iframe communication tests (Browser)
|
|
545
563
|
|
|
546
|
-
# Run
|
|
547
|
-
pnpm nx
|
|
548
|
-
pnpm nx test:browser hermes # Web Worker tests (Chromium)
|
|
549
|
-
pnpm nx test:chrome hermes # Chrome extension tests
|
|
550
|
-
pnpm nx test:node hermes # Child process tests
|
|
564
|
+
# Run all tests with coverage and merge reports
|
|
565
|
+
pnpm nx run hermes:test/coverage
|
|
551
566
|
|
|
552
|
-
# Debug browser tests
|
|
553
|
-
pnpm nx test
|
|
567
|
+
# Debug browser tests (visible browser)
|
|
568
|
+
pnpm nx run hermes:test/headed
|
|
554
569
|
```
|
|
555
570
|
|
|
556
571
|
For detailed testing documentation, see:
|
|
557
|
-
- [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) -
|
|
572
|
+
- [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) - Complete testing guide
|
|
558
573
|
- [TEST-COMMANDS.md](./docs/TEST-COMMANDS.md) - Quick command reference
|
|
559
574
|
- [TESTING-SETUP-SUMMARY.md](./docs/TESTING-SETUP-SUMMARY.md) - Setup overview
|
|
560
575
|
|
|
@@ -570,14 +585,15 @@ pnpm nx build hermes --watch
|
|
|
570
585
|
|
|
571
586
|
### Contributing
|
|
572
587
|
|
|
573
|
-
When adding new
|
|
588
|
+
When adding new submodule support:
|
|
574
589
|
|
|
575
|
-
1. Create
|
|
576
|
-
2. Add
|
|
577
|
-
3.
|
|
578
|
-
4.
|
|
590
|
+
1. Create submodule directory in `src/`
|
|
591
|
+
2. Add test files alongside code: `*.spec.ts`
|
|
592
|
+
3. Create submodule's `vitest.config.ts` in the submodule directory
|
|
593
|
+
4. Add test target in `project.json`
|
|
594
|
+
5. Update main `test` target to include new submodule
|
|
579
595
|
|
|
580
|
-
See [TESTING-GUIDE.md](./TESTING-GUIDE.md) for details on adding new
|
|
596
|
+
See [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) for details on adding new submodules.
|
|
581
597
|
|
|
582
598
|
## License
|
|
583
599
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.title { font: bold 24px sans-serif; fill: #2c3e50; }
|
|
5
|
+
.subtitle { font: 16px sans-serif; fill: #7f8c8d; }
|
|
6
|
+
.label { font: 14px sans-serif; fill: #34495e; }
|
|
7
|
+
.code { font: 11px monospace; fill: #2c3e50; }
|
|
8
|
+
.tab { fill: #ecf0f1; stroke: #95a5a6; stroke-width: 3; }
|
|
9
|
+
.service { fill: #9b59b6; stroke: #8e44ad; stroke-width: 2; }
|
|
10
|
+
.channel { fill: none; stroke: #e74c3c; stroke-width: 4; stroke-dasharray: 10,5; }
|
|
11
|
+
.arrow { stroke: #3498db; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
|
|
12
|
+
.broadcast-wave { fill: none; stroke: #e74c3c; stroke-width: 2; opacity: 0.6; }
|
|
13
|
+
text { text-anchor: middle; }
|
|
14
|
+
</style>
|
|
15
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
16
|
+
<polygon points="0 0, 10 3, 0 6" fill="#3498db" />
|
|
17
|
+
</marker>
|
|
18
|
+
</defs>
|
|
19
|
+
|
|
20
|
+
<!-- Title -->
|
|
21
|
+
<text x="450" y="35" class="title">Broadcast Channel Communication</text>
|
|
22
|
+
<text x="450" y="60" class="subtitle">Multi-tab/window messaging within same origin</text>
|
|
23
|
+
|
|
24
|
+
<!-- Central Channel -->
|
|
25
|
+
<circle cx="450" cy="320" r="80" class="channel"/>
|
|
26
|
+
<text x="450" y="310" class="label" style="font-weight: bold; font-size: 18px; fill: #e74c3c;">Broadcast</text>
|
|
27
|
+
<text x="450" y="335" class="label" style="font-weight: bold; font-size: 18px; fill: #e74c3c;">Channel</text>
|
|
28
|
+
<text x="450" y="360" class="code" style="fill: #e74c3c;">"my-app-channel"</text>
|
|
29
|
+
|
|
30
|
+
<!-- Broadcast waves -->
|
|
31
|
+
<circle cx="450" cy="320" r="100" class="broadcast-wave"/>
|
|
32
|
+
<circle cx="450" cy="320" r="120" class="broadcast-wave"/>
|
|
33
|
+
<circle cx="450" cy="320" r="140" class="broadcast-wave"/>
|
|
34
|
+
|
|
35
|
+
<!-- Tab 1 (Top Left) -->
|
|
36
|
+
<rect x="50" y="100" width="250" height="140" rx="8" class="tab"/>
|
|
37
|
+
<rect x="50" y="100" width="250" height="25" rx="8" style="fill: #3498db;"/>
|
|
38
|
+
<text x="175" y="118" class="label" style="fill: white; font-weight: bold;">Tab 1 🌐</text>
|
|
39
|
+
|
|
40
|
+
<rect x="70" y="145" width="210" height="80" rx="5" class="service"/>
|
|
41
|
+
<text x="175" y="170" class="label" style="fill: white; font-weight: bold; font-size: 13px;">BroadcastMessageService</text>
|
|
42
|
+
<text x="175" y="192" class="code" style="fill: #f39c12;">@Request('sync')</text>
|
|
43
|
+
<text x="175" y="210" class="code" style="fill: #2ecc71;">@Listen('notification')</text>
|
|
44
|
+
|
|
45
|
+
<!-- Tab 2 (Top Right) -->
|
|
46
|
+
<rect x="600" y="100" width="250" height="140" rx="8" class="tab"/>
|
|
47
|
+
<rect x="600" y="100" width="250" height="25" rx="8" style="fill: #3498db;"/>
|
|
48
|
+
<text x="725" y="118" class="label" style="fill: white; font-weight: bold;">Tab 2 🌐</text>
|
|
49
|
+
|
|
50
|
+
<rect x="620" y="145" width="210" height="80" rx="5" class="service"/>
|
|
51
|
+
<text x="725" y="170" class="label" style="fill: white; font-weight: bold; font-size: 13px;">BroadcastMessageService</text>
|
|
52
|
+
<text x="725" y="192" class="code" style="fill: #2ecc71;">@Listen('sync')</text>
|
|
53
|
+
<text x="725" y="210" class="code" style="fill: #f39c12;">@Request('notification')</text>
|
|
54
|
+
|
|
55
|
+
<!-- Tab 3 (Bottom Left) -->
|
|
56
|
+
<rect x="50" y="420" width="250" height="140" rx="8" class="tab"/>
|
|
57
|
+
<rect x="50" y="420" width="250" height="25" rx="8" style="fill: #3498db;"/>
|
|
58
|
+
<text x="175" y="438" class="label" style="fill: white; font-weight: bold;">Tab 3 🌐</text>
|
|
59
|
+
|
|
60
|
+
<rect x="70" y="465" width="210" height="80" rx="5" class="service"/>
|
|
61
|
+
<text x="175" y="490" class="label" style="fill: white; font-weight: bold; font-size: 13px;">BroadcastMessageService</text>
|
|
62
|
+
<text x="175" y="512" class="code" style="fill: #2ecc71;">@Listen('sync')</text>
|
|
63
|
+
<text x="175" y="530" class="code" style="fill: #2ecc71;">@Listen('notification')</text>
|
|
64
|
+
|
|
65
|
+
<!-- Tab 4 (Bottom Right) -->
|
|
66
|
+
<rect x="600" y="420" width="250" height="140" rx="8" class="tab"/>
|
|
67
|
+
<rect x="600" y="420" width="250" height="25" rx="8" style="fill: #3498db;"/>
|
|
68
|
+
<text x="725" y="438" class="label" style="fill: white; font-weight: bold;">Tab 4 🌐</text>
|
|
69
|
+
|
|
70
|
+
<rect x="620" y="465" width="210" height="80" rx="5" class="service"/>
|
|
71
|
+
<text x="725" y="490" class="label" style="fill: white; font-weight: bold; font-size: 13px;">BroadcastMessageService</text>
|
|
72
|
+
<text x="725" y="512" class="code" style="fill: #f39c12;">@Request('sync')</text>
|
|
73
|
+
<text x="725" y="530" class="code" style="fill: #f39c12;">@Request('notification')</text>
|
|
74
|
+
|
|
75
|
+
<!-- Arrows connecting tabs to channel -->
|
|
76
|
+
<path d="M 240 240 L 400 280" class="arrow"/>
|
|
77
|
+
<path d="M 650 240 L 490 280" class="arrow"/>
|
|
78
|
+
<path d="M 240 420 L 400 360" class="arrow"/>
|
|
79
|
+
<path d="M 650 420 L 490 360" class="arrow"/>
|
|
80
|
+
|
|
81
|
+
<!-- Info Box -->
|
|
82
|
+
<rect x="325" y="140" width="250" height="90" rx="5" style="fill: #34495e; stroke: #2c3e50; stroke-width: 2;"/>
|
|
83
|
+
<text x="450" y="165" class="label" style="fill: white; font-weight: bold;">All tabs share the channel</text>
|
|
84
|
+
<text x="450" y="190" class="label" style="fill: #ecf0f1; font-size: 12px;">Messages sent by one tab</text>
|
|
85
|
+
<text x="450" y="210" class="label" style="fill: #ecf0f1; font-size: 12px;">are received by all other tabs</text>
|
|
86
|
+
|
|
87
|
+
</svg>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.title { font: bold 24px sans-serif; fill: #2c3e50; }
|
|
5
|
+
.subtitle { font: 16px sans-serif; fill: #7f8c8d; }
|
|
6
|
+
.label { font: 14px sans-serif; fill: #34495e; }
|
|
7
|
+
.code { font: 11px monospace; fill: #2c3e50; }
|
|
8
|
+
.context { fill: #ecf0f1; stroke: #95a5a6; stroke-width: 3; }
|
|
9
|
+
.client { fill: #3498db; stroke: #2980b9; stroke-width: 2; }
|
|
10
|
+
.host { fill: #2ecc71; stroke: #27ae60; stroke-width: 2; }
|
|
11
|
+
.service { fill: #9b59b6; stroke: #8e44ad; stroke-width: 2; }
|
|
12
|
+
.arrow { stroke: #e74c3c; stroke-width: 2.5; fill: none; marker-end: url(#arrowhead); }
|
|
13
|
+
.arrow-back { stroke: #f39c12; stroke-width: 2.5; fill: none; marker-end: url(#arrowhead-back); }
|
|
14
|
+
text { text-anchor: middle; }
|
|
15
|
+
</style>
|
|
16
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
17
|
+
<polygon points="0 0, 10 3, 0 6" fill="#e74c3c" />
|
|
18
|
+
</marker>
|
|
19
|
+
<marker id="arrowhead-back" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
20
|
+
<polygon points="0 0, 10 3, 0 6" fill="#f39c12" />
|
|
21
|
+
</marker>
|
|
22
|
+
</defs>
|
|
23
|
+
|
|
24
|
+
<!-- Title -->
|
|
25
|
+
<text x="450" y="35" class="title">Chrome Extension Communication</text>
|
|
26
|
+
<text x="450" y="60" class="subtitle">Background script ↔ Content scripts, Popups, DevTools</text>
|
|
27
|
+
|
|
28
|
+
<!-- Background Script (Center/Hub) -->
|
|
29
|
+
<rect x="325" y="240" width="250" height="120" rx="8" class="context"/>
|
|
30
|
+
<text x="450" y="270" class="label" style="font-weight: bold; font-size: 16px;">Background Script</text>
|
|
31
|
+
<text x="450" y="290" class="label" style="font-size: 11px; fill: #7f8c8d;">(Service Worker)</text>
|
|
32
|
+
|
|
33
|
+
<rect x="345" y="305" width="210" height="45" rx="5" class="host"/>
|
|
34
|
+
<text x="450" y="325" class="label" style="fill: white; font-weight: bold; font-size: 13px;">ChromeMessageHost</text>
|
|
35
|
+
<text x="450" y="343" class="code" style="fill: white;">@Listen('fetchData')</text>
|
|
36
|
+
|
|
37
|
+
<!-- Content Script (Left) -->
|
|
38
|
+
<rect x="50" y="100" width="200" height="140" rx="8" class="context"/>
|
|
39
|
+
<text x="150" y="130" class="label" style="font-weight: bold;">Content Script</text>
|
|
40
|
+
<text x="150" y="148" class="label" style="font-size: 10px; fill: #7f8c8d;">(webpage)</text>
|
|
41
|
+
|
|
42
|
+
<rect x="70" y="165" width="160" height="60" rx="5" class="client"/>
|
|
43
|
+
<text x="150" y="185" class="label" style="fill: white; font-weight: bold; font-size: 12px;">ChromeMessageClient</text>
|
|
44
|
+
<text x="150" y="205" class="code" style="fill: white;">@Request('fetchData')</text>
|
|
45
|
+
<text x="150" y="220" class="code" style="fill: white;">@Request('saveSettings')</text>
|
|
46
|
+
|
|
47
|
+
<!-- Popup (Top Right) -->
|
|
48
|
+
<rect x="650" y="100" width="200" height="140" rx="8" class="context"/>
|
|
49
|
+
<text x="750" y="130" class="label" style="font-weight: bold;">Popup / Action</text>
|
|
50
|
+
<text x="750" y="148" class="label" style="font-size: 10px; fill: #7f8c8d;">(browser action)</text>
|
|
51
|
+
|
|
52
|
+
<rect x="670" y="165" width="160" height="60" rx="5" class="client"/>
|
|
53
|
+
<text x="750" y="185" class="label" style="fill: white; font-weight: bold; font-size: 12px;">ChromeMessageClient</text>
|
|
54
|
+
<text x="750" y="205" class="code" style="fill: white;">@Request('getState')</text>
|
|
55
|
+
<text x="750" y="220" class="code" style="fill: white;">@Request('updateBadge')</text>
|
|
56
|
+
|
|
57
|
+
<!-- DevTools (Bottom Left) -->
|
|
58
|
+
<rect x="50" y="420" width="200" height="140" rx="8" class="context"/>
|
|
59
|
+
<text x="150" y="450" class="label" style="font-weight: bold;">DevTools Panel</text>
|
|
60
|
+
<text x="150" y="468" class="label" style="font-size: 10px; fill: #7f8c8d;">(devtools page)</text>
|
|
61
|
+
|
|
62
|
+
<rect x="70" y="485" width="160" height="60" rx="5" class="client"/>
|
|
63
|
+
<text x="150" y="505" class="label" style="fill: white; font-weight: bold; font-size: 12px;">ChromeMessageClient</text>
|
|
64
|
+
<text x="150" y="525" class="code" style="fill: white;">@Request('inspect')</text>
|
|
65
|
+
|
|
66
|
+
<!-- Options Page (Bottom Right) -->
|
|
67
|
+
<rect x="650" y="420" width="200" height="140" rx="8" class="context"/>
|
|
68
|
+
<text x="750" y="450" class="label" style="font-weight: bold;">Options Page</text>
|
|
69
|
+
<text x="750" y="468" class="label" style="font-size: 10px; fill: #7f8c8d;">(settings)</text>
|
|
70
|
+
|
|
71
|
+
<rect x="670" y="485" width="160" height="60" rx="5" class="service"/>
|
|
72
|
+
<text x="750" y="505" class="label" style="fill: white; font-weight: bold; font-size: 12px;">ChromeMessageService</text>
|
|
73
|
+
<text x="750" y="525" class="code" style="fill: white;">@Request + @Listen</text>
|
|
74
|
+
|
|
75
|
+
<!-- Arrows from contexts to background -->
|
|
76
|
+
<!-- Content Script to Background -->
|
|
77
|
+
<path d="M 250 180 L 325 280" class="arrow"/>
|
|
78
|
+
<text x="270" y="220" class="code" style="fill: #e74c3c; font-size: 10px;">chrome.runtime</text>
|
|
79
|
+
<text x="270" y="235" class="code" style="fill: #e74c3c; font-size: 10px;">.sendMessage</text>
|
|
80
|
+
|
|
81
|
+
<!-- Background to Content Script -->
|
|
82
|
+
<path d="M 345 295 L 260 200" class="arrow-back"/>
|
|
83
|
+
|
|
84
|
+
<!-- Popup to Background -->
|
|
85
|
+
<path d="M 650 190 L 575 285" class="arrow"/>
|
|
86
|
+
<text x="630" y="225" class="code" style="fill: #e74c3c; font-size: 10px;">chrome.runtime</text>
|
|
87
|
+
<text x="630" y="240" class="code" style="fill: #e74c3c; font-size: 10px;">.sendMessage</text>
|
|
88
|
+
|
|
89
|
+
<!-- Background to Popup -->
|
|
90
|
+
<path d="M 555 290 L 660 200" class="arrow-back"/>
|
|
91
|
+
|
|
92
|
+
<!-- DevTools to Background -->
|
|
93
|
+
<path d="M 250 500 L 340 350" class="arrow"/>
|
|
94
|
+
|
|
95
|
+
<!-- Background to DevTools -->
|
|
96
|
+
<path d="M 355 360 L 260 520" class="arrow-back"/>
|
|
97
|
+
|
|
98
|
+
<!-- Options to Background -->
|
|
99
|
+
<path d="M 650 510 L 575 330" class="arrow"/>
|
|
100
|
+
|
|
101
|
+
<!-- Background to Options -->
|
|
102
|
+
<path d="M 555 335 L 660 520" class="arrow-back"/>
|
|
103
|
+
|
|
104
|
+
<!-- Legend -->
|
|
105
|
+
<rect x="320" y="470" width="260" height="90" rx="5" style="fill: #34495e; stroke: #2c3e50; stroke-width: 2;"/>
|
|
106
|
+
<text x="450" y="495" class="label" style="fill: white; font-weight: bold; font-size: 13px;">Chrome Runtime API</text>
|
|
107
|
+
<text x="340" y="520" class="code" style="fill: #3498db; text-anchor: start;">chrome.runtime.sendMessage()</text>
|
|
108
|
+
<text x="340" y="540" class="code" style="fill: #2ecc71; text-anchor: start;">chrome.runtime.onMessage</text>
|
|
109
|
+
|
|
110
|
+
</svg>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 400">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.title { font: bold 24px sans-serif; fill: #2c3e50; }
|
|
5
|
+
.subtitle { font: 16px sans-serif; fill: #7f8c8d; }
|
|
6
|
+
.label { font: 14px sans-serif; fill: #34495e; }
|
|
7
|
+
.decorator { font: bold 12px monospace; fill: #e74c3c; }
|
|
8
|
+
.box { fill: #3498db; stroke: #2980b9; stroke-width: 2; }
|
|
9
|
+
.box-alt { fill: #2ecc71; stroke: #27ae60; stroke-width: 2; }
|
|
10
|
+
.box-core { fill: #9b59b6; stroke: #8e44ad; stroke-width: 2; }
|
|
11
|
+
.arrow { stroke: #34495e; stroke-width: 2; fill: none; marker-end: url(#arrowhead); }
|
|
12
|
+
.arrow-bi { stroke: #e67e22; stroke-width: 2; fill: none; marker-end: url(#arrowhead-bi); marker-start: url(#arrowhead-bi-start); }
|
|
13
|
+
text { text-anchor: middle; }
|
|
14
|
+
</style>
|
|
15
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
16
|
+
<polygon points="0 0, 10 3, 0 6" fill="#34495e" />
|
|
17
|
+
</marker>
|
|
18
|
+
<marker id="arrowhead-bi" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
19
|
+
<polygon points="0 0, 10 3, 0 6" fill="#e67e22" />
|
|
20
|
+
</marker>
|
|
21
|
+
<marker id="arrowhead-bi-start" markerWidth="10" markerHeight="10" refX="1" refY="3" orient="auto">
|
|
22
|
+
<polygon points="10 0, 0 3, 10 6" fill="#e67e22" />
|
|
23
|
+
</marker>
|
|
24
|
+
</defs>
|
|
25
|
+
|
|
26
|
+
<!-- Title -->
|
|
27
|
+
<text x="400" y="30" class="title">Hermes Core Architecture</text>
|
|
28
|
+
<text x="400" y="55" class="subtitle">Base abstractions for all messaging modules</text>
|
|
29
|
+
|
|
30
|
+
<!-- MessageClient Box -->
|
|
31
|
+
<rect x="50" y="100" width="200" height="120" rx="5" class="box"/>
|
|
32
|
+
<text x="150" y="130" class="label" style="fill: white; font-weight: bold;">MessageClient</text>
|
|
33
|
+
<text x="150" y="155" class="decorator">@Request('path')</text>
|
|
34
|
+
<text x="150" y="180" class="label" style="fill: white; font-size: 12px;">Sends requests</text>
|
|
35
|
+
<text x="150" y="200" class="label" style="fill: white; font-size: 12px;">Receives responses</text>
|
|
36
|
+
|
|
37
|
+
<!-- MessageHost Box -->
|
|
38
|
+
<rect x="550" y="100" width="200" height="120" rx="5" class="box-alt"/>
|
|
39
|
+
<text x="650" y="130" class="label" style="fill: white; font-weight: bold;">MessageHost</text>
|
|
40
|
+
<text x="650" y="155" class="decorator">@Listen('path')</text>
|
|
41
|
+
<text x="650" y="180" class="label" style="fill: white; font-size: 12px;">Listens for requests</text>
|
|
42
|
+
<text x="650" y="200" class="label" style="fill: white; font-size: 12px;">Sends responses</text>
|
|
43
|
+
|
|
44
|
+
<!-- Arrow between Client and Host -->
|
|
45
|
+
<path d="M 250 160 L 550 160" class="arrow"/>
|
|
46
|
+
<text x="400" y="150" class="label" style="font-size: 12px;">Request/Response</text>
|
|
47
|
+
|
|
48
|
+
<!-- MessageService Box -->
|
|
49
|
+
<rect x="300" y="270" width="200" height="100" rx="5" class="box-core"/>
|
|
50
|
+
<text x="400" y="300" class="label" style="fill: white; font-weight: bold;">MessageService</text>
|
|
51
|
+
<text x="400" y="325" class="label" style="fill: white; font-size: 12px;">= MessageClient</text>
|
|
52
|
+
<text x="400" y="345" class="label" style="fill: white; font-size: 12px;">+ MessageHost</text>
|
|
53
|
+
<text x="400" y="365" class="label" style="fill: white; font-size: 11px; font-style: italic;">(Bidirectional)</text>
|
|
54
|
+
|
|
55
|
+
<!-- Arrows from Client and Host to Service -->
|
|
56
|
+
<path d="M 150 220 L 350 270" class="arrow" style="stroke-dasharray: 5,5;"/>
|
|
57
|
+
<path d="M 650 220 L 450 270" class="arrow" style="stroke-dasharray: 5,5;"/>
|
|
58
|
+
|
|
59
|
+
</svg>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 500">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.title { font: bold 24px sans-serif; fill: #2c3e50; }
|
|
5
|
+
.subtitle { font: 16px sans-serif; fill: #7f8c8d; }
|
|
6
|
+
.label { font: 14px sans-serif; fill: #34495e; }
|
|
7
|
+
.code { font: 12px monospace; fill: #2c3e50; }
|
|
8
|
+
.window { fill: #ecf0f1; stroke: #95a5a6; stroke-width: 3; }
|
|
9
|
+
.titlebar { fill: #bdc3c7; }
|
|
10
|
+
.iframe-box { fill: #fff; stroke: #3498db; stroke-width: 2; }
|
|
11
|
+
.client { fill: #3498db; stroke: #2980b9; stroke-width: 2; }
|
|
12
|
+
.host { fill: #2ecc71; stroke: #27ae60; stroke-width: 2; }
|
|
13
|
+
.arrow { stroke: #e74c3c; stroke-width: 2.5; fill: none; marker-end: url(#arrowhead); }
|
|
14
|
+
.arrow-back { stroke: #9b59b6; stroke-width: 2.5; fill: none; marker-end: url(#arrowhead-back); }
|
|
15
|
+
text { text-anchor: middle; }
|
|
16
|
+
</style>
|
|
17
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
18
|
+
<polygon points="0 0, 10 3, 0 6" fill="#e74c3c" />
|
|
19
|
+
</marker>
|
|
20
|
+
<marker id="arrowhead-back" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
21
|
+
<polygon points="0 0, 10 3, 0 6" fill="#9b59b6" />
|
|
22
|
+
</marker>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<!-- Title -->
|
|
26
|
+
<text x="450" y="35" class="title">Iframe Communication</text>
|
|
27
|
+
<text x="450" y="60" class="subtitle">Parent window ↔ Child iframe messaging</text>
|
|
28
|
+
|
|
29
|
+
<!-- Parent Window -->
|
|
30
|
+
<rect x="50" y="100" width="350" height="350" rx="8" class="window"/>
|
|
31
|
+
<rect x="50" y="100" width="350" height="30" rx="8" class="titlebar"/>
|
|
32
|
+
<text x="225" y="122" class="label" style="fill: #34495e; font-weight: bold;">Parent Window</text>
|
|
33
|
+
|
|
34
|
+
<!-- Parent Host -->
|
|
35
|
+
<rect x="80" y="160" width="290" height="80" rx="5" class="host"/>
|
|
36
|
+
<text x="225" y="185" class="label" style="fill: white; font-weight: bold;">IframeMessageHost</text>
|
|
37
|
+
<text x="225" y="210" class="code" style="fill: white;">@Listen('greeting')</text>
|
|
38
|
+
<text x="225" y="230" class="label" style="fill: white; font-size: 11px;">Responds to iframe requests</text>
|
|
39
|
+
|
|
40
|
+
<!-- Iframe inside Parent -->
|
|
41
|
+
<rect x="90" y="270" width="270" height="160" rx="5" class="iframe-box"/>
|
|
42
|
+
<rect x="90" y="270" width="270" height="25" rx="5" class="titlebar"/>
|
|
43
|
+
<text x="225" y="288" class="label" style="font-size: 12px; font-weight: bold;">Child Iframe</text>
|
|
44
|
+
|
|
45
|
+
<!-- Iframe Client -->
|
|
46
|
+
<rect x="110" y="320" width="230" height="90" rx="5" class="client"/>
|
|
47
|
+
<text x="225" y="345" class="label" style="fill: white; font-weight: bold;">IframeMessageClient</text>
|
|
48
|
+
<text x="225" y="370" class="code" style="fill: white;">@Request('greeting')</text>
|
|
49
|
+
<text x="225" y="395" class="label" style="fill: white; font-size: 11px;">Sends requests to parent</text>
|
|
50
|
+
|
|
51
|
+
<!-- Communication Arrows -->
|
|
52
|
+
<path d="M 340 360 Q 420 300 420 200" class="arrow"/>
|
|
53
|
+
<text x="460" y="280" class="label" style="fill: #e74c3c; font-weight: bold;">Request</text>
|
|
54
|
+
|
|
55
|
+
<path d="M 400 200 Q 400 280 320 340" class="arrow-back"/>
|
|
56
|
+
<text x="360" y="260" class="label" style="fill: #9b59b6; font-weight: bold;">Response</text>
|
|
57
|
+
|
|
58
|
+
<!-- Right side: Code Examples -->
|
|
59
|
+
<rect x="500" y="100" width="350" height="160" rx="5" style="fill: #2c3e50; stroke: #34495e; stroke-width: 2;"/>
|
|
60
|
+
<text x="675" y="130" class="label" style="fill: white; font-weight: bold;">Iframe (Client)</text>
|
|
61
|
+
<text x="520" y="160" class="code" style="fill: #f39c12; text-anchor: start;">const client = new</text>
|
|
62
|
+
<text x="520" y="180" class="code" style="fill: #f39c12; text-anchor: start;"> IframeMessageClient();</text>
|
|
63
|
+
<text x="520" y="210" class="code" style="fill: #3498db; text-anchor: start;">client.sayHello('John')</text>
|
|
64
|
+
<text x="520" y="230" class="code" style="fill: #3498db; text-anchor: start;"> .subscribe(response =>)</text>
|
|
65
|
+
<text x="520" y="250" class="code" style="fill: #2ecc71; text-anchor: start;"> console.log(response));</text>
|
|
66
|
+
|
|
67
|
+
<rect x="500" y="280" width="350" height="160" rx="5" style="fill: #2c3e50; stroke: #34495e; stroke-width: 2;"/>
|
|
68
|
+
<text x="675" y="310" class="label" style="fill: white; font-weight: bold;">Parent (Host)</text>
|
|
69
|
+
<text x="520" y="340" class="code" style="fill: #f39c12; text-anchor: start;">const host = new</text>
|
|
70
|
+
<text x="520" y="360" class="code" style="fill: #f39c12; text-anchor: start;"> IframeMessageHost();</text>
|
|
71
|
+
<text x="520" y="390" class="code" style="fill: #2ecc71; text-anchor: start;">@Listen('greeting')</text>
|
|
72
|
+
<text x="520" y="410" class="code" style="fill: #3498db; text-anchor: start;">return of(`Hello ${data}!`);</text>
|
|
73
|
+
|
|
74
|
+
</svg>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 500">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.title { font: bold 24px sans-serif; fill: #2c3e50; }
|
|
5
|
+
.subtitle { font: 16px sans-serif; fill: #7f8c8d; }
|
|
6
|
+
.label { font: 14px sans-serif; fill: #34495e; }
|
|
7
|
+
.code { font: 12px monospace; fill: #2c3e50; }
|
|
8
|
+
.thread { fill: #ecf0f1; stroke: #95a5a6; stroke-width: 3; }
|
|
9
|
+
.service { fill: #9b59b6; stroke: #8e44ad; stroke-width: 2; }
|
|
10
|
+
.arrow { stroke: #e74c3c; stroke-width: 3; fill: none; marker-end: url(#arrowhead); }
|
|
11
|
+
.arrow-back { stroke: #2ecc71; stroke-width: 3; fill: none; marker-end: url(#arrowhead-back); }
|
|
12
|
+
text { text-anchor: middle; }
|
|
13
|
+
</style>
|
|
14
|
+
<marker id="arrowhead" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
15
|
+
<polygon points="0 0, 10 3, 0 6" fill="#e74c3c" />
|
|
16
|
+
</marker>
|
|
17
|
+
<marker id="arrowhead-back" markerWidth="10" markerHeight="10" refX="9" refY="3" orient="auto">
|
|
18
|
+
<polygon points="0 0, 10 3, 0 6" fill="#2ecc71" />
|
|
19
|
+
</marker>
|
|
20
|
+
</defs>
|
|
21
|
+
|
|
22
|
+
<!-- Title -->
|
|
23
|
+
<text x="450" y="35" class="title">Web Worker Communication</text>
|
|
24
|
+
<text x="450" y="60" class="subtitle">Bidirectional messaging between main thread and worker</text>
|
|
25
|
+
|
|
26
|
+
<!-- Main Thread -->
|
|
27
|
+
<rect x="50" y="100" width="350" height="350" rx="8" class="thread"/>
|
|
28
|
+
<text x="225" y="130" class="label" style="font-weight: bold; font-size: 18px;">Main Thread</text>
|
|
29
|
+
|
|
30
|
+
<!-- Main Service -->
|
|
31
|
+
<rect x="80" y="160" width="290" height="110" rx="5" class="service"/>
|
|
32
|
+
<text x="225" y="190" class="label" style="fill: white; font-weight: bold;">WorkerMessageService</text>
|
|
33
|
+
<text x="225" y="215" class="code" style="fill: #f39c12;">@Request('processData')</text>
|
|
34
|
+
<text x="225" y="235" class="label" style="fill: white; font-size: 11px;">Send to worker</text>
|
|
35
|
+
<text x="225" y="255" class="code" style="fill: #2ecc71;">@Listen('progress')</text>
|
|
36
|
+
|
|
37
|
+
<!-- Worker initialization -->
|
|
38
|
+
<rect x="80" y="300" width="290" height="120" rx="5" style="fill: #34495e;"/>
|
|
39
|
+
<text x="225" y="330" class="label" style="fill: white; font-weight: bold;">Worker Initialization</text>
|
|
40
|
+
<text x="100" y="360" class="code" style="fill: #3498db; text-anchor: start;">const worker = new</text>
|
|
41
|
+
<text x="100" y="380" class="code" style="fill: #3498db; text-anchor: start;"> Worker('./worker.js');</text>
|
|
42
|
+
<text x="100" y="405" class="code" style="fill: #f39c12; text-anchor: start;">new MainThread(worker);</text>
|
|
43
|
+
|
|
44
|
+
<!-- Worker Thread -->
|
|
45
|
+
<rect x="500" y="100" width="350" height="350" rx="8" class="thread"/>
|
|
46
|
+
<text x="675" y="130" class="label" style="font-weight: bold; font-size: 18px;">Worker Thread</text>
|
|
47
|
+
|
|
48
|
+
<!-- Worker Service -->
|
|
49
|
+
<rect x="530" y="160" width="290" height="110" rx="5" class="service"/>
|
|
50
|
+
<text x="675" y="190" class="label" style="fill: white; font-weight: bold;">WorkerMessageService</text>
|
|
51
|
+
<text x="675" y="215" class="code" style="fill: #2ecc71;">@Listen('processData')</text>
|
|
52
|
+
<text x="675" y="235" class="label" style="fill: white; font-size: 11px;">Process requests</text>
|
|
53
|
+
<text x="675" y="255" class="code" style="fill: #f39c12;">@Request('progress')</text>
|
|
54
|
+
|
|
55
|
+
<!-- Worker context -->
|
|
56
|
+
<rect x="530" y="300" width="290" height="120" rx="5" style="fill: #34495e;"/>
|
|
57
|
+
<text x="675" y="330" class="label" style="fill: white; font-weight: bold;">Self Context</text>
|
|
58
|
+
<text x="550" y="360" class="code" style="fill: #2ecc71; text-anchor: start;">// Inside worker.js</text>
|
|
59
|
+
<text x="550" y="380" class="code" style="fill: #3498db; text-anchor: start;">const service = new</text>
|
|
60
|
+
<text x="550" y="400" class="code" style="fill: #3498db; text-anchor: start;"> WorkerThread(); // auto self</text>
|
|
61
|
+
|
|
62
|
+
<!-- Communication Arrows -->
|
|
63
|
+
<!-- Request arrow -->
|
|
64
|
+
<path d="M 370 200 L 530 200" class="arrow"/>
|
|
65
|
+
<text x="450" y="190" class="label" style="fill: #e74c3c; font-weight: bold;">postMessage(request)</text>
|
|
66
|
+
|
|
67
|
+
<!-- Response arrow -->
|
|
68
|
+
<path d="M 530 240 L 370 240" class="arrow-back"/>
|
|
69
|
+
<text x="450" y="260" class="label" style="fill: #2ecc71; font-weight: bold;">postMessage(response)</text>
|
|
70
|
+
|
|
71
|
+
<!-- Progress update arrow -->
|
|
72
|
+
<path d="M 530 350 L 370 350" class="arrow"/>
|
|
73
|
+
<text x="450" y="340" class="label" style="fill: #e74c3c; font-weight: bold; font-size: 12px;">progress updates</text>
|
|
74
|
+
|
|
75
|
+
</svg>
|