dsh-ffmpeg 0.6.2 → 0.6.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/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  [历史英文记录](docs/CHANGELOG.en.md)
6
6
 
7
+ ## 0.6.3 (2026-10-27)
8
+
9
+ - 修复分批更新时的新旧更新控件混用:保留原页面、草稿与安装保护,空闲后接管旧控制器,兼容旧入口。
10
+
7
11
  ## 0.6.2 (2026-10-27)
8
12
 
9
13
  - 更新控件移至原有工作台或原生插件详情页底部;更新记录与选项原地展开,移除独立更新菜单与页面。
@@ -176,7 +176,7 @@ function __stardustUpdatesGuard(React, name, { dirty = false, busy = false, reta
176
176
  function __StardustPluginUpdatesFooter({ React, name }) {
177
177
  const [, render] = React.useState(0), pool = __stardustUpdatesGuards();
178
178
  React.useEffect(() => { const fn = () => render(value => value + 1); pool.viewListeners.add(fn); return () => pool.viewListeners.delete(fn); }, []);
179
- const client = [...pool.clients].find(client => client.has(name));
179
+ const client = [...pool.clients].find(client => typeof client.Footer === 'function' && client.has(name));
180
180
  if (!client) return null;
181
181
  return React.createElement(client.Footer, { name });
182
182
  }
@@ -238,14 +238,22 @@ function __stardustUpdatesJoin(host, React, require, participant) {
238
238
  if (typeof root.plugin !== 'function') return;
239
239
  let record = pools.get(root);
240
240
  if (!record) {
241
- record = { refs: new Map(), timer: null, version: participant.version, alive: true, hold: false };
241
+ record = { refs: new Map(), timer: null, version: participant.version, alive: true, hold: false, uiRevision: 2 };
242
242
  pools.set(root, record);
243
+ __stardustUpdatesActivate(record, pools, root, React, require);
244
+ } else if (record.uiRevision !== 2 && !record.migration) {
245
+ // The first loaded participant may still own a pre-footer client. Keep
246
+ // its references and draft guards, wait for any admitted install, then
247
+ // replace that one client fiber instead of running two window heartbeats.
243
248
  const shared = record;
244
- record.fiber = root.plugin({ name: 'stardustlc-plugin-updates-client', inject: ['slots', 'locale', 'remote', 'remote.pluginManager'], apply(ctx) {
245
- const client = __stardustUpdatesClient(ctx, React, require, shared);
246
- ctx.effect(() => () => { shared.alive = false; client.dispose(); if (pools.get(root) === shared) pools.delete(root); });
247
- } });
248
- Promise.resolve(record.fiber).catch(() => { shared.alive = false; if (pools.get(root) === shared) pools.delete(root); });
249
+ record.migration = Promise.resolve().then(async () => {
250
+ while (shared.alive && shared.hold) await new Promise(resolve => setTimeout(resolve, 500));
251
+ if (!shared.alive || !shared.refs.size) return;
252
+ await shared.fiber?.dispose?.();
253
+ if (!shared.refs.size) return;
254
+ shared.alive = true; shared.uiRevision = 2; pools.set(root, shared);
255
+ __stardustUpdatesActivate(shared, pools, root, React, require);
256
+ }).catch(() => { /* The original page remains usable if host disposal fails. */ });
249
257
  }
250
258
  clearTimeout(record.timer);
251
259
  const ref = {}; record.refs.set(ref, participant);
@@ -259,10 +267,17 @@ function __stardustUpdatesJoin(host, React, require, participant) {
259
267
  if (!record.refs.size) record.timer = setTimeout(stop, 1000);
260
268
  });
261
269
  }
270
+ function __stardustUpdatesActivate(shared, pools, root, React, require) {
271
+ shared.fiber = root.plugin({ name: 'stardustlc-plugin-updates-client', inject: ['slots', 'locale', 'remote', 'remote.pluginManager'], apply(ctx) {
272
+ const client = __stardustUpdatesClient(ctx, React, require, shared);
273
+ ctx.effect(() => () => { shared.alive = false; client.dispose(); if (pools.get(root) === shared) pools.delete(root); });
274
+ } });
275
+ Promise.resolve(shared.fiber).catch(() => { shared.alive = false; if (pools.get(root) === shared) pools.delete(root); });
276
+ }
262
277
  function __stardustUpdatesClient(ctx, React, require, shared) {
263
278
  const h = React.createElement, W = createWorkbenchUI(React), route = new URL('api/stardustlc/plugin-updates', document.baseURI);
264
279
  const { useState, useEffect } = React, id = crypto.randomUUID(), listeners = new Set(), pool = __stardustUpdatesGuards(), requests = new Set(), notified = new Set(), knownRows = new Map();
265
- let alive = true, registered = false, state = null, lastInteraction = Date.now(), inPoll = false, manualOperation = false;
280
+ let alive = true, registered = false, state = null, lastInteraction = Date.now(), inPoll = false, manualOperation = false, legacyHint = null;
266
281
  const language = () => String(ctx.locale?.getSnapshot?.().active || '').startsWith('en') ? 'en' : 'zh';
267
282
  const t = (zh, en) => language() === 'en' ? en : zh;
268
283
  const preferences = name => state?.preferences.packages[name] || { checkEnabled: true, autoInstall: false, deferredUntil: 0, ignoredVersion: null };
@@ -387,11 +402,11 @@ function __stardustUpdatesClient(ctx, React, require, shared) {
387
402
  function Reminder() {
388
403
  useSnapshot();
389
404
  const row = state?.rows.find(row => { const prefs = preferences(row.name); return row.available && !row.updating && !row.bundledBy && prefs.checkEnabled && prefs.deferredUntil <= Date.now() && prefs.ignoredVersion !== row.release.version && !notified.has(row.name + '@' + row.release.version); });
390
- if (!row) return null;
405
+ if (!row && !legacyHint) return null;
391
406
  let Toast; try { Toast = require('@deepseek-ai/dsh-client-ui-primitives').Toast; } catch { return null; }
392
407
  if (!Toast) return null;
393
- const key = row.name + '@' + row.release.version;
394
- return h(Toast, { key, text: (language() === 'en' ? row.labelEn : row.label) + t('有新版本,可在页面底部查看。', ' has an update. Review it at the bottom of its page.'), icon: h(W.Icon, { name: 'refresh', size: 18 }), holdMs: 7000, onDone: () => { notified.add(key); notify(); } });
408
+ const hint = legacyHint, key = hint ? 'legacy-' + hint : row.name + '@' + row.release.version;
409
+ return h(Toast, { key, text: hint ? hint + t(':请打开「插件」中的此插件详情页,在底部管理更新。', ': open its details in Plugins to manage updates at the bottom.') : (language() === 'en' ? row.labelEn : row.label) + t('有新版本,可在页面底部查看。', ' has an update. Review it at the bottom of its page.'), icon: h(W.Icon, { name: 'refresh', size: 18 }), holdMs: 7000, onDone: () => { if (hint) legacyHint = null; else notified.add(key); notify(); } });
395
410
  }
396
411
  function register() {
397
412
  if (!alive) return;
@@ -410,7 +425,7 @@ function __stardustUpdatesClient(ctx, React, require, shared) {
410
425
  finally { inPoll = false; }
411
426
  }
412
427
  const timer = setInterval(() => { void poll(); }, 15000), first = setTimeout(() => { void poll(); }, 100);
413
- const client = { t, Footer: Panel, has: name => registered && !!originalRow(name), row: rowFor, dispose() {
428
+ const client = { t, Footer: Panel, Button: W.Button, open(name) { const footer = [...document.querySelectorAll('[data-plugin-update-footer]')].find(node => node.getAttribute('data-plugin-update-footer') === name); if (footer) footer.scrollIntoView({ block: 'end', behavior: 'smooth' }); else { legacyHint = name; notify(); } }, has: name => registered && !!originalRow(name), row: rowFor, dispose() {
414
429
  close(); alive = false; clearTimeout(first); clearInterval(timer); pool.clients.delete(client);
415
430
  pool.listeners.delete(guardChanged); listeners.clear();
416
431
  for (const event of ['pointerdown', 'keydown', 'input']) document.removeEventListener(event, interaction, true);
@@ -422,7 +437,7 @@ function __stardustUpdatesClient(ctx, React, require, shared) {
422
437
  }
423
438
 
424
439
  /* STARDUSTLC_UPDATE_CLIENT_BODY_START */
425
- window.__ModuleLoader__.load(__stardustUpdatesWrap({id:"dsh-ffmpeg",factory:require=>({apply(){}})},{"name":"dsh-ffmpeg","version":"0.1.0","hasWorkbench":false,"packageVersion":"0.6.2","label":"FFmpeg","labelEn":"FFmpeg","suiteComponent":true}));
440
+ window.__ModuleLoader__.load(__stardustUpdatesWrap({id:"dsh-ffmpeg",factory:require=>({apply(){}})},{"name":"dsh-ffmpeg","version":"0.1.0","hasWorkbench":false,"packageVersion":"0.6.3","label":"FFmpeg","labelEn":"FFmpeg","suiteComponent":true}));
426
441
 
427
442
  /* STARDUSTLC_UPDATE_CLIENT_BODY_END */
428
443
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ffmpeg",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "用自然语言调用 FFmpeg,处理已有音视频文件。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -70,6 +70,6 @@
70
70
  "author": "stardustlc",
71
71
  "packageManager": "pnpm@11.7.0",
72
72
  "dependencies": {
73
- "@stardustlc/dsh-updates": "0.1.2"
73
+ "@stardustlc/dsh-updates": "0.1.3"
74
74
  }
75
75
  }