@zfdx123/dsh-session-cleaner 1.0.5 → 1.0.7
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/client.js +43 -14
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -143,15 +143,31 @@ window.__ModuleLoader__.load({
|
|
|
143
143
|
* look. Null means the delete still works through the browser's own
|
|
144
144
|
* confirmation, and every glyph falls back to the hand-drawn SVG.
|
|
145
145
|
*/
|
|
146
|
+
/**
|
|
147
|
+
* Whether a value can be rendered as a React component.
|
|
148
|
+
*
|
|
149
|
+
* `typeof x === 'function'` is NOT enough: the shell's `Button` is built with
|
|
150
|
+
* `React.forwardRef(...)`, so its `typeof` is always `'object'`
|
|
151
|
+
* (`$$typeof = Symbol(react.forward_ref)`, `render` is the function). A guard
|
|
152
|
+
* that asks for `typeof primitives.Button === 'function'` is therefore always
|
|
153
|
+
* false, which throws away the whole kit even though Modal/Input/Switch really
|
|
154
|
+
* are functions — the failure looks like "only the icons are wrong".
|
|
155
|
+
*/
|
|
156
|
+
function isRenderable(value) {
|
|
157
|
+
if (typeof value === 'function') return true
|
|
158
|
+
if (typeof value !== 'object' || value === null) return false
|
|
159
|
+
return value.$$typeof === Symbol.for('react.forward_ref') || value.$$typeof === Symbol.for('react.memo')
|
|
160
|
+
}
|
|
161
|
+
|
|
146
162
|
function loadPrimitives(require) {
|
|
147
163
|
try {
|
|
148
164
|
const primitives = require(PRIMITIVES)
|
|
149
165
|
if (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
166
|
+
isRenderable(primitives?.Modal) &&
|
|
167
|
+
isRenderable(primitives?.Button) &&
|
|
168
|
+
isRenderable(primitives?.IconSearchOutlineRegular) &&
|
|
169
|
+
isRenderable(primitives?.IconChevronDownOutlineRegular) &&
|
|
170
|
+
isRenderable(primitives?.IconTrashOutlineRegular)
|
|
155
171
|
)
|
|
156
172
|
return primitives
|
|
157
173
|
} catch (error) {
|
|
@@ -701,7 +717,7 @@ window.__ModuleLoader__.load({
|
|
|
701
717
|
React.createElement(Glyph, {
|
|
702
718
|
key: 'chevron',
|
|
703
719
|
primitives,
|
|
704
|
-
name: '
|
|
720
|
+
name: 'IconChevronDownOutlineRegular',
|
|
705
721
|
size: 12,
|
|
706
722
|
box: Object.assign({}, S.chevron, collapsed ? S.chevronFolded : {}),
|
|
707
723
|
fallback: ChevronIcon,
|
|
@@ -723,7 +739,7 @@ window.__ModuleLoader__.load({
|
|
|
723
739
|
React.createElement(Glyph, {
|
|
724
740
|
key: 'i',
|
|
725
741
|
primitives,
|
|
726
|
-
name: '
|
|
742
|
+
name: 'IconSearchOutlineRegular',
|
|
727
743
|
size: 16,
|
|
728
744
|
box: S.searchGlyph,
|
|
729
745
|
fallback: SearchIcon,
|
|
@@ -981,7 +997,7 @@ window.__ModuleLoader__.load({
|
|
|
981
997
|
* root mounted behind it. Null keeps the hand-drawn SVG above in charge.
|
|
982
998
|
*/
|
|
983
999
|
function kitTrashIcon(primitives) {
|
|
984
|
-
const Icon = kitIcon(primitives, '
|
|
1000
|
+
const Icon = kitIcon(primitives, 'IconTrashOutlineRegular')
|
|
985
1001
|
if (Icon === null) return null
|
|
986
1002
|
try {
|
|
987
1003
|
const scratch = document.createElement('span')
|
|
@@ -992,7 +1008,7 @@ window.__ModuleLoader__.load({
|
|
|
992
1008
|
root.unmount()
|
|
993
1009
|
return node
|
|
994
1010
|
} catch (error) {
|
|
995
|
-
report('icon-fallback', { icon: '
|
|
1011
|
+
report('icon-fallback', { icon: 'IconTrashOutlineRegular', message: String(error?.message ?? error) })
|
|
996
1012
|
return null
|
|
997
1013
|
}
|
|
998
1014
|
}
|
|
@@ -1091,6 +1107,21 @@ window.__ModuleLoader__.load({
|
|
|
1091
1107
|
report('trigger', { name: name.slice(0, 60) })
|
|
1092
1108
|
}
|
|
1093
1109
|
|
|
1110
|
+
// 目录请求的序号:只有最新一次的结果允许写进 `catalog`。
|
|
1111
|
+
//
|
|
1112
|
+
// 回归:启动时一次拉取(下面 1142 行)与「行内 id 没解出来时」的重试
|
|
1113
|
+
// (1124 行)会同时在飞,先发的旧响应可能后到并覆盖 `catalog`。已经插进去的
|
|
1114
|
+
// 菜单项不会被重建(标签看起来是对的),但 `catalog` 会一直陈旧到刷新页面,
|
|
1115
|
+
// 于是**下一个**打开的菜单会把运行中的会话显示成可删除。
|
|
1116
|
+
let catalogSeq = 0
|
|
1117
|
+
const loadCatalog = () => {
|
|
1118
|
+
const seq = (catalogSeq += 1)
|
|
1119
|
+
return fetchCatalog().then((resolved) => {
|
|
1120
|
+
if (catalogSeq === seq) catalog = resolved
|
|
1121
|
+
return resolved
|
|
1122
|
+
})
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1094
1125
|
const attempt = (added) => {
|
|
1095
1126
|
const found = findSessionMenu(added)
|
|
1096
1127
|
if (found === undefined) return
|
|
@@ -1105,10 +1136,9 @@ window.__ModuleLoader__.load({
|
|
|
1105
1136
|
pendingRow = null
|
|
1106
1137
|
return
|
|
1107
1138
|
}
|
|
1108
|
-
|
|
1139
|
+
loadCatalog()
|
|
1109
1140
|
.then((resolved) => {
|
|
1110
|
-
|
|
1111
|
-
if (found.menu.isConnected) augmentMenu(found, row, catalog, ctx, dict)
|
|
1141
|
+
if (found.menu.isConnected) augmentMenu(found, row, resolved, ctx, dict)
|
|
1112
1142
|
})
|
|
1113
1143
|
.catch(() => {})
|
|
1114
1144
|
}
|
|
@@ -1123,9 +1153,8 @@ window.__ModuleLoader__.load({
|
|
|
1123
1153
|
})
|
|
1124
1154
|
document.addEventListener('pointerdown', onPointerDown, true)
|
|
1125
1155
|
observer.observe(document.body, { childList: true, subtree: true })
|
|
1126
|
-
|
|
1156
|
+
loadCatalog()
|
|
1127
1157
|
.then((resolved) => {
|
|
1128
|
-
catalog = resolved
|
|
1129
1158
|
report('catalog', { ok: resolved !== null, known: resolved === null ? 0 : resolved.byId.size })
|
|
1130
1159
|
})
|
|
1131
1160
|
.catch(() => {})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zfdx123/dsh-session-cleaner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "会话清理:在运行中的 web 运行时里彻底删除 DSH 会话——实时 store 条目、工作区记录、磁盘产物与投影缓存行一并清掉,并在会话行菜单里加一个删除入口。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/zfdx123/dsh-atelier/tree/main/packages/dsh-session-cleaner#readme",
|