-
Notifications
You must be signed in to change notification settings - Fork 4
Obsidian: Hello World #83
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # OBSIDIAN_PLUGIN_PATH="path/to/your/obsidian/plugins/folder" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Discourse Graphs | ||
|
|
||
| The Discourse Graph extension enables Roam users to seamlessly add additional semantic structure to their notes, including specified page types and link types that model scientific discourse, to enable more complex and structured knowledge synthesis work, such as a complex interdisciplinary literature review, and enhanced collaboration with others on this work. | ||
|
|
||
| For more information about Discourse Graphs, check out our website at [https://discoursegraphs.com](https://discoursegraphs.com) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "id": "@discourse-graph/obsidian", | ||
| "name": "Discourse Graph", | ||
| "version": "0.1.0", | ||
| "minAppVersion": "1.7.0", | ||
| "description": "Discourse Graph Plugin for Obsidian", | ||
| "author": "Discourse Graphs", | ||
| "authorUrl": "https://discoursegraphs.com", | ||
| "isDesktopOnly": false | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "name": "@discourse-graphs/obsidian", | ||
| "version": "0.1.0", | ||
| "description": "Discourse Graph Plugin for obsidian.md", | ||
| "main": "dist/main.js", | ||
| "private": true, | ||
| "scripts": { | ||
| "dev": "tsx scripts/dev.ts", | ||
| "build": "tsx scripts/build.ts" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "MIT", | ||
| "devDependencies": { | ||
| "@types/node": "^16.11.6", | ||
| "@typescript-eslint/eslint-plugin": "5.29.0", | ||
| "@typescript-eslint/parser": "5.29.0", | ||
| "builtin-modules": "3.3.0", | ||
| "esbuild": "0.17.3", | ||
| "obsidian": "^1.7.2", | ||
| "tslib": "2.4.0", | ||
| "tsx": "^4.19.2", | ||
| "typescript": "4.7.4" | ||
| }, | ||
| "dependencies": { | ||
| "react": "^19.0.0", | ||
| "react-dom": "^19.0.0" | ||
mdroidian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { compile } from "./compile"; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will generalize all of the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| const build = async () => { | ||
| process.env = { | ||
| ...process.env, | ||
| NODE_ENV: process.env.NODE_ENV || "production", | ||
| }; | ||
|
|
||
| console.log("Compiling ..."); | ||
| try { | ||
| await compile({}); | ||
| console.log("Compiling complete"); | ||
| } catch (error) { | ||
| console.error("Build failed on compile:", error); | ||
| process.exit(1); | ||
| } | ||
| }; | ||
|
|
||
| const main = async () => { | ||
| try { | ||
| await build(); | ||
| } catch (error) { | ||
| console.error(error); | ||
| process.exit(1); | ||
| } | ||
| }; | ||
| if (require.main === module) main(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| import esbuild from "esbuild"; | ||
| import fs from "fs"; | ||
| import path from "path"; | ||
| import { z } from "zod"; | ||
| import builtins from "builtin-modules"; | ||
| import dotenv from "dotenv"; | ||
|
|
||
| dotenv.config(); | ||
|
|
||
| const DEFAULT_FILES_INCLUDED = ["manifest.json"]; | ||
| const isProd = process.env.NODE_ENV === "production"; | ||
|
|
||
| const cliArgs = z.object({ | ||
| out: z.string().optional(), | ||
| root: z.string().optional(), | ||
| format: z.enum(["esm", "cjs"]).optional(), | ||
| external: z.array(z.string()), | ||
| mirror: z.string().optional(), | ||
| }); | ||
|
|
||
| type Builder = (opts: esbuild.BuildOptions) => Promise<void>; | ||
| export type CliOpts = Record<string, string | string[] | boolean>; | ||
|
|
||
| export const args = { | ||
| out: "main", | ||
| format: "cjs", | ||
| root: ".", | ||
| mirror: process.env.OBSIDIAN_PLUGIN_PATH, | ||
| external: [ | ||
| "obsidian", | ||
| "electron", | ||
| "@codemirror/autocomplete", | ||
| "@codemirror/collab", | ||
| "@codemirror/commands", | ||
| "@codemirror/language", | ||
| "@codemirror/lint", | ||
| "@codemirror/search", | ||
| "@codemirror/state", | ||
| "@codemirror/view", | ||
| "@lezer/common", | ||
| "@lezer/highlight", | ||
| "@lezer/lr", | ||
| ...builtins, | ||
| ], | ||
| } as CliOpts; | ||
|
|
||
| const readDir = (directoryPath: string): string[] => { | ||
| try { | ||
| if (!fs.existsSync(directoryPath)) { | ||
| console.error(`Directory does not exist: ${directoryPath}`); | ||
| return []; | ||
| } | ||
|
|
||
| return fs | ||
| .readdirSync(directoryPath, { withFileTypes: true }) | ||
| .flatMap((f) => { | ||
| const fullPath = `${directoryPath}/${f.name}`; | ||
| return f.isDirectory() ? readDir(fullPath) : [fullPath]; | ||
| }); | ||
| } catch (error) { | ||
| console.error(`Error reading directory ${directoryPath}:`, error); | ||
| return []; | ||
| } | ||
| }; | ||
|
|
||
| const appPath = (p: string): string => | ||
| path.resolve(fs.realpathSync(process.cwd()), p); | ||
|
|
||
| export const compile = ({ | ||
| opts = args, | ||
| builder = async (opts) => { | ||
| await esbuild.build(opts); | ||
| }, | ||
| }: { | ||
| opts?: CliOpts; | ||
| builder?: Builder; | ||
| }) => { | ||
| const { root = ".", out, format, external, mirror } = cliArgs.parse(opts); | ||
|
|
||
| const srcRoot = path.join(root, "src"); | ||
| const entryTs = "index.ts"; | ||
| const outdir = path.resolve(process.cwd(), root, "dist"); | ||
| const stylesDir = path.join(root, "src", "styles"); | ||
| const outputStylesFile = path.join(outdir, "styles.css"); | ||
|
|
||
|
Comment on lines
+83
to
+85
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Gracefully handle missing styles directory. |
||
| fs.mkdirSync(outdir, { recursive: true }); | ||
|
|
||
| const buildPromises = [] as Promise<void>[]; | ||
| buildPromises.push( | ||
| builder({ | ||
| absWorkingDir: process.cwd(), | ||
| entryPoints: [path.join(srcRoot, entryTs)], | ||
| outdir, | ||
| bundle: true, | ||
| format, | ||
| sourcemap: isProd ? undefined : "inline", | ||
| minify: isProd, | ||
| entryNames: out, | ||
| external: external, | ||
| plugins: [ | ||
| { | ||
| name: "log", | ||
| setup: (build) => { | ||
| build.onEnd((result) => { | ||
| console.log(`built with ${result.errors.length} errors`); | ||
| }); | ||
| }, | ||
| }, | ||
| { | ||
| name: "combineStyles", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is temp. need to include |
||
| setup(build) { | ||
| build.onEnd(async () => { | ||
| const styleFiles = fs | ||
| .readdirSync(stylesDir) | ||
| .filter((file) => file.endsWith(".css")); | ||
| const combinedStyles = styleFiles | ||
| .map((file) => | ||
| fs.readFileSync(path.join(stylesDir, file), "utf8"), | ||
| ) | ||
| .join("\n"); | ||
| fs.writeFileSync(outputStylesFile, combinedStyles); | ||
| }); | ||
| }, | ||
| }, | ||
| { | ||
| name: "copyDefaultFiles", | ||
| setup(build) { | ||
| build.onEnd(async () => { | ||
| DEFAULT_FILES_INCLUDED.map((f) => path.join(root, f)) | ||
| .filter((f) => fs.existsSync(f)) | ||
| .forEach((f) => { | ||
| fs.cpSync(f, path.join(outdir, path.basename(f))); | ||
| }); | ||
| }); | ||
| }, | ||
| }, | ||
| { | ||
| name: "mirrorFiles", | ||
| setup(build) { | ||
| build.onEnd(async () => { | ||
| if (!mirror) return; | ||
|
|
||
| const normalizedMirrorPath = path.normalize(mirror); | ||
| const resolvedMirrorPath = path.resolve( | ||
| root, | ||
| normalizedMirrorPath, | ||
| ); | ||
|
|
||
| if (!fs.existsSync(resolvedMirrorPath)) { | ||
| fs.mkdirSync(resolvedMirrorPath, { recursive: true }); | ||
| } | ||
|
|
||
| readDir(outdir) | ||
| .filter((file) => fs.existsSync(appPath(file))) | ||
| .forEach((file) => { | ||
| const destinationPath = path.join( | ||
| resolvedMirrorPath, | ||
| path.relative(outdir, file), | ||
| ); | ||
| fs.cpSync(appPath(file), destinationPath); | ||
| }); | ||
| }); | ||
| }, | ||
| }, | ||
| ], | ||
| }), | ||
| ); | ||
|
|
||
| return Promise.all(buildPromises); | ||
| }; | ||
|
|
||
| const main = async () => { | ||
| try { | ||
| await compile({}); | ||
| } catch (error) { | ||
| console.error(error); | ||
| process.exit(1); | ||
| } | ||
| }; | ||
| if (require.main === module) main(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import esbuild from "esbuild"; | ||
| import dotenv from "dotenv"; | ||
| import { compile, args } from "./compile"; | ||
|
|
||
| dotenv.config(); | ||
|
|
||
| const dev = () => { | ||
| process.env.NODE_ENV = process.env.NODE_ENV || "development"; | ||
| return new Promise<number>((resolve) => { | ||
| compile({ | ||
| opts: args, | ||
| builder: (opts: esbuild.BuildOptions) => | ||
| esbuild.context(opts).then((esb) => { | ||
| esb.watch(); | ||
| // Cleanup on process termination | ||
| const cleanup = () => { | ||
| esb.dispose(); | ||
| resolve(0); | ||
| }; | ||
| process.on('SIGINT', cleanup); | ||
| process.on('SIGTERM', cleanup); | ||
| return esb; | ||
| }), | ||
| }); | ||
| process.on("exit", resolve); | ||
| }); | ||
| }; | ||
|
|
||
| const main = async () => { | ||
| try { | ||
| await dev(); | ||
| } catch (error) { | ||
| console.error(error); | ||
| process.exit(1); | ||
| } | ||
| }; | ||
| if (require.main === module) main(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't just use
obsidianbecause the npm obsidian package is in our dependencies sad face. will probably namespace all of the plugins this way