dsh-plugin-shop 0.4.6 → 0.4.8

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 CHANGED
@@ -50,9 +50,9 @@ install them once with `npm install -g @deepseek-ai/dsh pnpm` and verify with
50
50
  # holds back very recent releases, so a bare `add dsh-plugin-shop` can hand
51
51
  # you an older version for a while. Pin the current release — refresh it
52
52
  # with `npm view dsh-plugin-shop version`.
53
- dsh plugin --profile web add dsh-plugin-shop@0.4.6
53
+ dsh plugin --profile web add dsh-plugin-shop@0.4.8
54
54
  # or straight through npx, nothing installed:
55
- npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-shop@0.4.6
55
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-shop@0.4.8
56
56
  ```
57
57
 
58
58
  Replace `web` with your profile if you use another one. Then restart `dsh` once — a
@@ -82,7 +82,7 @@ ls -1 "${DSH_HOME:-$HOME/.dsh}/profiles" | grep -v '^node_modules$'
82
82
  cooldown, and deterministic installs are the point of the agent path.
83
83
 
84
84
  ```sh
85
- dsh plugin --profile <profile> add dsh-plugin-shop@0.4.6
85
+ dsh plugin --profile <profile> add dsh-plugin-shop@0.4.8
86
86
  ```
87
87
 
88
88
  **3. Verify — do not skip this.** A zero exit from step 2 means pnpm resolved the
package/lib/client.js CHANGED
@@ -4640,6 +4640,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4640
4640
  }
4641
4641
  /** §7.2 once-per-second poll cadence, as a named constant. */
4642
4642
  const INSTALL_POLL_MS = 1e3;
4643
+ /** How long the check-update button reports "up to date" after a re-check
4644
+ * finds no newer release, before reverting to its idle label. */
4645
+ const CHECK_UP_TO_DATE_MS = 3e3;
4643
4646
  /** The next number of cards to show: the current window plus one batch,
4644
4647
  * clamped so the window never claims more cards than the list holds. */
4645
4648
  function nextVisibleCount(visible, total, batch) {
@@ -4830,6 +4833,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4830
4833
  updateFailed: "更新失败",
4831
4834
  updateTransportFailed: "更新请求未能送达。请稍后重试。",
4832
4835
  checkUpdate: "检查更新",
4836
+ upToDate: "已是最新版本",
4833
4837
  enabledSwitch: "启用",
4834
4838
  toggleFailed: "设置失败,请重试。",
4835
4839
  hotApplyNote: "无需重启,立即生效"
@@ -4899,6 +4903,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
4899
4903
  updateFailed: "Update failed",
4900
4904
  updateTransportFailed: "The update request could not be delivered. Please retry.",
4901
4905
  checkUpdate: "Check for updates",
4906
+ upToDate: "Up to date",
4902
4907
  enabledSwitch: "Enable",
4903
4908
  toggleFailed: "Failed to update. Please retry.",
4904
4909
  hotApplyNote: "takes effect without a restart"
@@ -5757,13 +5762,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5757
5762
  cancelled = true;
5758
5763
  };
5759
5764
  }, [version, request]);
5760
- const [checkingVersion, setCheckingVersion] = (0, react.useState)(false);
5765
+ const [checkState, setCheckState] = (0, react.useState)("idle");
5766
+ const upToDateTimer = (0, react.useRef)(null);
5767
+ (0, react.useEffect)(() => () => {
5768
+ if (upToDateTimer.current !== null) clearTimeout(upToDateTimer.current);
5769
+ }, []);
5761
5770
  const checkVersion = async () => {
5762
- setCheckingVersion(true);
5771
+ setCheckState("checking");
5763
5772
  try {
5764
- setSelfVersion(await version());
5765
- } catch {} finally {
5766
- setCheckingVersion(false);
5773
+ const result = await version();
5774
+ setSelfVersion(result);
5775
+ if (result.outdated) setCheckState("idle");
5776
+ else {
5777
+ setCheckState("up-to-date");
5778
+ upToDateTimer.current = setTimeout(() => setCheckState("idle"), CHECK_UP_TO_DATE_MS);
5779
+ }
5780
+ } catch {
5781
+ setCheckState("idle");
5767
5782
  }
5768
5783
  };
5769
5784
  (0, react.useEffect)(() => {
@@ -5922,9 +5937,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5922
5937
  type: "button",
5923
5938
  className: _dsh_plugin_shop_css_e3675a89_default.checkUpdateButton,
5924
5939
  "data-shop-check-update": true,
5925
- disabled: checkingVersion,
5940
+ disabled: checkState !== "idle",
5926
5941
  onClick: () => void checkVersion(),
5927
- children: t("checkUpdate")
5942
+ children: checkState === "up-to-date" ? t("upToDate") : t("checkUpdate")
5928
5943
  }),
5929
5944
  selfVersion.outdated && selfVersion.latest !== null && selfUpdate.view.kind === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5930
5945
  type: "button",
@@ -6091,6 +6106,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6091
6106
  //#region src/client/index.ts
6092
6107
  /** Dictionary namespace owned by this plugin. */
6093
6108
  const NS = "settings.shop";
6109
+ /** The boot-time warm fetch: the catalog the tab wants on its first open.
6110
+ * Started in apply — the client bundle boots with the web app, long before
6111
+ * the user reaches Settings — so the host's slow network fetch runs while
6112
+ * nobody is looking at the shop, and the tab's mount consumes this promise
6113
+ * instead of starting its own fetch. A rejection stays stored (the injected
6114
+ * catalog falls back to a fresh call); the extra catch keeps the
6115
+ * fire-and-forget from surfacing as an unhandled rejection. */
6116
+ let warmCatalog = null;
6094
6117
  /** Services required by the tab registration and the Remote mount.
6095
6118
  *
6096
6119
  * `remote.shop` is deliberately ABSENT: this package both mounts its own
@@ -6120,8 +6143,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
6120
6143
  if (!result.ok) throw new Error(`shop remote: ${result.error.code}: ${result.error.message}`);
6121
6144
  return result.value;
6122
6145
  };
6146
+ warmCatalog = null;
6147
+ warmCatalog = Promise.resolve(ns.catalog(void 0)).then((result) => unwrap(result));
6148
+ warmCatalog.catch(() => {});
6149
+ Promise.resolve(ns.installed()).then((result) => unwrap(result)).catch(() => {});
6150
+ Promise.resolve(ns.version()).then((result) => unwrap(result)).catch(() => {});
6123
6151
  const injected = () => ({
6124
- catalog: async (args) => unwrap(await ns.catalog(args)),
6152
+ catalog: async (args) => {
6153
+ if (args?.refresh === true) return unwrap(await ns.catalog(args));
6154
+ const warm = warmCatalog;
6155
+ if (warm !== null) try {
6156
+ return await warm;
6157
+ } catch {}
6158
+ const fresh = unwrap(await ns.catalog(args));
6159
+ warmCatalog = Promise.resolve(fresh);
6160
+ return fresh;
6161
+ },
6125
6162
  install: async (args) => unwrap(await ns.installStart(args)),
6126
6163
  installStatus: async (args) => unwrap(await ns.installStatus(args)),
6127
6164
  setEnabled: async (args) => unwrap(await ns.setEnabled(args)),
@@ -3,7 +3,7 @@
3
3
  * that browses the catalog, installs with acknowledgement, toggles
4
4
  * enablement, lists installed plugins, and restarts dsh after installs.
5
5
  * Mounts the shop Remote itself (the assembly does not know this package)
6
- * and holds no privilege beyond the seven `shop/*` methods (§5.3).
6
+ * and holds no privilege beyond the nine `shop/*` methods (§5.3).
7
7
  */
8
8
  import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
9
9
  import type { ShopLocaleKey } from './locales.ts';
@@ -64,6 +64,7 @@ export declare const zh: {
64
64
  updateFailed: string;
65
65
  updateTransportFailed: string;
66
66
  checkUpdate: string;
67
+ upToDate: string;
67
68
  enabledSwitch: string;
68
69
  toggleFailed: string;
69
70
  hotApplyNote: string;
@@ -135,6 +136,7 @@ export declare const en: {
135
136
  updateFailed: string;
136
137
  updateTransportFailed: string;
137
138
  checkUpdate: string;
139
+ upToDate: string;
138
140
  enabledSwitch: string;
139
141
  toggleFailed: string;
140
142
  hotApplyNote: string;
@@ -65,6 +65,9 @@ export declare const RESTART_GRACE_MS = 3000;
65
65
  /** §8 restart handoff: how long the client waits for the new server to
66
66
  * answer before reporting the manual restart command. */
67
67
  export declare const RESTART_WAIT_MS = 30000;
68
+ /** How long the check-update button reports "up to date" after a re-check
69
+ * finds no newer release, before reverting to its idle label. */
70
+ export declare const CHECK_UP_TO_DATE_MS = 3000;
68
71
  /** How many shelf cards mount at a time. The shelf holds ~1900 entries; one
69
72
  * commit of the whole grid is ~28k DOM nodes, so the list renders in batches
70
73
  * behind a sentinel (§A1) and grows on scroll. 48 is ~3-4 rows. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-shop",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "description": "The DeepSeek Harness plugin shop: browse, install, enable, and update dsh plugins from a git-auditable catalog.",
5
5
  "repository": {
6
6
  "type": "git",