@noob-stupid/dsh-plugin-console 0.3.47 → 0.3.49
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 +3 -3
- package/README.zh.md +282 -281
- package/lib/client.js +80 -8
- package/lib/index.js +485 -140
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -338,6 +338,9 @@ window.__ModuleLoader__.load({
|
|
|
338
338
|
gitUrlPlaceholder: "如 https://gitee.com/{owner}/{repo}.git",
|
|
339
339
|
gitSourceBtn: "Git 源",
|
|
340
340
|
marketIndexOffline: "离线数据 · 缓存于 {time}(索引源不可达,已回退上次成功结果)",
|
|
341
|
+
marketIndexStale: "市场索引未加载:搜索只覆盖 GitHub 实时结果(仓库名/描述/topics),收录条目与本地索引模糊匹配都用不上",
|
|
342
|
+
marketIndexRetry: "重试加载索引",
|
|
343
|
+
searchLoginHint: "未登录 GitHub:代码搜索不可用(按子包名搜索需要登录);仓库搜索仍可用",
|
|
341
344
|
marketIndexFrom: "索引来源:{source}",
|
|
342
345
|
marketIndexFailed: "市场索引加载失败",
|
|
343
346
|
unknown: "未知",
|
|
@@ -709,6 +712,9 @@ window.__ModuleLoader__.load({
|
|
|
709
712
|
gitUrlPlaceholder: "e.g. https://gitee.com/{owner}/{repo}.git",
|
|
710
713
|
gitSourceBtn: "Git sources",
|
|
711
714
|
marketIndexOffline: "Offline data · cached {time} (index sources unreachable, showing last successful result)",
|
|
715
|
+
marketIndexStale: "Market index not loaded: search only covers live GitHub results (name/description/topics); curated entries and local fuzzy matching are unavailable",
|
|
716
|
+
marketIndexRetry: "Retry loading index",
|
|
717
|
+
searchLoginHint: "GitHub not signed in: code search is unavailable (searching by subpackage name needs sign-in); repository search still works",
|
|
712
718
|
marketIndexFrom: "Index source: {source}",
|
|
713
719
|
marketIndexFailed: "Failed to load market index",
|
|
714
720
|
unknown: "unknown",
|
|
@@ -1152,6 +1158,8 @@ window.__ModuleLoader__.load({
|
|
|
1152
1158
|
const [updateCheck, setUpdateCheck] = react.useState(null);
|
|
1153
1159
|
// 静态插件索引(dsh-plugin topic 全量浏览):null=未加载 / {items, skills, loaded}
|
|
1154
1160
|
const [indexData, setIndexData] = react.useState(null);
|
|
1161
|
+
// 索引加载失败原因:null = 还没失败过(用于市场页顶部"索引未加载 + 重试"提示)
|
|
1162
|
+
const [indexError, setIndexError] = react.useState(null);
|
|
1155
1163
|
// 索引浏览当前展示条数(分页展示,避免一次渲染 500 条)
|
|
1156
1164
|
const [indexShown, setIndexShown] = react.useState(50);
|
|
1157
1165
|
// 已补标(官方/聚合标记)到的索引位置:随「加载更多」增量推进,避免一次性发上千请求
|
|
@@ -1725,11 +1733,15 @@ window.__ModuleLoader__.load({
|
|
|
1725
1733
|
() => {},
|
|
1726
1734
|
);
|
|
1727
1735
|
}, []);
|
|
1728
|
-
//
|
|
1729
|
-
|
|
1736
|
+
// 加载静态插件索引(GitHub 源空查询时秒开浏览,零 API 调用)。
|
|
1737
|
+
// 失败时记下原因:市场页顶部给出"索引未加载 → 只能搜 GitHub 实时结果"的提示 + 重试按钮
|
|
1738
|
+
//(2026-09-20 事故:另一位用户索引源全挂 + 未登录,三条检索路全断,搜 web-all 搜不到 dsh-web,
|
|
1739
|
+
// 而界面上只有一句"市场索引加载失败",看不出后果也没有重试入口)
|
|
1740
|
+
const loadMarketIndex = () => {
|
|
1730
1741
|
call("/plugin-console/market-index", {}).then(
|
|
1731
1742
|
(data) => {
|
|
1732
1743
|
if (data && Array.isArray(data.items)) {
|
|
1744
|
+
setIndexError(null);
|
|
1733
1745
|
setIndexData({
|
|
1734
1746
|
items: data.items,
|
|
1735
1747
|
skills: Array.isArray(data.skills) ? data.skills : [],
|
|
@@ -1748,8 +1760,15 @@ window.__ModuleLoader__.load({
|
|
|
1748
1760
|
}
|
|
1749
1761
|
}
|
|
1750
1762
|
},
|
|
1751
|
-
(error) =>
|
|
1763
|
+
(error) => {
|
|
1764
|
+
const text = error?.message ?? t("unknown");
|
|
1765
|
+
setIndexError(text);
|
|
1766
|
+
setMessage(t("marketIndexFailed") + ":" + text);
|
|
1767
|
+
},
|
|
1752
1768
|
);
|
|
1769
|
+
};
|
|
1770
|
+
react.useEffect(() => {
|
|
1771
|
+
loadMarketIndex();
|
|
1753
1772
|
// 市场状态记忆:关闭前搜索过 → 重开时自动恢复该搜索(query 已从 localStorage 初始化)
|
|
1754
1773
|
if (query !== "") {
|
|
1755
1774
|
search();
|
|
@@ -1994,6 +2013,36 @@ window.__ModuleLoader__.load({
|
|
|
1994
2013
|
scored.sort((a, b) => b.s - a.s);
|
|
1995
2014
|
return scored.slice(0, 12).map((x) => x.it);
|
|
1996
2015
|
};
|
|
2016
|
+
/** 合并服务端"增量检索"结果(npm 包名映射 / in:readme 重查 / 代码搜索子包):
|
|
2017
|
+
* npm 命中置顶,其余按增量顺序追加,最后接原有直连结果,全部按 fullName 去重。
|
|
2018
|
+
* 背景(2026-09-20):浏览器直连 GitHub 搜索成功时不会走服务端路由,而未登录用户恰恰只能走直连
|
|
2019
|
+
* →「只存在于 npm 包名 / README / 仓库文件里」的名字(如 web-all)永远补不上。 */
|
|
2020
|
+
function mergeSearchExtras(base, extras) {
|
|
2021
|
+
const seen = new Set();
|
|
2022
|
+
const npm = [];
|
|
2023
|
+
const rest = [];
|
|
2024
|
+
for (const it of extras) {
|
|
2025
|
+
const key = it.fullName ?? JSON.stringify(it);
|
|
2026
|
+
if (seen.has(key)) continue;
|
|
2027
|
+
seen.add(key);
|
|
2028
|
+
if (it.npmPackage === true) npm.push(it); else rest.push(it);
|
|
2029
|
+
}
|
|
2030
|
+
const out = [...npm, ...rest];
|
|
2031
|
+
for (const it of base) {
|
|
2032
|
+
const key = it.fullName ?? JSON.stringify(it);
|
|
2033
|
+
if (seen.has(key)) continue;
|
|
2034
|
+
seen.add(key);
|
|
2035
|
+
out.push(it);
|
|
2036
|
+
}
|
|
2037
|
+
return out;
|
|
2038
|
+
}
|
|
2039
|
+
/** 用 enrich 结果**就地更新**市场列表(按 fullName 打补丁),而不是整表替换——
|
|
2040
|
+
* 否则并行补进来的「增量检索」条目(npm 包名/子包)会被 enrich 回调冲掉。 */
|
|
2041
|
+
const applyEnriched = (enriched) => setMarket((m) => {
|
|
2042
|
+
if (m === null || m.status !== "ready" || !Array.isArray(enriched)) return m;
|
|
2043
|
+
const byName = new Map(enriched.map((x) => [x.fullName, x]));
|
|
2044
|
+
return { ...m, data: m.data.map((x) => byName.get(x.fullName) ?? x) };
|
|
2045
|
+
});
|
|
1997
2046
|
const search = () => {
|
|
1998
2047
|
setMarket({ status: "loading" });
|
|
1999
2048
|
setRepoInfo(null);
|
|
@@ -2044,7 +2093,7 @@ window.__ModuleLoader__.load({
|
|
|
2044
2093
|
(data) => {
|
|
2045
2094
|
setMarket({ status: "ready", data: data.items, direct: false, source: searchSource });
|
|
2046
2095
|
enrichOfficialBundle(data.items).then((enriched) => {
|
|
2047
|
-
|
|
2096
|
+
applyEnriched(enriched);
|
|
2048
2097
|
});
|
|
2049
2098
|
},
|
|
2050
2099
|
(error) => setMarket({ status: "error", error: friendlyGithubError(error) }),
|
|
@@ -2058,20 +2107,32 @@ window.__ModuleLoader__.load({
|
|
|
2058
2107
|
// 并行补标记:
|
|
2059
2108
|
// ① 客户端浏览器直连读根包 package.json(快,官方/聚合标记立即可筛)
|
|
2060
2109
|
enrichOfficialBundle(data).then((enriched) => {
|
|
2061
|
-
|
|
2110
|
+
applyEnriched(enriched);
|
|
2062
2111
|
});
|
|
2063
2112
|
// ② 服务端 curl 双通道 enrich(聚合子包 dsh.bundle 检查 → aggregateInstallable),后台补更精确标记
|
|
2064
2113
|
call("/plugin-console/enrich", { items: data }).then(
|
|
2065
|
-
(r) => { if (r && Array.isArray(r.items))
|
|
2114
|
+
(r) => { if (r && Array.isArray(r.items)) applyEnriched(r.items); },
|
|
2066
2115
|
() => {},
|
|
2067
2116
|
);
|
|
2117
|
+
// ③ 服务端"增量检索"(并行、不阻塞首屏):npm 包名映射 + in:readme 重查 + 代码搜索子包。
|
|
2118
|
+
// 直连搜索只覆盖 仓库名/描述/topics,包名与 README/文件里的名字补不上(2026-09-20 事故)
|
|
2119
|
+
if (query.trim() !== "") {
|
|
2120
|
+
call("/plugin-console/search", { q: query, page: 1, extras: true, all: repoLandOn === true }).then(
|
|
2121
|
+
(r) => {
|
|
2122
|
+
if (r !== null && r.codeSearchSkipped === true) setMessage(t("searchLoginHint"));
|
|
2123
|
+
if (r === null || !Array.isArray(r.items) || r.items.length === 0) return;
|
|
2124
|
+
setMarket((m) => (m !== null && m.status === "ready" ? { ...m, data: mergeSearchExtras(m.data, r.items) } : m));
|
|
2125
|
+
},
|
|
2126
|
+
() => {},
|
|
2127
|
+
);
|
|
2128
|
+
}
|
|
2068
2129
|
},
|
|
2069
2130
|
() => call("/plugin-console/search", { q: query, page: 1 }).then(
|
|
2070
2131
|
(data) => {
|
|
2071
2132
|
const items = data.items;
|
|
2072
2133
|
setMarket({ status: "ready", data: items, direct: false });
|
|
2073
2134
|
enrichOfficialBundle(items).then((enriched) => {
|
|
2074
|
-
|
|
2135
|
+
applyEnriched(enriched);
|
|
2075
2136
|
});
|
|
2076
2137
|
},
|
|
2077
2138
|
(error) => setMarket({ status: "error", error: friendlyGithubError(error) }),
|
|
@@ -2561,7 +2622,7 @@ window.__ModuleLoader__.load({
|
|
|
2561
2622
|
startSuiteJob(item);
|
|
2562
2623
|
return;
|
|
2563
2624
|
}
|
|
2564
|
-
if (item.subpackagePath && typeof item.packageName === "string" && item.packageName !== "") {
|
|
2625
|
+
if ((item.subpackagePath || item.npmPackage === true) && typeof item.packageName === "string" && item.packageName !== "") {
|
|
2565
2626
|
// monorepo 子包:搜索结果带 packageName,按 npm 包名安装
|
|
2566
2627
|
startJob(item.fullName, item.packageName, item.source ?? "github");
|
|
2567
2628
|
return;
|
|
@@ -3796,6 +3857,17 @@ setMessage(t("failed") + ":" + (data?.reason ?? "未知"));
|
|
|
3796
3857
|
t("marketIndexOffline").replace("{time}", indexData.cachedAt !== null ? new Date(indexData.cachedAt).toLocaleString() : "—")
|
|
3797
3858
|
+ (indexData.sourceName !== null ? " · " + t("marketIndexFrom").replace("{source}", indexData.sourceName) : ""))
|
|
3798
3859
|
: null,
|
|
3860
|
+
// 索引彻底没加载成功:说清后果(只剩 GitHub 实时结果)+ 给重试入口。
|
|
3861
|
+
// 2026-09-20 事故:这种状态下"包名/README/子包里的名字"搜不到,而界面上只有一句加载失败
|
|
3862
|
+
indexData === null && indexError !== null
|
|
3863
|
+
? el("p", { className: styles.message, "data-warn": "true" },
|
|
3864
|
+
t("marketIndexStale") + " ",
|
|
3865
|
+
el("button", {
|
|
3866
|
+
type: "button",
|
|
3867
|
+
className: styles.toggle,
|
|
3868
|
+
onClick: () => loadMarketIndex(),
|
|
3869
|
+
}, t("marketIndexRetry")))
|
|
3870
|
+
: null,
|
|
3799
3871
|
el("div", { className: styles.search, id: "pc-market-search" },
|
|
3800
3872
|
el("div", { className: styles.searchInner },
|
|
3801
3873
|
el("input", {
|