Linux のネイティブ inotify を使い、ファイルシステムの変更をリアルタイムで監視します。watch() メソッドは、ファイル変更イベントの SSE(Server-Sent Events)ストリームを返します。ストリームは parseSSEStream() で消費します。
ディレクトリのファイルシステム変更を監視します。イベントの SSE ストリームを返します。
const stream = await sandbox.watch(path: string, options?: WatchOptions): Promise<ReadableStream<Uint8Array>>パラメーター:
path- 絶対パス、または/workspaceからの相対パス(例:/app/srcまたはsrc)options(任意):recursive- サブディレクトリを再帰的に監視します(デフォルト:true)include- 含める glob パターン(例:['*.ts', '*.js'])。excludeと同時には使えません。exclude- 除外する glob パターン(デフォルト:['.git', 'node_modules', '.DS_Store'])。includeと同時には使えません。sessionId- 監視を実行するセッション(省略時は、enableDefaultSessionが false でない限りデフォルトセッションを使います)
戻り値: Promise<ReadableStream<Uint8Array>> — FileWatchSSEEvent オブジェクトの SSE ストリーム
import { parseSSEStream } from "@cloudflare/sandbox";
const stream = await sandbox.watch("/workspace/src", {
recursive: true,
include: ["*.ts", "*.js"],
});
const controller = new AbortController();
for await (const event of parseSSEStream(stream, controller.signal)) {
switch (event.type) {
case "watching":
console.log(`Watch established on ${event.path} (id: ${event.watchId})`);
break;
case "event":
console.log(`${event.eventType}: ${event.path}`);
break;
case "error":
console.error(`Watch error: ${event.error}`);
break;
case "stopped":
console.log(`Watch stopped: ${event.reason}`);
break;
}
}
// Cancel the watch by aborting — cleans up the watcher server-side
controller.abort();import { parseSSEStream } from "@cloudflare/sandbox";
import type { FileWatchSSEEvent } from "@cloudflare/sandbox";
const stream = await sandbox.watch("/workspace/src", {
recursive: true,
include: ["*.ts", "*.js"],
});
const controller = new AbortController();
for await (const event of parseSSEStream<FileWatchSSEEvent>(
stream,
controller.signal,
)) {
switch (event.type) {
case "watching":
console.log(`Watch established on ${event.path} (id: ${event.watchId})`);
break;
case "event":
console.log(`${event.eventType}: ${event.path}`);
break;
case "error":
console.error(`Watch error: ${event.error}`);
break;
case "stopped":
console.log(`Watch stopped: ${event.reason}`);
break;
}
}
// Cancel the watch by aborting — cleans up the watcher server-side
controller.abort();watch ストリームが出すすべての SSE イベントのユニオン型です。
type FileWatchSSEEvent =
| { type: "watching"; path: string; watchId: string }
| {
type: "event";
eventType: FileWatchEventType;
path: string;
isDirectory: boolean;
timestamp: string;
}
| { type: "error"; error: string }
| { type: "stopped"; reason: string };watching— 監視が確立されたときに 1 回出ます。watchIdと監視対象のpathを含みます。event— ファイルシステムの変更ごとに出ます。eventType、変更されたpath、ディレクトリかどうか(isDirectory)を含みます。error— 監視でエラーが起きたときに出ます。stopped— 監視が停止したときに出ます。reasonを含みます。
検出できるファイルシステム変更の種類です。
type FileWatchEventType =
| "create"
| "modify"
| "delete"
| "move_from"
| "move_to"
| "attrib";create— ファイルまたはディレクトリが作成されたmodify— ファイルの内容が変わったdelete— ファイルまたはディレクトリが削除されたmove_from— ファイルまたはディレクトリが移動で離れた(名前変更/移動の元)move_to— ファイルまたはディレクトリがここに移動した(名前変更/移動の先)attrib— ファイルまたはディレクトリの属性が変わった(権限、タイムスタンプ)
ディレクトリ監視の設定オプションです。
interface WatchOptions {
/** Watch subdirectories recursively (default: true) */
recursive?: boolean;
/** Glob patterns to include. Cannot be used together with `exclude`. */
include?: string[];
/** Glob patterns to exclude. Cannot be used together with `include`. Default: ['.git', 'node_modules', '.DS_Store'] */
exclude?: string[];
/** Session to run the watch in. If omitted, the sandbox's implicit execution mode is used. */
sessionId?: string;
}ReadableStream<Uint8Array> を、型付きのイベント AsyncGenerator に変換します。ストリームをキャンセルする任意の AbortSignal を受け取れます。
function parseSSEStream<T>(
stream: ReadableStream<Uint8Array>,
signal?: AbortSignal,
): AsyncGenerator<T>;パラメーター:
stream—watch()が返す SSE ストリームsignal(任意) — ストリームをキャンセルするAbortSignal。abort するとリーダーがキャンセルされ、サーバー側のクリーンアップに伝わります。
消費ループの外から監視を止めるには、シグナルの abort を推奨します。
const controller = new AbortController();
// Cancel after 60 seconds
setTimeout(() => controller.abort(), 60_000);
for await (const event of parseSSEStream<FileWatchSSEEvent>(
stream,
controller.signal,
)) {
// process events
}include と exclude は、予測しやすい照合のため、限られた glob トークンを受け付けます。
| トークン | 意味 | 例 |
|---|---|---|
* |
パスセグメント内の任意の文字に一致 | *.ts は index.ts に一致 |
** |
ディレクトリ境界を越えて一致 | **/*.test.ts |
? |
1 文字に一致 | ?.js は a.js に一致 |
文字クラス([abc])、ブレース展開({a,b})、バックスラッシュエスケープは未対応です。これらのトークンを含むパターンはバリデーションエラーで拒否されます。
- ファイルシステムの変更を監視するガイド — パターン、推奨事項、実例
- ファイル管理ガイド — ファイル操作