dshmarket 1.18.1 → 1.19.0-beta.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.
package/client/client.js CHANGED
@@ -42,6 +42,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
42
42
  setSelfUpToDateHint: "",
43
43
  setSelfUpdate: "更新",
44
44
  setSelfUpdatedHint: "已下载完成。重启 DeepSeek Harness 后新版本才会生效——前端页面会立即更新,服务端不会。",
45
+ setRegion: "下载区域",
46
+ setRegionGlobal: "全球",
47
+ setRegionChina: "中国大陆",
48
+ setRegionGlobalHint: "从 npm 和 GitHub 官方源下载。",
49
+ setRegionChinaHint: "中国大陆访问更快。仅改变下载线路,插件来源不变。",
50
+ setRegionAuto: "已根据网络状况自动选择,可随时切换。",
45
51
  setChannel: "更新通道",
46
52
  setChannelStable: "稳定版",
47
53
  setChannelBeta: "Beta",
@@ -402,6 +408,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
402
408
  setSelfUpToDateHint: "",
403
409
  setSelfUpdate: "Update",
404
410
  setSelfUpdatedHint: "Downloaded. Restart DeepSeek Harness for it to take effect — the frontend updates at once, the server does not.",
411
+ setRegion: "Download region",
412
+ setRegionGlobal: "Global",
413
+ setRegionChina: "China mainland",
414
+ setRegionGlobalHint: "Downloads directly from npm and GitHub.",
415
+ setRegionChinaHint: "Faster in mainland China. Changes the download route, not the source.",
416
+ setRegionAuto: "Selected from a network check. Change it anytime.",
405
417
  setChannel: "Update channel",
406
418
  setChannelStable: "Stable",
407
419
  setChannelBeta: "Beta",
@@ -1071,6 +1083,32 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
1071
1083
  ];
1072
1084
  }
1073
1085
  /**
1086
+ * Prefix for github.com URLs this page loads, or null to address them
1087
+ * directly. Set from the status poll, which gets it from the download region.
1088
+ *
1089
+ * Module state rather than a prop: the URLs it applies to are built in four
1090
+ * places across two files (avatars, README fetches, screenshot thumbnails),
1091
+ * and threading one string through every card would put it in signatures
1092
+ * that have no other reason to know about networking.
1093
+ *
1094
+ * Applied at the LAST moment, never stored. Extracted image URLs stay
1095
+ * canonical, so changing region re-renders against the new route instead of
1096
+ * leaving a page full of links to a proxy the user just switched away from.
1097
+ */
1098
+ let githubProxy = null;
1099
+ /** Point browser-side github.com requests at a proxy, or null for direct. */
1100
+ function setGithubProxy(proxy) {
1101
+ githubProxy = proxy;
1102
+ }
1103
+ /** The proxy in force, for callers that must decide between two URL shapes. */
1104
+ function githubProxyInUse() {
1105
+ return githubProxy;
1106
+ }
1107
+ /** `url` through the proxy in force, or unchanged when there is none. */
1108
+ function githubUrl(url) {
1109
+ return githubProxy === null ? url : `${githubProxy}/${url}`;
1110
+ }
1111
+ /**
1074
1112
  * Image hosts screenshots may load from (#61) — GitHub's own hosting only.
1075
1113
  * Any other host is dropped BEFORE an <img> is created: a screenshot URL is
1076
1114
  * a request carrying the user's IP, so registry data and README content are
@@ -1146,7 +1184,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
1146
1184
  if (cached !== void 0) return cached;
1147
1185
  const fetchReadme = async (path) => {
1148
1186
  try {
1149
- const res = await fetch(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/${path === null ? "" : path + "/"}README.md`);
1187
+ const res = await fetch(githubUrl(`https://raw.githubusercontent.com/${owner}/${repo}/HEAD/${path === null ? "" : path + "/"}README.md`));
1150
1188
  return res.ok ? await res.text() : null;
1151
1189
  } catch {
1152
1190
  return null;
@@ -3238,7 +3276,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
3238
3276
  });
3239
3277
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
3240
3278
  className: Market_module_css_default.av,
3241
- src: `https://github.com/${encodeURIComponent(owner)}.png?size=96`,
3279
+ src: githubUrl(`https://github.com/${encodeURIComponent(owner)}.png?size=96`),
3242
3280
  alt: "",
3243
3281
  loading: "lazy",
3244
3282
  onError: () => setFailed(true)
@@ -3323,6 +3361,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
3323
3361
  * share a cache entry with the full-size open anyway.
3324
3362
  */
3325
3363
  function thumbUrl(src, height) {
3364
+ if (githubProxyInUse() !== null) return githubUrl(src);
3326
3365
  return `https://images.weserv.nl/?url=${encodeURIComponent(src.replace(/^https?:\/\//, ""))}&h=${String(height)}&fit=inside&we=1`;
3327
3366
  }
3328
3367
  /**
@@ -4049,6 +4088,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
4049
4088
  loadCatalog();
4050
4089
  fetch("/dsh-market/status", { cache: "no-store" }).then((res) => res.json()).then((status) => {
4051
4090
  setEnvReady(status.pnpm !== false);
4091
+ setGithubProxy(typeof status.githubProxy === "string" ? status.githubProxy : null);
4052
4092
  if (typeof status.boot === "string") {
4053
4093
  setBootId(status.boot);
4054
4094
  try {
@@ -7098,6 +7138,16 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
7098
7138
  beta: "setChannelBetaHint",
7099
7139
  dev: "setChannelDevHint"
7100
7140
  };
7141
+ const REGIONS = ["global", "china"];
7142
+ const asRegion = (value) => REGIONS.includes(value) ? value : null;
7143
+ const REGION_LABEL = {
7144
+ global: "setRegionGlobal",
7145
+ china: "setRegionChina"
7146
+ };
7147
+ const REGION_HINT = {
7148
+ global: "setRegionGlobalHint",
7149
+ china: "setRegionChinaHint"
7150
+ };
7101
7151
  /**
7102
7152
  * Read the server's answer, taking the list of channels FROM it.
7103
7153
  *
@@ -7107,11 +7157,15 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
7107
7157
  */
7108
7158
  function readStatus(body) {
7109
7159
  const offered = (body.channels ?? []).map(asChannel).filter((c) => c !== null);
7160
+ const regions = (body.regions ?? []).map(asRegion).filter((r) => r !== null);
7110
7161
  return {
7111
7162
  version: body.version ?? null,
7112
7163
  restart: body.restart === true,
7113
7164
  channel: asChannel(body.channel) ?? "stable",
7114
- channels: offered.length > 0 ? offered : ["stable", "beta"]
7165
+ channels: offered.length > 0 ? offered : ["stable", "beta"],
7166
+ region: asRegion(body.region) ?? "global",
7167
+ regions: regions.length > 0 ? regions : REGIONS,
7168
+ regionAuto: body.regionAuto === true
7115
7169
  };
7116
7170
  }
7117
7171
  function readUpdate(own) {
@@ -7158,12 +7212,16 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
7158
7212
  try {
7159
7213
  const body = await (await fetch("/dsh-market/status", { cache: "no-store" })).json();
7160
7214
  if (live) setStatus(readStatus(body));
7215
+ setGithubProxy(typeof body.githubProxy === "string" ? body.githubProxy : null);
7161
7216
  } catch {
7162
7217
  if (live) setStatus({
7163
7218
  version: null,
7164
7219
  restart: false,
7165
7220
  channel: "stable",
7166
- channels: ["stable", "beta"]
7221
+ channels: ["stable", "beta"],
7222
+ region: "global",
7223
+ regions: REGIONS,
7224
+ regionAuto: false
7167
7225
  });
7168
7226
  }
7169
7227
  try {
@@ -7273,6 +7331,37 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
7273
7331
  refreshUpdate,
7274
7332
  t
7275
7333
  ]);
7334
+ /**
7335
+ * Select a download region — and show the one the SERVER accepted, on the
7336
+ * same reasoning as the channel above.
7337
+ *
7338
+ * A hand-made choice retires the one-time notice: the market no longer has
7339
+ * anything to explain once the user has answered for themselves.
7340
+ */
7341
+ const onRegion = (0, react.useCallback)((next) => {
7342
+ setError(null);
7343
+ (async () => {
7344
+ try {
7345
+ const body = await post("/dsh-market/region", { region: next });
7346
+ if (body.ok !== true) {
7347
+ setError(body.error ?? t("setSelfFailed"));
7348
+ return;
7349
+ }
7350
+ const accepted = asRegion(body.region) ?? next;
7351
+ setStatus((current) => current === null ? current : {
7352
+ ...current,
7353
+ region: accepted,
7354
+ regionAuto: false
7355
+ });
7356
+ try {
7357
+ const status = await (await fetch("/dsh-market/status", { cache: "no-store" })).json();
7358
+ setGithubProxy(typeof status.githubProxy === "string" ? status.githubProxy : null);
7359
+ } catch {}
7360
+ } catch (cause) {
7361
+ setError(cause instanceof Error ? cause.message : String(cause));
7362
+ }
7363
+ })();
7364
+ }, [post, t]);
7276
7365
  /** One label + hint block with an optional action, the host's row shape. */
7277
7366
  const row = (label, hint, action) => (0, react.createElement)("div", { className: Market_module_css_default.setRow }, (0, react.createElement)("div", { className: Market_module_css_default.setLabelBox }, (0, react.createElement)("div", { className: Market_module_css_default.setLabel }, label), (0, react.createElement)("div", { className: Market_module_css_default.setHint }, hint)), action);
7278
7367
  const body = phase === "removed" ? row(t("setSelfRemoved"), t("setSelfRemovedHint"), null) : (0, react.createElement)(react.Fragment, null, row(update?.updateAvailable === true && update.latest !== null ? `${t("setSelfUpdateReady")} ${update.latest}` : update?.channelSwitch != null ? `${t("setChannelSwitch")} ${update.channelSwitch}` : t("setSelfUpToDate"), phase === "updated" ? t("setSelfUpdatedHint") : update?.channelSwitch != null ? t("setChannelSwitchHint") : update?.updateAvailable === true ? t("setSelfUpdateHint") : t("setSelfUpToDateHint"), phase === "updated" ? null : update?.updateAvailable === true ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
@@ -7294,7 +7383,15 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
7294
7383
  onClick: () => {
7295
7384
  onChannel(id);
7296
7385
  }
7297
- }, t(CHANNEL_LABEL[id]))))), row(t("setSelfRemove"), t("setSelfRemoveHint"), phase === "confirming" || busy ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
7386
+ }, t(CHANNEL_LABEL[id]))))), row(t("setRegion"), status?.regionAuto === true ? `${t(REGION_HINT[status.region])} ${t("setRegionAuto")}` : t(REGION_HINT[status?.region ?? "global"]), (0, react.createElement)("div", { className: Market_module_css_default.setSeg }, (status?.regions ?? REGIONS).map((id) => (0, react.createElement)("button", {
7387
+ key: id,
7388
+ type: "button",
7389
+ className: status?.region === id ? `${Market_module_css_default.setSegBtn} ${Market_module_css_default.setSegOn}` : Market_module_css_default.setSegBtn,
7390
+ disabled: busy || status === null,
7391
+ onClick: () => {
7392
+ onRegion(id);
7393
+ }
7394
+ }, t(REGION_LABEL[id]))))), row(t("setSelfRemove"), t("setSelfRemoveHint"), phase === "confirming" || busy ? null : (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
7298
7395
  variant: "outline",
7299
7396
  size: "sm",
7300
7397
  className: Market_module_css_default.setDanger,