跳到主要内容

SyncFolderPushCommand

SyncFolderPushCommand 是一个高级命令,旨在高效地将本地目录与您的 DID Space 中的远程目录同步。它能智能地比较本地和远程状态,上传新的或已修改的文件,并可选择性地删除远程存在但本地已不存在的文件。此命令简化了诸如部署静态网站、备份重要数据或分发数字资产等常见任务。

它处理了并发、重试和一致性检查等复杂问题,为管理文件夹同步提供了一种强大而直接的方式。

使用场景

  • 部署静态网站:将您的本地构建目录(例如 ./dist./build)推送到您 DID Space 中的公共文件夹,以部署或更新网站。
  • 数据备份:定期将包含重要文档或用户数据的本地文件夹同步到您的 DID Space,以进行安全备份。
  • 资产分发:上传一个包含图像、视频或其他您的应用程序需要提供给用户的资产的文件夹。

输入参数

SyncFolderPushCommand 在其输入对象中接受以下参数。

  • source string | SourceObject[] (required) — 指定要同步的本地源。这可以是一个表示本地目录路径的字符串,也可以是一个用于更精细控制的对象数组。
  • target string (required) — 文件将同步到的您 DID Space 中的目标路径。它应以“/”结尾。
  • metadata ObjectMetadata — 附加到目标文件夹对象的自定义元数据。
  • preview PreviewTemplate — 为目标文件夹设置的预览模板。更多详情,请参阅管理文件夹预览指南。
  • strictSync boolean (default: false) — 如果为 true,将删除远程目标中存在但本地源中不存在的文件。请谨慎使用。
  • filter (object: Object) => boolean — 一个用于筛选应包含在同步中的本地对象的函数。返回 true 以包含对象,返回 false 以排除对象。
  • onProgress (progress: OnProgressInput) => void — 一个定期触发的回调函数,用于报告同步进度。
  • onAfterUpload (result: OnAfterUploadInput) => void — 一个在每个单独文件上传完成后触发的回调函数。
  • concurrency number (default: 4) — 并行上传的文件数量。最大值为 CPU 核心数。
  • retryCount number (default: 3) — 单个文件上传失败的重试次数。最大值为 10。
  • tmpDir string — 用于处理文件的临时目录的路径。默认为系统生成的临时目录。
  • debug boolean (default: false) — 如果为 true,则启用向控制台输出详细的调试日志。

输出

该命令返回一个 Promise,其解析值为以下对象。

  • statusCode number — 整个操作的 HTTP 状态码。200 表示成功。
  • statusMessage string — 提供有关操作结果更多详细信息的消息。
  • data object — 一个包含同步过程结果的对象。
  • size number — 所有成功上传文件的总大小,单位为字节。
  • count number — 尝试的总操作数(上传和删除)。
  • errorCount number — 失败的操作数。
  • duration number — 同步所花费的总时间,单位为秒。

示例

此示例演示了如何将名为 ./my-blog-dist 的本地文件夹同步到 DID Space 中的 /blog/ 目录。

Syncing a Local Folder

typescript
import { SpaceClient, SyncFolderPushCommand } from '@blocklet/did-space-js';
import getWallet from '@blocklet/sdk/lib/wallet';
import path from 'path';
import fs from 'fs-extra';

// 确保示例所需的源目录和文件存在
const sourceDir = path.join(__dirname, 'my-blog-dist');
fs.ensureDirSync(sourceDir);
fs.writeFileSync(path.join(sourceDir, 'index.html'), '<h1>Hello World</h1>');
fs.ensureDirSync(path.join(sourceDir, 'assets'));
fs.writeFileSync(path.join(sourceDir, 'assets', 'style.css'), 'body { color: #333; }');

async function syncWebsite() {
  const wallet = getWallet();
  const client = new SpaceClient({
    endpoint: 'https://www.didspaces.com/app/api/space/...',
    wallet,
  });

  const command = new SyncFolderPushCommand({
    source: sourceDir,
    target: '/blog/',
    strictSync: true, // 删除源目录中不存在的远程文件
    onProgress: ({ completed, total }) => {
      const percentage = total > 0 ? ((completed / total) * 100).toFixed(2) : 0;
      console.log(`Sync progress: ${completed}/${total} files (${percentage}%)`);
    },
  });

  const output = await client.send(command);

  if (output.statusCode === 200) {
    console.log('Sync completed successfully!');
    console.log(`Total files processed: ${output.data.count}`);
    console.log(`Errors: ${output.data.errorCount}`);
    console.log(`Duration: ${output.data.duration}s`);
  } else {
    console.error('Sync failed:', output.statusMessage);
  }

  // 清理创建的目录
  fs.removeSync(sourceDir);
}

syncWebsite();

示例响应(成功)

Response Data

json
{
  "statusCode": 200,
  "data": {
    "size": 48,
    "errorCount": 0,
    "count": 2,
    "duration": 1.25
  }
}

最佳实践

确保数据一致性

在同步文件时,特别是从一个可能正在被频繁写入的目录同步时,存在上传不完整或损坏文件的风险。为防止这种情况,SyncFolderPushCommand 会在上传前先将每个文件复制到一个临时目录。这确保了上传时使用的是文件的稳定快照,从而防止出现 Unexpected end of form 错误并确保数据完整性。

安全使用 strictSync

strictSync: true 选项功能强大,可确保远程目录与本地源完全一致。然而,这是一个破坏性操作。远程服务器上任何本地源目录中不存在的文件都将被永久删除。在启用此选项之前,请务必仔细检查您的 sourcetarget 路径。

自定义筛选

您可以使用 filter 函数对哪些文件被同步进行精细控制。例如,您可以排除点文件、日志文件或特定目录。

Filtering Files

typescript
const command = new SyncFolderPushCommand({
  source: './project',
  target: '/my-project/',
  filter: (object) => {
    // 排除所有以点开头的文件(例如 .DS_Store、.env)
    if (object.name.startsWith('.')) {
      return false;
    }
    // 排除 node_modules 目录
    if (object.key.includes('/node_modules/')) {
      return false;
    }
    return true;
  },
});