60 lines · 2.0 KB · TypeScript
RawDownload
import { statfsSync, statSync } from "node:fs";import { Effect } from "effect";import type { VolumeInfo } from "../contracts";import { neverFails, type DeviceProbe } from "./probe";import { hostPlatform } from "./host"; /** * `statfsSync` works on all three platforms, so free space needs no shellout and no * per-OS parser. Disk model and rotational-ness do need vendor tools; they are reported * as null here rather than shelling out on every sample. */const readVolume = (mount: string): { key: string; volume: VolumeInfo } | null => {  try {    const device = statSync(mount).dev;    const stats = statfsSync(mount);    const blockSize = Number(stats.bsize);    const total = Number(stats.blocks) * blockSize;    const free = Number(stats.bavail) * blockSize;    if (!Number.isFinite(total) || total <= 0) return null;    return {      key: String(device),      volume: {        mount,        totalBytes: total,        freeBytes: Number.isFinite(free) && free >= 0 ? free : 0,        filesystem: null,        model: null,        rotational: null,      },    };  } catch {    return null;  }}; export const systemRoot = (): string => (hostPlatform() === "win32" ? "C:\\" : "/"); /** Sample the system root plus whichever paths matter to this install (model store, *  data root). Duplicate mounts collapse, so passing several paths on one volume is free. */export const readVolumes = (paths: readonly string[]): readonly VolumeInfo[] => {  const seen = new Map<string, VolumeInfo>();  for (const path of [systemRoot(), ...paths]) {    const reading = readVolume(path);    if (!reading) continue;    if (!seen.has(reading.key)) seen.set(reading.key, reading.volume);  }  return [...seen.values()];}; export const storageProbe = (paths: readonly string[]): DeviceProbe => ({  id: "storage",  detect: () => true,  run: () =>    neverFails(      Effect.sync(() => {        const storage = readVolumes(paths);        return { fragment: { storage }, capabilities: storage.length > 0 ? ["storage" as const] : [] };      }),    ),});