Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#45 , Implement hot-reloading #90

Merged
merged 2 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 70 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"types": "./dist/src/index.d.ts",
"dependencies": {
"@portaljs/remark-wiki-link": "^1.0.4",
"chokidar": "^3.5.3",
"gray-matter": "^4.0.3",
"knex": "^2.4.2",
"react-markdown": "^9.0.1",
Expand Down
9 changes: 7 additions & 2 deletions src/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { MarkdownDB } from "../lib/markdowndb.js";
// TODO get these from markdowndb.config.js or something
const dbPath = "markdown.db";
const ignorePatterns = [/Excalidraw/, /\.obsidian/, /DS_Store/];
const [contentPath] = process.argv.slice(2);
const [contentPath, watchFlag] = process.argv.slice(2);

if (!contentPath) {
throw new Error("Invalid/Missing path to markdown content folder");
}

const watchEnabled = watchFlag && watchFlag === "--watch";

const client = new MarkdownDB({
client: "sqlite3",
connection: {
Expand All @@ -23,6 +25,9 @@ await client.init();
await client.indexFolder({
folderPath: contentPath,
ignorePatterns: ignorePatterns,
watch: watchEnabled,
});

process.exit();
if (!watchEnabled) {
process.exit();
}
2 changes: 1 addition & 1 deletion src/lib/indexFolder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
const result = schemas[documentType].safeParse(flattenedFileObject);

if (!result.success) {
const error: ZodError = (result as any).error;

Check warning on line 41 in src/lib/indexFolder.ts

View workflow job for this annotation

GitHub Actions / Lint & format check

Unexpected any. Specify a different type

error.errors.forEach((err) => {
const errorMessage = `Error: In ${
Expand All @@ -56,7 +56,7 @@
return files;
}

function shouldIncludeFile(
export function shouldIncludeFile(
filePath: string,
ignorePatterns?: RegExp[]
): boolean {
Expand Down
67 changes: 66 additions & 1 deletion src/lib/markdowndb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import knex, { Knex } from "knex";

import { MddbFile, MddbTag, MddbLink, MddbFileTag } from "./schema.js";
import { indexFolder } from "./indexFolder.js";
import { indexFolder, shouldIncludeFile } from "./indexFolder.js";
import {
resetDatabaseTables,
mapFileToInsert,
Expand All @@ -13,6 +13,9 @@
} from "./databaseUtils.js";
import fs from "fs";
import { CustomConfig } from "./CustomConfig.js";
import { FileInfo, processFile } from "./process.js";
import chokidar from "chokidar";
import { recursiveWalkDir } from "./recursiveWalkDir.js";

const defaultFilePathToUrl = (filePath: string) => {
let url = filePath
Expand All @@ -23,7 +26,7 @@
return encodeURI(url);
};

const resolveLinkToUrlPath = (link: string, sourceFilePath?: string) => {

Check warning on line 29 in src/lib/markdowndb.ts

View workflow job for this annotation

GitHub Actions / Lint & format check

'resolveLinkToUrlPath' is assigned a value but never used
if (!sourceFilePath) {
return link;
}
Expand Down Expand Up @@ -74,11 +77,13 @@
ignorePatterns = [],
pathToUrlResolver = defaultFilePathToUrl,
customConfig = {},
watch = false,
}: {
folderPath: string;
ignorePatterns?: RegExp[];
pathToUrlResolver?: (filePath: string) => string;
customConfig?: CustomConfig;
watch?: boolean;
}) {
await resetDatabaseTables(this.db);

Expand All @@ -88,6 +93,66 @@
customConfig,
ignorePatterns
);
await this.saveDataToDisk(fileObjects);

if (watch) {
const watcher = chokidar.watch(folderPath, {
ignoreInitial: true,
});

const filePathsToIndex = recursiveWalkDir(folderPath);
const computedFields = customConfig.computedFields || [];

const handleFileEvent = (event: string, filePath: string) => {
if (!shouldIncludeFile(filePath, ignorePatterns)) {
return;
}

if (event === "unlink") {
const index = fileObjects.findIndex(
(obj) => obj.file_path === filePath
);
if (index !== -1) {
fileObjects.splice(index, 1);
}
console.log(`File ${filePath} has been removed`);
return;
}

const fileObject = processFile(
folderPath,
filePath,
pathToUrlResolver,
filePathsToIndex,
computedFields
);
const index = fileObjects.findIndex(
(obj) => obj.file_path === filePath
);

if (index !== -1) {
fileObjects[index] = fileObject;
} else {
fileObjects.push(fileObject);
}

console.log(
`File ${filePath} has been ${event === "add" ? "added" : "updated"}`
);
};

watcher
.on("add", (filePath) => handleFileEvent("add", filePath))
.on("change", (filePath) => handleFileEvent("change", filePath))
.on("unlink", (filePath) => handleFileEvent("unlink", filePath))
.on("all", () => this.saveDataToDisk(fileObjects))
.on("error", (error) => console.error(`Watcher error: ${error}`));
}
}

private async saveDataToDisk(fileObjects: FileInfo[]) {
await resetDatabaseTables(this.db);

const filesToInsert = fileObjects.map(mapFileToInsert);
const uniqueTags = getUniqueValues(
fileObjects.flatMap((file) => file.tags)
Expand Down Expand Up @@ -252,7 +317,7 @@
}
}

function writeJsonToFile(filePath: string, jsonData: any[]) {

Check warning on line 320 in src/lib/markdowndb.ts

View workflow job for this annotation

GitHub Actions / Lint & format check

Unexpected any. Specify a different type
try {
const directory = path.dirname(filePath);
if (!fs.existsSync(directory)) {
Expand Down
Loading