@silicajs/core 0.6.0 → 0.7.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","../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, slugifyAssetPath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n sourcePath: 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 sourcePath: string;\n assetPath: 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 sourcePath = relativePath.replace(/\\\\/g, \"/\");\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 sourcePath,\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 sourcePath,\n assetPath: slugifyAssetPath(sourcePath, config.ordering),\n });\n }\n }\n\n assertUniqueAssetPaths(assets);\n\n return { markdown, assets };\n}\n\nfunction assertUniqueAssetPaths(assets: ContentAssetFile[]) {\n const sourcePathByAssetPath = new Map<string, string>();\n for (const asset of assets) {\n const existing = sourcePathByAssetPath.get(asset.assetPath);\n if (existing && existing !== asset.sourcePath) {\n throw new Error(\n `Asset path collision: ${existing} and ${asset.sourcePath} both map to ${asset.assetPath}`,\n );\n }\n sourcePathByAssetPath.set(asset.assetPath, asset.sourcePath);\n }\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 createAssetResolutionIndex,\n createWikiLinkResolutionIndex,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n stripNumericPrefix,\n type AssetResolutionIndex,\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 assetEntries = scan.assets.map(({ sourcePath, assetPath }) => ({\n sourcePath,\n assetPath,\n }));\n const allSlugs = markdownFiles.map((file) => file.slug);\n const wikilinkIndex = createWikiLinkResolutionIndex(\n allSlugs,\n config.ordering,\n );\n const assetIndex = createAssetResolutionIndex(assetEntries, config.ordering);\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.sourcePath)),\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 assetIndex,\n assetEntries,\n });\n\n for (const [index, file] of markdownFiles.entries()) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.sourcePath)),\n ) ?? {};\n const analysis = analyses[index]!;\n\n const title =\n analysis.title ?? titleFromFilePath(file.sourcePath, config.ordering);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes && hasNumericPrefixInPath(file.sourcePath)\n ? numericPrefixSortKey(file.sourcePath)\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.sourcePath)),\n sourcePath: file.sourcePath,\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 assets: assetEntries,\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 assetIndex: AssetResolutionIndex;\n assetEntries: Array<{ sourcePath: string; assetPath: string }>;\n};\n\ntype AnalysisWorkerFile = {\n index: number;\n slug: string;\n sourcePath: 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(\n files,\n config,\n options.wikilinkIndex,\n options.assetIndex,\n );\n }\n\n return analyzeMarkdownFilesParallel(\n files,\n config,\n allSlugs,\n options.assetEntries,\n workerCount,\n );\n}\n\nasync function analyzeMarkdownFilesSerial(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n wikilinkIndex: WikiLinkResolutionIndex,\n assetIndex: AssetResolutionIndex,\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 sourcePath: file.sourcePath,\n wikilinkIndex,\n assetIndex,\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 assetEntries: Array<{ sourcePath: string; assetPath: 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 sourcePath: file.sourcePath,\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 assetEntries,\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.sourcePath);\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 sourcePath: entry.sourcePath,\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; assetPath: 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.assetPath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.assetPath),\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 { ContentAssetFile } from \"./files.js\";\nimport type {\n Graph,\n Manifest,\n ManifestEntry,\n PrerenderManifest,\n RenderCacheState,\n ResolvedSilicaConfig,\n} from \"./types.js\";\nimport { normalizeAssetReference } from \"./path.js\";\n\nexport const VAULT_DATABASE_FILENAME = \"vault.db\";\nexport const VAULT_DATABASE_VERSION = \"2\";\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 assets: Array<Pick<ContentAssetFile, \"sourcePath\" | \"assetPath\">>;\n};\n\nexport type VaultDbNote = {\n slug: string;\n file: string;\n sourcePath: 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 source_path 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 TABLE asset_aliases (\n strategy_key TEXT NOT NULL,\n alias TEXT NOT NULL,\n asset_path TEXT NOT NULL,\n sort_key TEXT,\n PRIMARY KEY (strategy_key, alias, asset_path)\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 CREATE INDEX asset_aliases_lookup_idx\n ON asset_aliases(strategy_key, alias, sort_key, asset_path);\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 source_path,\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 @sourcePath,\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 const insertAssetAlias = db.prepare(`\n INSERT OR IGNORE INTO asset_aliases (\n strategy_key,\n alias,\n asset_path,\n sort_key\n )\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 sourcePath: entry.sourcePath,\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 for (const asset of input.assets) {\n for (const [strategy, alias] of makeAssetAliases(\n asset.sourcePath,\n input.config.ordering,\n )) {\n insertAssetAlias.run(strategy, alias, asset.assetPath, asset.assetPath);\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\nfunction makeAssetAliases(\n sourcePath: string,\n ordering: ResolvedSilicaConfig[\"ordering\"],\n): Array<[string, string]> {\n const aliases = new Map<string, string>();\n const normalized = normalizeAssetReference(sourcePath, ordering);\n const basename = normalizeAssetReference(\n path.posix.basename(sourcePath),\n ordering,\n );\n if (normalized) aliases.set(`absolute:${normalized}`, normalized);\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","path","fs","isListedEntry","selected"]}
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, slugifyAssetPath, slugifyFilePath } from \"./path.js\";\n\nexport type ContentMarkdownFile = {\n absolutePath: string;\n sourcePath: 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 sourcePath: string;\n assetPath: 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 sourcePath = relativePath.replace(/\\\\/g, \"/\");\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 sourcePath,\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 sourcePath,\n assetPath: slugifyAssetPath(sourcePath, config.ordering),\n });\n }\n }\n\n assertUniqueAssetPaths(assets);\n\n return { markdown, assets };\n}\n\nfunction assertUniqueAssetPaths(assets: ContentAssetFile[]) {\n const sourcePathByAssetPath = new Map<string, string>();\n for (const asset of assets) {\n const existing = sourcePathByAssetPath.get(asset.assetPath);\n if (existing && existing !== asset.sourcePath) {\n throw new Error(\n `Asset path collision: ${existing} and ${asset.sourcePath} both map to ${asset.assetPath}`,\n );\n }\n sourcePathByAssetPath.set(asset.assetPath, asset.sourcePath);\n }\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 createAssetResolutionIndex,\n createWikiLinkResolutionIndex,\n hasNumericPrefixInPath,\n numericPrefixSortKey,\n stripNumericPrefix,\n type AssetResolutionIndex,\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 assetEntries = scan.assets.map(({ sourcePath, assetPath }) => ({\n sourcePath,\n assetPath,\n }));\n const allSlugs = markdownFiles.map((file) => file.slug);\n const wikilinkIndex = createWikiLinkResolutionIndex(\n allSlugs,\n config.ordering,\n );\n const assetIndex = createAssetResolutionIndex(assetEntries, config.ordering);\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.sourcePath)),\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 assetIndex,\n assetEntries,\n });\n\n for (const [index, file] of markdownFiles.entries()) {\n const gitDates =\n gitDatesByPath.get(\n normalizeGitPath(path.join(config.contentDir, file.sourcePath)),\n ) ?? {};\n const analysis = analyses[index]!;\n\n const title =\n analysis.title ?? titleFromFilePath(file.sourcePath, config.ordering);\n const menuLabel = getMenuLabel(file.frontmatter, title);\n const sortKey =\n config.ordering.numericPrefixes && hasNumericPrefixInPath(file.sourcePath)\n ? numericPrefixSortKey(file.sourcePath)\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.sourcePath)),\n sourcePath: file.sourcePath,\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 assets: assetEntries,\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 assetIndex: AssetResolutionIndex;\n assetEntries: Array<{ sourcePath: string; assetPath: string }>;\n};\n\ntype AnalysisWorkerFile = {\n index: number;\n slug: string;\n sourcePath: 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(\n files,\n config,\n options.wikilinkIndex,\n options.assetIndex,\n );\n }\n\n return analyzeMarkdownFilesParallel(\n files,\n config,\n allSlugs,\n options.assetEntries,\n workerCount,\n );\n}\n\nasync function analyzeMarkdownFilesSerial(\n files: ContentMarkdownFile[],\n config: ResolvedSilicaConfig,\n wikilinkIndex: WikiLinkResolutionIndex,\n assetIndex: AssetResolutionIndex,\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 sourcePath: file.sourcePath,\n wikilinkIndex,\n assetIndex,\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 assetEntries: Array<{ sourcePath: string; assetPath: 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 sourcePath: file.sourcePath,\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 assetEntries,\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.sourcePath);\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 sourcePath: entry.sourcePath,\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; assetPath: 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.assetPath)),\n );\n await fs.copyFile(\n asset.absolutePath,\n path.join(destinationRoot, asset.assetPath),\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 { ContentAssetFile } from \"./files.js\";\nimport type {\n Graph,\n Manifest,\n ManifestEntry,\n PrerenderManifest,\n RenderCacheState,\n ResolvedSilicaConfig,\n} from \"./types.js\";\nimport { normalizeAssetReference } from \"./path.js\";\n\nexport const VAULT_DATABASE_FILENAME = \"vault.db\";\nexport const VAULT_DATABASE_VERSION = \"2\";\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 assets: Array<Pick<ContentAssetFile, \"sourcePath\" | \"assetPath\">>;\n};\n\nexport type VaultDbNote = {\n slug: string;\n file: string;\n sourcePath: 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 source_path 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 TABLE asset_aliases (\n strategy_key TEXT NOT NULL,\n alias TEXT NOT NULL,\n asset_path TEXT NOT NULL,\n sort_key TEXT,\n PRIMARY KEY (strategy_key, alias, asset_path)\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 CREATE INDEX asset_aliases_lookup_idx\n ON asset_aliases(strategy_key, alias, sort_key, asset_path);\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 source_path,\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 @sourcePath,\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 const insertAssetAlias = db.prepare(`\n INSERT OR IGNORE INTO asset_aliases (\n strategy_key,\n alias,\n asset_path,\n sort_key\n )\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 sourcePath: entry.sourcePath,\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 for (const asset of input.assets) {\n for (const [strategy, alias] of makeAssetAliases(\n asset.sourcePath,\n input.config.ordering,\n )) {\n insertAssetAlias.run(strategy, alias, asset.assetPath, asset.assetPath);\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\nfunction makeAssetAliases(\n sourcePath: string,\n ordering: ResolvedSilicaConfig[\"ordering\"],\n): Array<[string, string]> {\n const aliases = new Map<string, string>();\n const normalized = normalizeAssetReference(sourcePath, ordering);\n const basename = normalizeAssetReference(\n path.posix.basename(sourcePath),\n ordering,\n );\n if (normalized) aliases.set(`absolute:${normalized}`, normalized);\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","path","fs","isListedEntry","selected"]}
@@ -3,7 +3,7 @@ import {
3
3
  asFullSlug,
4
4
  createAssetResolutionIndex,
5
5
  createWikiLinkResolutionIndex
6
- } from "./chunk-2EKH4A4V.js";
6
+ } from "./chunk-4A6TRY75.js";
7
7
 
8
8
  // src/precompute-worker.ts
9
9
  import { parentPort, workerData } from "worker_threads";
package/dist/runtime.d.ts CHANGED
@@ -1,19 +1,9 @@
1
- import { j as RenderContext, A as AnalyzeResult, k as RenderResult } from './theme-DuygYyeF.js';
2
- export { a as AssetResolutionEntry, b as AssetResolutionIndex, B as BrokenLink, G as Graph, M as Manifest, d as ManifestEntry, e as MarkdownComponents, N as Navigation, f as NavigationEntry, g as PrerenderManifest, i as RenderCacheState, l as ResolvedSilicaConfig, o as SilicaCalloutProps, p as SilicaCodeBlockProps, r as SilicaEmbedProps, s as SilicaMermaidProps, y as SilicaTheme, T as ThemeBacklink, C as ThemeBreadcrumb, E as ThemeLayoutConfig, H as ThemePage, I as ThemePageProps, J as ThemeProviderComponent, K as ThemeRootLayoutProps, L as ThemeSiteLayoutProps, O as TocItem, W as WikiLinkResolutionIndex, U as asFullSlug, Y as createAssetResolutionIndex, Z as createWikiLinkResolutionIndex, _ as hrefToSlug, a0 as normalizeAssetReference, a2 as normalizeSlug, a4 as resolveAssetPath, a5 as resolveRelative, a6 as resolveRelativeAsset, a7 as resolveWikiLink, a8 as simplifySlug, a9 as slugToHref, aa as slugifyAssetPath } from './theme-DuygYyeF.js';
1
+ import { m as RenderContext, A as AnalyzeResult, n as RenderResult } from './theme-D67Ma7mz.js';
2
+ export { a as AssetResolutionEntry, b as AssetResolutionIndex, B as BrokenLink, G as Graph, M as Manifest, d as ManifestEntry, e as MarkdownComponents, N as Navigation, f as NavigationEntry, P as PageProperty, g as PagePropertyPart, h as PagePropertyResolution, j as PrerenderManifest, l as RenderCacheState, o as ResolvedSilicaConfig, r as SilicaCalloutProps, s as SilicaCodeBlockProps, u as SilicaEmbedProps, v as SilicaMermaidProps, D as SilicaTheme, T as ThemeBacklink, H as ThemeBreadcrumb, J as ThemeLayoutConfig, K as ThemePage, L as ThemePageProps, O as ThemeProviderComponent, Q as ThemeRootLayoutProps, U as ThemeSiteLayoutProps, V as TocItem, W as WikiLinkResolutionIndex, X as analyzePagePropertyLinks, Z as asFullSlug, a0 as createAssetResolutionIndex, a1 as createWikiLinkResolutionIndex, a2 as formatPropertyLabel, a3 as formatPropertyValue, a4 as getMenuLabel, a5 as getPageProperties, a6 as getResolvedPageProperties, a7 as hrefToSlug, a9 as normalizeAssetReference, ab as normalizeSlug, ad as resolveAssetPath, ae as resolvePagePropertyValue, af as resolveRelative, ag as resolveRelativeAsset, ah as resolveWikiLink, ai as simplifySlug, aj as slugToHref, ak as slugifyAssetPath } from './theme-D67Ma7mz.js';
3
3
  import 'react';
4
4
  import '@silicajs/search';
5
5
  import '@silicajs/remark-obsidian';
6
6
 
7
- type PageProperty = {
8
- key: string;
9
- label: string;
10
- value: string;
11
- };
12
- declare function getMenuLabel(frontmatter: Record<string, unknown>, title: string): string;
13
- declare function getPageProperties(frontmatter: Record<string, unknown>): PageProperty[];
14
- declare function formatPropertyLabel(key: string): string;
15
- declare function formatPropertyValue(value: unknown): string | undefined;
16
-
17
7
  declare function renderMarkdown(raw: string, context: RenderContext): Promise<RenderResult>;
18
8
  declare function renderMarkdownHtml(raw: string, context: RenderContext): Promise<string>;
19
9
  declare function analyzeMarkdown(raw: string, context: RenderContext): Promise<AnalyzeResult>;
@@ -27,4 +17,4 @@ declare function getMetaDescription(entry: {
27
17
 
28
18
  declare function tagToHref(tag: string): string;
29
19
 
30
- export { AnalyzeResult, type PageProperty, RenderContext, RenderResult, analyzeMarkdown, formatPropertyLabel, formatPropertyValue, generateDescriptionFromContent, getDescription, getMenuLabel, getMetaDescription, getPageProperties, getTitle, renderMarkdown, renderMarkdownHtml, tagToHref };
20
+ export { AnalyzeResult, RenderContext, RenderResult, analyzeMarkdown, generateDescriptionFromContent, getDescription, getMetaDescription, getTitle, renderMarkdown, renderMarkdownHtml, tagToHref };
package/dist/runtime.js CHANGED
@@ -1,17 +1,17 @@
1
- import {
2
- formatPropertyLabel,
3
- formatPropertyValue,
4
- getMenuLabel,
5
- getPageProperties
6
- } from "./chunk-HFUUGJO6.js";
7
1
  import {
8
2
  analyzeMarkdown,
3
+ analyzePagePropertyLinks,
9
4
  asFullSlug,
10
5
  createAssetResolutionIndex,
11
6
  createWikiLinkResolutionIndex,
7
+ formatPropertyLabel,
8
+ formatPropertyValue,
12
9
  generateDescriptionFromContent,
13
10
  getDescription,
11
+ getMenuLabel,
14
12
  getMetaDescription,
13
+ getPageProperties,
14
+ getResolvedPageProperties,
15
15
  getTitle,
16
16
  hrefToSlug,
17
17
  normalizeAssetReference,
@@ -19,6 +19,7 @@ import {
19
19
  renderMarkdown,
20
20
  renderMarkdownHtml,
21
21
  resolveAssetPath,
22
+ resolvePagePropertyValue,
22
23
  resolveRelative,
23
24
  resolveRelativeAsset,
24
25
  resolveWikiLink,
@@ -26,9 +27,10 @@ import {
26
27
  slugToHref,
27
28
  slugifyAssetPath,
28
29
  tagToHref
29
- } from "./chunk-2EKH4A4V.js";
30
+ } from "./chunk-4A6TRY75.js";
30
31
  export {
31
32
  analyzeMarkdown,
33
+ analyzePagePropertyLinks,
32
34
  asFullSlug,
33
35
  createAssetResolutionIndex,
34
36
  createWikiLinkResolutionIndex,
@@ -39,6 +41,7 @@ export {
39
41
  getMenuLabel,
40
42
  getMetaDescription,
41
43
  getPageProperties,
44
+ getResolvedPageProperties,
42
45
  getTitle,
43
46
  hrefToSlug,
44
47
  normalizeAssetReference,
@@ -46,6 +49,7 @@ export {
46
49
  renderMarkdown,
47
50
  renderMarkdownHtml,
48
51
  resolveAssetPath,
52
+ resolvePagePropertyValue,
49
53
  resolveRelative,
50
54
  resolveRelativeAsset,
51
55
  resolveWikiLink,
@@ -24,6 +24,7 @@ type SlugifyOptions = {
24
24
  type WikiLinkResolutionIndex = {
25
25
  candidates: ReadonlySet<string>;
26
26
  uniqueSlugByBasename: ReadonlyMap<string, string | null>;
27
+ slugsByBasename?: ReadonlyMap<string, readonly string[]>;
27
28
  };
28
29
  type AssetResolutionIndex = {
29
30
  assetPathBySourcePath: ReadonlyMap<string, string | null>;
@@ -294,6 +295,45 @@ type PrecomputeResult = {
294
295
  brokenLinks: BrokenLink[];
295
296
  };
296
297
 
298
+ type PagePropertyTextPart = {
299
+ type: "text";
300
+ value: string;
301
+ };
302
+ type PagePropertyLinkPart = {
303
+ type: "link";
304
+ value: string;
305
+ target: string;
306
+ slug: string;
307
+ href: string;
308
+ };
309
+ type PagePropertyBrokenLinkPart = {
310
+ type: "broken-link";
311
+ value: string;
312
+ target: string;
313
+ };
314
+ type PagePropertyPart = PagePropertyTextPart | PagePropertyLinkPart | PagePropertyBrokenLinkPart;
315
+ type PageProperty = {
316
+ key: string;
317
+ label: string;
318
+ value: string;
319
+ parts?: PagePropertyPart[];
320
+ };
321
+ type PagePropertyResolution = {
322
+ parts: PagePropertyPart[];
323
+ links: string[];
324
+ brokenLinks: BrokenLink[];
325
+ };
326
+ declare function getMenuLabel(frontmatter: Record<string, unknown>, title: string): string;
327
+ declare function getPageProperties(frontmatter: Record<string, unknown>): PageProperty[];
328
+ declare function getResolvedPageProperties(frontmatter: Record<string, unknown>, context: RenderContext): PageProperty[];
329
+ declare function analyzePagePropertyLinks(frontmatter: Record<string, unknown>, context: RenderContext): {
330
+ links: string[];
331
+ brokenLinks: BrokenLink[];
332
+ };
333
+ declare function resolvePagePropertyValue(value: string, context: RenderContext): PagePropertyResolution;
334
+ declare function formatPropertyLabel(key: string): string;
335
+ declare function formatPropertyValue(value: unknown): string | undefined;
336
+
297
337
  type ThemeBreadcrumb = {
298
338
  label: string;
299
339
  href?: string;
@@ -328,6 +368,7 @@ type ThemePage = {
328
368
  description?: string;
329
369
  content: React.ReactNode;
330
370
  frontmatter: Record<string, unknown>;
371
+ pageProperties?: PageProperty[];
331
372
  toc: TocItem[];
332
373
  tags: string[];
333
374
  entry: ManifestEntry;
@@ -345,4 +386,4 @@ type SilicaTheme = {
345
386
  components?: MarkdownComponents;
346
387
  };
347
388
 
348
- export { joinSegments as $, type AnalyzeResult as A, type BrokenLink as B, type ThemeBreadcrumb as C, type ThemeConfig as D, type ThemeLayoutConfig as E, type FilePath as F, type Graph as G, type ThemePage as H, type ThemePageProps as I, type ThemeProviderComponent as J, type ThemeRootLayoutProps as K, type ThemeSiteLayoutProps as L, type Manifest as M, type Navigation as N, type TocItem as O, type PrecomputeResult as P, asFilePath as Q, type RelativeURL as R, type SilicaAuthConfig as S, type ThemeBacklink as T, asFullSlug as U, asRelativeURL as V, type WikiLinkResolutionIndex as W, asSimpleSlug as X, createAssetResolutionIndex as Y, createWikiLinkResolutionIndex as Z, hrefToSlug as _, type AssetResolutionEntry as a, normalizeAssetReference as a0, normalizePath as a1, normalizeSlug as a2, pathToRoot as a3, resolveAssetPath as a4, resolveRelative as a5, resolveRelativeAsset as a6, resolveWikiLink as a7, simplifySlug as a8, slugToHref as a9, slugifyAssetPath as aa, slugifyFilePath as ab, slugifySegment as ac, type AssetResolutionIndex as b, type FullSlug as c, type ManifestEntry as d, type MarkdownComponents as e, type NavigationEntry as f, type PrerenderManifest as g, type PrerenderSelectorContext as h, type RenderCacheState as i, type RenderContext as j, type RenderResult as k, type ResolvedSilicaConfig as l, type ResolvedSilicaPrerenderConfig as m, type ResolvedSilicaRenderConfig as n, type SilicaCalloutProps as o, type SilicaCodeBlockProps as p, type SilicaConfig as q, type SilicaEmbedProps as r, type SilicaMermaidProps as s, type SilicaNextConfig as t, type SilicaNextConfigOverride as u, type SilicaPrerenderConfig as v, type SilicaPrerenderSelectionOptions as w, type SilicaRenderConfig as x, type SilicaTheme as y, type SimpleSlug as z };
389
+ export { asSimpleSlug as $, type AnalyzeResult as A, type BrokenLink as B, type SilicaRenderConfig as C, type SilicaTheme as D, type SimpleSlug as E, type FilePath as F, type Graph as G, type ThemeBreadcrumb as H, type ThemeConfig as I, type ThemeLayoutConfig as J, type ThemePage as K, type ThemePageProps as L, type Manifest as M, type Navigation as N, type ThemeProviderComponent as O, type PageProperty as P, type ThemeRootLayoutProps as Q, type RelativeURL as R, type SilicaAuthConfig as S, type ThemeBacklink as T, type ThemeSiteLayoutProps as U, type TocItem as V, type WikiLinkResolutionIndex as W, analyzePagePropertyLinks as X, asFilePath as Y, asFullSlug as Z, asRelativeURL as _, type AssetResolutionEntry as a, createAssetResolutionIndex as a0, createWikiLinkResolutionIndex as a1, formatPropertyLabel as a2, formatPropertyValue as a3, getMenuLabel as a4, getPageProperties as a5, getResolvedPageProperties as a6, hrefToSlug as a7, joinSegments as a8, normalizeAssetReference as a9, normalizePath as aa, normalizeSlug as ab, pathToRoot as ac, resolveAssetPath as ad, resolvePagePropertyValue as ae, resolveRelative as af, resolveRelativeAsset as ag, resolveWikiLink as ah, simplifySlug as ai, slugToHref as aj, slugifyAssetPath as ak, slugifyFilePath as al, slugifySegment as am, type AssetResolutionIndex as b, type FullSlug as c, type ManifestEntry as d, type MarkdownComponents as e, type NavigationEntry as f, type PagePropertyPart as g, type PagePropertyResolution as h, type PrecomputeResult as i, type PrerenderManifest as j, type PrerenderSelectorContext as k, type RenderCacheState as l, type RenderContext as m, type RenderResult as n, type ResolvedSilicaConfig as o, type ResolvedSilicaPrerenderConfig as p, type ResolvedSilicaRenderConfig as q, type SilicaCalloutProps as r, type SilicaCodeBlockProps as s, type SilicaConfig as t, type SilicaEmbedProps as u, type SilicaMermaidProps as v, type SilicaNextConfig as w, type SilicaNextConfigOverride as x, type SilicaPrerenderConfig as y, type SilicaPrerenderSelectionOptions as z };
package/dist/theme.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import 'react';
2
- export { e as MarkdownComponents, o as SilicaCalloutProps, p as SilicaCodeBlockProps, r as SilicaEmbedProps, s as SilicaMermaidProps, y as SilicaTheme, T as ThemeBacklink, C as ThemeBreadcrumb, E as ThemeLayoutConfig, H as ThemePage, I as ThemePageProps, J as ThemeProviderComponent, K as ThemeRootLayoutProps, L as ThemeSiteLayoutProps } from './theme-DuygYyeF.js';
2
+ export { e as MarkdownComponents, r as SilicaCalloutProps, s as SilicaCodeBlockProps, u as SilicaEmbedProps, v as SilicaMermaidProps, D as SilicaTheme, T as ThemeBacklink, H as ThemeBreadcrumb, J as ThemeLayoutConfig, K as ThemePage, L as ThemePageProps, O as ThemeProviderComponent, Q as ThemeRootLayoutProps, U as ThemeSiteLayoutProps } from './theme-D67Ma7mz.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.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Markdown pipeline, slug system, and precompute artifacts for Silica.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "lint": "tsc --noEmit"
32
32
  },
33
33
  "dependencies": {
34
- "@shikijs/rehype": "^4.1.0",
34
+ "@shikijs/rehype": "^4.2.0",
35
35
  "@silicajs/remark-obsidian": "^0.1.0",
36
36
  "@silicajs/search": "^0.3.1",
37
37
  "better-sqlite3": "^12.10.0",
@@ -54,7 +54,7 @@
54
54
  "remark-math": "^6.0.0",
55
55
  "remark-parse": "^11.0.0",
56
56
  "remark-rehype": "^11.1.2",
57
- "shiki": "^4.1.0",
57
+ "shiki": "^4.2.0",
58
58
  "unified": "^11.0.5",
59
59
  "unist-util-visit": "^5.1.0",
60
60
  "zod": "^4.4.3"