Reindex refactor feature complete

This commit is contained in:
Zef Hemel
2026-01-07 15:44:04 +01:00
parent c93d656ac6
commit 596b92cd55
21 changed files with 390 additions and 139 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ import type {
PageCreatingContent,
PageCreatingEvent,
} from "@silverbulletmd/silverbullet/type/event";
import type { StyleObject } from "../plugs/index/style.ts";
import type { StyleObject } from "../plugs/index/space_style.ts";
import { jitter, throttle } from "@silverbulletmd/silverbullet/lib/async";
import { EventedSpacePrimitives } from "./spaces/evented_space_primitives.ts";
import { HttpSpacePrimitives } from "./spaces/http_space_primitives.ts";
+2 -2
View File
@@ -1,5 +1,5 @@
import type { System } from "./plugos/system.ts";
import type { ScriptObject } from "../plugs/index/script.ts";
import type { SpaceLuaObject } from "../plugs/index/space_lua.ts";
import { LuaEnv, LuaRuntimeError, LuaStackFrame } from "./space_lua/runtime.ts";
import { parse as parseLua, parseExpressionString } from "./space_lua/parse.ts";
import { evalStatement } from "./space_lua/eval.ts";
@@ -24,7 +24,7 @@ export class SpaceLuaEnvironment {
* @param system
*/
async reload() {
const allScripts: ScriptObject[] = await this.system.invokeFunction(
const allScripts: SpaceLuaObject[] = await this.system.invokeFunction(
"index.queryLuaObjects",
["space-lua", {
objectVariable: "script",
+1
View File
@@ -4,6 +4,7 @@ import type { EventSubscriptionDef } from "./manifest.ts";
export type IndexTreeEvent = {
name: string;
tree: ParseTree;
text: string;
};
export type PageCreatingEvent = {
+2 -37
View File
@@ -67,47 +67,13 @@ functions:
events:
- page:index
indexParagraphs:
path: "./paragraph.ts:indexParagraphs"
events:
- page:index
# Backlinks
indexLinks:
path: "./page_links.ts:indexLinks"
events:
- page:index
# Tables
indexTables:
path: "table.ts:indexTables"
events:
- page:index
# Headers
headerComplete:
path: header.ts:headerComplete
events:
- editor:complete
# Lua
indexSpaceLua:
path: script.ts:indexSpaceLua
events:
- page:index
# Style
indexSpaceStyle:
path: style.ts:indexSpaceStyle
events:
- page:index
# Hashtags
indexTags:
path: tags.ts:indexTags
events:
- page:index
tagComplete:
path: tags.ts:tagComplete
events:
@@ -136,6 +102,8 @@ functions:
requireMode: rw
requireEditor: page
# Refactoring Commands
renameDocumentCommand:
path: "./refactor.ts:renameDocumentCommand"
command:
@@ -143,7 +111,6 @@ functions:
requireMode: rw
requireEditor: notpage
# Refactoring Commands
extractToPageCommand:
path: ./refactor.ts:extractToPageCommand
command:
@@ -437,8 +404,6 @@ config:
type: number
alias:
type: string
asTemplate:
type: boolean
header:
type: object
properties:
+17 -4
View File
@@ -11,11 +11,18 @@ import { indexPage as pageIndexPage } from "./page.ts";
import { indexData } from "./data.ts";
import { indexItems } from "./item.ts";
import { indexHeaders } from "./header.ts";
import { indexParagraphs } from "./paragraph.ts";
import { indexLinks } from "./page_links.ts";
import { indexTables } from "./table.ts";
import { indexSpaceLua } from "./space_lua.ts";
import { indexSpaceStyle } from "./space_style.ts";
import { indexTags } from "./tags.ts";
export type IndexerFunction = (
pageMeta: PageMeta,
frontmatter: FrontMatter,
tree: ParseTree,
text: string,
) => Promise<ObjectValue<any>[]>;
const allIndexers: IndexerFunction[] = [
@@ -23,20 +30,26 @@ const allIndexers: IndexerFunction[] = [
indexData,
indexItems,
indexHeaders,
indexParagraphs,
indexLinks,
indexTables,
indexSpaceLua,
indexSpaceStyle,
indexTags,
];
export async function indexPage({ name, tree }: IndexTreeEvent) {
export async function indexPage({ name, tree, text }: IndexTreeEvent) {
const pageMeta = await space.getPageMeta(name);
const frontmatter = extractFrontMatter(tree);
console.log("Now going to index page", name);
// console.log("Now going to index page", name);
// Index the page
const index = await Promise.all(allIndexers.map((indexer) => {
return indexer(pageMeta, frontmatter, tree);
return indexer(pageMeta, frontmatter, tree, text);
}));
console.log("Found these objects", index.flat());
// console.log("Found these objects", index.flat());
await indexObjects<any>(name, index.flat());
}
+1 -1
View File
@@ -15,7 +15,7 @@ const itemsMd = `
* [ ] Sub task
`;
Deno.test("Test item extraction", async () => {
Deno.test("Test item indexing", async () => {
createMockSystem();
const tree = parseMarkdown(itemsMd);
const frontmatter = extractFrontMatter(tree);
+1 -1
View File
@@ -15,7 +15,7 @@ hello: attribute
`.trim();
Deno.test("Test page indexer", async () => {
Deno.test("Test page indexing", async () => {
createMockSystem();
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
+44
View File
@@ -0,0 +1,44 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexLinks } from "./page_links.ts";
const testPage = `
---
attribute: "[[fm-link]]"
---
This is a [[page-link]] to [[aliased-link|aliased]], or [this](md-link), and [[broken]]
`.trim();
Deno.test("Test page link indexing", async () => {
const { space } = createMockSystem();
// Create dummy targets to avoid a lot of aspiring pages
await space.writePage("page-link", "");
await space.writePage("fm-link", "");
await space.writePage("aliased-link", "");
await space.writePage("folder/md-link", "");
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "folder/test",
name: "folder/test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
const objects = await indexLinks(pageMeta, frontmatter, tree, testPage);
// console.log(objects);
assertEquals(objects.length, 6); // 5 links + 1 aspiring page
assertEquals(objects[0].toPage, "fm-link");
assertEquals(objects[1].toPage, "page-link");
assertEquals(objects[2].toPage, "aliased-link");
assertEquals(objects[2].alias, "aliased");
assertEquals(objects[3].toPage, "folder/md-link"); // relative
});
+24 -28
View File
@@ -1,16 +1,16 @@
import {
collectNodesOfType,
findNodeOfType,
type ParseTree,
renderToText,
traverseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import {
isLocalURL,
resolveMarkdownLink,
} from "@silverbulletmd/silverbullet/lib/resolve";
import { indexObjects, queryLuaObjects } from "./api.ts";
import { extractFrontMatter } from "./frontmatter.ts";
import { queryLuaObjects } from "./api.ts";
import type { FrontMatter } from "./frontmatter.ts";
import { updateITags } from "./tags.ts";
import {
getNameFromPath,
@@ -23,7 +23,10 @@ import {
wikiLinkRegex,
} from "../../client/markdown_parser/constants.ts";
import { lua, space } from "@silverbulletmd/silverbullet/syscalls";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
export type LinkObject = ObjectValue<
{
@@ -35,7 +38,6 @@ export type LinkObject = ObjectValue<
pos: number;
snippet: string;
alias?: string;
asTemplate: boolean;
toFile?: never;
} | {
// Document Link
@@ -46,7 +48,6 @@ export type LinkObject = ObjectValue<
pos: number;
snippet: string;
alias?: string;
asTemplate: boolean;
toPage?: never;
}
>;
@@ -64,16 +65,21 @@ export type AspiringPageObject = ObjectValue<{
name: string;
}>;
export async function indexLinks({ name, tree }: IndexTreeEvent) {
const links: ObjectValue<LinkObject>[] = [];
const frontmatter = await extractFrontMatter(tree);
const pageText = renderToText(tree);
export async function indexLinks(
pageMeta: PageMeta,
frontmatter: FrontMatter,
tree: ParseTree,
pageText: string,
) {
const objects: ObjectValue<any>[] = [];
// If this is a meta template page, we don't want to index links
if (frontmatter.tags?.find((t) => t.startsWith("meta/template"))) {
return;
return [];
}
const name = pageMeta.name;
traverseTree(tree, (n): boolean => {
// Index [[WikiLinks]]
if (n.type === "WikiLink") {
@@ -88,7 +94,6 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
snippet: extractSnippetAroundIndex(pageText, pos),
pos,
page: name,
asTemplate: false,
};
const ref = parseToRef(url);
@@ -105,7 +110,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
link.alias = wikiLinkAlias.children![0].text!;
}
updateITags(link, frontmatter);
links.push(link);
objects.push(link);
return true;
}
@@ -135,7 +140,6 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
snippet: extractSnippetAroundIndex(pageText, pos),
pos,
page: name,
asTemplate: false,
};
const ref = parseToRef(url);
@@ -152,7 +156,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
link.alias = alias;
}
updateITags(link, frontmatter);
links.push(link);
objects.push(link);
return true;
}
@@ -176,7 +180,6 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
page: name,
snippet: extractSnippetAroundIndex(pageText, pos),
pos: pos,
asTemplate: false,
};
const ref = parseToRef(stringRef);
@@ -193,24 +196,19 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
link.alias = alias;
}
updateITags(link, frontmatter);
links.push(link);
objects.push(link);
}
}
}
return false;
});
// console.log("Found", links, "page link(s)");
if (links.length > 0) {
await indexObjects(name, links);
}
// Now let's check which are aspiring pages
const aspiringPages: ObjectValue<AspiringPageObject>[] = [];
for (const link of links) {
for (const link of objects.slice()) {
if (link.toPage) {
// TODO: Optimize fileExists to be more efficient
if (!await space.fileExists(`${link.toPage}.md`)) {
aspiringPages.push({
objects.push({
ref: `${name}@${link.pos}`,
tag: "aspiring-page",
page: name,
@@ -228,9 +226,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
}
}
if (aspiringPages.length > 0) {
await indexObjects(name, aspiringPages);
}
return objects;
}
export async function getBackLinks(
+47
View File
@@ -0,0 +1,47 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexParagraphs } from "./paragraph.ts";
const testPage = `
#tag-only
Some paragraph
Another paragraph that is #tagged
* Item paragraph (don't index)
`.trim();
Deno.test("Test paragraph indexing", async () => {
const { config } = createMockSystem();
config.set("index.paragraph.all", true);
let tree = parseMarkdown(testPage);
let frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "test",
name: "test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
let paragraphs = await indexParagraphs(pageMeta, frontmatter, tree);
console.log(paragraphs);
assertEquals(paragraphs.length, 2);
assertEquals([...new Set(paragraphs[0].itags)], ["paragraph", "tag-only"]);
assertEquals(paragraphs[1].tags, ["tagged"]);
config.set("index.paragraph.all", false);
tree = parseMarkdown(testPage);
frontmatter = extractFrontMatter(tree);
paragraphs = await indexParagraphs(pageMeta, frontmatter, tree);
assertEquals(paragraphs.length, 1);
});
+24 -20
View File
@@ -1,15 +1,18 @@
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import { indexObjects } from "./api.ts";
import {
findParentMatching,
type ParseTree,
renderToText,
traverseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import { cleanTags, collectTags, updateITags } from "./tags.ts";
import { extractFrontMatter } from "./frontmatter.ts";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type { FrontMatter } from "./frontmatter.ts";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
import { system } from "@silverbulletmd/silverbullet/syscalls";
import { cleanAttributes, collectAttributes } from "./attribute.ts";
import { deepClone } from "@silverbulletmd/silverbullet/lib/json";
/** ParagraphObject An index object for the top level text nodes */
export type ParagraphObject = ObjectValue<
@@ -20,16 +23,18 @@ export type ParagraphObject = ObjectValue<
} & Record<string, any>
>;
export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
export async function indexParagraphs(
pageMeta: PageMeta,
frontmatter: FrontMatter,
tree: ParseTree,
) {
const shouldIndexAll = await system.getConfig(
"index.paragraph.all",
true,
false,
);
const objects: ParagraphObject[] = [];
const frontmatter = extractFrontMatter(tree);
traverseTree(tree, (p) => {
if (p.type !== "Paragraph") {
return false;
@@ -37,26 +42,27 @@ export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
if (findParentMatching(p, (n) => n.type === "ListItem")) {
// Not looking at paragraphs nested in a list
return false;
return true;
}
const fullText = renderToText(p);
// Collect tags and remove from the tree
// Collect tags
const tags = collectTags(p);
if (tags.length === 0 && !shouldIndexAll) {
// Don't index paragraphs without a hashtag
return false;
return true;
}
// Extract attributes
const attrs = collectAttributes(p);
// Clean tree
cleanTags(p);
cleanAttributes(p);
const text = renderToText(p);
// Clean tree, just to check if it's effectively empty or not
const cleanP = deepClone(p, ["parent"]);
cleanTags(cleanP);
cleanAttributes(cleanP);
const text = renderToText(cleanP);
if (!text.trim()) {
// Empty paragraph, just tags and attributes maybe
@@ -66,9 +72,9 @@ export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
const pos = p.from!;
const paragraph: ParagraphObject = {
tag: "paragraph",
ref: `${page}@${pos}`,
ref: `${pageMeta.name}@${pos}`,
text: fullText,
page,
page: pageMeta.name,
pos,
...attrs,
};
@@ -84,7 +90,5 @@ export async function indexParagraphs({ name: page, tree }: IndexTreeEvent) {
return true;
});
// console.log("Paragraph objects", objects);
await indexObjects<ParagraphObject>(page, objects);
return objects;
}
+3 -1
View File
@@ -24,9 +24,10 @@ export async function reindexSpace() {
console.log("Queing", files.length, "pages to be indexed.");
// Queue all file names to be indexed
const startTime = Date.now();
await mq.batchSend("indexQueue", files.map((file) => file.name));
await mq.awaitEmptyQueue("indexQueue");
console.log("And done with full index!");
console.log("Done with full index after", Date.now() - startTime, "ms");
}
setTimeout(updateIndexProgressInUI, uiUpdateInterval);
@@ -85,6 +86,7 @@ async function indexFile(path: string) {
await events.dispatchEvent("page:index", {
name,
tree,
text,
} as IndexTreeEvent);
} else {
await events.dispatchEvent("document:index", path);
+41
View File
@@ -0,0 +1,41 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexSpaceLua } from "./space_lua.ts";
const testPage = `
Hello
\`\`\`space-lua
function sup()
end
\`\`\`
\`\`\`space-lua
-- priority: 10
function sup()
end
\`\`\`
`.trim();
Deno.test("Test space lua indexing", async () => {
createMockSystem();
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "folder/test",
name: "folder/test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
const objects = await indexSpaceLua(pageMeta, frontmatter, tree);
assertEquals(objects.length, 2);
assertEquals(objects[0].priority, undefined);
assertEquals(objects[1].priority, 10);
});
@@ -1,18 +1,25 @@
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import {
collectNodesOfType,
findNodeOfType,
type ParseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import { indexObjects } from "./api.ts";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
import type { FrontMatter } from "./frontmatter.ts";
export type ScriptObject = ObjectValue<{
export type SpaceLuaObject = ObjectValue<{
script: string;
priority?: number;
}>;
export async function indexSpaceLua({ name, tree }: IndexTreeEvent) {
const allScripts: ScriptObject[] = [];
export function indexSpaceLua(
pageMeta: PageMeta,
_frontmatter: FrontMatter,
tree: ParseTree,
) {
const allSpaceLuas: SpaceLuaObject[] = [];
collectNodesOfType(tree, "FencedCode").map((t) => {
const codeInfoNode = findNodeOfType(t, "CodeInfo");
if (!codeInfoNode) {
@@ -31,12 +38,12 @@ export async function indexSpaceLua({ name, tree }: IndexTreeEvent) {
// Parse out "-- priority: <number>"
const priority = codeText.match(/--\s*priority:\s*(-?\d+)/)?.[1];
allScripts.push({
ref: `${name}@${t.from!}`,
allSpaceLuas.push({
ref: `${pageMeta.name}@${t.from!}`,
tag: "space-lua",
script: codeText,
priority: priority !== undefined ? +priority : undefined,
});
});
await indexObjects<ScriptObject>(name, allScripts);
return Promise.resolve(allSpaceLuas);
}
+39
View File
@@ -0,0 +1,39 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexSpaceStyle } from "./space_style.ts";
const testPage = `
Hello
\`\`\`space-style
.hello {}
\`\`\`
\`\`\`space-style
/* priority: 10 */
.hello2 {}
\`\`\`
`.trim();
Deno.test("Test space style indexing", async () => {
createMockSystem();
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "folder/test",
name: "folder/test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
const objects = await indexSpaceStyle(pageMeta, frontmatter, tree);
assertEquals(objects.length, 2);
assertEquals(objects[0].priority, undefined);
assertEquals(objects[1].priority, 10);
});
@@ -1,17 +1,24 @@
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import {
collectNodesOfType,
findNodeOfType,
type ParseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import { indexObjects } from "./api.ts";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
import type { FrontMatter } from "./frontmatter.ts";
export type StyleObject = ObjectValue<{
style: string;
priority?: number;
}>;
export async function indexSpaceStyle({ name, tree }: IndexTreeEvent) {
export function indexSpaceStyle(
pageMeta: PageMeta,
_frontmatter: FrontMatter,
tree: ParseTree,
) {
const allStyles: StyleObject[] = [];
// Also collect CSS from custom styles in config
@@ -37,12 +44,12 @@ export async function indexSpaceStyle({ name, tree }: IndexTreeEvent) {
const priority = codeText.match(/\/\*+\s*priority:\s*(-?\d+)/)?.[1];
allStyles.push({
ref: `${name}@${t.from!}`,
ref: `${pageMeta.name}@${t.from!}`,
tag: "space-style",
style: codeText,
priority: priority !== undefined ? +priority : undefined,
});
});
await indexObjects<StyleObject>(name, allStyles);
return Promise.resolve(allStyles);
}
+36
View File
@@ -0,0 +1,36 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexTables } from "./table.ts";
const testPage = `
| name | age |
|----------|----------|
| Frank | 20 |
| Fred | 21 |
`.trim();
Deno.test("Test table indexing", async () => {
createMockSystem();
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "test",
name: "test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
const datas = await indexTables(pageMeta, frontmatter, tree);
assertEquals(datas.length, 2);
assertEquals(datas[0].name, "Frank");
assertEquals(datas[0].age, "20");
assertEquals(datas[1].name, "Fred");
assertEquals(datas[1].age, "21");
});
+14 -8
View File
@@ -1,4 +1,3 @@
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import {
renderToText,
replaceNodesMatching,
@@ -8,9 +7,12 @@ import {
collectNodesOfType,
type ParseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import { indexObjects } from "./api.ts";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
import { extractHashtag } from "@silverbulletmd/silverbullet/lib/tags";
import type { FrontMatter } from "./frontmatter.ts";
type TableRowObject =
& ObjectValue<{
@@ -47,7 +49,11 @@ function concatChildrenTextsPreserveLinks(nodes: ParseTree[]): string {
return nodes.map((c) => renderToText(c)).join("").trim();
}
export async function indexTables({ name: pageName, tree }: IndexTreeEvent) {
export function indexTables(
pageMeta: PageMeta,
_frontmatter: FrontMatter,
tree: ParseTree,
) {
const result: ObjectValue<TableRowObject>[] = [];
collectNodesMatching(
@@ -72,11 +78,11 @@ export async function indexTables({ name: pageName, tree }: IndexTreeEvent) {
const cells = collectNodesOfType(row, "TableCell");
const tableRow: TableRowObject = {
tableref: `${pageName}@${table.from}`,
ref: `${pageName}@${row.from}`,
tableref: `${pageMeta.name}@${table.from}`,
ref: `${pageMeta.name}@${row.from}`,
tag: "table",
tags: [...tags],
page: pageName,
page: pageMeta.name,
pos: row.from!,
};
cells.forEach((c, i) => {
@@ -94,5 +100,5 @@ export async function indexTables({ name: pageName, tree }: IndexTreeEvent) {
},
);
await indexObjects(pageName, result);
return Promise.resolve(result);
}
+38
View File
@@ -0,0 +1,38 @@
import { parseMarkdown } from "../../client/markdown_parser/parser.ts";
import { createMockSystem } from "../../plug-api/system_mock.ts";
import type { PageMeta } from "@silverbulletmd/silverbullet/type/index";
import { extractFrontMatter } from "./frontmatter.ts";
import { assertEquals } from "@std/assert";
import { indexTags } from "./tags.ts";
const testPage = `
#page-tag
* Item #item-tag
* [ ] Task #task-tag
`.trim();
Deno.test("Test tag indexing", async () => {
createMockSystem();
const tree = parseMarkdown(testPage);
const frontmatter = extractFrontMatter(tree);
const pageMeta: PageMeta = {
ref: "folder/test",
name: "folder/test",
tag: "page",
created: "",
lastModified: "",
perm: "rw",
};
const objects = await indexTags(pageMeta, frontmatter, tree);
assertEquals(objects.length, 3);
assertEquals(objects[0].name, "page-tag");
assertEquals(objects[0].parent, "page");
assertEquals(objects[1].name, "item-tag");
assertEquals(objects[1].parent, "item");
assertEquals(objects[2].name, "task-tag");
assertEquals(objects[2].parent, "task");
});
+25 -20
View File
@@ -1,6 +1,5 @@
import type { IndexTreeEvent } from "@silverbulletmd/silverbullet/type/event";
import { extractFrontMatter, type FrontMatter } from "./frontmatter.ts";
import { indexObjects, queryLuaObjects } from "./api.ts";
import type { FrontMatter } from "./frontmatter.ts";
import { queryLuaObjects } from "./api.ts";
import {
addParentPointers,
collectNodesOfType,
@@ -9,7 +8,10 @@ import {
replaceNodesMatching,
traverseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
import type {
ObjectValue,
PageMeta,
} from "@silverbulletmd/silverbullet/type/index";
import type { CompleteEvent } from "@silverbulletmd/silverbullet/type/client";
import { tagRegex } from "../../client/markdown_parser/constants.ts";
import { extractHashtag } from "@silverbulletmd/silverbullet/lib/tags";
@@ -20,10 +22,17 @@ export type TagObject = ObjectValue<{
parent: string;
}>;
export async function indexTags({ name, tree }: IndexTreeEvent) {
/**
* Handles indexing of page, item and task level tags, data tags are handled in data.ts
*/
export function indexTags(
pageMeta: PageMeta,
frontmatter: FrontMatter,
tree: ParseTree,
) {
const tags = new Set<string>(); // name:parent
addParentPointers(tree);
const pageTags: string[] = extractFrontMatter(tree).tags || [];
const pageTags: string[] = frontmatter.tags || [];
for (const pageTag of pageTags) {
tags.add(`${pageTag}:page`);
}
@@ -40,20 +49,16 @@ export async function indexTags({ name, tree }: IndexTreeEvent) {
tags.add(`${tagName}:page`);
}
});
// console.log("Indexing these tags", tags);
await indexObjects<TagObject>(
name,
[...tags].map((tag) => {
const [tagName, parent] = tag.split(":");
return {
ref: tag,
tag: "tag",
name: tagName,
page: name,
parent,
};
}),
);
return Promise.resolve([...tags].map((tag) => {
const [tagName, parent] = tag.split(":");
return {
ref: tag,
tag: "tag",
name: tagName,
page: pageMeta.name,
parent,
};
}));
}
export async function tagComplete(completeEvent: CompleteEvent) {
+1 -1
View File
@@ -6,7 +6,7 @@ Whenever a commit is pushed to the `main` branch, within ~10 minutes, it will be
* Removed full-text search plug from the main distribution, this has now been moved to [a separate repo](https://github.com/silverbulletmd/basic-search) (installable via the library manager). This dramatically improves indexing speed. But actually: install [Silversearch](https://github.com/MrMugame/silversearch) instead.
* Indexer refactor:
* For consistency with items, `task` `refs` now point to the item’s position resulting in a slight positional shift, if you have code relying on this, you may have to adjust it
*
* `page:index` now also received `text` attribute
* Disabled indexing all paragraph text (even those not tagged) by default, this caused significant indexing overhead. [See discussion](https://community.silverbullet.md/t/who-is-using-paragraph-for-queries/3686).
* To re-enable: `config.set("index.paragraph.all", true)`
* Production builds now include sourcemaps for easier debugging in browser DevTools. If you don't want to serve sourcemaps publicly, you can block `*.js.map` files at your reverse proxy level (see [[TLS#Blocking sourcemaps]]).