Cleanup and federation prep
This commit is contained in:
parent
fe4887dc78
commit
afa160d2c2
@ -22,15 +22,19 @@ export class FallbackSpacePrimitives implements SpacePrimitives {
|
|||||||
try {
|
try {
|
||||||
return await this.primary.readFile(name);
|
return await this.primary.readFile(name);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// console.info(
|
if (e.message === "Not found") {
|
||||||
// `Could not read file ${name} from primary, trying fallback, primary read error:`,
|
console.info("Reading file content from fallback for", name);
|
||||||
// e.message,
|
} else {
|
||||||
// );
|
console.warn(
|
||||||
|
`Could not read file ${name} from primary, trying fallback, primary read error`,
|
||||||
|
e.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const result = await this.fallback.readFile(name);
|
const result = await this.fallback.readFile(name);
|
||||||
return {
|
return {
|
||||||
data: result.data,
|
data: result.data,
|
||||||
meta: { ...result.meta, neverSync: true },
|
meta: { ...result.meta, noSync: true },
|
||||||
};
|
};
|
||||||
} catch (fallbackError: any) {
|
} catch (fallbackError: any) {
|
||||||
console.error("Error during readFile fallback", fallbackError.message);
|
console.error("Error during readFile fallback", fallbackError.message);
|
||||||
@ -42,14 +46,18 @@ export class FallbackSpacePrimitives implements SpacePrimitives {
|
|||||||
async getFileMeta(name: string): Promise<FileMeta> {
|
async getFileMeta(name: string): Promise<FileMeta> {
|
||||||
try {
|
try {
|
||||||
return await this.primary.getFileMeta(name);
|
return await this.primary.getFileMeta(name);
|
||||||
} catch (e) {
|
} catch (e: any) {
|
||||||
// console.info(
|
if (e.message === "Not found") {
|
||||||
// `Could not fetch file ${name} metadata from primary, trying fallback, primary read error`,
|
console.info("Fetching file meta from fallback for", name);
|
||||||
// e.message,
|
} else {
|
||||||
// );
|
console.warn(
|
||||||
|
`Could not fetch file ${name} metadata from primary, trying fallback, primary read error`,
|
||||||
|
e.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const meta = await this.fallback.getFileMeta(name);
|
const meta = await this.fallback.getFileMeta(name);
|
||||||
return { ...meta, neverSync: true };
|
return { ...meta, noSync: true };
|
||||||
} catch (fallbackError) {
|
} catch (fallbackError) {
|
||||||
console.error(
|
console.error(
|
||||||
"Error during getFileMeta fallback",
|
"Error during getFileMeta fallback",
|
||||||
|
@ -6,5 +6,5 @@ export type FileMeta = {
|
|||||||
contentType: string;
|
contentType: string;
|
||||||
size: number;
|
size: number;
|
||||||
perm: "ro" | "rw";
|
perm: "ro" | "rw";
|
||||||
neverSync?: boolean;
|
noSync?: boolean;
|
||||||
} & Record<string, any>;
|
} & Record<string, any>;
|
||||||
|
@ -3,7 +3,7 @@ export function resolvePath(
|
|||||||
pathToResolve: string,
|
pathToResolve: string,
|
||||||
fullUrl = false,
|
fullUrl = false,
|
||||||
): string {
|
): string {
|
||||||
if (currentPage.startsWith("!") && !pathToResolve.startsWith("!")) {
|
if (isFederationPath(currentPage) && !isFederationPath(pathToResolve)) {
|
||||||
let domainPart = currentPage.split("/")[0];
|
let domainPart = currentPage.split("/")[0];
|
||||||
if (fullUrl) {
|
if (fullUrl) {
|
||||||
domainPart = domainPart.substring(1);
|
domainPart = domainPart.substring(1);
|
||||||
@ -18,3 +18,7 @@ export function resolvePath(
|
|||||||
return pathToResolve;
|
return pathToResolve;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFederationPath(path: string) {
|
||||||
|
return path.startsWith("!");
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { editor, markdown, space } from "$sb/silverbullet-syscall/mod.ts";
|
import { editor, markdown, space, sync } from "$sb/silverbullet-syscall/mod.ts";
|
||||||
import {
|
import {
|
||||||
removeParentPointers,
|
removeParentPointers,
|
||||||
renderToText,
|
renderToText,
|
||||||
@ -7,15 +7,29 @@ import {
|
|||||||
import { renderDirectives } from "./directives.ts";
|
import { renderDirectives } from "./directives.ts";
|
||||||
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
|
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
|
||||||
import { PageMeta } from "../../web/types.ts";
|
import { PageMeta } from "../../web/types.ts";
|
||||||
|
import { isFederationPath } from "$sb/lib/resolve.ts";
|
||||||
|
|
||||||
export async function updateDirectivesOnPageCommand() {
|
export async function updateDirectivesOnPageCommand() {
|
||||||
// If `arg` is a string, it's triggered automatically via an event, not explicitly via a command
|
// If `arg` is a string, it's triggered automatically via an event, not explicitly via a command
|
||||||
const pageMeta = await space.getPageMeta(await editor.getCurrentPage());
|
const currentPage = await editor.getCurrentPage();
|
||||||
|
const pageMeta = await space.getPageMeta(currentPage);
|
||||||
const text = await editor.getText();
|
const text = await editor.getText();
|
||||||
const tree = await markdown.parseMarkdown(text);
|
const tree = await markdown.parseMarkdown(text);
|
||||||
const metaData = await extractFrontmatter(tree, ["$disableDirectives"]);
|
const metaData = await extractFrontmatter(tree, ["$disableDirectives"]);
|
||||||
|
|
||||||
|
if (isFederationPath(currentPage)) {
|
||||||
|
console.info("Current page is a federation page, not updating directives.");
|
||||||
|
}
|
||||||
|
|
||||||
if (metaData.$disableDirectives) {
|
if (metaData.$disableDirectives) {
|
||||||
// Not updating, directives disabled
|
console.info("Directives disabled in page meta, not updating them.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await sync.hasInitialSyncCompleted())) {
|
||||||
|
console.info(
|
||||||
|
"Initial sync hasn't completed yet, not updating directives.",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +110,6 @@ export async function updateDirectivesOnPageCommand() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pure server driven implementation of directive updating
|
|
||||||
export async function updateDirectives(
|
export async function updateDirectives(
|
||||||
pageMeta: PageMeta,
|
pageMeta: PageMeta,
|
||||||
text: string,
|
text: string,
|
||||||
|
@ -35,14 +35,6 @@ export async function directiveDispatcher(
|
|||||||
const directiveStartText = renderToText(directiveStart).trim();
|
const directiveStartText = renderToText(directiveStart).trim();
|
||||||
const directiveEndText = renderToText(directiveEnd).trim();
|
const directiveEndText = renderToText(directiveEnd).trim();
|
||||||
|
|
||||||
if (!(await sync.hasInitialSyncCompleted())) {
|
|
||||||
console.info(
|
|
||||||
"Initial sync hasn't completed yet, not updating directives.",
|
|
||||||
);
|
|
||||||
// Render the query directive as-is
|
|
||||||
return renderToText(directiveTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directiveStart.children!.length === 1) {
|
if (directiveStart.children!.length === 1) {
|
||||||
// Everything not #query
|
// Everything not #query
|
||||||
const match = directiveStartRegex.exec(directiveStart.children![0].text!);
|
const match = directiveStartRegex.exec(directiveStart.children![0].text!);
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
import { queryRegex } from "$sb/lib/query.ts";
|
import { queryRegex } from "$sb/lib/query.ts";
|
||||||
import { ParseTree, renderToText } from "$sb/lib/tree.ts";
|
import {
|
||||||
|
findNodeOfType,
|
||||||
|
ParseTree,
|
||||||
|
renderToText,
|
||||||
|
traverseTree,
|
||||||
|
} from "$sb/lib/tree.ts";
|
||||||
import { markdown, space } from "$sb/silverbullet-syscall/mod.ts";
|
import { markdown, space } from "$sb/silverbullet-syscall/mod.ts";
|
||||||
import Handlebars from "handlebars";
|
import Handlebars from "handlebars";
|
||||||
|
|
||||||
@ -9,6 +14,7 @@ import { directiveRegex } from "./directives.ts";
|
|||||||
import { updateDirectives } from "./command.ts";
|
import { updateDirectives } from "./command.ts";
|
||||||
import { buildHandebarOptions } from "./util.ts";
|
import { buildHandebarOptions } from "./util.ts";
|
||||||
import { PageMeta } from "../../web/types.ts";
|
import { PageMeta } from "../../web/types.ts";
|
||||||
|
import { resolvePath } from "$sb/lib/resolve.ts";
|
||||||
|
|
||||||
const templateRegex = /\[\[([^\]]+)\]\]\s*(.*)\s*/;
|
const templateRegex = /\[\[([^\]]+)\]\]\s*(.*)\s*/;
|
||||||
|
|
||||||
@ -24,7 +30,7 @@ export async function templateDirectiveRenderer(
|
|||||||
if (!match) {
|
if (!match) {
|
||||||
throw new Error(`Invalid template directive: ${arg}`);
|
throw new Error(`Invalid template directive: ${arg}`);
|
||||||
}
|
}
|
||||||
const template = match[1];
|
let templatePath = match[1];
|
||||||
const args = match[2];
|
const args = match[2];
|
||||||
let parsedArgs = {};
|
let parsedArgs = {};
|
||||||
if (args) {
|
if (args) {
|
||||||
@ -39,20 +45,29 @@ export async function templateDirectiveRenderer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let templateText = "";
|
let templateText = "";
|
||||||
if (template.startsWith("http://") || template.startsWith("https://")) {
|
if (
|
||||||
|
templatePath.startsWith("http://") || templatePath.startsWith("https://")
|
||||||
|
) {
|
||||||
try {
|
try {
|
||||||
const req = await fetch(template);
|
const req = await fetch(templatePath);
|
||||||
templateText = await req.text();
|
templateText = await req.text();
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
templateText = `ERROR: ${e.message}`;
|
templateText = `ERROR: ${e.message}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
templateText = await space.readPage(template);
|
templatePath = resolvePath(pageMeta.name, templatePath);
|
||||||
|
templateText = await space.readPage(templatePath);
|
||||||
}
|
}
|
||||||
const tree = await markdown.parseMarkdown(templateText);
|
const tree = await markdown.parseMarkdown(templateText);
|
||||||
await extractFrontmatter(tree, [], true); // Remove entire frontmatter section, if any
|
await extractFrontmatter(tree, [], true); // Remove entire frontmatter section, if any
|
||||||
|
|
||||||
|
// Resolve paths in the template
|
||||||
|
rewritePageRefs(tree, templatePath);
|
||||||
|
|
||||||
let newBody = renderToText(tree);
|
let newBody = renderToText(tree);
|
||||||
|
|
||||||
|
// console.log("Rewritten template:", newBody);
|
||||||
|
|
||||||
// if it's a template injection (not a literal "include")
|
// if it's a template injection (not a literal "include")
|
||||||
if (directive === "use") {
|
if (directive === "use") {
|
||||||
const templateFn = Handlebars.compile(
|
const templateFn = Handlebars.compile(
|
||||||
@ -67,6 +82,40 @@ export async function templateDirectiveRenderer(
|
|||||||
return newBody.trim();
|
return newBody.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rewritePageRefs(tree: ParseTree, templatePath: string) {
|
||||||
|
traverseTree(tree, (n): boolean => {
|
||||||
|
if (n.type === "DirectiveStart") {
|
||||||
|
const pageRef = findNodeOfType(n, "PageRef")!;
|
||||||
|
if (pageRef) {
|
||||||
|
const pageRefName = pageRef.children![0].text!.slice(2, -2);
|
||||||
|
pageRef.children![0].text = `[[${
|
||||||
|
resolvePath(templatePath, pageRefName)
|
||||||
|
}]]`;
|
||||||
|
}
|
||||||
|
const directiveText = n.children![0].text;
|
||||||
|
// #use or #import
|
||||||
|
if (directiveText) {
|
||||||
|
const match = /\[\[(.+)\]\]/.exec(directiveText);
|
||||||
|
if (match) {
|
||||||
|
const pageRefName = match[1];
|
||||||
|
n.children![0].text = directiveText.replace(
|
||||||
|
match[0],
|
||||||
|
`[[${resolvePath(templatePath, pageRefName)}]]`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (n.type === "WikiLinkPage") {
|
||||||
|
n.children![0].text = resolvePath(templatePath, n.children![0].text!);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function cleanTemplateInstantiations(text: string) {
|
export function cleanTemplateInstantiations(text: string) {
|
||||||
return text.replaceAll(directiveRegex, (
|
return text.replaceAll(directiveRegex, (
|
||||||
_fullMatch,
|
_fullMatch,
|
||||||
|
@ -192,9 +192,9 @@ export class SyncService {
|
|||||||
let remoteHash: number | undefined;
|
let remoteHash: number | undefined;
|
||||||
try {
|
try {
|
||||||
const localMeta = await this.localSpacePrimitives.getFileMeta(name);
|
const localMeta = await this.localSpacePrimitives.getFileMeta(name);
|
||||||
if (localMeta.neverSync) {
|
if (localMeta.noSync) {
|
||||||
console.info(
|
console.info(
|
||||||
"File marked as neverSync, skipping sync in this cycle",
|
"File marked as no sync, skipping sync in this cycle",
|
||||||
name,
|
name,
|
||||||
);
|
);
|
||||||
await this.registerSyncStop();
|
await this.registerSyncStop();
|
||||||
|
Loading…
Reference in New Issue
Block a user