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/ ディレクトリに同期する方法を示します。
ローカルフォルダの同期
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();成功時のレスポンス例
レスポンスデータ
{
"statusCode": 200,
"data": {
"size": 48,
"errorCount": 0,
"count": 2,
"duration": 1.25
}
}ベストプラクティス
データ整合性の確保
ファイルを同期する際、特にアクティブに書き込みが行われる可能性のあるディレクトリから同期する場合、不完全または破損したファイルをアップロードするリスクがあります。これを防ぐため、SyncFolderPushCommand は各ファイルをアップロードする前にまず一時ディレクトリにコピーします。これにより、アップロードにはファイルの安定したスナップショットが使用され、Unexpected end of form エラーを防ぎ、データ整合性を確保します。
strictSync の安全な使用
strictSync: true オプションは、リモートディレクトリがローカルソースの正確なミラーであることを保証する強力な機能です。しかし、これは破壊的な操作です。ローカルのソースディレクトリに存在しないリモートサーバー上のファイルはすべて永久に削除されます。このオプションを有効にする前に、必ず source と target のパスを再確認してください。
カスタムフィルタリング
filter 関数を使用して、どのファイルを同期するかを細かく制御できます。例えば、ドットファイル、ログファイル、または特定のディレクトリを除外することができます。
ファイルのフィルタリング
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;
},
});