fix(components): delete each boot-clear database name once per page load - #19
Open
pythonlearner1025 wants to merge 1 commit into
Open
fix(components): delete each boot-clear database name once per page load#19pythonlearner1025 wants to merge 1 commit into
pythonlearner1025 wants to merge 1 commit into
Conversation
`maybeClearLodyCacheOnBoot` memoized the clear MODE rather than the fact that the clear had run. `runPendingClearOnBoot` removes the localStorage flag on its first run, so every later caller in the same page load still awaited a truthy mode and deleted whatever `extraNames` it was handed. `RuntimeProvider` passes the current workspace's two IndexedDB names on every runtime build (runtime-provider.tsx:241). So after one Settings -> Clear cache, each subsequent runtime rebuild in that tab deleted that workspace's Loro repo again -- including one the runtime had already re-created and re-synced. Track the caller-supplied names deleted during this page load and skip the ones already handled. A name first contributed later during boot -- the documented purpose of `extraNames` -- is still deleted once. Model: claude-opus-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issue
Same-repository branch; no intake Issue per
.github/AGENTS.md("Same-repository branches do not create or require an Issue solely for intake").Problem / pressure
maybeClearLodyCacheOnBootmemoizes the clear mode, not the fact that the clear already ran:runPendingClearOnBootremoves the localStorage flag in itsfinallyon the first run (clear-local-cache.ts:400-406) and then returns the mode, which the module-level promise atclear-local-cache.ts:388holds for the rest of the page load. Somodestays truthy forever, the guard at:424never closes, and every later caller deletes whateverextraNamesit was handed — even though the pending clear is long finished.RuntimeProvideris such a caller, and it passes the current workspace's two IndexedDB names on every runtime build:That call sits inside the init effect whose deps include
workspaceSlugandeffectiveWorkspaceId(runtime-provider.tsx:355-369), so it re-runs on an ordinary workspace switch — or a switch away and back. The result: after one Settings → Clear cache, each subsequent runtime build in that tab deletes that workspace's Loro repo database again, including one the runtime has since re-created and fully re-synced. IndexedDBdeleteDatabasedoes not care that the database is new; it destroys the live replica, and the user sees the workspace empty itself again for no reason they can connect to any action.The intent of
extraNamesis documented atclear-local-cache.ts:416-418: a caller arriving later in the same boot (RuntimeProvider, afterAppInitializer.tsx:59-61has already started the clear) can still contribute its databases. So the memo genuinely cannot be a plain "already ran" flag — the actual invariant is per name, not per call.Summary
Track the caller-supplied database names already deleted during this page load in a module-level
Set<string>, and delete only the unclaimed ones. Names are claimed synchronously betweenawait bootClearPromiseresuming and the first delete starting, so two concurrent callers cannot both claim the same name.resetBootClearMemoForTestsclears the set alongside the promise.Two tests added next to the existing suite in
packages/components/tests/clear-local-cache.test.ts, using that file's existing hand-rolledindexedDBfake (no new dependency).Before / after
lody-loro-repo-db-*andlody-loro-stream-cursors-*.Test plan
Ran from
packages/componentsagainst a standalone clone (Node 22.20.0, pnpm 10.20.0):vitest run tests/clear-local-cache.test.ts— 9 → 11 tests. The newdeletes a caller-supplied database once per page load, not on every later callfails onmainwithexpected [ Array(2) ] to have a length of 1 but got 2(the second delete, empirically), and passes with the fix. All 11 pass after.vitest run(full@lody/componentssuite) — attempted, did not complete. The sandbox this was prepared in has 4 cores and was under a load average above 30 from an unrelated concurrent job; the run was killed by a wall-clock timeout, and several unrelated suites had already tripped vitest's 5s per-test timeout under that contention. I am reporting this rather than quoting a pass I did not observe. Re-run pending on a quiet box; CI is the authority here.tsgo --noEmitinpackages/components— clean.oxlint --ignore-pattern packages/acp-extension-kimi(repolint:fast) — 0 errors. The one warning reported onclear-local-cache.tsis the pre-existingno-use-before-defineat:141, untouched by this change.prettier --checkon both changed files — clean.Not run: the full
pnpm check.pnpm installin this sandbox needed--ignore-scripts(no native postinstall builds), andpnpm test:cispans workspaces such asapps/cliwhose nativebetter-sqlite3binding is therefore absent.pnpm formatwas not run repo-wide;prettier --checkon the changed files stands in for it.pnpm lint(the--type-awarevariant) was not run — onlylint:fast.Context handoff
Instructions for reviewing agents
clear-local-cache.ts:422-440— whether a per-nameSetis the right invariant versus a per-call "already ran" flag, givenextraNames' documented late-contributor purpose at:416-418.indexedDBfake, not a real browser; I did not measure how oftenRuntimeProvider's init effect actually re-runs in production, only that its deps (workspaceSlug,effectiveWorkspaceId) change on a workspace switch.Authoring context
extraNames' intent.clear-local-cache.tsand its existing test file; do not add dependencies; do not change the settings/crash-screen entry points or the hard-reset path.fake-indexeddbto model database re-creation; the observable that matters is thatdeleteDatabaseis not issued a second time for the name, which the existing fake records directly. Did not touch therunPendingClearOnBootinternal sweep, whose names are not caller-supplied.main); lower confidence in the frequency of the user-visible symptom, which depends on how often a session rebuilds its runtime.