dsh-crossterm 0.3.39 → 0.4.0

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/lib/bus.js CHANGED
@@ -22,7 +22,7 @@ import os from 'node:os'
22
22
  import path from 'node:path'
23
23
  import crypto from 'node:crypto'
24
24
 
25
- export const VERSION = '0.3.39'
25
+ export const VERSION = '0.4.0'
26
26
 
27
27
  /** DSH 的家目录:与宿主其它状态(sessions / profiles)同一个根,多终端天然共享 */
28
28
  export function dshHome() {
@@ -145,15 +145,26 @@ export async function backupAttachments({ pan, layout, objectsRoot, stateFile, l
145
145
  const remoteDir = layout.paths.attachmentDir
146
146
  const result = { ok: true, total: 0, uploaded: 0, skipped: 0, bytes: 0, pending: 0, error: '' }
147
147
  let files = []
148
- try { files = fs.readdirSync(objectsRoot, { withFileTypes: true }).filter((d) => d.isFile()).map((d) => d.name) } catch { return result }
148
+ // DSH 的附件仓库是两层结构:objects/<前两位>/<sha256>,只读顶层会一个都拿不到。
149
+ try {
150
+ for (const bucket of fs.readdirSync(objectsRoot, { withFileTypes: true })) {
151
+ if (bucket.isFile()) { files.push({ name: bucket.name, dir: objectsRoot }); continue }
152
+ if (!bucket.isDirectory()) continue
153
+ const sub = path.join(objectsRoot, bucket.name)
154
+ let inner = []
155
+ try { inner = fs.readdirSync(sub, { withFileTypes: true }) } catch { continue }
156
+ for (const f of inner) if (f.isFile()) files.push({ name: f.name, dir: sub })
157
+ }
158
+ } catch { return result }
149
159
  result.total = files.length
150
- const todo = files.filter((f) => !state.attachments[f])
160
+ const todo = files.filter((f) => !state.attachments[f.name])
151
161
  result.skipped = files.length - todo.length
152
162
  result.pending = Math.max(0, todo.length - maxFiles)
153
163
  if (!todo.length) return result
154
164
  await pan.mkdir(remoteDir)
155
- for (const name of todo.slice(0, maxFiles)) {
156
- const full = path.join(objectsRoot, name)
165
+ for (const item of todo.slice(0, maxFiles)) {
166
+ const name = item.name
167
+ const full = path.join(item.dir, name)
157
168
  try {
158
169
  const st = fs.statSync(full)
159
170
  await pan.put(full, `${remoteDir}/${name}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crossterm",
3
- "version": "0.3.39",
3
+ "version": "0.4.0",
4
4
  "description": "DSH 跨终端互联:同一账号下的多个 DSH 终端/进程互发邮件与文件(主题内联、正文落盘,收件方自己读)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",