{"version":3,"file":"scan-CY2O9ty6.cjs","names":[],"sources":["../../src/island/scan.ts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport type { Dirent } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\n\n// --- Island scanner ---\n//\n// Walks `src/islands/` and lists every island component module. Each `.ts`\n// file (recursively) is treated as one island whose name is derived from its\n// path relative to the islands root:\n//\n//   src/islands/LikeButton.ts        -> \"LikeButton\"\n//   src/islands/nav/MobileMenu.ts    -> \"nav/MobileMenu\"\n//\n// The name must match the first argument passed to `island(name, ...)` on the\n// server so the client registry can look the component up during hydration.\n\n/** A single island component discovered by the scanner. */\nexport interface IslandModule {\n  /** Registry name, derived from the path relative to the islands dir. */\n  name: string;\n  /** Absolute file system path to the island module. */\n  filePath: string;\n}\n\nasync function walk(dir: string): Promise<string[]> {\n  let entries: Dirent<string>[];\n  try {\n    entries = (await readdir(dir, {\n      withFileTypes: true,\n      encoding: \"utf8\",\n    })) as Dirent<string>[];\n  } catch {\n    return [];\n  }\n\n  const files: string[] = [];\n  for (const entry of entries) {\n    const full = join(dir, entry.name);\n    if (entry.isDirectory()) {\n      files.push(...(await walk(full)));\n    } else if (\n      entry.isFile() &&\n      entry.name.endsWith(\".ts\") &&\n      !entry.name.endsWith(\".d.ts\") &&\n      !entry.name.endsWith(\".test.ts\")\n    ) {\n      files.push(full);\n    }\n  }\n  return files;\n}\n\nfunction toIslandName(islandsDir: string, filePath: string): string {\n  return relative(islandsDir, filePath)\n    .replace(/\\.ts$/, \"\")\n    .split(sep)\n    .join(\"/\");\n}\n\n/**\n * Scans an islands directory for island component modules.\n *\n * @param islandsDir Absolute path to the islands directory (e.g. \"src/islands\").\n * @returns Discovered island modules, sorted by name.\n */\nexport async function scanIslands(islandsDir: string): Promise<IslandModule[]> {\n  const files = await walk(islandsDir);\n  return files\n    .map((filePath) => ({ name: toIslandName(islandsDir, filePath), filePath }))\n    .sort((a, b) => a.name.localeCompare(b.name));\n}\n"],"mappings":"yDAwBA,eAAe,EAAK,EAAgC,CAClD,IAAI,EACJ,GAAI,CACF,EAAW,MAAA,EAAM,EAAA,QAAA,CAAQ,EAAK,CAC5B,cAAe,GACf,SAAU,MACZ,CAAC,CACH,MAAQ,CACN,MAAO,CAAC,CACV,CAEA,IAAM,EAAkB,CAAC,EACzB,IAAK,IAAM,KAAS,EAAS,CAC3B,IAAM,GAAA,EAAO,EAAA,KAAA,CAAK,EAAK,EAAM,IAAI,EAC7B,EAAM,YAAY,EACpB,EAAM,KAAK,GAAI,MAAM,EAAK,CAAI,CAAE,EAEhC,EAAM,OAAO,GACb,EAAM,KAAK,SAAS,KAAK,GACzB,CAAC,EAAM,KAAK,SAAS,OAAO,GAC5B,CAAC,EAAM,KAAK,SAAS,UAAU,GAE/B,EAAM,KAAK,CAAI,CAEnB,CACA,OAAO,CACT,CAEA,SAAS,EAAa,EAAoB,EAA0B,CAClE,OAAA,EAAO,EAAA,SAAA,CAAS,EAAY,CAAQ,CAAC,CAClC,QAAQ,QAAS,EAAE,CAAC,CACpB,MAAM,EAAA,GAAG,CAAC,CACV,KAAK,GAAG,CACb,CAQA,eAAsB,EAAY,EAA6C,CAE7E,OAAO,MADa,EAAK,CAAU,EAAA,CAEhC,IAAK,IAAc,CAAE,KAAM,EAAa,EAAY,CAAQ,EAAG,UAAS,EAAE,CAAC,CAC3E,MAAM,EAAG,IAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,CAChD"}