@silicajs/core 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/logo.ts","../src/files.ts","../src/precompute.ts"],"sourcesContent":["import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { createJiti } from \"jiti\";\nimport { resolvePublicAssetPath } from \"./logo.js\";\nimport type { ResolvedSilicaConfig, SilicaConfig } from \"./types.js\";\n\nexport function defineConfig(config: SilicaConfig): SilicaConfig {\n return config;\n}\n\nexport async function loadConfig(\n projectRoot = process.cwd(),\n): Promise<ResolvedSilicaConfig> {\n const configPath = path.join(projectRoot, \"silica.config.ts\");\n const jsConfigPath = path.join(projectRoot, \"silica.config.js\");\n const configFile = existsSync(configPath)\n ? configPath\n : existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined;\n\n let userConfig: SilicaConfig = {};\n if (configFile) {\n const jiti = createJiti(projectRoot, { interopDefault: true });\n const loaded = await jiti.import<SilicaConfig | { default: SilicaConfig }>(\n configFile,\n );\n userConfig = \"default\" in loaded ? loaded.default : loaded;\n }\n\n return resolveConfig(userConfig, projectRoot);\n}\n\nexport function resolveConfig(\n config: SilicaConfig = {},\n projectRoot = process.cwd(),\n): ResolvedSilicaConfig {\n const auth = config.auth === false ? undefined : config.auth;\n const authEnabled = Boolean(\n auth?.enabled ??\n auth?.provider ??\n auth?.allowedDomains?.length ??\n auth?.allowedEmails?.length,\n );\n const allowedDomains = auth?.allowedDomains ?? [];\n const allowedEmails = auth?.allowedEmails ?? [];\n\n if (\n authEnabled &&\n allowedDomains.length === 0 &&\n allowedEmails.length === 0\n ) {\n throw new Error(\n \"Silica auth requires at least one allowedDomains or allowedEmails entry.\",\n );\n }\n\n return {\n projectRoot,\n title: config.title ?? \"Silica\",\n description: config.description ?? \"A Silica knowledge site\",\n logo: resolvePublicAssetPath(config.logo),\n baseUrl: config.baseUrl,\n contentDir: config.contentDir ?? \"content\",\n theme: config.theme ?? \"default\",\n auth: authEnabled\n ? {\n provider: auth?.provider ?? \"google\",\n enabled: true,\n allowedDomains,\n allowedEmails,\n }\n : undefined,\n wikilinks: {\n strategy: config.wikilinks?.strategy ?? \"shortest\",\n strict: config.wikilinks?.strict ?? false,\n },\n tags: {\n inline: config.tags?.inline ?? true,\n },\n ordering: {\n numericPrefixes: config.ordering?.numericPrefixes ?? true,\n },\n filters: {\n removeDrafts: config.filters?.removeDrafts ?? true,\n explicitPublish: config.filters?.explicitPublish ?? false,\n },\n };\n}\n","/** Normalize a public asset path or pass through absolute URLs. */\nexport function resolvePublicAssetPath(asset?: string): string | undefined {\n const trimmed = asset?.trim();\n if (!trimmed) return undefined;\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed;\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n","import path from \"node:path\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport matter from \"gray-matter\";\nimport type { ResolvedSilicaConfig } from \"./types.js\";\nimport { asFilePath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n relativePath: string;\n slug: string;\n raw: string;\n body: string;\n frontmatter: Record<string, unknown>;\n stats: {\n birthtime?: Date;\n mtime?: Date;\n };\n};\n\nexport type ContentAssetFile = {\n absolutePath: string;\n relativePath: string;\n};\n\nexport type ContentScan = {\n markdown: ContentMarkdownFile[];\n assets: ContentAssetFile[];\n};\n\nexport async function scanContent(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n): Promise<ContentScan> {\n const contentRoot = path.join(projectRoot, config.contentDir);\n const realContentRoot = await fs.realpath(contentRoot);\n const entries = await fg(\"**/*\", {\n cwd: contentRoot,\n dot: false,\n followSymbolicLinks: false,\n onlyFiles: true,\n unique: true,\n });\n\n const markdown: ContentMarkdownFile[] = [];\n const assets: ContentAssetFile[] = [];\n\n for (const relativePath of entries.sort()) {\n const absolutePath = path.join(contentRoot, relativePath);\n const stats = await fs.lstat(absolutePath);\n if (!stats.isFile()) continue;\n if (!(await isWithinRoot(absolutePath, realContentRoot))) continue;\n\n if (isMarkdownFile(relativePath)) {\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const parsed = matter(raw);\n markdown.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n slug: slugifyFilePath(\n asFilePath(relativePath),\n config.contentDir,\n config.ordering,\n ),\n raw,\n body: parsed.content,\n frontmatter: parsed.data,\n stats: {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n },\n });\n } else {\n assets.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n });\n }\n }\n\n return { markdown, assets };\n}\n\nasync function isWithinRoot(\n absolutePath: string,\n realRoot: string,\n): Promise<boolean> {\n const realPath = await fs.realpath(absolutePath);\n const relative = path.relative(realRoot, realPath);\n return (\n relative === \"\" ||\n (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n );\n}\n\nexport function isMarkdownFile(filePath: string): boolean {\n return /\\.(md|markdown|mdx)$/i.test(filePath);\n}\n","import crypto from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Worker } from \"node:worker_threads\";\nimport fs from \"fs-extra\";\nimport {\n buildSearchDatabase,\n SEARCH_DATABASE_FILENAME,\n type SearchRecord,\n} from \"@silicajs/search\";\nimport { loadConfig } from \"./config.js\";\nimport { scanContent, type ContentMarkdownFile } from \"./files.js\";\nimport {\n asFullSlug,\n createWikiLinkResolutionIndex,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n stripNumericPrefix,\n slugToHref,\n type WikiLinkResolutionIndex,\n} from \"./path.js\";\nimport { getMenuLabel } from \"./pipeline/frontmatter.js\";\nimport { analyzeMarkdown } from \"./pipeline/index.js\";\nimport type {\n AnalyzeResult,\n BrokenLink,\n Graph,\n Manifest,\n ManifestEntry,\n Navigation,\n PrecomputeResult,\n ResolvedSilicaConfig,\n} from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\nconst MIN_PARALLEL_ANALYSIS_FILES = 64;\nconst ANALYSIS_BATCH_SIZE = 16;\nconst MAX_ANALYSIS_WORKERS = 12;\n\nexport type PrecomputeOptions = {\n projectRoot?: string;\n config?: ResolvedSilicaConfig;\n analysisConcurrency?: number;\n};\n\nexport async function precompute(\n options: PrecomputeOptions = {},\n): Promise<PrecomputeResult> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const config = options.config ?? (await loadConfig(projectRoot));\n const scan = await scanContent(projectRoot, config);\n const markdownFiles = filterPublished(scan.markdown, config);\n const allSlugs = markdownFiles.map((file) => file.slug);\n const wikilinkIndex = createWikiLinkResolutionIndex(\n allSlugs,\n config.ordering,\n );\n const entries: ManifestEntry[] = [];\n const graphLinks: Record<string, string[]> = {};\n const brokenLinks: BrokenLink[] = [];\n const searchRecords: SearchRecord[] = [];\n const runtimeContentRoot = path.join(projectRoot, \".silica/content\");\n const relativeGitPaths = markdownFiles.map((file) =>\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n );\n const gitDatesByPath = await getGitDatesForFiles(\n projectRoot,\n relativeGitPaths,\n );\n\n await fs.ensureDir(path.join(projectRoot, \".silica\"));\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public/silica\"));\n await writeRuntimeMarkdown(runtimeContentRoot, markdownFiles);\n const analyses = await analyzeMarkdownFiles(markdownFiles, config, allSlugs, {\n concurrency: options.analysisConcurrency,\n wikilinkIndex,\n });\n\n for (const [index, file] of markdownFiles.entries()) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n ) ?? {};\n const analysis = analyses[index]!;\n\n const title =\n analysis.title ?? titleFromFilePath(file.relativePath, config.ordering);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes &&\n hasNumericPrefixInPath(file.relativePath)\n ? numericPrefixSortKey(file.relativePath)\n : undefined;\n const entry: ManifestEntry = {\n slug: file.slug,\n title,\n menuLabel,\n description: analysis.description,\n generatedDescription: analysis.generatedDescription,\n tags: analysis.tags,\n file: normalizeGitPath(path.join(\".silica/content\", file.relativePath)),\n relativeFile: file.relativePath,\n sortKey,\n created: stringifyDate(\n getDate(file.frontmatter.created) ??\n getDate(file.frontmatter.date) ??\n gitDates.created ??\n file.stats.birthtime,\n ),\n modified: stringifyDate(\n getDate(file.frontmatter.modified) ??\n gitDates.modified ??\n file.stats.mtime,\n ),\n frontmatter: file.frontmatter,\n };\n entries.push(entry);\n graphLinks[file.slug] = analysis.links;\n brokenLinks.push(...analysis.brokenLinks);\n if (isListedEntry(entry)) {\n searchRecords.push({\n id: file.slug,\n slug: file.slug,\n title,\n content: analysis.plainText,\n description: analysis.description,\n tags: analysis.tags,\n });\n }\n }\n\n await copyAssets(projectRoot, config, scan.assets);\n\n const manifest = makeManifest(config, entries);\n const graph = makeGraph(graphLinks, brokenLinks);\n const buildId = crypto.randomUUID();\n await buildSearchDatabase(\n searchRecords,\n path.join(projectRoot, \".silica\", SEARCH_DATABASE_FILENAME),\n );\n await fs.remove(path.join(projectRoot, \".silica/search-index.json\"));\n\n await writeJson(\n path.join(projectRoot, \".silica/manifest.json\"),\n serializeManifest(manifest),\n );\n await writeJson(\n path.join(projectRoot, \".silica/navigation.json\"),\n makeNavigation(manifest),\n );\n await writeJson(path.join(projectRoot, \".silica/graph.json\"), graph);\n await writeJson(path.join(projectRoot, \".silica/config.json\"), config);\n await fs.writeFile(\n path.join(projectRoot, \".silica/build-id.txt\"),\n `${buildId}\\n`,\n );\n await writeSitemapAndRobots(projectRoot, config, manifest);\n\n if (config.wikilinks.strict && brokenLinks.length > 0) {\n const message = brokenLinks\n .map((link) => `${link.source} -> ${link.target}`)\n .join(\"\\n\");\n throw new Error(`Broken wikilinks detected:\\n${message}`);\n }\n\n return {\n manifest,\n graph,\n searchRecords,\n buildId,\n brokenLinks,\n };\n}\n\ntype AnalyzeMarkdownFilesOptions = {\n concurrency?: number;\n wikilinkIndex: WikiLinkResolutionIndex;\n};\n\ntype AnalysisWorkerFile = {\n index: number;\n slug: string;\n raw: string;\n};\n\ntype AnalysisWorkerMessage = {\n id: number;\n files: AnalysisWorkerFile[];\n};\n\ntype AnalysisWorkerResult = {\n id: number;\n results?: Array<{ index: number; analysis: AnalyzeResult }>;\n error?: string;\n};\n\nasync function analyzeMarkdownFiles(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n allSlugs: string[],\n options: AnalyzeMarkdownFilesOptions,\n): Promise<AnalyzeResult[]> {\n const workerCount = getAnalysisWorkerCount(files.length, options.concurrency);\n if (workerCount <= 1) {\n return analyzeMarkdownFilesSerial(files, config, options.wikilinkIndex);\n }\n\n return analyzeMarkdownFilesParallel(files, config, allSlugs, workerCount);\n}\n\nasync function analyzeMarkdownFilesSerial(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n wikilinkIndex: WikiLinkResolutionIndex,\n): Promise<AnalyzeResult[]> {\n const analyses: AnalyzeResult[] = [];\n for (const file of files) {\n analyses.push(\n await analyzeMarkdown(file.raw, {\n slug: asFullSlug(file.slug),\n wikilinkIndex,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n }),\n );\n }\n return analyses;\n}\n\nfunction analyzeMarkdownFilesParallel(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n allSlugs: string[],\n workerCount: number,\n): Promise<AnalyzeResult[]> {\n return new Promise((resolve, reject) => {\n const workerUrl = new URL(\"./precompute-worker.js\", import.meta.url);\n const workers: Worker[] = [];\n const analyses: AnalyzeResult[] = new Array(files.length);\n let nextIndex = 0;\n let completed = 0;\n let settled = false;\n\n const rejectOnce = (error: unknown) => {\n if (settled) return;\n settled = true;\n for (const worker of workers) {\n void worker.terminate();\n }\n reject(error);\n };\n\n const resolveIfDone = () => {\n if (completed < files.length || settled) return;\n settled = true;\n for (const worker of workers) {\n void worker.terminate();\n }\n resolve(analyses);\n };\n\n const sendNext = (worker: Worker) => {\n if (settled || nextIndex >= files.length) return;\n const start = nextIndex;\n const batch = files\n .slice(start, start + ANALYSIS_BATCH_SIZE)\n .map((file, offset) => ({\n index: start + offset,\n slug: file.slug,\n raw: file.raw,\n }));\n nextIndex += batch.length;\n worker.postMessage({\n id: start,\n files: batch,\n } satisfies AnalysisWorkerMessage);\n };\n\n for (let index = 0; index < workerCount; index += 1) {\n const worker = new Worker(workerUrl, {\n workerData: {\n allSlugs,\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n },\n });\n workers.push(worker);\n worker.on(\"message\", (message: AnalysisWorkerResult) => {\n if (message.error) {\n rejectOnce(new Error(message.error));\n return;\n }\n for (const result of message.results ?? []) {\n analyses[result.index] = result.analysis;\n }\n completed += message.results?.length ?? 0;\n resolveIfDone();\n sendNext(worker);\n });\n worker.on(\"error\", rejectOnce);\n worker.on(\"exit\", (code) => {\n if (!settled && code !== 0) {\n rejectOnce(\n new Error(`Precompute analysis worker exited with ${code}`),\n );\n }\n });\n sendNext(worker);\n }\n });\n}\n\nfunction getAnalysisWorkerCount(\n fileCount: number,\n requestedConcurrency: number | undefined,\n): number {\n if (fileCount === 0) return 1;\n if (\n requestedConcurrency === undefined &&\n fileCount < MIN_PARALLEL_ANALYSIS_FILES\n ) {\n return 1;\n }\n\n const available = Math.max(\n 1,\n os.availableParallelism?.() ?? os.cpus().length,\n );\n const requested = getRequestedAnalysisConcurrency(\n requestedConcurrency,\n available,\n );\n const usefulWorkers = Math.ceil(fileCount / ANALYSIS_BATCH_SIZE);\n return Math.max(1, Math.min(fileCount, requested, usefulWorkers));\n}\n\nfunction getRequestedAnalysisConcurrency(\n requestedConcurrency: number | undefined,\n available: number,\n): number {\n if (requestedConcurrency === undefined) {\n return Math.min(available, MAX_ANALYSIS_WORKERS);\n }\n if (!Number.isFinite(requestedConcurrency)) return 1;\n return Math.max(1, Math.floor(requestedConcurrency));\n}\n\nasync function writeRuntimeMarkdown(\n runtimeContentRoot: string,\n files: ContentMarkdownFile[],\n): Promise<void> {\n await fs.emptyDir(runtimeContentRoot);\n for (const file of files) {\n const destination = path.join(runtimeContentRoot, file.relativePath);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, file.raw);\n }\n}\n\nfunction serializeManifest(\n manifest: Manifest,\n): Omit<Manifest, \"allSlugs\" | \"bySlug\"> {\n return {\n version: manifest.version,\n generatedAt: manifest.generatedAt,\n contentDir: manifest.contentDir,\n entries: manifest.entries,\n };\n}\n\nfunction makeNavigation(manifest: Manifest): Navigation {\n return {\n version: 1,\n entries: manifest.entries.filter(isListedEntry).map((entry) => ({\n slug: entry.slug,\n title: entry.menuLabel,\n sortKey: entry.sortKey,\n })),\n };\n}\n\nexport async function getGitDates(\n projectRoot: string,\n relativePath: string,\n): Promise<{ created?: Date; modified?: Date }> {\n return (\n (\n await getGitDatesForFiles(projectRoot, [normalizeGitPath(relativePath)])\n ).get(normalizeGitPath(relativePath)) ?? {}\n );\n}\n\nasync function getGitDatesForFiles(\n projectRoot: string,\n relativePaths: string[],\n): Promise<Map<string, { created?: Date; modified?: Date }>> {\n const wanted = new Set(relativePaths.map(normalizeGitPath));\n const datesByPath = new Map<string, { created?: Date; modified?: Date }>();\n if (wanted.size === 0) return datesByPath;\n\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"log\", \"--format=__SILICA_COMMIT__%aI\", \"--name-only\", \"--\", ...wanted],\n {\n cwd: projectRoot,\n timeout: 2_000,\n },\n );\n let commitDate: Date | undefined;\n for (const line of stdout.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"__SILICA_COMMIT__\")) {\n const parsed = new Date(trimmed.slice(\"__SILICA_COMMIT__\".length));\n commitDate = Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n continue;\n }\n const relativePath = normalizeGitPath(trimmed);\n if (!commitDate || !wanted.has(relativePath)) continue;\n const dates = datesByPath.get(relativePath) ?? {};\n dates.modified ??= commitDate;\n dates.created = commitDate;\n datesByPath.set(relativePath, dates);\n }\n } catch {\n return datesByPath;\n }\n return datesByPath;\n}\n\nfunction normalizeGitPath(relativePath: string): string {\n return relativePath.replace(/\\\\/g, \"/\");\n}\n\nfunction filterPublished(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n): ContentMarkdownFile[] {\n return files.filter((file) => {\n if (config.filters.removeDrafts && file.frontmatter.draft === true)\n return false;\n if (config.filters.explicitPublish && file.frontmatter.publish !== true)\n return false;\n return true;\n });\n}\n\nfunction makeManifest(\n config: ResolvedSilicaConfig,\n entries: ManifestEntry[],\n): Manifest {\n const sorted = [...entries].sort(compareManifestEntries);\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n contentDir: config.contentDir,\n allSlugs: sorted.map((entry) => entry.slug),\n entries: sorted,\n bySlug: Object.fromEntries(sorted.map((entry) => [entry.slug, entry])),\n };\n}\n\nfunction compareManifestEntries(a: ManifestEntry, b: ManifestEntry): number {\n if (a.sortKey || b.sortKey) {\n return (\n (a.sortKey ?? fallbackSortKey(a.slug)).localeCompare(\n b.sortKey ?? fallbackSortKey(b.slug),\n ) || a.slug.localeCompare(b.slug)\n );\n }\n\n return a.slug.localeCompare(b.slug);\n}\n\nfunction fallbackSortKey(slug: string): string {\n return slug\n .split(\"/\")\n .map((segment) => `~~~~~~~~~~:${segment}`)\n .join(\"/\");\n}\n\nfunction makeGraph(\n links: Record<string, string[]>,\n brokenLinks: BrokenLink[],\n): Graph {\n const backlinks: Record<string, string[]> = {};\n for (const [source, targets] of Object.entries(links)) {\n links[source] = [...new Set(targets)].sort();\n for (const target of targets) {\n backlinks[target] ??= [];\n backlinks[target]!.push(source);\n }\n }\n\n for (const [target, sources] of Object.entries(backlinks)) {\n backlinks[target] = [...new Set(sources)].sort();\n }\n\n return {\n version: 1,\n links,\n backlinks,\n brokenLinks,\n };\n}\n\nasync function copyAssets(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n assets: Array<{ absolutePath: string; relativePath: string }>,\n): Promise<void> {\n const destinationRoot = path.join(projectRoot, \".silica/next/public/silica\");\n await fs.emptyDir(destinationRoot);\n for (const asset of assets) {\n await fs.ensureDir(\n path.dirname(path.join(destinationRoot, asset.relativePath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.relativePath),\n );\n }\n\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public\"));\n await fs.writeFile(path.join(destinationRoot, \".gitkeep\"), \"\");\n}\n\nasync function writeSitemapAndRobots(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n manifest: Manifest,\n): Promise<void> {\n const publicRoot = path.join(projectRoot, \".silica/next/public\");\n await fs.ensureDir(publicRoot);\n const baseUrl = (config.baseUrl ?? \"http://localhost:3000\").replace(\n /\\/$/,\n \"\",\n );\n const urls = manifest.entries\n .filter(isListedEntry)\n .map(\n (entry) => ` <url><loc>${baseUrl}${slugToHref(entry.slug)}</loc></url>`,\n )\n .join(\"\\n\");\n if (!(await fs.pathExists(path.join(projectRoot, \"public/sitemap.xml\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"sitemap.xml\"),\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${urls}\\n</urlset>\\n`,\n );\n }\n if (!(await fs.pathExists(path.join(projectRoot, \"public/robots.txt\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"robots.txt\"),\n `User-agent: *\\nAllow: /\\nSitemap: ${baseUrl}/sitemap.xml\\n`,\n );\n }\n}\n\nasync function writeJson(filePath: string, value: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeJson(filePath, value, { spaces: 2 });\n}\n\nfunction getDate(value: unknown): Date | undefined {\n if (value instanceof Date) return value;\n if (typeof value === \"string\" || typeof value === \"number\") {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.valueOf())) return parsed;\n }\n return undefined;\n}\n\nexport function isListedEntry(entry: ManifestEntry): boolean {\n return entry.frontmatter.listed !== false;\n}\n\nfunction stringifyDate(value?: Date): string | undefined {\n return value?.toISOString();\n}\n\nfunction titleFromFilePath(\n relativePath: string,\n ordering: ResolvedSilicaConfig[\"ordering\"],\n): string {\n const stem = path.posix\n .basename(normalizeGitPath(relativePath))\n .replace(/\\.(md|markdown|mdx)$/i, \"\");\n const title = ordering.numericPrefixes ? stripNumericPrefix(stem) : stem;\n return /^index$/i.test(title) ? \"Home\" : title;\n}\n"],"mappings":"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","names":["path","path","path","fs","path","fs"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/logo.ts","../src/files.ts","../src/precompute.ts","../src/vault-db.ts"],"sourcesContent":["import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { createJiti } from \"jiti\";\nimport { resolvePublicAssetPath } from \"./logo.js\";\nimport type {\n ResolvedSilicaConfig,\n ResolvedSilicaPrerenderConfig,\n SilicaConfig,\n SilicaPrerenderConfig,\n} from \"./types.js\";\n\nexport function defineConfig(config: SilicaConfig): SilicaConfig {\n return config;\n}\n\nexport async function loadConfig(\n projectRoot = process.cwd(),\n): Promise<ResolvedSilicaConfig> {\n const configPath = path.join(projectRoot, \"silica.config.ts\");\n const jsConfigPath = path.join(projectRoot, \"silica.config.js\");\n const configFile = existsSync(configPath)\n ? configPath\n : existsSync(jsConfigPath)\n ? jsConfigPath\n : undefined;\n\n let userConfig: SilicaConfig = {};\n if (configFile) {\n const jiti = createJiti(projectRoot, { interopDefault: true });\n const loaded = await jiti.import<SilicaConfig | { default: SilicaConfig }>(\n configFile,\n );\n userConfig = \"default\" in loaded ? loaded.default : loaded;\n }\n\n return resolveConfig(userConfig, projectRoot);\n}\n\nexport function resolveConfig(\n config: SilicaConfig = {},\n projectRoot = process.cwd(),\n): ResolvedSilicaConfig {\n const auth = config.auth === false ? undefined : config.auth;\n const authEnabled = Boolean(\n auth?.enabled ??\n auth?.provider ??\n auth?.allowedDomains?.length ??\n auth?.allowedEmails?.length,\n );\n const allowedDomains = auth?.allowedDomains ?? [];\n const allowedEmails = auth?.allowedEmails ?? [];\n\n if (\n authEnabled &&\n allowedDomains.length === 0 &&\n allowedEmails.length === 0\n ) {\n throw new Error(\n \"Silica auth requires at least one allowedDomains or allowedEmails entry.\",\n );\n }\n\n return {\n projectRoot,\n title: config.title ?? \"Silica\",\n description: config.description ?? \"A Silica knowledge site\",\n logo: resolvePublicAssetPath(config.logo),\n baseUrl: config.baseUrl,\n contentDir: config.contentDir ?? \"content\",\n theme: config.theme ?? \"default\",\n auth: authEnabled\n ? {\n provider: auth?.provider ?? \"google\",\n enabled: true,\n allowedDomains,\n allowedEmails,\n }\n : undefined,\n wikilinks: {\n strategy: config.wikilinks?.strategy ?? \"shortest\",\n strict: config.wikilinks?.strict ?? false,\n },\n tags: {\n inline: config.tags?.inline ?? true,\n },\n ordering: {\n numericPrefixes: config.ordering?.numericPrefixes ?? true,\n },\n filters: {\n removeDrafts: config.filters?.removeDrafts ?? true,\n explicitPublish: config.filters?.explicitPublish ?? false,\n },\n render: {\n prerender: resolvePrerenderConfig(config.render?.prerender),\n cache: {\n storage: config.render?.cache?.storage ?? \"filesystem\",\n directory: config.render?.cache?.directory,\n },\n },\n };\n}\n\nfunction resolvePrerenderConfig(\n prerender: SilicaPrerenderConfig | undefined,\n): ResolvedSilicaPrerenderConfig {\n if (!prerender || prerender === \"all\") return { strategy: \"all\" };\n if (prerender === \"none\") return { strategy: \"none\" };\n if (\"strategy\" in prerender && prerender.strategy === \"all\") {\n return { ...prerender, strategy: \"all\" };\n }\n if (\"strategy\" in prerender && prerender.strategy === \"none\") {\n return { ...prerender, strategy: \"none\" };\n }\n if (\"strategy\" in prerender && prerender.strategy === \"custom\") {\n return { ...prerender, strategy: \"custom\" };\n }\n return { ...prerender, strategy: \"depth\" };\n}\n","/** Normalize a public asset path or pass through absolute URLs. */\nexport function resolvePublicAssetPath(asset?: string): string | undefined {\n const trimmed = asset?.trim();\n if (!trimmed) return undefined;\n if (trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) {\n return trimmed;\n }\n return trimmed.startsWith(\"/\") ? trimmed : `/${trimmed}`;\n}\n","import path from \"node:path\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport matter from \"gray-matter\";\nimport type { ResolvedSilicaConfig } from \"./types.js\";\nimport { asFilePath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n relativePath: string;\n slug: string;\n raw: string;\n body: string;\n frontmatter: Record<string, unknown>;\n stats: {\n birthtime?: Date;\n mtime?: Date;\n };\n};\n\nexport type ContentAssetFile = {\n absolutePath: string;\n relativePath: string;\n};\n\nexport type ContentScan = {\n markdown: ContentMarkdownFile[];\n assets: ContentAssetFile[];\n};\n\nexport async function scanContent(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n): Promise<ContentScan> {\n const contentRoot = path.join(projectRoot, config.contentDir);\n const realContentRoot = await fs.realpath(contentRoot);\n const entries = await fg(\"**/*\", {\n cwd: contentRoot,\n dot: false,\n followSymbolicLinks: false,\n onlyFiles: true,\n unique: true,\n });\n\n const markdown: ContentMarkdownFile[] = [];\n const assets: ContentAssetFile[] = [];\n\n for (const relativePath of entries.sort()) {\n const absolutePath = path.join(contentRoot, relativePath);\n const stats = await fs.lstat(absolutePath);\n if (!stats.isFile()) continue;\n if (!(await isWithinRoot(absolutePath, realContentRoot))) continue;\n\n if (isMarkdownFile(relativePath)) {\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const parsed = matter(raw);\n markdown.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n slug: slugifyFilePath(\n asFilePath(relativePath),\n config.contentDir,\n config.ordering,\n ),\n raw,\n body: parsed.content,\n frontmatter: parsed.data,\n stats: {\n birthtime: stats.birthtime,\n mtime: stats.mtime,\n },\n });\n } else {\n assets.push({\n absolutePath,\n relativePath: relativePath.replace(/\\\\/g, \"/\"),\n });\n }\n }\n\n return { markdown, assets };\n}\n\nasync function isWithinRoot(\n absolutePath: string,\n realRoot: string,\n): Promise<boolean> {\n const realPath = await fs.realpath(absolutePath);\n const relative = path.relative(realRoot, realPath);\n return (\n relative === \"\" ||\n (!relative.startsWith(\"..\") && !path.isAbsolute(relative))\n );\n}\n\nexport function isMarkdownFile(filePath: string): boolean {\n return /\\.(md|markdown|mdx)$/i.test(filePath);\n}\n","import crypto from \"node:crypto\";\nimport { execFile } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { Worker } from \"node:worker_threads\";\nimport fs from \"fs-extra\";\nimport { type SearchRecord } from \"@silicajs/search\";\nimport { loadConfig } from \"./config.js\";\nimport { scanContent, type ContentMarkdownFile } from \"./files.js\";\nimport {\n asFullSlug,\n createWikiLinkResolutionIndex,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n stripNumericPrefix,\n slugToHref,\n type WikiLinkResolutionIndex,\n} from \"./path.js\";\nimport { getMenuLabel } from \"./pipeline/frontmatter.js\";\nimport { analyzeMarkdown } from \"./pipeline/index.js\";\nimport type {\n AnalyzeResult,\n BrokenLink,\n Graph,\n Manifest,\n ManifestEntry,\n PrecomputeResult,\n PrerenderManifest,\n RenderCacheState,\n ResolvedSilicaConfig,\n} from \"./types.js\";\nimport { writeVaultDatabase } from \"./vault-db.js\";\n\nconst execFileAsync = promisify(execFile);\nconst MIN_PARALLEL_ANALYSIS_FILES = 64;\nconst ANALYSIS_BATCH_SIZE = 16;\nconst MAX_ANALYSIS_WORKERS = 12;\nconst RENDER_CACHE_SCHEMA_VERSION = \"silica-render-v1\";\n\nexport type PrecomputeOptions = {\n projectRoot?: string;\n config?: ResolvedSilicaConfig;\n analysisConcurrency?: number;\n};\n\nexport async function precompute(\n options: PrecomputeOptions = {},\n): Promise<PrecomputeResult> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const config = options.config ?? (await loadConfig(projectRoot));\n const scan = await scanContent(projectRoot, config);\n const markdownFiles = filterPublished(scan.markdown, config);\n const allSlugs = markdownFiles.map((file) => file.slug);\n const wikilinkIndex = createWikiLinkResolutionIndex(\n allSlugs,\n config.ordering,\n );\n const entries: ManifestEntry[] = [];\n const graphLinks: Record<string, string[]> = {};\n const brokenLinks: BrokenLink[] = [];\n const searchRecords: SearchRecord[] = [];\n const runtimeContentRoot = path.join(projectRoot, \".silica/content\");\n const relativeGitPaths = markdownFiles.map((file) =>\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n );\n const gitDatesByPath = await getGitDatesForFiles(\n projectRoot,\n relativeGitPaths,\n );\n\n await fs.ensureDir(path.join(projectRoot, \".silica\"));\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public/silica\"));\n await writeRuntimeMarkdown(runtimeContentRoot, markdownFiles);\n const analyses = await analyzeMarkdownFiles(markdownFiles, config, allSlugs, {\n concurrency: options.analysisConcurrency,\n wikilinkIndex,\n });\n\n for (const [index, file] of markdownFiles.entries()) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.relativePath)),\n ) ?? {};\n const analysis = analyses[index]!;\n\n const title =\n analysis.title ?? titleFromFilePath(file.relativePath, config.ordering);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes &&\n hasNumericPrefixInPath(file.relativePath)\n ? numericPrefixSortKey(file.relativePath)\n : undefined;\n const entry: ManifestEntry = {\n slug: file.slug,\n title,\n menuLabel,\n description: analysis.description,\n generatedDescription: analysis.generatedDescription,\n tags: analysis.tags,\n file: normalizeGitPath(path.join(\".silica/content\", file.relativePath)),\n relativeFile: file.relativePath,\n sortKey,\n created: stringifyDate(\n getDate(file.frontmatter.created) ??\n getDate(file.frontmatter.date) ??\n gitDates.created ??\n file.stats.birthtime,\n ),\n modified: stringifyDate(\n getDate(file.frontmatter.modified) ??\n gitDates.modified ??\n file.stats.mtime,\n ),\n frontmatter: file.frontmatter,\n contentHash: hashString(file.raw),\n embeds: analysis.embeds,\n };\n entries.push(entry);\n graphLinks[file.slug] = analysis.links;\n brokenLinks.push(...analysis.brokenLinks);\n if (isListedEntry(entry)) {\n searchRecords.push({\n id: file.slug,\n slug: file.slug,\n title,\n content: analysis.plainText,\n description: analysis.description,\n tags: analysis.tags,\n });\n }\n }\n\n await copyAssets(projectRoot, config, scan.assets);\n\n const manifest = makeManifest(config, entries);\n const graph = makeGraph(graphLinks, brokenLinks);\n const renderHashes = makeRenderHashes(manifest, graph);\n const cacheState = await makeRenderCacheState(projectRoot, config, manifest);\n const prerender = makePrerenderManifest(manifest, graph, config);\n await writeVaultDatabase(projectRoot, {\n config,\n manifest,\n graph,\n renderHashes,\n cacheState,\n prerender,\n searchRecords,\n });\n await writeSitemapAndRobots(projectRoot, config, manifest);\n\n if (config.wikilinks.strict && brokenLinks.length > 0) {\n const message = brokenLinks\n .map((link) => `${link.source} -> ${link.target}`)\n .join(\"\\n\");\n throw new Error(`Broken wikilinks detected:\\n${message}`);\n }\n\n return {\n manifest,\n graph,\n searchRecords,\n prerender,\n cacheState,\n brokenLinks,\n };\n}\n\ntype AnalyzeMarkdownFilesOptions = {\n concurrency?: number;\n wikilinkIndex: WikiLinkResolutionIndex;\n};\n\ntype AnalysisWorkerFile = {\n index: number;\n slug: string;\n raw: string;\n};\n\ntype AnalysisWorkerMessage = {\n id: number;\n files: AnalysisWorkerFile[];\n};\n\ntype AnalysisWorkerResult = {\n id: number;\n results?: Array<{ index: number; analysis: AnalyzeResult }>;\n error?: string;\n};\n\nasync function analyzeMarkdownFiles(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n allSlugs: string[],\n options: AnalyzeMarkdownFilesOptions,\n): Promise<AnalyzeResult[]> {\n const workerCount = getAnalysisWorkerCount(files.length, options.concurrency);\n if (workerCount <= 1) {\n return analyzeMarkdownFilesSerial(files, config, options.wikilinkIndex);\n }\n\n return analyzeMarkdownFilesParallel(files, config, allSlugs, workerCount);\n}\n\nasync function analyzeMarkdownFilesSerial(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n wikilinkIndex: WikiLinkResolutionIndex,\n): Promise<AnalyzeResult[]> {\n const analyses: AnalyzeResult[] = [];\n for (const file of files) {\n analyses.push(\n await analyzeMarkdown(file.raw, {\n slug: asFullSlug(file.slug),\n wikilinkIndex,\n assetBaseUrl: \"/silica\",\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n }),\n );\n }\n return analyses;\n}\n\nfunction analyzeMarkdownFilesParallel(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n allSlugs: string[],\n workerCount: number,\n): Promise<AnalyzeResult[]> {\n return new Promise((resolve, reject) => {\n const workerUrl = new URL(\"./precompute-worker.js\", import.meta.url);\n const workers: Worker[] = [];\n const analyses: AnalyzeResult[] = new Array(files.length);\n let nextIndex = 0;\n let completed = 0;\n let settled = false;\n\n const rejectOnce = (error: unknown) => {\n if (settled) return;\n settled = true;\n for (const worker of workers) {\n void worker.terminate();\n }\n reject(error);\n };\n\n const resolveIfDone = () => {\n if (completed < files.length || settled) return;\n settled = true;\n for (const worker of workers) {\n void worker.terminate();\n }\n resolve(analyses);\n };\n\n const sendNext = (worker: Worker) => {\n if (settled || nextIndex >= files.length) return;\n const start = nextIndex;\n const batch = files\n .slice(start, start + ANALYSIS_BATCH_SIZE)\n .map((file, offset) => ({\n index: start + offset,\n slug: file.slug,\n raw: file.raw,\n }));\n nextIndex += batch.length;\n worker.postMessage({\n id: start,\n files: batch,\n } satisfies AnalysisWorkerMessage);\n };\n\n for (let index = 0; index < workerCount; index += 1) {\n const worker = new Worker(workerUrl, {\n workerData: {\n allSlugs,\n wikilinkStrategy: config.wikilinks.strategy,\n tags: config.tags,\n ordering: config.ordering,\n },\n });\n workers.push(worker);\n worker.on(\"message\", (message: AnalysisWorkerResult) => {\n if (message.error) {\n rejectOnce(new Error(message.error));\n return;\n }\n for (const result of message.results ?? []) {\n analyses[result.index] = result.analysis;\n }\n completed += message.results?.length ?? 0;\n resolveIfDone();\n sendNext(worker);\n });\n worker.on(\"error\", rejectOnce);\n worker.on(\"exit\", (code) => {\n if (!settled && code !== 0) {\n rejectOnce(\n new Error(`Precompute analysis worker exited with ${code}`),\n );\n }\n });\n sendNext(worker);\n }\n });\n}\n\nfunction getAnalysisWorkerCount(\n fileCount: number,\n requestedConcurrency: number | undefined,\n): number {\n if (fileCount === 0) return 1;\n if (\n requestedConcurrency === undefined &&\n fileCount < MIN_PARALLEL_ANALYSIS_FILES\n ) {\n return 1;\n }\n\n const available = Math.max(\n 1,\n os.availableParallelism?.() ?? os.cpus().length,\n );\n const requested = getRequestedAnalysisConcurrency(\n requestedConcurrency,\n available,\n );\n const usefulWorkers = Math.ceil(fileCount / ANALYSIS_BATCH_SIZE);\n return Math.max(1, Math.min(fileCount, requested, usefulWorkers));\n}\n\nfunction getRequestedAnalysisConcurrency(\n requestedConcurrency: number | undefined,\n available: number,\n): number {\n if (requestedConcurrency === undefined) {\n return Math.min(available, MAX_ANALYSIS_WORKERS);\n }\n if (!Number.isFinite(requestedConcurrency)) return 1;\n return Math.max(1, Math.floor(requestedConcurrency));\n}\n\nasync function writeRuntimeMarkdown(\n runtimeContentRoot: string,\n files: ContentMarkdownFile[],\n): Promise<void> {\n await fs.emptyDir(runtimeContentRoot);\n for (const file of files) {\n const destination = path.join(runtimeContentRoot, file.relativePath);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, file.raw);\n }\n}\n\nasync function makeRenderCacheState(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n manifest: Manifest,\n): Promise<RenderCacheState> {\n const themeHash = await getThemeHash(projectRoot, config.theme);\n const configHash = hashStable({\n title: config.title,\n description: config.description,\n logo: config.logo,\n baseUrl: config.baseUrl,\n contentDir: config.contentDir,\n theme: config.theme,\n auth: config.auth,\n wikilinks: config.wikilinks,\n tags: config.tags,\n ordering: config.ordering,\n filters: config.filters,\n });\n const navigationHash = hashStable({\n entries: manifest.entries.filter(isListedEntry).map((entry) => ({\n slug: entry.slug,\n menuLabel: entry.menuLabel,\n sortKey: entry.sortKey,\n })),\n });\n const tagIndexHash = hashStable({\n entries: manifest.entries.filter(isListedEntry).map((entry) => ({\n slug: entry.slug,\n title: entry.title,\n description: entry.description,\n tags: entry.tags,\n })),\n });\n return {\n version: 1,\n renderEnvironmentHash: hashStable({\n version: RENDER_CACHE_SCHEMA_VERSION,\n configHash,\n themeHash,\n }),\n configHash,\n navigationHash,\n tagIndexHash,\n themeHash,\n rendererVersion: RENDER_CACHE_SCHEMA_VERSION,\n generatedAt: new Date().toISOString(),\n };\n}\n\nfunction makeRenderHashes(\n manifest: Manifest,\n graph: Graph,\n): Record<string, string> {\n const memo = new Map<string, string>();\n const renderHashForSlug = (\n slug: string,\n seen = new Set<string>(),\n ): string => {\n const cached = memo.get(slug);\n if (cached) return cached;\n const entry = manifest.bySlug[slug];\n if (!entry) return hashStable({ missing: slug });\n if (seen.has(slug)) {\n return hashStable({ slug, contentHash: entry.contentHash, cycle: true });\n }\n const nextSeen = new Set(seen).add(slug);\n const embedded = entry.embeds.map((target) => ({\n slug: target,\n renderHash: renderHashForSlug(target, nextSeen),\n }));\n const backlinks = (graph.backlinks[slug] ?? []).map((source) => ({\n slug: source,\n title: manifest.bySlug[source]?.title ?? source,\n }));\n const renderHash = hashStable({\n entry: {\n slug: entry.slug,\n title: entry.title,\n menuLabel: entry.menuLabel,\n description: entry.description,\n generatedDescription: entry.generatedDescription,\n tags: entry.tags,\n relativeFile: entry.relativeFile,\n sortKey: entry.sortKey,\n created: entry.created,\n modified: entry.modified,\n frontmatter: entry.frontmatter,\n contentHash: entry.contentHash,\n },\n embedded,\n backlinks,\n });\n memo.set(slug, renderHash);\n return renderHash;\n };\n\n for (const slug of manifest.allSlugs) {\n renderHashForSlug(slug);\n }\n return Object.fromEntries(memo);\n}\n\nfunction makePrerenderManifest(\n manifest: Manifest,\n graph: Graph,\n config: ResolvedSilicaConfig,\n): PrerenderManifest {\n return {\n version: 1,\n slugs: selectPrerenderSlugs(manifest, graph, config),\n };\n}\n\nfunction selectPrerenderSlugs(\n manifest: Manifest,\n graph: Graph,\n config: ResolvedSilicaConfig,\n): string[] {\n const prerender = config.render.prerender;\n const entries = manifest.entries;\n const scoreBySlug = new Map<string, number>();\n let candidates: ManifestEntry[] = [];\n\n if (prerender.strategy === \"all\") {\n candidates = entries;\n } else if (prerender.strategy === \"depth\") {\n candidates = entries.filter(\n (entry) =>\n entry.slug === \"index\" || getSlugDepth(entry.slug) <= prerender.depth,\n );\n } else if (prerender.strategy === \"custom\") {\n const context = { manifest, graph };\n candidates = entries.filter((entry) => {\n const selected = prerender.select?.(entry, context);\n if (typeof selected === \"number\" && Number.isFinite(selected)) {\n scoreBySlug.set(entry.slug, selected);\n return true;\n }\n return selected === true;\n });\n }\n\n const selected = new Set(\n [...candidates]\n .sort((left, right) => {\n const scoreDelta =\n (scoreBySlug.get(right.slug) ?? 0) -\n (scoreBySlug.get(left.slug) ?? 0);\n return scoreDelta || compareManifestEntries(left, right);\n })\n .slice(0, prerender.limit ?? candidates.length)\n .map((entry) => entry.slug),\n );\n\n for (const slug of prerender.include ?? []) {\n if (manifest.bySlug[slug]) selected.add(slug);\n }\n for (const slug of prerender.exclude ?? []) {\n selected.delete(slug);\n }\n\n return manifest.entries\n .map((entry) => entry.slug)\n .filter((slug) => selected.has(slug));\n}\n\nfunction getSlugDepth(slug: string): number {\n const segments = slug.split(\"/\").filter(Boolean);\n return Math.max(0, segments.length - 1);\n}\n\nasync function getThemeHash(\n projectRoot: string,\n theme: ResolvedSilicaConfig[\"theme\"],\n): Promise<string | undefined> {\n const themeName = getThemeName(theme);\n if (!themeName?.startsWith(\".\")) return undefined;\n const themeRoot = path.resolve(projectRoot, themeName);\n if (!(await fs.pathExists(themeRoot))) return undefined;\n const files = await readThemeFiles(themeRoot);\n return hashStable(files);\n}\n\nfunction getThemeName(\n theme: ResolvedSilicaConfig[\"theme\"],\n): string | undefined {\n if (typeof theme === \"string\") return theme;\n if (typeof theme === \"object\" && theme !== null) return theme.name;\n return undefined;\n}\n\nasync function readThemeFiles(\n root: string,\n current = root,\n): Promise<Array<{ path: string; content: string }>> {\n const entries = await fs.readdir(current, { withFileTypes: true });\n const results: Array<{ path: string; content: string }> = [];\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n const absolutePath = path.join(current, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await readThemeFiles(root, absolutePath)));\n } else if (entry.isFile()) {\n results.push({\n path: normalizeGitPath(path.relative(root, absolutePath)),\n content: await fs.readFile(absolutePath, \"utf8\"),\n });\n }\n }\n return results;\n}\n\nexport async function getGitDates(\n projectRoot: string,\n relativePath: string,\n): Promise<{ created?: Date; modified?: Date }> {\n return (\n (\n await getGitDatesForFiles(projectRoot, [normalizeGitPath(relativePath)])\n ).get(normalizeGitPath(relativePath)) ?? {}\n );\n}\n\nasync function getGitDatesForFiles(\n projectRoot: string,\n relativePaths: string[],\n): Promise<Map<string, { created?: Date; modified?: Date }>> {\n const wanted = new Set(relativePaths.map(normalizeGitPath));\n const datesByPath = new Map<string, { created?: Date; modified?: Date }>();\n if (wanted.size === 0) return datesByPath;\n\n try {\n const { stdout } = await execFileAsync(\n \"git\",\n [\"log\", \"--format=__SILICA_COMMIT__%aI\", \"--name-only\", \"--\", ...wanted],\n {\n cwd: projectRoot,\n timeout: 2_000,\n },\n );\n let commitDate: Date | undefined;\n for (const line of stdout.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.startsWith(\"__SILICA_COMMIT__\")) {\n const parsed = new Date(trimmed.slice(\"__SILICA_COMMIT__\".length));\n commitDate = Number.isNaN(parsed.valueOf()) ? undefined : parsed;\n continue;\n }\n const relativePath = normalizeGitPath(trimmed);\n if (!commitDate || !wanted.has(relativePath)) continue;\n const dates = datesByPath.get(relativePath) ?? {};\n dates.modified ??= commitDate;\n dates.created = commitDate;\n datesByPath.set(relativePath, dates);\n }\n } catch {\n return datesByPath;\n }\n return datesByPath;\n}\n\nfunction normalizeGitPath(relativePath: string): string {\n return relativePath.replace(/\\\\/g, \"/\");\n}\n\nfunction hashString(value: string): string {\n return crypto.createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction hashStable(value: unknown): string {\n return hashString(stableStringify(value));\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === undefined) return \"undefined\";\n if (value instanceof Date) return JSON.stringify(value.toISOString());\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n if (value && typeof value === \"object\") {\n const entries = Object.entries(value)\n .filter(([, entryValue]) => typeof entryValue !== \"function\")\n .sort(([left], [right]) => left.localeCompare(right));\n return `{${entries\n .map(\n ([key, entryValue]) =>\n `${JSON.stringify(key)}:${stableStringify(entryValue)}`,\n )\n .join(\",\")}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction filterPublished(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n): ContentMarkdownFile[] {\n return files.filter((file) => {\n if (config.filters.removeDrafts && file.frontmatter.draft === true)\n return false;\n if (config.filters.explicitPublish && file.frontmatter.publish !== true)\n return false;\n return true;\n });\n}\n\nfunction makeManifest(\n config: ResolvedSilicaConfig,\n entries: ManifestEntry[],\n): Manifest {\n const sorted = [...entries].sort(compareManifestEntries);\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n contentDir: config.contentDir,\n allSlugs: sorted.map((entry) => entry.slug),\n entries: sorted,\n bySlug: Object.fromEntries(sorted.map((entry) => [entry.slug, entry])),\n };\n}\n\nfunction compareManifestEntries(a: ManifestEntry, b: ManifestEntry): number {\n if (a.sortKey || b.sortKey) {\n return (\n (a.sortKey ?? fallbackSortKey(a.slug)).localeCompare(\n b.sortKey ?? fallbackSortKey(b.slug),\n ) || a.slug.localeCompare(b.slug)\n );\n }\n\n return a.slug.localeCompare(b.slug);\n}\n\nfunction fallbackSortKey(slug: string): string {\n return slug\n .split(\"/\")\n .map((segment) => `~~~~~~~~~~:${segment}`)\n .join(\"/\");\n}\n\nfunction makeGraph(\n links: Record<string, string[]>,\n brokenLinks: BrokenLink[],\n): Graph {\n const backlinks: Record<string, string[]> = {};\n for (const [source, targets] of Object.entries(links)) {\n links[source] = [...new Set(targets)].sort();\n for (const target of targets) {\n backlinks[target] ??= [];\n backlinks[target]!.push(source);\n }\n }\n\n for (const [target, sources] of Object.entries(backlinks)) {\n backlinks[target] = [...new Set(sources)].sort();\n }\n\n return {\n version: 1,\n links,\n backlinks,\n brokenLinks,\n };\n}\n\nasync function copyAssets(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n assets: Array<{ absolutePath: string; relativePath: string }>,\n): Promise<void> {\n const destinationRoot = path.join(projectRoot, \".silica/next/public/silica\");\n await fs.emptyDir(destinationRoot);\n for (const asset of assets) {\n await fs.ensureDir(\n path.dirname(path.join(destinationRoot, asset.relativePath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.relativePath),\n );\n }\n\n await fs.ensureDir(path.join(projectRoot, \".silica/next/public\"));\n await fs.writeFile(path.join(destinationRoot, \".gitkeep\"), \"\");\n}\n\nasync function writeSitemapAndRobots(\n projectRoot: string,\n config: ResolvedSilicaConfig,\n manifest: Manifest,\n): Promise<void> {\n const publicRoot = path.join(projectRoot, \".silica/next/public\");\n await fs.ensureDir(publicRoot);\n const baseUrl = (config.baseUrl ?? \"http://localhost:3000\").replace(\n /\\/$/,\n \"\",\n );\n const urls = manifest.entries\n .filter(isListedEntry)\n .map(\n (entry) => ` <url><loc>${baseUrl}${slugToHref(entry.slug)}</loc></url>`,\n )\n .join(\"\\n\");\n if (!(await fs.pathExists(path.join(projectRoot, \"public/sitemap.xml\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"sitemap.xml\"),\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n${urls}\\n</urlset>\\n`,\n );\n }\n if (!(await fs.pathExists(path.join(projectRoot, \"public/robots.txt\")))) {\n await fs.writeFile(\n path.join(publicRoot, \"robots.txt\"),\n `User-agent: *\\nAllow: /\\nSitemap: ${baseUrl}/sitemap.xml\\n`,\n );\n }\n}\n\nfunction getDate(value: unknown): Date | undefined {\n if (value instanceof Date) return value;\n if (typeof value === \"string\" || typeof value === \"number\") {\n const parsed = new Date(value);\n if (!Number.isNaN(parsed.valueOf())) return parsed;\n }\n return undefined;\n}\n\nexport function isListedEntry(entry: ManifestEntry): boolean {\n return entry.frontmatter.listed !== false;\n}\n\nfunction stringifyDate(value?: Date): string | undefined {\n return value?.toISOString();\n}\n\nfunction titleFromFilePath(\n relativePath: string,\n ordering: ResolvedSilicaConfig[\"ordering\"],\n): string {\n const stem = path.posix\n .basename(normalizeGitPath(relativePath))\n .replace(/\\.(md|markdown|mdx)$/i, \"\");\n const title = ordering.numericPrefixes ? stripNumericPrefix(stem) : stem;\n return /^index$/i.test(title) ? \"Home\" : title;\n}\n","import path from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport fs from \"fs-extra\";\nimport {\n buildSearchTables,\n makeExcerpt,\n type SearchRecord,\n} from \"@silicajs/search\";\nimport type {\n Graph,\n Manifest,\n ManifestEntry,\n PrerenderManifest,\n RenderCacheState,\n ResolvedSilicaConfig,\n} from \"./types.js\";\n\nexport const VAULT_DATABASE_FILENAME = \"vault.db\";\nexport const VAULT_DATABASE_VERSION = \"1\";\n\nexport type VaultDbBuildInput = {\n config: ResolvedSilicaConfig;\n manifest: Manifest;\n graph: Graph;\n renderHashes: Record<string, string>;\n cacheState: RenderCacheState;\n prerender: PrerenderManifest;\n searchRecords: SearchRecord[];\n};\n\nexport type VaultDbNote = {\n slug: string;\n file: string;\n relativeFile: string;\n title: string;\n menuLabel: string;\n description?: string;\n generatedDescription?: string;\n frontmatter: Record<string, unknown>;\n tags: string[];\n created?: string;\n modified?: string;\n sortKey?: string;\n listed: boolean;\n contentHash: string;\n renderHash: string;\n prerender: boolean;\n};\n\nexport async function writeVaultDatabase(\n projectRoot: string,\n input: VaultDbBuildInput,\n): Promise<string> {\n const silicaRoot = path.join(projectRoot, \".silica\");\n await fs.ensureDir(silicaRoot);\n\n const databasePath = path.join(silicaRoot, VAULT_DATABASE_FILENAME);\n const temporaryPath = path.join(silicaRoot, `${VAULT_DATABASE_FILENAME}.tmp`);\n await removeDatabaseFiles(temporaryPath);\n\n const db = new Database(temporaryPath);\n try {\n db.pragma(\"journal_mode = DELETE\");\n db.pragma(\"foreign_keys = ON\");\n db.pragma(\"synchronous = OFF\");\n createVaultDatabaseSchema(db);\n populateVaultDatabase(db, input);\n db.exec(\"VACUUM\");\n } finally {\n db.close();\n }\n\n await removeDatabaseFiles(databasePath);\n await fs.rename(temporaryPath, databasePath);\n await removeDatabaseSidecars(temporaryPath);\n return databasePath;\n}\n\nexport function createVaultDatabaseSchema(db: Database.Database): void {\n db.exec(`\n CREATE TABLE vault_metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n\n CREATE TABLE notes (\n slug TEXT PRIMARY KEY,\n file TEXT NOT NULL,\n relative_file TEXT NOT NULL,\n title TEXT NOT NULL,\n menu_label TEXT NOT NULL,\n description TEXT,\n generated_description TEXT,\n frontmatter_json TEXT NOT NULL,\n tags_json TEXT NOT NULL,\n search_excerpt TEXT NOT NULL DEFAULT '',\n created TEXT,\n modified TEXT,\n sort_key TEXT,\n listed INTEGER NOT NULL,\n content_hash TEXT NOT NULL,\n render_hash TEXT NOT NULL,\n prerender INTEGER NOT NULL\n );\n\n CREATE TABLE note_tags (\n slug TEXT NOT NULL,\n tag TEXT NOT NULL,\n PRIMARY KEY (slug, tag),\n FOREIGN KEY (slug) REFERENCES notes(slug) ON DELETE CASCADE\n );\n\n CREATE TABLE links (\n source_slug TEXT NOT NULL,\n target_slug TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('link', 'embed')),\n PRIMARY KEY (source_slug, target_slug, kind)\n );\n\n CREATE TABLE broken_links (\n source_slug TEXT NOT NULL,\n target TEXT NOT NULL\n );\n\n CREATE TABLE slug_aliases (\n strategy_key TEXT NOT NULL,\n alias TEXT NOT NULL,\n slug TEXT NOT NULL,\n sort_key TEXT,\n PRIMARY KEY (strategy_key, alias, slug)\n );\n\n CREATE INDEX notes_prerender_idx ON notes(prerender, slug);\n CREATE INDEX notes_listed_sort_idx ON notes(listed, sort_key, slug);\n CREATE INDEX links_target_idx ON links(target_slug, kind, source_slug);\n CREATE INDEX links_source_idx ON links(source_slug, kind, target_slug);\n CREATE INDEX note_tags_tag_idx ON note_tags(tag, slug);\n CREATE INDEX slug_aliases_lookup_idx\n ON slug_aliases(strategy_key, alias, sort_key, slug);\n `);\n}\n\nexport function populateVaultDatabase(\n db: Database.Database,\n input: VaultDbBuildInput,\n): void {\n const prerenderSlugs = new Set(input.prerender.slugs);\n const searchBySlug = new Map(\n input.searchRecords.map((record) => [record.slug, record]),\n );\n\n const insertMetadata = db.prepare(`\n INSERT INTO vault_metadata (key, value) VALUES (?, ?)\n `);\n const insertNote = db.prepare(`\n INSERT INTO notes (\n slug,\n file,\n relative_file,\n title,\n menu_label,\n description,\n generated_description,\n frontmatter_json,\n tags_json,\n search_excerpt,\n created,\n modified,\n sort_key,\n listed,\n content_hash,\n render_hash,\n prerender\n )\n VALUES (\n @slug,\n @file,\n @relativeFile,\n @title,\n @menuLabel,\n @description,\n @generatedDescription,\n @frontmatterJson,\n @tagsJson,\n @searchExcerpt,\n @created,\n @modified,\n @sortKey,\n @listed,\n @contentHash,\n @renderHash,\n @prerender\n )\n `);\n const insertTag = db.prepare(`\n INSERT OR IGNORE INTO note_tags (slug, tag) VALUES (?, ?)\n `);\n const insertLink = db.prepare(`\n INSERT OR IGNORE INTO links (source_slug, target_slug, kind)\n VALUES (?, ?, ?)\n `);\n const insertBrokenLink = db.prepare(`\n INSERT INTO broken_links (source_slug, target) VALUES (?, ?)\n `);\n const insertAlias = db.prepare(`\n INSERT OR IGNORE INTO slug_aliases (strategy_key, alias, slug, sort_key)\n VALUES (?, ?, ?, ?)\n `);\n\n const insertAll = db.transaction(() => {\n insertMetadata.run(\"version\", VAULT_DATABASE_VERSION);\n insertMetadata.run(\"generatedAt\", input.manifest.generatedAt);\n insertMetadata.run(\"contentDir\", input.manifest.contentDir);\n insertMetadata.run(\"configJson\", JSON.stringify(input.config));\n insertMetadata.run(\n \"renderEnvironmentHash\",\n input.cacheState.renderEnvironmentHash,\n );\n insertMetadata.run(\"configHash\", input.cacheState.configHash);\n insertMetadata.run(\"navigationHash\", input.cacheState.navigationHash);\n insertMetadata.run(\"tagIndexHash\", input.cacheState.tagIndexHash);\n insertMetadata.run(\"rendererVersion\", input.cacheState.rendererVersion);\n insertMetadata.run(\"cacheStateJson\", JSON.stringify(input.cacheState));\n\n for (const entry of input.manifest.entries) {\n const searchRecord = searchBySlug.get(entry.slug);\n insertNote.run({\n slug: entry.slug,\n file: entry.file,\n relativeFile: entry.relativeFile,\n title: entry.title,\n menuLabel: entry.menuLabel,\n description: entry.description,\n generatedDescription: entry.generatedDescription,\n frontmatterJson: JSON.stringify(entry.frontmatter),\n tagsJson: JSON.stringify(entry.tags),\n searchExcerpt: searchRecord\n ? makeExcerpt(\n searchRecord.content,\n searchRecord.description ?? searchRecord.title,\n )\n : \"\",\n created: entry.created,\n modified: entry.modified,\n sortKey: entry.sortKey,\n listed: isListedEntry(entry) ? 1 : 0,\n contentHash: entry.contentHash,\n renderHash: input.renderHashes[entry.slug] ?? \"missing\",\n prerender: prerenderSlugs.has(entry.slug) ? 1 : 0,\n });\n\n for (const tag of entry.tags) {\n for (const hierarchyTag of tagHierarchy(tag)) {\n insertTag.run(entry.slug, hierarchyTag);\n }\n }\n }\n\n for (const [source, targets] of Object.entries(input.graph.links)) {\n for (const target of targets) {\n insertLink.run(source, target, \"link\");\n }\n }\n for (const entry of input.manifest.entries) {\n for (const target of entry.embeds) {\n insertLink.run(entry.slug, target, \"embed\");\n }\n }\n for (const brokenLink of input.graph.brokenLinks) {\n insertBrokenLink.run(brokenLink.source, brokenLink.target);\n }\n for (const entry of input.manifest.entries) {\n for (const [strategy, alias] of makeSlugAliases(entry.slug)) {\n insertAlias.run(\n strategy,\n alias,\n entry.slug,\n entry.sortKey ?? entry.slug,\n );\n }\n }\n });\n\n insertAll();\n buildSearchTables(db, input.searchRecords);\n}\n\nfunction isListedEntry(entry: ManifestEntry): boolean {\n return entry.frontmatter.listed !== false;\n}\n\nfunction tagHierarchy(tag: string): string[] {\n const normalized = tag.trim().replace(/^#/, \"\").toLowerCase();\n const segments = normalized.split(\"/\").filter(Boolean);\n return segments.map((_, index) => segments.slice(0, index + 1).join(\"/\"));\n}\n\nfunction makeSlugAliases(slug: string): Array<[string, string]> {\n const aliases = new Map<string, string>();\n const simplified = slug === \"index\" ? \"\" : slug.replace(/\\/index$/, \"\");\n const basename = simplified.split(\"/\").at(-1) ?? \"\";\n aliases.set(`absolute:${slug}`, slug);\n if (simplified) aliases.set(`absolute:${simplified}`, simplified);\n if (basename) aliases.set(`shortest:${basename}`, basename);\n return [...aliases.entries()].map(([key, alias]) => [\n key.split(\":\")[0] ?? \"shortest\",\n alias,\n ]);\n}\n\nasync function removeDatabaseFiles(databasePath: string): Promise<void> {\n await fs.remove(databasePath);\n await removeDatabaseSidecars(databasePath);\n}\n\nasync function removeDatabaseSidecars(databasePath: string): Promise<void> {\n await Promise.all([\n fs.remove(`${databasePath}-wal`),\n fs.remove(`${databasePath}-shm`),\n fs.remove(`${databasePath}-journal`),\n ]);\n}\n"],"mappings":"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","names":["path","path","path","fs","path","fs","path","fs","isListedEntry","selected"]}
@@ -2,7 +2,7 @@ import {
2
2
  analyzeMarkdown,
3
3
  asFullSlug,
4
4
  createWikiLinkResolutionIndex
5
- } from "./chunk-FOKUARB2.js";
5
+ } from "./chunk-BEINUFYU.js";
6
6
 
7
7
  // src/precompute-worker.ts
8
8
  import { parentPort, workerData } from "worker_threads";
package/dist/runtime.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as RenderContext, A as AnalyzeResult, f as RenderResult } from './theme-D361xin9.js';
2
- export { B as BrokenLink, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, g as ResolvedSilicaConfig, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, o as SilicaTheme, T as ThemeBacklink, q as ThemeBreadcrumb, s as ThemeLayoutConfig, t as ThemePage, u as ThemePageProps, v as ThemeProviderComponent, w as ThemeRootLayoutProps, x as ThemeSiteLayoutProps, y as TocItem, W as WikiLinkResolutionIndex, H as createWikiLinkResolutionIndex, I as hrefToSlug, U as resolveWikiLink, V as simplifySlug, X as slugToHref } from './theme-D361xin9.js';
1
+ import { h as RenderContext, A as AnalyzeResult, i as RenderResult } from './theme-BK5ZRXFG.js';
2
+ export { B as BrokenLink, G as Graph, M as Manifest, b as ManifestEntry, c as MarkdownComponents, N as Navigation, d as NavigationEntry, e as PrerenderManifest, g as RenderCacheState, j as ResolvedSilicaConfig, m as SilicaCalloutProps, n as SilicaCodeBlockProps, p as SilicaEmbedProps, q as SilicaMermaidProps, w as SilicaTheme, T as ThemeBacklink, y as ThemeBreadcrumb, C as ThemeLayoutConfig, D as ThemePage, E as ThemePageProps, H as ThemeProviderComponent, I as ThemeRootLayoutProps, J as ThemeSiteLayoutProps, K as TocItem, W as WikiLinkResolutionIndex, O as asFullSlug, V as createWikiLinkResolutionIndex, X as hrefToSlug, _ as normalizeSlug, a0 as resolveRelative, a1 as resolveWikiLink, a2 as simplifySlug, a3 as slugToHref } from './theme-BK5ZRXFG.js';
3
3
  import 'react';
4
4
  import '@silicajs/search';
5
5
  import '@silicajs/remark-obsidian';
package/dist/runtime.js CHANGED
@@ -6,21 +6,25 @@ import {
6
6
  } from "./chunk-HFUUGJO6.js";
7
7
  import {
8
8
  analyzeMarkdown,
9
+ asFullSlug,
9
10
  createWikiLinkResolutionIndex,
10
11
  generateDescriptionFromContent,
11
12
  getDescription,
12
13
  getMetaDescription,
13
14
  getTitle,
14
15
  hrefToSlug,
16
+ normalizeSlug,
15
17
  renderMarkdown,
16
18
  renderMarkdownHtml,
19
+ resolveRelative,
17
20
  resolveWikiLink,
18
21
  simplifySlug,
19
22
  slugToHref,
20
23
  tagToHref
21
- } from "./chunk-FOKUARB2.js";
24
+ } from "./chunk-BEINUFYU.js";
22
25
  export {
23
26
  analyzeMarkdown,
27
+ asFullSlug,
24
28
  createWikiLinkResolutionIndex,
25
29
  formatPropertyLabel,
26
30
  formatPropertyValue,
@@ -31,8 +35,10 @@ export {
31
35
  getPageProperties,
32
36
  getTitle,
33
37
  hrefToSlug,
38
+ normalizeSlug,
34
39
  renderMarkdown,
35
40
  renderMarkdownHtml,
41
+ resolveRelative,
36
42
  resolveWikiLink,
37
43
  simplifySlug,
38
44
  slugToHref,
@@ -77,8 +77,36 @@ type SilicaConfig = {
77
77
  removeDrafts?: boolean;
78
78
  explicitPublish?: boolean;
79
79
  };
80
+ render?: SilicaRenderConfig;
80
81
  nextConfig?: SilicaNextConfigOverride;
81
82
  };
83
+ type SilicaRenderConfig = {
84
+ prerender?: SilicaPrerenderConfig;
85
+ cache?: {
86
+ storage?: "memory" | "filesystem";
87
+ directory?: string;
88
+ };
89
+ };
90
+ type SilicaPrerenderSelectionOptions = {
91
+ include?: string[];
92
+ exclude?: string[];
93
+ limit?: number;
94
+ };
95
+ type PrerenderSelectorContext = {
96
+ manifest: Manifest;
97
+ graph: Graph;
98
+ };
99
+ type SilicaPrerenderConfig = "all" | "none" | ({
100
+ strategy: "all";
101
+ } & SilicaPrerenderSelectionOptions) | ({
102
+ strategy: "none";
103
+ } & SilicaPrerenderSelectionOptions) | ({
104
+ strategy?: "depth";
105
+ depth: number;
106
+ } & SilicaPrerenderSelectionOptions) | ({
107
+ strategy: "custom";
108
+ select?: (entry: ManifestEntry, context: PrerenderSelectorContext) => boolean | number;
109
+ } & SilicaPrerenderSelectionOptions);
82
110
  type ResolvedSilicaConfig = {
83
111
  projectRoot: string;
84
112
  title: string;
@@ -102,7 +130,26 @@ type ResolvedSilicaConfig = {
102
130
  removeDrafts: boolean;
103
131
  explicitPublish: boolean;
104
132
  };
133
+ render: ResolvedSilicaRenderConfig;
105
134
  };
135
+ type ResolvedSilicaRenderConfig = {
136
+ prerender: ResolvedSilicaPrerenderConfig;
137
+ cache: {
138
+ storage: "memory" | "filesystem";
139
+ directory?: string;
140
+ };
141
+ };
142
+ type ResolvedSilicaPrerenderConfig = ({
143
+ strategy: "all";
144
+ } & SilicaPrerenderSelectionOptions) | ({
145
+ strategy: "none";
146
+ } & SilicaPrerenderSelectionOptions) | ({
147
+ strategy: "depth";
148
+ depth: number;
149
+ } & SilicaPrerenderSelectionOptions) | ({
150
+ strategy: "custom";
151
+ select?: (entry: ManifestEntry, context: PrerenderSelectorContext) => boolean | number;
152
+ } & SilicaPrerenderSelectionOptions);
106
153
  type TocItem = {
107
154
  id: string;
108
155
  text: string;
@@ -121,6 +168,8 @@ type ManifestEntry = {
121
168
  created?: string;
122
169
  modified?: string;
123
170
  frontmatter: Record<string, unknown>;
171
+ contentHash: string;
172
+ embeds: string[];
124
173
  };
125
174
  type Manifest = {
126
175
  version: 1;
@@ -151,7 +200,8 @@ type BrokenLink = {
151
200
  };
152
201
  type RenderContext = {
153
202
  slug: FullSlug | string;
154
- wikilinkIndex: WikiLinkResolutionIndex;
203
+ wikilinkIndex?: WikiLinkResolutionIndex;
204
+ resolveWikiLink?: (currentSlug: FullSlug | string, target: string) => string | undefined;
155
205
  assetBaseUrl?: string;
156
206
  resolveEmbed?: (target: ObsidianLinkTarget) => Promise<string | undefined> | string | undefined;
157
207
  embedDepth?: number;
@@ -197,6 +247,7 @@ type RenderResult = {
197
247
  type AnalyzeResult = {
198
248
  frontmatter: Record<string, unknown>;
199
249
  links: string[];
250
+ embeds: string[];
200
251
  brokenLinks: BrokenLink[];
201
252
  plainText: string;
202
253
  title?: string;
@@ -204,11 +255,26 @@ type AnalyzeResult = {
204
255
  generatedDescription?: string;
205
256
  tags: string[];
206
257
  };
258
+ type PrerenderManifest = {
259
+ version: 1;
260
+ slugs: string[];
261
+ };
262
+ type RenderCacheState = {
263
+ version: 1;
264
+ renderEnvironmentHash: string;
265
+ configHash: string;
266
+ navigationHash: string;
267
+ tagIndexHash: string;
268
+ themeHash?: string;
269
+ rendererVersion: string;
270
+ generatedAt: string;
271
+ };
207
272
  type PrecomputeResult = {
208
273
  manifest: Manifest;
209
274
  graph: Graph;
210
275
  searchRecords: SearchRecord[];
211
- buildId: string;
276
+ prerender: PrerenderManifest;
277
+ cacheState: RenderCacheState;
212
278
  brokenLinks: BrokenLink[];
213
279
  };
214
280
 
@@ -263,4 +329,4 @@ type SilicaTheme = {
263
329
  components?: MarkdownComponents;
264
330
  };
265
331
 
266
- export { type AnalyzeResult as A, type BrokenLink as B, asFullSlug as C, asRelativeURL as D, asSimpleSlug as E, type FilePath as F, type Graph as G, createWikiLinkResolutionIndex as H, hrefToSlug as I, joinSegments as J, normalizePath as K, normalizeSlug as L, type Manifest as M, type Navigation as N, pathToRoot as O, type PrecomputeResult as P, resolveRelative as Q, type RelativeURL as R, type SilicaAuthConfig as S, type ThemeBacklink as T, resolveWikiLink as U, simplifySlug as V, type WikiLinkResolutionIndex as W, slugToHref as X, slugifyFilePath as Y, slugifySegment as Z, type FullSlug as a, type ManifestEntry as b, type MarkdownComponents as c, type NavigationEntry as d, type RenderContext as e, type RenderResult as f, type ResolvedSilicaConfig as g, type SilicaCalloutProps as h, type SilicaCodeBlockProps as i, type SilicaConfig as j, type SilicaEmbedProps as k, type SilicaMermaidProps as l, type SilicaNextConfig as m, type SilicaNextConfigOverride as n, type SilicaTheme as o, type SimpleSlug as p, type ThemeBreadcrumb as q, type ThemeConfig as r, type ThemeLayoutConfig as s, type ThemePage as t, type ThemePageProps as u, type ThemeProviderComponent as v, type ThemeRootLayoutProps as w, type ThemeSiteLayoutProps as x, type TocItem as y, asFilePath as z };
332
+ export { pathToRoot as $, type AnalyzeResult as A, type BrokenLink as B, type ThemeLayoutConfig as C, type ThemePage as D, type ThemePageProps as E, type FilePath as F, type Graph as G, type ThemeProviderComponent as H, type ThemeRootLayoutProps as I, type ThemeSiteLayoutProps as J, type TocItem as K, asFilePath as L, type Manifest as M, type Navigation as N, asFullSlug as O, type PrecomputeResult as P, asRelativeURL as Q, type RelativeURL as R, type SilicaAuthConfig as S, type ThemeBacklink as T, asSimpleSlug as U, createWikiLinkResolutionIndex as V, type WikiLinkResolutionIndex as W, hrefToSlug as X, joinSegments as Y, normalizePath as Z, normalizeSlug as _, type FullSlug as a, resolveRelative as a0, resolveWikiLink as a1, simplifySlug as a2, slugToHref as a3, slugifyFilePath as a4, slugifySegment as a5, type ManifestEntry as b, type MarkdownComponents as c, type NavigationEntry as d, type PrerenderManifest as e, type PrerenderSelectorContext as f, type RenderCacheState as g, type RenderContext as h, type RenderResult as i, type ResolvedSilicaConfig as j, type ResolvedSilicaPrerenderConfig as k, type ResolvedSilicaRenderConfig as l, type SilicaCalloutProps as m, type SilicaCodeBlockProps as n, type SilicaConfig as o, type SilicaEmbedProps as p, type SilicaMermaidProps as q, type SilicaNextConfig as r, type SilicaNextConfigOverride as s, type SilicaPrerenderConfig as t, type SilicaPrerenderSelectionOptions as u, type SilicaRenderConfig as v, type SilicaTheme as w, type SimpleSlug as x, type ThemeBreadcrumb as y, type ThemeConfig as z };
package/dist/theme.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import 'react';
2
- export { c as MarkdownComponents, h as SilicaCalloutProps, i as SilicaCodeBlockProps, k as SilicaEmbedProps, l as SilicaMermaidProps, o as SilicaTheme, T as ThemeBacklink, q as ThemeBreadcrumb, s as ThemeLayoutConfig, t as ThemePage, u as ThemePageProps, v as ThemeProviderComponent, w as ThemeRootLayoutProps, x as ThemeSiteLayoutProps } from './theme-D361xin9.js';
2
+ export { c as MarkdownComponents, m as SilicaCalloutProps, n as SilicaCodeBlockProps, p as SilicaEmbedProps, q as SilicaMermaidProps, w as SilicaTheme, T as ThemeBacklink, y as ThemeBreadcrumb, C as ThemeLayoutConfig, D as ThemePage, E as ThemePageProps, H as ThemeProviderComponent, I as ThemeRootLayoutProps, J as ThemeSiteLayoutProps } from './theme-BK5ZRXFG.js';
3
3
  import '@silicajs/search';
4
4
  import '@silicajs/remark-obsidian';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicajs/core",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Markdown pipeline, slug system, and precompute artifacts for Silica.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,7 +33,8 @@
33
33
  "dependencies": {
34
34
  "@shikijs/rehype": "^4.1.0",
35
35
  "@silicajs/remark-obsidian": "^0.1.0",
36
- "@silicajs/search": "^0.2.0",
36
+ "@silicajs/search": "^0.3.0",
37
+ "better-sqlite3": "^12.10.0",
37
38
  "fast-glob": "^3.3.3",
38
39
  "fs-extra": "^11.3.5",
39
40
  "github-slugger": "^2.0.0",