From d618a4e3f376028902e481b78466e8fbedd860aa Mon Sep 17 00:00:00 2001
From: Jacky Zhao <j.zhao2k19@gmail.com>
Date: Mon, 10 Mar 2025 06:36:10 +0000
Subject: [PATCH] fix(explorer): dont rely on data to get slug, compute it in trie
---
quartz/util/fileTrie.ts | 101 +++++++++++++++++++++++++-------------------------
1 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/quartz/util/fileTrie.ts b/quartz/util/fileTrie.ts
index ed87b4f..7195237 100644
--- a/quartz/util/fileTrie.ts
+++ b/quartz/util/fileTrie.ts
@@ -7,55 +7,64 @@
}
export class FileTrieNode<T extends FileTrieData = ContentDetails> {
- children: Array<FileTrieNode<T>>
- slugSegment: string
- displayName: string
- data: T | null
- depth: number
isFolder: boolean
+ children: Array<FileTrieNode<T>>
- constructor(segment: string, data?: T, depth: number = 0) {
+ private slugSegments: string[]
+ data: T | null
+
+ constructor(segments: string[], data?: T) {
this.children = []
- this.slugSegment = segment
- this.displayName = data?.title ?? segment
+ this.slugSegments = segments
this.data = data ?? null
- this.depth = depth
- this.isFolder = segment === "index"
+ this.isFolder = false
+ }
+
+ get displayName(): string {
+ return this.data?.title ?? this.slugSegment ?? ""
+ }
+
+ get slug(): FullSlug {
+ const path = joinSegments(...this.slugSegments) as FullSlug
+ if (this.isFolder) {
+ return joinSegments(path, "index") as FullSlug
+ }
+
+ return path
+ }
+
+ get slugSegment(): string {
+ return this.slugSegments[this.slugSegments.length - 1]
+ }
+
+ private makeChild(path: string[], file?: T) {
+ const fullPath = [...this.slugSegments, path[0]]
+ const child = new FileTrieNode<T>(fullPath, file)
+ this.children.push(child)
+ return child
}
private insert(path: string[], file: T) {
- if (path.length === 0) return
+ if (path.length === 0) {
+ throw new Error("path is empty")
+ }
- const nextSegment = path[0]
-
- // base case, insert here
+ // if we are inserting, we are a folder
+ this.isFolder = true
+ const segment = path[0]
if (path.length === 1) {
- if (nextSegment === "index") {
- // index case (we are the root and we just found index.md)
+ // base case, we are at the end of the path
+ if (segment === "index") {
this.data ??= file
- const title = file.title
- if (title !== "index") {
- this.displayName = title
- }
} else {
- // direct child
- this.children.push(new FileTrieNode(nextSegment, file, this.depth + 1))
- this.isFolder = true
+ this.makeChild(path, file)
}
-
- return
+ } else if (path.length > 1) {
+ // recursive case, we are not at the end of the path
+ const child =
+ this.children.find((c) => c.slugSegment === segment) ?? this.makeChild(path, undefined)
+ child.insert(path.slice(1), file)
}
-
- // find the right child to insert into, creating it if it doesn't exist
- path = path.splice(1)
- let child = this.children.find((c) => c.slugSegment === nextSegment)
- if (!child) {
- child = new FileTrieNode<T>(nextSegment, undefined, this.depth + 1)
- this.children.push(child)
- child.isFolder = true
- }
-
- child.insert(path, file)
}
// Add new file to trie
@@ -88,7 +97,7 @@
}
static fromEntries<T extends FileTrieData>(entries: [FullSlug, T][]) {
- const trie = new FileTrieNode<T>("")
+ const trie = new FileTrieNode<T>([])
entries.forEach(([, entry]) => trie.add(entry))
return trie
}
@@ -98,22 +107,12 @@
* in the a flat array including the full path and the node
*/
entries(): [FullSlug, FileTrieNode<T>][] {
- const traverse = (
- node: FileTrieNode<T>,
- currentPath: string,
- ): [FullSlug, FileTrieNode<T>][] => {
- const segments = [currentPath, node.slugSegment]
- const fullPath = joinSegments(...segments) as FullSlug
-
- const indexQualifiedPath =
- node.isFolder && node.depth > 0 ? (joinSegments(fullPath, "index") as FullSlug) : fullPath
-
- const result: [FullSlug, FileTrieNode<T>][] = [[indexQualifiedPath, node]]
-
- return result.concat(...node.children.map((child) => traverse(child, fullPath)))
+ const traverse = (node: FileTrieNode<T>): [FullSlug, FileTrieNode<T>][] => {
+ const result: [FullSlug, FileTrieNode<T>][] = [[node.slug, node]]
+ return result.concat(...node.children.map(traverse))
}
- return traverse(this, "")
+ return traverse(this)
}
/**
--
Gitblit v1.10.0