@aigne/doc-smith 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,48 +1,1088 @@
1
+ - 使用 d2 展示架构关系、流程与组件交互
1
2
  - 使用 d2 图表解释复杂的概念 (```d2``` format),让页面内容展示形式更丰富
2
- - 使用 d2 展示架构关系、流程与组件交互,节点与连线文案保持简洁
3
- - d2 代码块必须完整且可渲染,避免使用未闭合的语法与奇异字符
4
- - d2 图表使用补充说明:
5
- - 示例:
6
- {% include "diy-examples.md" %}
7
- - 官方示例:
8
- {% include "official-examples.md" %}
9
- - 其他注意事项:
10
- - 图表应简洁明了,节点和连线命名准确。
11
- - 每个 d2 代码块必须完整闭合,避免语法错误。
12
- - 不要添加注释说明,因为生成的图片无法进行交互。
13
- - 不要随意更改节点和连线的颜色,这样会破坏配置好的主题。
14
- - 节点的名称尽量使用 " 进行包裹,避免出现异常。
15
- - bad: `SDK: @blocklet/js-sdk`
16
- - good: `SDK: "@blocklet/js-sdk"`
17
- - d2 中的 `shape` 只有这些值: `rectangle`, `square`, `page`, `parallelogram`, `document`, `cylinder`, `queue`, `package`, `step`, `callout`, `stored_data`, `person`, `diamond`, `oval`, `circle`, `hexagon`, `cloud`, `c4-person`,不要随意创建其他的 shape,会导致图表报错
18
- - 页面的整体布局使用 `direction: down`,这样能确保图表适合在网页中进行阅读;子图中可以根据情况来使用其他的方向布局,需要确保图表的整体效果看起来不会太宽
19
- - 如果一个对象中的元素太多了(超过3个),请使用 `grid-columns` 限制一下单行的列数,`grid-columns` 的值不要超过 3,例如
20
- ```d2
21
- "Instance": {
3
+ - 使用的 d2 的版本是 0.7.x,d2 官方的文档请查看 https://d2lang.com/tour/intro/
4
+ - 图表应简洁明了,节点和连线命名准确,节点与连线文案保持简洁,不要太长
5
+ - bad
6
+ ```d2
7
+ "TokenService": {
8
+ label: "TokenService (Handles token storage & refresh)"
9
+ shape: class
10
+ }
11
+ ```
12
+ - good
13
+ ```d2
14
+ "TokenService": {
15
+ label: "TokenService"
16
+ shape: class
17
+ }
18
+ ```
19
+ - 连线上的文字描述,尽量简洁明了,一般来说只需要使用单个词或两个词即可
20
+ - bad:
21
+ ```d2
22
+ "User Login" -> "Session Creation": "User submits login form with credentials"
23
+ ```
24
+ - good:
25
+ ```d2
26
+ "User Login" -> "Session Creation": "login"
27
+ ```
28
+ - d2 代码块必须完整且可渲染,避免使用未闭合的语法与奇异字符,避免语法错误
29
+ - 确保每一个节点都有 label 属性,用来表达节点的名称
30
+ - 如果节点的 label 过长,则应该使用 `\n` 来进行换行
31
+ - bad
32
+ ```d2
33
+ "AuthService": {
34
+ label: "AuthService (Handles user authentication, profile management, privacy settings, and related actions)"
35
+ shape: class
36
+ }
37
+ ```
38
+ - good
39
+ ```d2
40
+ "AuthService": {
41
+ label: "AuthService\n(Handles user authentication,\nprofile management, privacy settings,\nand related actions)"
42
+ shape: class
43
+ }
44
+ ```
45
+ - **非常重要** 如果节点的名称包含了特殊字符(如 `@`、` `、`/`, 空格等),请将名称中的特殊字符转换为 `-`,然后使用 label 来表达原始的名称,确保节点的名称一定不要使用 `"` 包裹
46
+ - bad:
47
+ ```d2
48
+ "@blocklet/js-sdk": {
49
+ shape: package
50
+
51
+ TokenService: {
52
+ shape: class
53
+ }
54
+ }
55
+ ```
56
+ - good:
57
+ ```d2
58
+ "blocklet-js-sdk": {
59
+ shape: package
60
+ label: "@blocklet/js-sdk
61
+
62
+ TokenService: {
63
+ shape: class
64
+ }
65
+ }
66
+ ```
67
+ - 必须确保每个节点和子节点是有名称的
68
+ - bad:
69
+ ```d2
70
+ "SDK Core Instance": {
71
+ shape: package
72
+ "TokenService": "Manages session and refresh tokens"
73
+ "Services": {
74
+ grid-columns: 2
75
+ "AuthService": ""
76
+ "BlockletService": ""
77
+ }
78
+ }
79
+ ```
80
+ - good:
81
+ ```d2
82
+ "SDK Core Instance": {
83
+ shape: package
84
+ "TokenService": "Manages session and refresh tokens"
85
+ "Services": {
86
+ grid-columns: 2
87
+ "AuthService": "AuthService"
88
+ "BlockletService": "BlockletService"
89
+ }
90
+ }
91
+ ```
92
+ - 不要为节点添加 `tooltip`,保持简单即可
93
+ - bad
94
+ ```d2
95
+ "AuthService": {
96
+ label: "AuthService"
97
+ tooltip: "Manages user profiles, privacy, and authentication actions"
98
+ shape: class
99
+ }
100
+ ```
101
+ - good
102
+ ```d2
103
+ "AuthService": {
104
+ label: "AuthService"
105
+ shape: class
106
+ }
107
+ ```
108
+ - 不要随意给节点/连线填充颜色,除非节点/连线有明确的 yes/no 的状态,此时可以添加 `error`, `warning`, `success` 之类的颜色
109
+ - bad
110
+ ```d2
111
+ "TokenService" {
112
+ shape: class
113
+ style.fill: "#fffbe6"
114
+ }
115
+ ```
116
+ - good
117
+ ```d2
118
+ "TokenService" {
119
+ shape: class
120
+ }
121
+ ```
122
+ - 对于单个节点和连线,不要使用 `animate: true`,避免有些地方有,但有些地方没有的情况(看起来会很奇怪)
123
+ - 连线的箭头方向必须正确,确保箭头指向关系的下游端
124
+ - 连线的样式,尽量保持一致,不要有些实线,有些虚线的情况,除非有明确的区分意义
125
+ - 页面的整体布局使用 `direction: down`,这样能确保图表适合在网页中进行阅读;子图中可以根据情况来使用其他的方向布局,需要确保图表的整体效果看起来不会太宽
126
+ - bad:
127
+ ```d2
128
+ direction: right
129
+
130
+ "online": {
131
+ shape: circle
132
+ style.fill: "#52c41a"
133
+ }
134
+
135
+ "offline": {
136
+ shape: circle
137
+ style.fill: "#faad14"
138
+ }
139
+
140
+ "expired": {
141
+ shape: circle
142
+ style.fill: "#ff4d4f"
143
+ }
144
+
145
+ "New Login" -> "online": "User authenticates"
146
+ "online" -> "offline": "User closes app/browser"
147
+ "online" -> "expired": "Token expires"
148
+ "offline" -> "online": "User returns"
149
+ "offline" -> "expired": "Extended inactivity"
150
+ ```
151
+ - good:
152
+ ```d2
153
+ direction: down
154
+
155
+ "online": {
156
+ shape: circle
157
+ style.fill: "#52c41a"
158
+ }
159
+
160
+ "offline": {
161
+ shape: circle
162
+ style.fill: "#faad14"
163
+ }
164
+
165
+ "expired": {
166
+ shape: circle
167
+ style.fill: "#ff4d4f"
168
+ }
169
+
170
+ "New Login" -> "online": "User authenticates"
171
+ "online" -> "offline": "User closes app/browser"
172
+ "online" -> "expired": "Token expires"
173
+ "offline" -> "online": "User returns"
174
+ "offline" -> "expired": "Extended inactivity"
175
+ ```
176
+ - 如果一个节点中的字节点太多了(超过3个),请使用 `grid-columns` 限制一下单行的列数,`grid-columns` 的值优先使用2,最大不要超过 3,例如
177
+ - good:
178
+ ```d2
179
+ "Instance": {
180
+ grid-columns: 3
181
+ "A": "A"
182
+ "B": "B"
183
+ "C": "C"
184
+ "D": "D"
185
+ "E": "E"
186
+ }
187
+ ```
188
+ ```d2
189
+ "Instance": {
190
+ grid-columns: 2
191
+ "A": "A"
192
+ "B": "B"
193
+ "C": "C"
194
+ "D": "D"
195
+ }
196
+ ```
197
+ - 每一个容器节点中,最好设置 `grid-columns`
198
+ - bad:
199
+ ```d2
200
+ direction: down
201
+
202
+ "SDK": "@blocklet/js-sdk" {
203
+ shape: package
204
+
205
+ "Core Instance": {
206
+ shape: rectangle
207
+ "BlockletSDK": "Main SDK Class"
208
+ }
209
+
210
+ "Services": {
211
+ grid-columns: 3
212
+ "AuthService": "User Authentication" {
213
+ shape: class
214
+ }
215
+ "TokenService": "Token Management" {
216
+ shape: class
217
+ }
218
+ "UserSessionService": "Session Management" {
219
+ shape: class
220
+ }
221
+ "BlockletService": "Blocklet Metadata" {
222
+ shape: class
223
+ }
224
+ "FederatedService": "Federated Login" {
225
+ shape: class
226
+ }
227
+ }
228
+
229
+ "HTTP Clients": {
230
+ grid-columns: 2
231
+ "createAxios": "Axios-based Client" {
232
+ shape: rectangle
233
+ }
234
+ "createFetch": "Fetch-based Client" {
235
+ shape: rectangle
236
+ }
237
+ }
238
+ }
239
+
240
+ "Your App": "Application Code" {
241
+ shape: rectangle
242
+ }
243
+
244
+ "Blocklet Services": "Remote APIs" {
245
+ shape: cylinder
246
+ }
247
+
248
+ "Your App" -> "SDK": "Import & Use"
249
+ "SDK" -> "Blocklet Services": "Authenticated Requests"
250
+ "Blocklet Services" -> "SDK": "Responses & Tokens"
251
+ ```
252
+ - good:
253
+ ```d2
254
+ direction: down
255
+
256
+ "SDK": "@blocklet/js-sdk" {
257
+ shape: package
258
+ grid-columns: 1
259
+
260
+ "Core Instance": {
261
+ shape: rectangle
262
+ "BlockletSDK": "Main SDK Class"
263
+ }
264
+
265
+ "Services": {
266
+ grid-columns: 3
267
+ "AuthService": "User Authentication" {
268
+ shape: class
269
+ }
270
+ "TokenService": "Token Management" {
271
+ shape: class
272
+ }
273
+ "UserSessionService": "Session Management" {
274
+ shape: class
275
+ }
276
+ "BlockletService": "Blocklet Metadata" {
277
+ shape: class
278
+ }
279
+ "FederatedService": "Federated Login" {
280
+ shape: class
281
+ }
282
+ }
283
+
284
+ "HTTP Clients": {
285
+ grid-columns: 2
286
+ "createAxios": "Axios-based Client" {
287
+ shape: rectangle
288
+ }
289
+ "createFetch": "Fetch-based Client" {
290
+ shape: rectangle
291
+ }
292
+ }
293
+ }
294
+
295
+ "Your App": "Application Code" {
296
+ shape: rectangle
297
+ }
298
+
299
+ "Blocklet Services": "Remote APIs" {
300
+ shape: cylinder
301
+ }
302
+
303
+ "Your App" -> "SDK": "Import & Use"
304
+ "SDK" -> "Blocklet Services": "Authenticated Requests"
305
+ "Blocklet Services" -> "SDK": "Responses & Tokens"
306
+ ```
307
+ - 必须保证一个图中,所有的节点都是有关联的,不需要为图表设置 legend,如果有节点不存在关联性,则应该移除这些节点,或者拆分成多个独立的图表
308
+ - bad:
309
+ ```d2
310
+ direction: down
311
+
312
+ "Your App": {
313
+ shape: rectangle
314
+ }
315
+
316
+ "SDK Request Helper": {
317
+ label: "@blocklet/js-sdk (createAxios / createFetch)"
318
+ shape: package
319
+ }
320
+
321
+ "Blocklet Service": {
322
+ shape: cylinder
323
+ }
324
+
325
+ "Token Refresh Endpoint": {
326
+ label: "/api/did/refreshSession"
327
+ shape: rectangle
328
+ }
329
+
330
+ "Your App" -> "SDK Request Helper": "1. Make API Call (e.g., /api/profile)"
331
+
332
+ "SDK Request Helper" -> "Blocklet Service": "2. Adds Auth Header & Sends Request" {
333
+ style {
334
+ stroke-dash: 2
335
+ }
336
+ }
337
+
338
+ "Success Path": {
339
+ style.stroke: "#52c41a"
340
+
341
+ "Blocklet Service" -> "SDK Request Helper": "3a. 200 OK (Token Valid)"
342
+ "SDK Request Helper" -> "Your App": "4a. Returns Data"
343
+ }
344
+
345
+
346
+ "Token Renewal Path": {
347
+ style.stroke: "#faad14"
348
+
349
+ "Blocklet Service" -> "SDK Request Helper": "3b. 401 Unauthorized (Token Expired)"
350
+ "SDK Request Helper" -> "Token Refresh Endpoint": "4b. Request New Token"
351
+ "Token Refresh Endpoint" -> "SDK Request Helper": "5b. New Tokens"
352
+ "SDK Request Helper" -> "Blocklet Service": "6b. Retry Original Request"
353
+ "Blocklet Service" -> "SDK Request Helper": "7b. 200 OK" {
354
+ style.stroke: "#52c41a"
355
+ }
356
+ "SDK Request Helper" -> "Your App": "8b. Returns Data Transparently" {
357
+ style.stroke: "#52c41a"
358
+ }
359
+ }
360
+ ```
361
+ - good:
362
+ ```d2
363
+ direction: down
364
+
365
+ "Your App": {
366
+ shape: rectangle
367
+ }
368
+
369
+ "SDK Request Helper": {
370
+ label: "@blocklet/js-sdk (createAxios / createFetch)"
371
+ shape: package
372
+ }
373
+
374
+ "Blocklet Service": {
375
+ shape: cylinder
376
+ }
377
+
378
+ "Token Refresh Endpoint": {
379
+ label: "/api/did/refreshSession"
380
+ shape: rectangle
381
+ }
382
+
383
+ "Your App" -> "SDK Request Helper": "1. Make API Call (e.g., /api/profile)"
384
+
385
+ "SDK Request Helper" -> "Blocklet Service": "2. Adds Auth Header & Sends Request" {
386
+ style {
387
+ stroke-dash: 2
388
+ }
389
+ }
390
+ ```
391
+ ```d2
392
+ "Success Path": {
393
+ style.stroke: "#52c41a"
394
+
395
+ "Blocklet Service" -> "SDK Request Helper": "3a. 200 OK (Token Valid)"
396
+ "SDK Request Helper" -> "Your App": "4a. Returns Data"
397
+ }
398
+ ```
399
+ ```d2
400
+ "Token Renewal Path": {
401
+ style.stroke: "#faad14"
402
+
403
+ "Blocklet Service" -> "SDK Request Helper": "3b. 401 Unauthorized (Token Expired)"
404
+ "SDK Request Helper" -> "Token Refresh Endpoint": "4b. Request New Token"
405
+ "Token Refresh Endpoint" -> "SDK Request Helper": "5b. New Tokens"
406
+ "SDK Request Helper" -> "Blocklet Service": "6b. Retry Original Request"
407
+ "Blocklet Service" -> "SDK Request Helper": "7b. 200 OK" {
408
+ style.stroke: "#52c41a"
409
+ }
410
+ "SDK Request Helper" -> "Your App": "8b. Returns Data Transparently" {
411
+ style.stroke: "#52c41a"
412
+ }
413
+ }
414
+ ```
415
+ - 当有关联关系的节点,处于一个节点内部时,则它们的关联关系也应该写在节点内部
416
+ - bad
417
+ ```d2
418
+ direction: down
419
+
420
+ "@blocklet/js-sdk": {
421
+ shape: package
422
+
423
+ "Main SDK Instance": {
424
+ shape: rectangle
425
+ "BlockletSDK Class": "Main entry point"
426
+ "getBlockletSDK()": "Singleton factory"
427
+ }
428
+
429
+ "HTTP Clients": {
430
+ shape: rectangle
431
+ grid-columns: 2
432
+ "createAxios()": "Axios-based client"
433
+ "createFetch()": "Fetch-based client"
434
+ }
435
+
436
+ "Core Services": {
437
+ shape: rectangle
438
+ grid-columns: 3
439
+ "AuthService": "User authentication"
440
+ "TokenService": "Token management"
441
+ "BlockletService": "Blocklet metadata"
442
+ "UserSessionService": "Session management"
443
+ "FederatedService": "Federated login"
444
+ "ComponentService": "Component utilities"
445
+ }
446
+ }
447
+
448
+ "Main SDK Instance" -> "HTTP Clients": "Uses for requests"
449
+ "Main SDK Instance" -> "Core Services": "Provides access to"
450
+ "HTTP Clients" -> "Core Services": "Configured with"
451
+ ```
452
+ - good
453
+ ```d2
454
+ direction: down
455
+
456
+ "@blocklet/js-sdk": {
457
+ shape: package
458
+
459
+ "Main SDK Instance": {
460
+ shape: rectangle
461
+ "BlockletSDK Class": "Main entry point"
462
+ "getBlockletSDK()": "Singleton factory"
463
+ }
464
+
465
+ "HTTP Clients": {
466
+ shape: rectangle
467
+ grid-columns: 2
468
+ "createAxios()": "Axios-based client"
469
+ "createFetch()": "Fetch-based client"
470
+ }
471
+
472
+ "Core Services": {
473
+ shape: rectangle
474
+ grid-columns: 3
475
+ "AuthService": "User authentication"
476
+ "TokenService": "Token management"
477
+ "BlockletService": "Blocklet metadata"
478
+ "UserSessionService": "Session management"
479
+ "FederatedService": "Federated login"
480
+ "ComponentService": "Component utilities"
481
+ }
482
+
483
+ "Main SDK Instance" -> "HTTP Clients": "Uses for requests"
484
+ "Main SDK Instance" -> "Core Services": "Provides access to"
485
+ "HTTP Clients" -> "Core Services": "Configured with"
486
+ }
487
+ ```
488
+ - bad:
489
+ ```d2
490
+ direction: down
491
+
492
+ "Your App": {
493
+ shape: rectangle
494
+ }
495
+
496
+ "SDK Request Helper": {
497
+ label: "@blocklet/js-sdk (createAxios / createFetch)"
498
+ shape: package
499
+ }
500
+
501
+ "Blocklet Service": {
502
+ shape: cylinder
503
+ }
504
+
505
+
506
+ "Your App" -> "SDK Request Helper": "1. Make API Call (e.g., /api/profile)"
507
+
508
+ "SDK Request Helper" -> "Blocklet Service": "2. Adds Auth Header & Sends Request" {
509
+ style {
510
+ stroke-dash: 2
511
+ }
512
+ }
513
+
514
+ "Token Renewal Path": {
515
+ style.stroke: "#faad14"
516
+
517
+ "Blocklet Service" -> "SDK Request Helper": "3. 401 Unauthorized (Token Expired)"
518
+ "SDK Request Helper" -> "Token Refresh Endpoint": "4. Request New Token"
519
+ "Token Refresh Endpoint" -> "SDK Request Helper": "5. New Tokens Received"
520
+ "SDK Request Helper" -> "Blocklet Service": "6. Retry Original Request with New Token"
521
+ "Blocklet Service" -> "SDK Request Helper": "7. 200 OK" {
522
+ style.stroke: "#52c41a"
523
+ }
524
+ "SDK Request Helper" -> "Your App": "8. Returns Data Transparently" {
525
+ style.stroke: "#52c41a"
526
+ }
527
+ }
528
+ ```
529
+ - good:
530
+ ```d2
531
+ direction: down
532
+
533
+ "Your App": {
534
+ shape: rectangle
535
+ }
536
+
537
+ "SDK Request Helper": {
538
+ label: "@blocklet/js-sdk (createAxios / createFetch)"
539
+ shape: package
540
+ }
541
+
542
+ "Blocklet Service": {
543
+ shape: cylinder
544
+ }
545
+
546
+
547
+ "Your App" -> "SDK Request Helper": "1. Make API Call (e.g., /api/profile)"
548
+
549
+ "SDK Request Helper" -> "Blocklet Service": "2. Adds Auth Header & Sends Request" {
550
+ style {
551
+ stroke-dash: 2
552
+ }
553
+ }
554
+
555
+ "Blocklet Service" -> "SDK Request Helper": "3. 401 Unauthorized (Token Expired)"
556
+ "SDK Request Helper" -> "Token Refresh Endpoint": "4. Request New Token"
557
+ "Token Refresh Endpoint" -> "SDK Request Helper": "5. New Tokens Received"
558
+ "SDK Request Helper" -> "Blocklet Service": "6. Retry Original Request with New Token"
559
+ "Blocklet Service" -> "SDK Request Helper": "7. 200 OK" {
560
+ style.stroke: "#52c41a"
561
+ }
562
+ "SDK Request Helper" -> "Your App": "8. Returns Data Transparently" {
563
+ style.stroke: "#52c41a"
564
+ }
565
+ ```
566
+ - 如果整个图表只有一个容器节点,就不要增加这个容器节点,直接将内部的节点放在最外层
567
+ - bad:
568
+ ```d2
569
+ direction: down
570
+
571
+ "User Sessions Flow": {
572
+ shape: package
573
+ grid-columns: 1
574
+
575
+ "User Login": {
576
+ shape: person
577
+ style.fill: "#e6f7ff"
578
+ }
579
+
580
+ "Session Creation": {
581
+ shape: rectangle
582
+ style.fill: "#f6ffed"
583
+ }
584
+
585
+ "Session Storage": {
586
+ shape: cylinder
587
+ style.fill: "#fff7e6"
588
+ }
589
+
590
+ "Multi-Device Access": {
591
+ shape: package
592
+ grid-columns: 3
593
+ "Web Browser": {
594
+ shape: rectangle
595
+ }
596
+ "Mobile App": {
597
+ shape: rectangle
598
+ }
599
+ "Desktop App": {
600
+ shape: rectangle
601
+ }
602
+ }
603
+ "User Login" -> "Session Creation": "Authenticate"
604
+ "Session Creation" -> "Session Storage": "Store session"
605
+ "Session Storage" -> "Multi-Device Access": "Access from devices"
606
+ }
607
+ ```
608
+ - good:
609
+ ```d2
610
+ direction: down
611
+
612
+ "User Login": {
613
+ shape: person
614
+ style.fill: "#e6f7ff"
615
+ }
616
+
617
+ "Session Creation": {
618
+ shape: rectangle
619
+ style.fill: "#f6ffed"
620
+ }
621
+
622
+ "Session Storage": {
623
+ shape: cylinder
624
+ style.fill: "#fff7e6"
625
+ }
626
+
627
+ "Multi-Device Access": {
628
+ shape: package
629
+ grid-columns: 3
630
+ "Web Browser": {
631
+ shape: rectangle
632
+ }
633
+ "Mobile App": {
634
+ shape: rectangle
635
+ }
636
+ "Desktop App": {
637
+ shape: rectangle
638
+ }
639
+ }
640
+ "User Login" -> "Session Creation": "Authenticate"
641
+ "Session Creation" -> "Session Storage": "Store session"
642
+ "Session Storage" -> "Multi-Device Access": "Access from devices"
643
+ ```
644
+ - 某些情况下,单纯的设置 `direction: down` 还无法控制图表的整体方向,可以再结合 `grid-columns: 1` 来进行设置
645
+ - bad:
646
+ ```d2
647
+ direction: down
648
+
649
+ "Your Application": {
650
+ shape: rectangle
651
+ }
652
+
653
+ "@blocklet/js-sdk": {
654
+ shape: package
655
+ grid-columns: 1
656
+
657
+ "AuthService": {
658
+ shape: class
659
+ }
660
+ }
661
+
662
+ "Blocklet API Endpoints": {
663
+ shape: cylinder
664
+ grid-columns: 2
665
+ "/api/user/profile": {}
666
+ "/api/user/privacy/config": {}
667
+ "/api/user/notification/config": {}
668
+ "/api/user/logout": {}
669
+ "/api/user/follow/{did}": {}
670
+ "/api/user": {}
671
+ }
672
+
673
+ "Your Application" -> "@blocklet/js-sdk".AuthService: "e.g., sdk.auth.getProfile()"
674
+ "@blocklet/js-sdk".AuthService -> "Blocklet API Endpoints": "Makes authenticated API calls"
675
+ ```
676
+ - good:
677
+ ```d2
678
+ direction: down
679
+ grid-columns: 1
680
+
681
+ "Your Application": {
682
+ shape: rectangle
683
+ }
684
+
685
+ "@blocklet/js-sdk": {
686
+ shape: package
687
+ grid-columns: 1
688
+
689
+ "AuthService": {
690
+ shape: class
691
+ }
692
+ }
693
+
694
+ "Blocklet API Endpoints": {
695
+ shape: cylinder
696
+ grid-columns: 2
697
+ "/api/user/profile": {}
698
+ "/api/user/privacy/config": {}
699
+ "/api/user/notification/config": {}
700
+ "/api/user/logout": {}
701
+ "/api/user/follow/{did}": {}
702
+ "/api/user": {}
703
+ }
704
+
705
+ "Your Application" -> "@blocklet/js-sdk".AuthService: "e.g., sdk.auth.getProfile()"
706
+ "@blocklet/js-sdk".AuthService -> "Blocklet API Endpoints": "Makes authenticated API calls"
707
+ ```
708
+ - **非常重要** 当容器节点中子节点个数与 `grid-columns` 值相同时,则应该去掉容器节点中的 `grid-columns` 字段
709
+ - bad:
710
+ ```d2
711
+ "@blocklet/js-sdk": {
712
+ shape: package
713
+ grid-columns: 1
714
+
715
+ "AuthService": {
716
+ shape: class
717
+ }
718
+ }
719
+ ```
720
+ - good:
721
+ ```d2
722
+ "@blocklet/js-sdk": {
723
+ shape: package
724
+
725
+ "AuthService": {
726
+ shape: class
727
+ }
728
+ }
729
+ ```
730
+ - bad:
731
+ ```d2
732
+ "Browser Storage": {
733
+ shape: package
734
+ grid-columns: 2
735
+
736
+ "Cookies": {
737
+ shape: document
738
+ "Session Token": {}
739
+ }
740
+
741
+ "LocalStorage": {
742
+ shape: stored_data
743
+ "Refresh Token": {}
744
+ }
745
+ }
746
+ ```
747
+ - good:
748
+ ```d2
749
+ "Browser Storage": {
750
+ shape: package
751
+
752
+ "Cookies": {
753
+ shape: document
754
+ "Session Token": {}
755
+ }
756
+
757
+ "LocalStorage": {
758
+ shape: stored_data
759
+ "Refresh Token": {}
760
+ }
761
+ }
762
+ ```
763
+ - 当一个容器节点外部有节点与当前容器节点内部节点相互关联时,应该将这些节点放在同一层级
764
+ - bad:
765
+ ```d2
766
+ direction: down
767
+
768
+ "Federated Login Group": {
769
+ shape: package
770
+
771
+ "Master App": {
772
+ shape: rectangle
773
+ style.stroke: "#0052cc"
774
+ style.stroke-width: 2
775
+ "Provides central authentication"
776
+ }
777
+
778
+ "Member App 1 (Current App)": {
779
+ shape: rectangle
780
+ "User interacts here"
781
+ }
782
+
783
+ "Member App 2": {
784
+ shape: rectangle
785
+ }
786
+
787
+ "Master App" -> "Member App 1 (Current App)": "Shares user session"
788
+ "Master App" -> "Member App 2": "Shares user session"
789
+ }
790
+
791
+ User: {
792
+ shape: person
793
+ }
794
+
795
+ User -> "Member App 1 (Current App)": "Logs in via Master App"
796
+ ```
797
+ - good:
798
+ ```d2
799
+ direction: down
800
+
801
+ "Federated Login Group": {
802
+ shape: package
803
+
804
+ "Master App": {
805
+ shape: rectangle
806
+ style.stroke: "#0052cc"
807
+ style.stroke-width: 2
808
+ "Provides central authentication"
809
+ }
810
+
811
+ "Member App 1 (Current App)": {
812
+ shape: rectangle
813
+ "User interacts here"
814
+ }
815
+
816
+ "Member App 2": {
817
+ shape: rectangle
818
+ }
819
+
820
+ "Master App" -> "Member App 1 (Current App)": "Shares user session"
821
+ "Master App" -> "Member App 2": "Shares user session"
822
+
823
+ User: {
824
+ shape: person
825
+ }
826
+
827
+ User -> "Member App 1 (Current App)": "Logs in via Master App"
828
+ }
829
+
830
+ ```
831
+ - **非常重要** 当存在多层容器节点嵌套时,外层的容器节点应该使用 `grid-columns: 1`
832
+ - bad:
833
+ ```d2
834
+ direction: down
835
+
836
+ "User Account": {
837
+ shape: person
838
+ }
839
+
840
+ "Sessions": {
841
+ shape: package
842
+ grid-columns: 3
843
+
844
+ "Web Browser Session": {
845
+ shape: rectangle
846
+ "IP: 192.168.1.10"
847
+ "UA: Chrome on macOS"
848
+ "Status: online"
849
+ }
850
+
851
+ "iOS App Session": {
852
+ shape: rectangle
853
+ "IP: 10.0.0.5"
854
+ "UA: MyApp/1.2 iOS"
855
+ "Status: online"
856
+ }
857
+
858
+ "Old Laptop Session": {
859
+ shape: rectangle
860
+ "IP: 172.16.0.20"
861
+ "UA: Firefox on Windows"
862
+ "Status: expired"
863
+ }
864
+ }
865
+
866
+ "User Account" -> "Sessions": "Has multiple"
867
+ ```
868
+ - good:
869
+ ```d2
870
+ direction: down
871
+
872
+ "User Account": {
873
+ shape: person
874
+ }
875
+
876
+ "Sessions": {
877
+ shape: package
878
+ grid-columns: 1
879
+
880
+ "Web Browser Session": {
881
+ shape: rectangle
882
+ "IP: 192.168.1.10"
883
+ "UA: Chrome on macOS"
884
+ "Status: online"
885
+ }
886
+
887
+ "iOS App Session": {
888
+ shape: rectangle
889
+ "IP: 10.0.0.5"
890
+ "UA: MyApp/1.2 iOS"
891
+ "Status: online"
892
+ }
893
+
894
+ "Old Laptop Session": {
895
+ shape: rectangle
896
+ "IP: 172.16.0.20"
897
+ "UA: Firefox on Windows"
898
+ "Status: expired"
899
+ }
900
+ }
901
+
902
+ "User Account" -> "Sessions": "Has multiple"
903
+ ```
904
+ - 当一个节点容器中包含了其他的节点容器,建议使用 `grid-gap` 来增加各个节点容器的距离,尽量大于 `100`
905
+ - bad:
906
+ ```d2
907
+ direction: down
908
+
909
+ "Your Application": {
910
+ shape: rectangle
911
+ }
912
+
913
+ "SDK: @blocklet/js-sdk": {
914
+ shape: package
915
+ grid-columns: 1
916
+
917
+ "HTTP Clients": {
918
+ shape: rectangle
919
+ grid-columns: 2
920
+ "createAxios()": "Axios-based client"
921
+ "createFetch()": "Fetch-based client"
922
+ }
923
+
924
+ "Core Services": {
925
+ shape: rectangle
926
+ grid-columns: 3
927
+ "AuthService": "User & Auth"
928
+ "TokenService": "Token Management"
929
+ "UserSessionService": "Session Data"
930
+ "BlockletService": "Blocklet Metadata"
931
+ "FederatedService": "Federated Login"
932
+ }
933
+
934
+ "HTTP Clients" -> "Core Services".TokenService: "Uses for auth tokens"
935
+ }
936
+
937
+ "Blocklet Services": {
938
+ shape: cylinder
939
+ "Remote APIs"
940
+ }
941
+
942
+ "Your Application" -> "SDK: @blocklet/js-sdk": "Imports & Initializes"
943
+ "SDK: @blocklet/js-sdk" -> "Blocklet Services": "Makes authenticated requests"
944
+ ```
945
+ - bad:
946
+ ```d2
947
+ direction: down
948
+
949
+ "Your Application": {
950
+ shape: rectangle
951
+ }
952
+
953
+ "SDK: @blocklet/js-sdk": {
954
+ shape: package
955
+ grid-columns: 1
956
+ grid-gap: 100
957
+
958
+ "HTTP Clients": {
959
+ shape: rectangle
960
+ grid-columns: 2
961
+ "createAxios()": "Axios-based client"
962
+ "createFetch()": "Fetch-based client"
963
+ }
964
+
965
+ "Core Services": {
966
+ shape: rectangle
22
967
  grid-columns: 3
23
- "A": "A"
24
- "B": "B"
25
- "C": "C"
26
- "D": "D"
27
- "E": "E"
28
- }
29
- ```
30
- - 尽量保证一个图中,只有一个关联所有元素的图,不要产生多个没有任何连接的子图
31
- - 确保 `style` 中的值都是可用的,错误的字段会导致图片生成失败
32
- - 尽量确保每个子元素是有名称的
33
- - bad:
34
- ```d2
35
- "SDK Core Instance": {
968
+ "AuthService": "User & Auth"
969
+ "TokenService": "Token Management"
970
+ "UserSessionService": "Session Data"
971
+ "BlockletService": "Blocklet Metadata"
972
+ "FederatedService": "Federated Login"
973
+ }
974
+
975
+ "HTTP Clients" -> "Core Services".TokenService: "Uses for auth tokens"
976
+ }
977
+
978
+ "Blocklet Services": {
979
+ shape: cylinder
980
+ "Remote APIs"
981
+ }
982
+
983
+ "Your Application" -> "SDK: @blocklet/js-sdk": "Imports & Initializes"
984
+ "SDK: @blocklet/js-sdk" -> "Blocklet Services": "Makes authenticated requests"
985
+ ```
986
+ - 如果节点的 `shape: person`,则不要加任何其他内部的文字
987
+ - bad:
988
+ ```d2
989
+ "User Account": {
990
+ shape: person
991
+ "did:z... (John Doe)"
992
+ }
993
+ ```
994
+ - good:
995
+ ```d2
996
+ "User Account": {
997
+ shape: person
998
+ }
999
+ ```
1000
+ - **非常重要** 在绘制连线的时候,一定要注意连接的节点的 ID 到底是什么,它可能有多个层级,但一定要弄清楚关系才能添加连线
1001
+ - bad:
1002
+ ```d2
1003
+ direction: down
1004
+
1005
+ "User-Browser": {
1006
+ label: "User's Browser"
1007
+ shape: rectangle
1008
+
1009
+ "React-App": {
1010
+ label: "Your React App"
1011
+ shape: rectangle
1012
+
1013
+ "Uploader-Component": {
1014
+ label: "@blocklet/uploader"
36
1015
  shape: package
37
- "TokenService": "Manages session and refresh tokens"
38
- "Services": {
39
- grid-columns: 2
40
- "AuthService": ""
41
- "BlockletService": ""
42
- "FederatedService": ""
43
- "UserSessionService": ""
44
- }
45
- }
46
- ```
47
- - 使用 animate: true 可以让图表增加动画效果,看起来效果更好
48
- - 针对节点的状态(yes or no),可以给定不同的颜色(error,warning,success)来增强表现力
1016
+ }
1017
+ }
1018
+ }
1019
+
1020
+ "Blocklet-Server": {
1021
+ label: "Your Blocklet Server"
1022
+ shape: rectangle
1023
+
1024
+ "Express-App": {
1025
+ label: "Your Express App"
1026
+ shape: rectangle
1027
+
1028
+ "Uploader-Middleware": {
1029
+ label: "@blocklet/uploader-server"
1030
+ shape: package
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ "File-System": {
1036
+ label: "Storage\n(e.g., File System)"
1037
+ shape: cylinder
1038
+ }
1039
+
1040
+ "Uploader-Component" -> "Uploader-Middleware": "HTTP POST Request\n(File Upload)"
1041
+ "Uploader-Middleware" -> "File-System": "Saves File"
1042
+ ```
1043
+ - good:
1044
+ ```d2
1045
+ direction: down
1046
+
1047
+ "User-Browser": {
1048
+ label: "User's Browser"
1049
+ shape: rectangle
1050
+
1051
+ "React-App": {
1052
+ label: "Your React App"
1053
+ shape: rectangle
1054
+
1055
+ "Uploader-Component": {
1056
+ label: "@blocklet/uploader"
1057
+ shape: package
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+ "Blocklet-Server": {
1063
+ label: "Your Blocklet Server"
1064
+ shape: rectangle
1065
+
1066
+ "Express-App": {
1067
+ label: "Your Express App"
1068
+ shape: rectangle
1069
+
1070
+ "Uploader-Middleware": {
1071
+ label: "@blocklet/uploader-server"
1072
+ shape: package
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ "File-System": {
1078
+ label: "Storage\n(e.g., File System)"
1079
+ shape: cylinder
1080
+ }
1081
+
1082
+ User-Browser.React-App.Uploader-Component -> Blocklet-Server.Express-App.Uploader-Middleware: "HTTP POST Request\n(File Upload)"
1083
+ Blocklet-Server.Express-App.Uploader-Middleware -> "File-System": "Saves File"
1084
+ ```
1085
+ - 对于节点 shape 的选择,可以参考
1086
+ {% include "shape-rules.md" %}
1087
+ - 示例参考:
1088
+ {% include "diy-examples.md" %}