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
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
{
"statusCode": 200,
"data": {
"size": 48,
"errorCount": 0,
"count": 2,
"duration": 1.25
}
}最佳实践
确保数据一致性
在同步文件时,特别是从一个可能正在被频繁写入的目录同步时,存在上传不完整或损坏文件的风险。为防止这种情况,SyncFolderPushCommand 会在上传前先将每个文件复制到一个临时目录。这确保了上传时使用的是文件的稳定快照,从而防止出现 Unexpected end of form 错误并确保数据完整性。
安全使用 strictSync
strictSync: true 选项功能强大,可确保远程目录与本地源完全一致。然而,这是一个破坏性操作。远程服务器上任何本地源目录中不存在的文件都将被永久删除。在启用此选项之前,请务必仔细检查您的 source 和 target 路径。
自定义筛选
您可以使用 filter 函数对哪些文件被同步进行精细控制。例如,您可以排除点文件、日志文件或特定目录。
Filtering Files
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;
},
});