fix(typst): correct auto-compile default and debounce detection for Typst projects
Build and Deploy Verso / deploy (push) Successful in 11m37s
Build and Deploy Verso / deploy (push) Successful in 11m37s
The previous implementation used useState() to detect the project type, but the file tree is loaded asynchronously after the WebSocket joinProject event, so pathInFolder() always returns null on the initial render. Use useEffect() instead — it re-runs when getRootDocInfo's reference changes (i.e. when the file tree populates), correctly detecting .typ root docs. Also adds updateAutoCompileDebounce() to DocumentCompiler so the tight debounce can be applied at that point. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -260,4 +260,15 @@ export default class DocumentCompiler {
|
||||
) {
|
||||
this.defaultOptions[option] = value
|
||||
}
|
||||
|
||||
updateAutoCompileDebounce(debounceMs: number, maxWaitMs: number) {
|
||||
this.debouncedAutoCompile.cancel()
|
||||
this.debouncedAutoCompile = debounce(
|
||||
() => {
|
||||
this.compile({ isAutoCompileOnChange: true })
|
||||
},
|
||||
debounceMs,
|
||||
{ maxWait: maxWaitMs }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,11 +155,6 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
const { findEntityByPath } = useFileTreePathContext()
|
||||
const getRootDocInfo = useRootDoc()
|
||||
|
||||
// Captured once at mount; drives auto-compile defaults and debounce timing.
|
||||
const [isTypstProject] = useState(() =>
|
||||
getRootDocInfo().rootResourcePath.endsWith('.typ')
|
||||
)
|
||||
|
||||
// whether a compile is in progress
|
||||
const [compiling, setCompiling] = useState(false)
|
||||
|
||||
@@ -264,10 +259,10 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
|
||||
const [position, setPosition] = usePdfScrollPosition(lastCompileRootDocId)
|
||||
|
||||
// whether autocompile is switched on (Typst projects default to enabled)
|
||||
// whether autocompile is switched on
|
||||
const [autoCompile, setAutoCompile] = usePersistedState(
|
||||
`autocompile_enabled:${projectId}`,
|
||||
isTypstProject,
|
||||
false,
|
||||
{ listen: true }
|
||||
)
|
||||
|
||||
@@ -340,10 +335,6 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
signal,
|
||||
openDocs,
|
||||
getRootDocInfo,
|
||||
// Typst compiles are near-instant via `typst watch`; use a much tighter
|
||||
// debounce so the PDF refreshes as the user types.
|
||||
autoCompileDebounce: isTypstProject ? 300 : undefined,
|
||||
autoCompileMaxWait: isTypstProject ? 1000 : undefined,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -352,6 +343,22 @@ export const LocalCompileProvider: FC<React.PropsWithChildren> = ({
|
||||
compiler.getRootDocInfo = getRootDocInfo
|
||||
}, [compiler, getRootDocInfo])
|
||||
|
||||
// Typst projects compile near-instantly via `typst watch`.
|
||||
// getRootDocInfo() returns accurate paths only after the file tree loads
|
||||
// (project joins via WebSocket), so we do detection in an effect that re-runs
|
||||
// when its reference changes. window.localStorage is checked directly to
|
||||
// distinguish "no stored preference" from an explicit user choice.
|
||||
useEffect(() => {
|
||||
const { rootResourcePath } = getRootDocInfo()
|
||||
if (!rootResourcePath.endsWith('.typ')) return
|
||||
// Default auto-compile ON for Typst — only if user has never set a pref.
|
||||
if (window.localStorage.getItem(`autocompile_enabled:${projectId}`) === null) {
|
||||
setAutoCompile(true)
|
||||
}
|
||||
// Tighten the debounce so the PDF updates as the user types.
|
||||
compiler.updateAutoCompileDebounce(300, 1000)
|
||||
}, [compiler, getRootDocInfo, projectId, setAutoCompile])
|
||||
|
||||
// keep draft setting in sync with the compiler
|
||||
useEffect(() => {
|
||||
compiler.setOption('draft', draft)
|
||||
|
||||
Reference in New Issue
Block a user