fix: add async-mutex to builds on large vaults
| | |
| | | "@clack/prompts": "^0.6.3", |
| | | "@floating-ui/dom": "^1.4.0", |
| | | "@napi-rs/simple-git": "^0.1.8", |
| | | "async-mutex": "^0.4.0", |
| | | "chalk": "^4.1.2", |
| | | "chokidar": "^3.5.3", |
| | | "cli-spinner": "^0.2.10", |
| | |
| | | "url": "https://github.com/sponsors/wooorm" |
| | | } |
| | | }, |
| | | "node_modules/async-mutex": { |
| | | "version": "0.4.0", |
| | | "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", |
| | | "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", |
| | | "dependencies": { |
| | | "tslib": "^2.4.0" |
| | | } |
| | | }, |
| | | "node_modules/asynckit": { |
| | | "version": "0.4.0", |
| | | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", |
| | |
| | | "url": "https://github.com/sponsors/wooorm" |
| | | } |
| | | }, |
| | | "node_modules/tslib": { |
| | | "version": "2.6.2", |
| | | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", |
| | | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" |
| | | }, |
| | | "node_modules/tsx": { |
| | | "version": "3.12.7", |
| | | "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz", |
| | |
| | | "@clack/prompts": "^0.6.3", |
| | | "@floating-ui/dom": "^1.4.0", |
| | | "@napi-rs/simple-git": "^0.1.8", |
| | | "async-mutex": "^0.4.0", |
| | | "chalk": "^4.1.2", |
| | | "chokidar": "^3.5.3", |
| | | "cli-spinner": "^0.2.10", |
| | |
| | | import serveHandler from "serve-handler" |
| | | import { WebSocketServer } from "ws" |
| | | import { randomUUID } from "crypto" |
| | | import { Mutex } from "async-mutex" |
| | | |
| | | const ORIGIN_NAME = "origin" |
| | | const UPSTREAM_NAME = "upstream" |
| | |
| | | ], |
| | | }) |
| | | |
| | | const buildMutex = new Mutex() |
| | | const timeoutIds = new Set() |
| | | const build = async (clientRefresh) => { |
| | | await buildMutex.acquire() |
| | | const result = await ctx.rebuild().catch((err) => { |
| | | console.error(`${chalk.red("Couldn't parse Quartz configuration:")} ${fp}`) |
| | | console.log(`Reason: ${chalk.grey(err)}`) |
| | |
| | | const { default: buildQuartz } = await import(cacheFile + `?update=${randomUUID()}`) |
| | | await buildQuartz(argv, clientRefresh) |
| | | clientRefresh() |
| | | buildMutex.release() |
| | | } |
| | | |
| | | const rebuild = (clientRefresh) => { |
| | |
| | | import { glob, toPosixPath } from "./util/glob" |
| | | import { trace } from "./util/trace" |
| | | import { options } from "./util/sourcemap" |
| | | import { Mutex } from "async-mutex" |
| | | |
| | | async function buildQuartz(argv: Argv, clientRefresh: () => void) { |
| | | const ctx: BuildCtx = { |
| | |
| | | } |
| | | |
| | | const initialSlugs = ctx.allSlugs |
| | | let timeoutIds: Set<ReturnType<typeof setTimeout>> = new Set() |
| | | let toRebuild: Set<FilePath> = new Set() |
| | | let toRemove: Set<FilePath> = new Set() |
| | | let trackedAssets: Set<FilePath> = new Set() |
| | | const buildMutex = new Mutex() |
| | | const timeoutIds: Set<ReturnType<typeof setTimeout>> = new Set() |
| | | const toRebuild: Set<FilePath> = new Set() |
| | | const toRemove: Set<FilePath> = new Set() |
| | | const trackedAssets: Set<FilePath> = new Set() |
| | | async function rebuild(fp: string, action: "add" | "change" | "delete") { |
| | | // don't do anything for gitignored files |
| | | if (ignored(fp)) { |
| | |
| | | // debounce rebuilds every 250ms |
| | | timeoutIds.add( |
| | | setTimeout(async () => { |
| | | await buildMutex.acquire() |
| | | const perf = new PerfTimer() |
| | | console.log(chalk.yellow("Detected change, rebuilding...")) |
| | | try { |
| | |
| | | clientRefresh() |
| | | toRebuild.clear() |
| | | toRemove.clear() |
| | | buildMutex.release() |
| | | }, 250), |
| | | ) |
| | | } |
| | |
| | | const opts = { ...defaultOptions, ...userOpts } |
| | | function RecentNotes(props: QuartzComponentProps) { |
| | | const { allFiles, fileData, displayClass } = props |
| | | const pages = allFiles.filter(opts.filter).sort(opts.sort).slice(0, opts.limit) |
| | | const pages = allFiles.filter(opts.filter).sort(opts.sort) |
| | | const remaining = Math.max(0, pages.length - opts.limit) |
| | | return ( |
| | | <div class={`recent-notes ${displayClass}`}> |
| | | <h3>{opts.title}</h3> |
| | | <ul class="recent-ul"> |
| | | {pages.map((page) => { |
| | | {pages.slice(0, opts.limit).map((page) => { |
| | | const title = page.frontmatter?.title |
| | | const tags = page.frontmatter?.tags ?? [] |
| | | |