MCPcopy Create free account
hub / github.com/backnotprop/plannotator / handleFileBrowserFilesStream

Function handleFileBrowserFilesStream

packages/server/reference-watch.ts:126–192  ·  view source on GitHub ↗
(
	req: Request,
	options?: { disableIdleTimeout?: () => void },
)

Source from the content-addressed store, hash-verified

124}
125
126export function handleFileBrowserFilesStream(
127 req: Request,
128 options?: { disableIdleTimeout?: () => void },
129): Response {
130 const url = new URL(req.url);
131 const rawDirPaths = url.searchParams.getAll("dirPath");
132 if (rawDirPaths.length === 0) {
133 return Response.json({ error: "Missing dirPath parameter" }, { status: 400 });
134 }
135
136 const dirPaths: string[] = [];
137 const clientDirPaths: string[] = [];
138 for (const rawDirPath of rawDirPaths) {
139 const dirPath = resolveUserPath(rawDirPath);
140 if (!isValidDirectory(dirPath)) {
141 return Response.json({ error: "Invalid directory path" }, { status: 400 });
142 }
143 if (!dirPaths.includes(dirPath)) {
144 dirPaths.push(dirPath);
145 clientDirPaths.push(rawDirPath);
146 }
147 }
148
149 options?.disableIdleTimeout?.();
150 const entries = dirPaths.map((dirPath) => ensureWatcher(dirPath));
151
152 let controllerRef: ReadableStreamDefaultController | null = null;
153 let heartbeatTimer: ReturnType<typeof setInterval> | null = null;
154 const stream = new ReadableStream({
155 start(controller) {
156 controllerRef = controller;
157 for (let i = 0; i < entries.length; i++) {
158 const entry = entries[i]!;
159 const clientDirPath = clientDirPaths[i] ?? entry.dirPath;
160 entry.subscribers.set(controller, clientDirPath);
161 controller.enqueue(serialize({
162 type: "ready",
163 dirPath: clientDirPath,
164 reason: "initial",
165 timestamp: Date.now(),
166 }));
167 }
168 heartbeatTimer = setInterval(() => {
169 try {
170 controller.enqueue(encoder.encode(": heartbeat\n\n"));
171 } catch {
172 for (const entry of entries) releaseSubscriber(entry, controller);
173 if (heartbeatTimer) clearInterval(heartbeatTimer);
174 }
175 }, HEARTBEAT_MS);
176 },
177 cancel() {
178 if (heartbeatTimer) clearInterval(heartbeatTimer);
179 if (controllerRef) {
180 for (const entry of entries) releaseSubscriber(entry, controllerRef);
181 }
182 },
183 });

Callers 3

fetchFunction · 0.90
fetchFunction · 0.90

Calls 5

resolveUserPathFunction · 0.90
getAllMethod · 0.80
isValidDirectoryFunction · 0.70
ensureWatcherFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected