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