@ninkch/dsh-infinite-canvas 0.17.8 → 0.17.9

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.
Files changed (2) hide show
  1. package/client.js +18 -19
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -1610,6 +1610,20 @@ window.__ModuleLoader__.load({
1610
1610
  }
1611
1611
  return { migrated: done, total: targets.length };
1612
1612
  }
1613
+ /** 数据根目录就绪后自动把浏览器 IndexedDB 里的存量资产搬到磁盘(替代原"迁移历史资产"按钮,全自动无需手动触发)。 */
1614
+ async function autoMigrateAssetsToRoot() {
1615
+ if (!S.dataRoot) return;
1616
+ try {
1617
+ const all = await idbAll();
1618
+ const pending = all.some((r) => r && r.blob && !r.rel);
1619
+ if (!pending) return;
1620
+ const r = await migrateAssetsToDisk();
1621
+ if (r.migrated) {
1622
+ toast(T('dataRootMigrated').replace('{n}', String(r.migrated)));
1623
+ update((s) => { s.assetsTick++; });
1624
+ }
1625
+ } catch { /* 静默:迁移失败不影响主流程,下次设置数据根目录时再试 */ }
1626
+ }
1613
1627
  function useAssetUrl(id) {
1614
1628
  const [url, setUrl] = useState(null);
1615
1629
  useEffect(() => {
@@ -6546,7 +6560,6 @@ window.__ModuleLoader__.load({
6546
6560
  const [val, setVal] = useState('');
6547
6561
  const [busy, setBusy] = useState(false);
6548
6562
  const [picking, setPicking] = useState(false);
6549
- const [mig, setMig] = useState(null); // null | {done,total} | 'done'
6550
6563
  useEffect(() => { if (S.dataRoot) setVal(S.dataRoot); }, [S.dataRoot]);
6551
6564
  const save = async () => {
6552
6565
  if (busy) return;
@@ -6556,7 +6569,7 @@ window.__ModuleLoader__.load({
6556
6569
  await refreshDataRoot();
6557
6570
  toast(T('dataRootSaved') + (S.dataRoot ? ':' + S.dataRoot : ''));
6558
6571
  assetIndexSynced = false; // 换了目录:索引要往新目录重建
6559
- syncAssetIndexToHost();
6572
+ autoMigrateAssetsToRoot().then(() => syncAssetIndexToHost()); // 先搬存量资产,再对齐索引
6560
6573
  } catch (e) { toast('设置失败:' + ((e && e.message) || e)); }
6561
6574
  setBusy(false);
6562
6575
  };
@@ -6566,7 +6579,7 @@ window.__ModuleLoader__.load({
6566
6579
  setVal(S.dataRoot || root);
6567
6580
  toast(T('dataRootSaved') + ':' + S.dataRoot);
6568
6581
  assetIndexSynced = false; // 换了目录:索引要往新目录重建
6569
- syncAssetIndexToHost();
6582
+ autoMigrateAssetsToRoot().then(() => syncAssetIndexToHost());
6570
6583
  };
6571
6584
  const browse = async () => {
6572
6585
  if (busy || picking) return;
@@ -6608,16 +6621,6 @@ window.__ModuleLoader__.load({
6608
6621
  } catch (e) { toast('导入失败:' + ((e && e.message) || e)); }
6609
6622
  setBusy(false);
6610
6623
  };
6611
- const migrate = async () => {
6612
- if (busy || picking || mig) return;
6613
- setBusy(true); setMig({ done: 0, total: 0 });
6614
- try {
6615
- const r = await migrateAssetsToDisk((done, total) => setMig({ done, total }));
6616
- setMig('done');
6617
- toast(T('dataRootMigrated').replace('{n}', String(r.migrated)));
6618
- } catch (e) { setMig(null); toast('迁移失败:' + ((e && e.message) || e)); }
6619
- setBusy(false);
6620
- };
6621
6624
  return h('div', { key: 'dataroot', className: 'dshic-card' },
6622
6625
  h('div', { className: 'dshic-row' },
6623
6626
  Ic('image', 12),
@@ -6638,10 +6641,6 @@ window.__ModuleLoader__.load({
6638
6641
  picking ? h('div', { className: 'dshic-hint', key: 'picking' }, T('dataRootPicking')) : null,
6639
6642
  h('div', { className: 'dshic-row', key: 'row2' },
6640
6643
  S.dataRoot ? h('button', { type: 'button', className: 'dshic-mini', onPointerDown: (e) => e.stopPropagation(), onClick: openDir }, T('dataRootOpen')) : null,
6641
- S.dataRoot ? h('button', { type: 'button', className: 'dshic-mini', disabled: busy || picking || !!mig, onPointerDown: (e) => e.stopPropagation(), onClick: migrate }, mig === 'done' ? T('dataRootMigratedDone') : T('dataRootMigrate')) : null,
6642
- (mig && mig !== 'done') ? h('span', { style: { fontSize: 11, opacity: 0.85 } }, T('dataRootMigrating') + ' ' + mig.done + '/' + mig.total) : null,
6643
- ),
6644
- h('div', { className: 'dshic-row', key: 'row3' },
6645
6644
  S.dataRoot ? h('button', { type: 'button', className: 'dshic-mini is-ghost', disabled: busy || picking, onPointerDown: (e) => e.stopPropagation(), onClick: importFromRoot }, Ic('folder', 11), T('dataRootImportBtn')) : null,
6646
6645
  S.dataRoot ? InfoTip(T('dataRootImportHint')) : null,
6647
6646
  h('div', { className: 'dshic-flex' }),
@@ -7250,8 +7249,8 @@ window.__ModuleLoader__.load({
7250
7249
  probeCraft();
7251
7250
  // 检查更新(Host RPC;Host 旧版未带此方法时静默)
7252
7251
  checkUpdate(true);
7253
- // 数据根目录(Host 旧版静默降级为 IndexedDB 模式);就绪后把 IDB 资产元数据补齐进数据目录索引
7254
- refreshDataRoot().then(() => syncAssetIndexToHost()).catch(() => { /* 静默 */ });
7252
+ // 数据根目录(Host 旧版静默降级为 IndexedDB 模式);就绪后自动搬存量资产到磁盘,再对齐索引
7253
+ refreshDataRoot().then(() => autoMigrateAssetsToRoot()).then(() => syncAssetIndexToHost()).catch(() => { /* 静默 */ });
7255
7254
  // 对话 ↔ 画布同步(启动一次 + 3s 轮询;旧 Host 自动停轮询)
7256
7255
  hostSyncTick().then(() => pushAllProjectsToHost());
7257
7256
  const hostSyncTimer = setInterval(() => hostSyncTick(), 3000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ninkch/dsh-infinite-canvas",
3
- "version": "0.17.8",
3
+ "version": "0.17.9",
4
4
  "description": "Node-based short-drama studio for DeepSeek Harness: script → storyboard → assets → shots → voiced, subtitled final cut on an infinite canvas.",
5
5
  "keywords": [
6
6
  "dsh",