@co0ontty/wand 1.10.0 → 1.14.3
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 +48 -12
- package/dist/config.d.ts +2 -1
- package/dist/config.js +51 -0
- package/dist/message-truncator.d.ts +16 -0
- package/dist/message-truncator.js +76 -0
- package/dist/process-manager.d.ts +4 -0
- package/dist/process-manager.js +74 -21
- package/dist/server-session-routes.js +29 -1
- package/dist/server.js +276 -11
- package/dist/structured-session-manager.d.ts +2 -0
- package/dist/structured-session-manager.js +10 -0
- package/dist/types.d.ts +28 -0
- package/dist/web-ui/content/scripts.js +799 -66
- package/dist/web-ui/content/styles.css +247 -27
- package/dist/ws-broadcast.d.ts +3 -2
- package/dist/ws-broadcast.js +8 -2
- package/package.json +1 -1
|
@@ -1080,6 +1080,46 @@
|
|
|
1080
1080
|
padding-right: 64px;
|
|
1081
1081
|
}
|
|
1082
1082
|
|
|
1083
|
+
.session-title-row {
|
|
1084
|
+
display: flex;
|
|
1085
|
+
align-items: flex-start;
|
|
1086
|
+
justify-content: space-between;
|
|
1087
|
+
gap: 8px;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
.session-title-row .session-title,
|
|
1091
|
+
.session-title-row .session-command {
|
|
1092
|
+
flex: 1;
|
|
1093
|
+
min-width: 0;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
.session-time {
|
|
1097
|
+
flex-shrink: 0;
|
|
1098
|
+
font-size: 0.6875rem;
|
|
1099
|
+
color: var(--text-muted);
|
|
1100
|
+
white-space: nowrap;
|
|
1101
|
+
line-height: 1.4;
|
|
1102
|
+
padding-top: 1px;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.session-activity {
|
|
1106
|
+
font-size: 0.6875rem;
|
|
1107
|
+
color: var(--accent);
|
|
1108
|
+
white-space: nowrap;
|
|
1109
|
+
overflow: hidden;
|
|
1110
|
+
text-overflow: ellipsis;
|
|
1111
|
+
line-height: 1.3;
|
|
1112
|
+
opacity: 0.85;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
.session-recovery-hint {
|
|
1116
|
+
font-size: 0.625rem;
|
|
1117
|
+
color: var(--text-muted);
|
|
1118
|
+
background: rgba(150, 118, 85, 0.08);
|
|
1119
|
+
padding: 1px 5px;
|
|
1120
|
+
border-radius: 3px;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1083
1123
|
/* ===== 会话操作按钮 ===== */
|
|
1084
1124
|
.session-actions {
|
|
1085
1125
|
position: absolute;
|
|
@@ -2102,6 +2142,7 @@
|
|
|
2102
2142
|
padding: 10px;
|
|
2103
2143
|
overflow: hidden;
|
|
2104
2144
|
min-height: 0;
|
|
2145
|
+
min-width: 0;
|
|
2105
2146
|
margin: 0 6px 6px;
|
|
2106
2147
|
border-radius: var(--radius-md);
|
|
2107
2148
|
border: 1px solid rgba(140, 110, 85, 0.35);
|
|
@@ -2118,22 +2159,16 @@
|
|
|
2118
2159
|
align-items: stretch;
|
|
2119
2160
|
}
|
|
2120
2161
|
|
|
2121
|
-
.terminal-container >
|
|
2122
|
-
flex: 1;
|
|
2123
|
-
min-height: 0;
|
|
2124
|
-
position: relative;
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
|
-
.terminal-container > #output .xterm {
|
|
2162
|
+
.terminal-container > .xterm {
|
|
2128
2163
|
position: absolute;
|
|
2129
2164
|
top: 0;
|
|
2130
2165
|
left: 0;
|
|
2131
2166
|
right: 0;
|
|
2132
2167
|
bottom: 0;
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2168
|
+
width: 100%;
|
|
2169
|
+
height: 100%;
|
|
2170
|
+
padding: 0;
|
|
2171
|
+
overflow: hidden;
|
|
2137
2172
|
}
|
|
2138
2173
|
|
|
2139
2174
|
.terminal-container .xterm-viewport {
|
|
@@ -2144,8 +2179,9 @@
|
|
|
2144
2179
|
display: none;
|
|
2145
2180
|
}
|
|
2146
2181
|
|
|
2147
|
-
.terminal-container .xterm {
|
|
2148
|
-
|
|
2182
|
+
.terminal-container .xterm-screen {
|
|
2183
|
+
max-width: 100%;
|
|
2184
|
+
overflow: hidden;
|
|
2149
2185
|
}
|
|
2150
2186
|
|
|
2151
2187
|
/* ===== 自定义终端滚动条 ===== */
|
|
@@ -2847,6 +2883,28 @@
|
|
|
2847
2883
|
scrollbar-gutter: stable;
|
|
2848
2884
|
}
|
|
2849
2885
|
|
|
2886
|
+
/* ===== 历史消息懒加载 ===== */
|
|
2887
|
+
.chat-load-more {
|
|
2888
|
+
display: flex;
|
|
2889
|
+
justify-content: center;
|
|
2890
|
+
padding: 8px 0;
|
|
2891
|
+
}
|
|
2892
|
+
.chat-load-more-btn {
|
|
2893
|
+
background: var(--bg-hover);
|
|
2894
|
+
border: 1px solid var(--border-subtle);
|
|
2895
|
+
border-radius: var(--radius-md);
|
|
2896
|
+
color: var(--text-secondary);
|
|
2897
|
+
font-size: 0.75rem;
|
|
2898
|
+
padding: 6px 16px;
|
|
2899
|
+
cursor: pointer;
|
|
2900
|
+
transition: all 0.2s ease;
|
|
2901
|
+
}
|
|
2902
|
+
.chat-load-more-btn:hover {
|
|
2903
|
+
background: var(--accent-muted);
|
|
2904
|
+
color: var(--accent);
|
|
2905
|
+
border-color: var(--accent);
|
|
2906
|
+
}
|
|
2907
|
+
|
|
2850
2908
|
/* ===== 消息动画 ===== */
|
|
2851
2909
|
@keyframes messageSlide {
|
|
2852
2910
|
from {
|
|
@@ -3878,6 +3936,38 @@
|
|
|
3878
3936
|
font-style: italic;
|
|
3879
3937
|
}
|
|
3880
3938
|
|
|
3939
|
+
/* ── Tool content lazy-load states ── */
|
|
3940
|
+
.tool-content-loading {
|
|
3941
|
+
font-size: 0.75rem;
|
|
3942
|
+
color: var(--text-muted);
|
|
3943
|
+
font-style: italic;
|
|
3944
|
+
padding: 8px 0;
|
|
3945
|
+
}
|
|
3946
|
+
.tool-content-loading::before {
|
|
3947
|
+
content: "";
|
|
3948
|
+
display: inline-block;
|
|
3949
|
+
width: 12px;
|
|
3950
|
+
height: 12px;
|
|
3951
|
+
border: 2px solid var(--text-muted);
|
|
3952
|
+
border-top-color: transparent;
|
|
3953
|
+
border-radius: 50%;
|
|
3954
|
+
animation: tool-content-spin 0.6s linear infinite;
|
|
3955
|
+
vertical-align: middle;
|
|
3956
|
+
margin-right: 6px;
|
|
3957
|
+
}
|
|
3958
|
+
@keyframes tool-content-spin {
|
|
3959
|
+
to { transform: rotate(360deg); }
|
|
3960
|
+
}
|
|
3961
|
+
.tool-content-error {
|
|
3962
|
+
font-size: 0.75rem;
|
|
3963
|
+
color: var(--error);
|
|
3964
|
+
padding: 8px 0;
|
|
3965
|
+
cursor: pointer;
|
|
3966
|
+
}
|
|
3967
|
+
.tool-content-error:hover {
|
|
3968
|
+
text-decoration: underline;
|
|
3969
|
+
}
|
|
3970
|
+
|
|
3881
3971
|
/* ── Inline Terminal Display (Bash) ── */
|
|
3882
3972
|
.inline-terminal {
|
|
3883
3973
|
margin: 3px 0;
|
|
@@ -5506,9 +5596,19 @@
|
|
|
5506
5596
|
}
|
|
5507
5597
|
.session-modal .modal-body {
|
|
5508
5598
|
padding-top: 16px;
|
|
5599
|
+
padding-bottom: 8px;
|
|
5509
5600
|
}
|
|
5510
5601
|
.session-modal .field:last-of-type {
|
|
5511
|
-
margin-bottom:
|
|
5602
|
+
margin-bottom: 6px;
|
|
5603
|
+
}
|
|
5604
|
+
.session-modal .modal-footer {
|
|
5605
|
+
flex-shrink: 0;
|
|
5606
|
+
padding: 12px 22px 18px;
|
|
5607
|
+
border-top: 1px solid var(--border-subtle);
|
|
5608
|
+
}
|
|
5609
|
+
.session-modal .modal-footer .error-message {
|
|
5610
|
+
margin-top: 8px;
|
|
5611
|
+
margin-bottom: 0;
|
|
5512
5612
|
}
|
|
5513
5613
|
.mode-cards {
|
|
5514
5614
|
display: flex;
|
|
@@ -6068,8 +6168,8 @@
|
|
|
6068
6168
|
gap: 1px;
|
|
6069
6169
|
}
|
|
6070
6170
|
.terminal-scale-overlay-btn {
|
|
6071
|
-
min-width:
|
|
6072
|
-
height:
|
|
6171
|
+
min-width: 26px;
|
|
6172
|
+
height: 26px;
|
|
6073
6173
|
font-size: 0.75rem;
|
|
6074
6174
|
}
|
|
6075
6175
|
.terminal-scale-overlay-label {
|
|
@@ -6268,8 +6368,8 @@
|
|
|
6268
6368
|
display: inline-flex;
|
|
6269
6369
|
align-items: center;
|
|
6270
6370
|
justify-content: center;
|
|
6271
|
-
width:
|
|
6272
|
-
height:
|
|
6371
|
+
width: 28px;
|
|
6372
|
+
height: 28px;
|
|
6273
6373
|
border: none;
|
|
6274
6374
|
border-radius: 50%;
|
|
6275
6375
|
background: transparent;
|
|
@@ -6303,14 +6403,14 @@
|
|
|
6303
6403
|
display: none;
|
|
6304
6404
|
}
|
|
6305
6405
|
.inline-shortcuts-expanded-row .shortcut-key {
|
|
6306
|
-
height:
|
|
6307
|
-
min-width:
|
|
6406
|
+
height: 28px;
|
|
6407
|
+
min-width: 28px;
|
|
6308
6408
|
font-size: 0.5625rem;
|
|
6309
6409
|
padding: 0 4px;
|
|
6310
6410
|
flex: 0 0 auto;
|
|
6311
6411
|
}
|
|
6312
6412
|
.inline-shortcuts-expanded-row .shortcut-key.shortcut-dir {
|
|
6313
|
-
min-width:
|
|
6413
|
+
min-width: 24px;
|
|
6314
6414
|
}
|
|
6315
6415
|
|
|
6316
6416
|
/* 回到底部按钮 - 紧凑 */
|
|
@@ -6342,7 +6442,7 @@
|
|
|
6342
6442
|
.mini-keyboard-header { padding: 6px 10px 4px; }
|
|
6343
6443
|
.mini-keyboard-body { padding: 6px; gap: 4px; }
|
|
6344
6444
|
.mk-row { gap: 3px; }
|
|
6345
|
-
.mk-key { min-width:
|
|
6445
|
+
.mk-key { min-width: 38px; height: 34px; font-size: 0.625rem; border-radius: 6px; }
|
|
6346
6446
|
|
|
6347
6447
|
.floating-pad {
|
|
6348
6448
|
right: 0;
|
|
@@ -6482,6 +6582,7 @@
|
|
|
6482
6582
|
.modal-header { padding: 10px 12px; min-height: 40px; }
|
|
6483
6583
|
.modal-body { padding: 10px 12px; }
|
|
6484
6584
|
.modal-footer { padding: 8px 12px; }
|
|
6585
|
+
.session-modal .modal-footer { padding: 10px 12px 14px; }
|
|
6485
6586
|
|
|
6486
6587
|
.tool-card {
|
|
6487
6588
|
padding: 10px;
|
|
@@ -6511,6 +6612,11 @@
|
|
|
6511
6612
|
.blank-chat-hint { font-size: 0.6875rem; }
|
|
6512
6613
|
.mode-btn-group { gap: 4px; margin-top: 8px; }
|
|
6513
6614
|
.mode-btn { padding: 5px 10px; font-size: 0.6875rem; min-height: 36px; }
|
|
6615
|
+
|
|
6616
|
+
/* 防止小屏溢出 */
|
|
6617
|
+
.notification-bubble { max-width: calc(100vw - 24px); }
|
|
6618
|
+
.blank-chat-cwd-dropdown { min-width: 0; width: calc(100vw - 32px); max-width: 320px; }
|
|
6619
|
+
.toast-message { max-width: calc(100vw - 32px); }
|
|
6514
6620
|
}
|
|
6515
6621
|
|
|
6516
6622
|
/* iPhone 14/15 等标准屏幕 (390px - 420px) - 使用基础移动端样式,略微调整 */
|
|
@@ -6532,8 +6638,8 @@
|
|
|
6532
6638
|
@media (max-width: 390px) {
|
|
6533
6639
|
/* 继承 max-width: 640px 的样式,此处仅做小屏微调 */
|
|
6534
6640
|
.floating-sidebar-toggle {
|
|
6535
|
-
width:
|
|
6536
|
-
height:
|
|
6641
|
+
width: 28px;
|
|
6642
|
+
height: 28px;
|
|
6537
6643
|
}
|
|
6538
6644
|
.floating-sidebar-toggle .hamburger-icon { width: 11px; height: 8px; }
|
|
6539
6645
|
|
|
@@ -6555,21 +6661,22 @@
|
|
|
6555
6661
|
}
|
|
6556
6662
|
|
|
6557
6663
|
.input-composer { border-radius: 8px; }
|
|
6558
|
-
.input-textarea { min-height: 28px; padding: 5px 6px 2px; font-size:
|
|
6664
|
+
.input-textarea { min-height: 28px; padding: 5px 6px 2px; font-size: 16px; }
|
|
6559
6665
|
|
|
6560
|
-
.btn-circle { width:
|
|
6666
|
+
.btn-circle { width: 28px; height: 28px; min-width: 28px; }
|
|
6561
6667
|
|
|
6562
6668
|
.session-item {
|
|
6563
6669
|
padding: 6px 8px;
|
|
6564
6670
|
min-height: 40px;
|
|
6565
6671
|
}
|
|
6566
|
-
.session-action-btn { width:
|
|
6672
|
+
.session-action-btn { width: 30px; height: 30px; min-width: 30px; min-height: 30px; }
|
|
6567
6673
|
|
|
6568
6674
|
.sidebar { top: 0; width: min(240px, calc(100vw - 10px)); }
|
|
6569
6675
|
|
|
6570
6676
|
.modal { max-height: 80vh; }
|
|
6571
6677
|
.modal-header { padding: 8px 10px; min-height: 36px; }
|
|
6572
6678
|
.modal-body { padding: 8px 10px; }
|
|
6679
|
+
.session-modal .modal-footer { padding: 8px 10px 12px; }
|
|
6573
6680
|
.field-row { grid-template-columns: 1fr; gap: 0; }
|
|
6574
6681
|
|
|
6575
6682
|
.btn { min-height: 36px; padding: 8px 12px; }
|
|
@@ -7031,6 +7138,11 @@
|
|
|
7031
7138
|
color: var(--fg-secondary);
|
|
7032
7139
|
line-height: 1.4;
|
|
7033
7140
|
margin-bottom: 0;
|
|
7141
|
+
max-height: 4.2em;
|
|
7142
|
+
overflow: hidden;
|
|
7143
|
+
display: -webkit-box;
|
|
7144
|
+
-webkit-line-clamp: 3;
|
|
7145
|
+
-webkit-box-orient: vertical;
|
|
7034
7146
|
}
|
|
7035
7147
|
.notification-bubble-actions {
|
|
7036
7148
|
margin-top: 6px;
|
|
@@ -7267,6 +7379,27 @@
|
|
|
7267
7379
|
margin-top: 10px;
|
|
7268
7380
|
}
|
|
7269
7381
|
|
|
7382
|
+
.settings-connect-url-box {
|
|
7383
|
+
display: flex;
|
|
7384
|
+
align-items: center;
|
|
7385
|
+
gap: 8px;
|
|
7386
|
+
background: var(--bg-primary);
|
|
7387
|
+
border: 1px solid var(--border-subtle);
|
|
7388
|
+
border-radius: 6px;
|
|
7389
|
+
padding: 6px 10px;
|
|
7390
|
+
margin-top: 6px;
|
|
7391
|
+
}
|
|
7392
|
+
|
|
7393
|
+
.settings-connect-url-text {
|
|
7394
|
+
flex: 1;
|
|
7395
|
+
font-family: var(--font-mono, monospace);
|
|
7396
|
+
font-size: 13px;
|
|
7397
|
+
color: var(--text-primary);
|
|
7398
|
+
word-break: break-all;
|
|
7399
|
+
user-select: all;
|
|
7400
|
+
-webkit-user-select: all;
|
|
7401
|
+
}
|
|
7402
|
+
|
|
7270
7403
|
.settings-divider {
|
|
7271
7404
|
border: none;
|
|
7272
7405
|
border-top: 1px solid var(--border-subtle);
|
|
@@ -7340,6 +7473,93 @@
|
|
|
7340
7473
|
cursor: pointer;
|
|
7341
7474
|
}
|
|
7342
7475
|
|
|
7476
|
+
/* Switch card list */
|
|
7477
|
+
.switch-card-list {
|
|
7478
|
+
display: flex;
|
|
7479
|
+
flex-direction: column;
|
|
7480
|
+
gap: 8px;
|
|
7481
|
+
}
|
|
7482
|
+
.switch-card {
|
|
7483
|
+
display: block;
|
|
7484
|
+
background: var(--bg-secondary);
|
|
7485
|
+
border: 1px solid var(--border);
|
|
7486
|
+
border-radius: 10px;
|
|
7487
|
+
padding: 12px 14px;
|
|
7488
|
+
cursor: pointer;
|
|
7489
|
+
transition: border-color 0.2s, background 0.2s;
|
|
7490
|
+
user-select: none;
|
|
7491
|
+
}
|
|
7492
|
+
.switch-card:hover {
|
|
7493
|
+
border-color: var(--text-muted);
|
|
7494
|
+
}
|
|
7495
|
+
.switch-card-header {
|
|
7496
|
+
display: flex;
|
|
7497
|
+
align-items: center;
|
|
7498
|
+
gap: 10px;
|
|
7499
|
+
}
|
|
7500
|
+
.switch-card-title {
|
|
7501
|
+
flex: 1;
|
|
7502
|
+
font-size: 0.8125rem;
|
|
7503
|
+
font-weight: 600;
|
|
7504
|
+
color: var(--text-primary);
|
|
7505
|
+
}
|
|
7506
|
+
.switch-card-desc {
|
|
7507
|
+
font-size: 0.75rem;
|
|
7508
|
+
color: var(--text-muted);
|
|
7509
|
+
margin-top: 0;
|
|
7510
|
+
max-height: 0;
|
|
7511
|
+
overflow: hidden;
|
|
7512
|
+
opacity: 0;
|
|
7513
|
+
transition: max-height 0.25s ease, opacity 0.2s ease, margin-top 0.25s ease;
|
|
7514
|
+
}
|
|
7515
|
+
/* When switch is ON, expand the description */
|
|
7516
|
+
.switch-card:has(.switch-toggle:checked) .switch-card-desc {
|
|
7517
|
+
max-height: 40px;
|
|
7518
|
+
opacity: 1;
|
|
7519
|
+
margin-top: 8px;
|
|
7520
|
+
}
|
|
7521
|
+
.switch-card:has(.switch-toggle:checked) {
|
|
7522
|
+
border-color: var(--accent);
|
|
7523
|
+
background: color-mix(in srgb, var(--accent) 6%, var(--bg-secondary));
|
|
7524
|
+
}
|
|
7525
|
+
|
|
7526
|
+
/* Switch toggle (iOS style) */
|
|
7527
|
+
.switch-toggle {
|
|
7528
|
+
position: absolute;
|
|
7529
|
+
opacity: 0;
|
|
7530
|
+
width: 0;
|
|
7531
|
+
height: 0;
|
|
7532
|
+
pointer-events: none;
|
|
7533
|
+
}
|
|
7534
|
+
.switch-slider {
|
|
7535
|
+
position: relative;
|
|
7536
|
+
display: inline-block;
|
|
7537
|
+
width: 40px;
|
|
7538
|
+
height: 22px;
|
|
7539
|
+
min-width: 40px;
|
|
7540
|
+
background: #c4b8a8;
|
|
7541
|
+
border-radius: 11px;
|
|
7542
|
+
transition: background 0.25s;
|
|
7543
|
+
}
|
|
7544
|
+
.switch-slider::after {
|
|
7545
|
+
content: "";
|
|
7546
|
+
position: absolute;
|
|
7547
|
+
top: 3px;
|
|
7548
|
+
left: 3px;
|
|
7549
|
+
width: 16px;
|
|
7550
|
+
height: 16px;
|
|
7551
|
+
background: #fff;
|
|
7552
|
+
border-radius: 50%;
|
|
7553
|
+
transition: transform 0.25s;
|
|
7554
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
|
7555
|
+
}
|
|
7556
|
+
.switch-toggle:checked + .switch-slider {
|
|
7557
|
+
background: var(--accent);
|
|
7558
|
+
}
|
|
7559
|
+
.switch-toggle:checked + .switch-slider::after {
|
|
7560
|
+
transform: translateX(18px);
|
|
7561
|
+
}
|
|
7562
|
+
|
|
7343
7563
|
.field-file {
|
|
7344
7564
|
font-size: 0.8rem;
|
|
7345
7565
|
padding: 6px;
|
package/dist/ws-broadcast.d.ts
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* Handles debounced output events, backpressure control, and client subscriptions.
|
|
4
4
|
*/
|
|
5
5
|
import { WebSocketServer } from "ws";
|
|
6
|
-
import type { SessionSnapshot, ProcessEvent } from "./types.js";
|
|
6
|
+
import type { CardExpandDefaults, SessionSnapshot, ProcessEvent } from "./types.js";
|
|
7
7
|
export type { ProcessEvent } from "./types.js";
|
|
8
8
|
export declare class WsBroadcastManager {
|
|
9
9
|
private wss;
|
|
10
10
|
private clients;
|
|
11
11
|
private outputDebounceCache;
|
|
12
12
|
private eventEmitter;
|
|
13
|
-
|
|
13
|
+
private getCardDefaults;
|
|
14
|
+
constructor(wss: WebSocketServer, getCardDefaults?: () => CardExpandDefaults);
|
|
14
15
|
/** Set up connection handling. Should be called once during server startup. */
|
|
15
16
|
setup(getSession: (id: string) => SessionSnapshot | null): void;
|
|
16
17
|
/** Emit a process event to all subscribed WebSocket clients. */
|
package/dist/ws-broadcast.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { WebSocket } from "ws";
|
|
6
6
|
import { EventEmitter } from "node:events";
|
|
7
7
|
import { validateSession } from "./auth.js";
|
|
8
|
+
import { truncateMessagesForTransport } from "./message-truncator.js";
|
|
8
9
|
// ── Constants ──
|
|
9
10
|
const MAX_QUEUE_SIZE = 500;
|
|
10
11
|
const OUTPUT_DEBOUNCE_MS = 16;
|
|
@@ -14,8 +15,10 @@ export class WsBroadcastManager {
|
|
|
14
15
|
clients = new Set();
|
|
15
16
|
outputDebounceCache = new Map();
|
|
16
17
|
eventEmitter = new EventEmitter();
|
|
17
|
-
|
|
18
|
+
getCardDefaults;
|
|
19
|
+
constructor(wss, getCardDefaults) {
|
|
18
20
|
this.wss = wss;
|
|
21
|
+
this.getCardDefaults = getCardDefaults ?? (() => ({}));
|
|
19
22
|
}
|
|
20
23
|
/** Set up connection handling. Should be called once during server startup. */
|
|
21
24
|
setup(getSession) {
|
|
@@ -45,10 +48,13 @@ export class WsBroadcastManager {
|
|
|
45
48
|
if (msg.type === "subscribe" && msg.sessionId) {
|
|
46
49
|
const snapshot = getSession(msg.sessionId);
|
|
47
50
|
if (snapshot) {
|
|
51
|
+
const truncatedMessages = snapshot.messages
|
|
52
|
+
? truncateMessagesForTransport(snapshot.messages, this.getCardDefaults())
|
|
53
|
+
: undefined;
|
|
48
54
|
ws.send(JSON.stringify({
|
|
49
55
|
type: "init",
|
|
50
56
|
sessionId: msg.sessionId,
|
|
51
|
-
data: { ...snapshot, messages:
|
|
57
|
+
data: { ...snapshot, messages: truncatedMessages, output: snapshot.output },
|
|
52
58
|
}));
|
|
53
59
|
}
|
|
54
60
|
else {
|