Repository navigation
Replies: 1 comment
|
I read this against 22ddee3. The gap is one branch wide: Fix, in if (selected === null) {
this.listingRead++
this.patch({ listing: null })
}It has to sit in the same synchronous block as the clearing — anything after an Your spec sketch matches the existing helpers: |
Uh oh!
There was an error while loading. Please reload this page.
Removing the last market source clears Discover, but a refresh response that was already in flight can repopulate its listing afterwards. The configured sources remain empty and
selectedremainsnull; onlylistingcomes back.Versions and validation scope
dsh-v0.2.1-rc.3: commit1f81c047fc48fa190a683e469daa699857e9afe8.masterchecked on 2026-10-26:22ddee3792402c3e70ec5f86a63c3e3e895a2f60.v26.10.0(its engine is>=24.9.0); release tag tested with Node.jsv22.22.2(within its supported engine range). Both usetsx@4.22.4and published@deepseek-ai/dsh-client-store@0.2.1-rc.3.DiscoverControllersource from both commits with controlled remote Promises, and separately reproduced the release behavior with the actual publishedPluginMarketHost and a delayed loopback HTTP index. No complete desktop GUI or live-network incidence was measured.Reproduction
pluginMarket.search()response pending.setIndexes([])and the followinglistIndexes()complete.indexes: [],selected: null,listing: null.Expected: the response belongs to a removed source and is ignored; Discover stays in its empty/add-first-source state.
Actual:
listing.urlbecomes A again. A successful response producesstatus: 'ready'; a failed response also restores the old listing withstatus: 'error'.Both the release-tag source and current-master source reproduced this in 10/10 controlled success cases and 10/10 controlled error cases. Those counts describe the deliberately controlled ordering, not normal-user incidence.
Example after the late success:
{ "indexes": [], "selected": null, "listing": { "url": "https://market.example/index.json", "status": "ready" } }Host-backed release reproduction
The published
@deepseek-ai/dsh-plugin-market@0.2.1-rc.3fetched a real local HTTP index. I held its second HTTP response, removed the source, and verified the actual Host'slistIndexes()returned[]. Releasing that HTTP response still restored the removed index's plugin in the release-source client. A subsequent real Host search returnedplugin-market/unknown-index, while the client retained the old listing; reloading the source list cleared it.This integration used real Host fetch/parse-worker/search/
setIndexescode. Settings was a test service that applied the validated source change viaupdateVolatile; installed-bundle inventory was an empty fixture, and RemoteResult calls were adapted directly. It did not exercise disk persistence, WebSocket transport, Chromium, or the full GUI.The existing
packages/client/ui-plugin-market/tests/market-store.client.spec.tshelpers can demonstrate the missing case:The standalone harness executes this ordering against both checked sources and also exercises an
ok: falseresult. I have not run the repository-wide test suite. Two passing controls isolate the edge case: deleting a source without a pending refresh stays empty, and deleting A while B remains configured correctly ignores A's late response.Cause and impact
In the release source,
loadIndexes()clearslistingwhenselected === null, but it does not invalidate the outstanding listing read. The asynchronousload()only checkslistingRead, so it can still callsettle()afterwards. The same paths remain on current master, at lines 309 and 333 respectively.The source-management menu remains available while a listing loads, and its Remove button is disabled only while a source save is running, so the refresh → manage sources → remove sequence is reachable through the declared UI controls. The visible effect follows from
DiscoverSectionchoosing the empty state bylisting === nulland otherwise renderingBrowser; it does not hide that restored listing becauseselectedandindexesare empty. I checked that rendering branch in both source versions, but did not run a full GUI rendering test. This report does not claim the source was re-added to settings or that a plugin was installed automatically.Incrementing the listing-read generation when clearing the last selection prevented the restoration in a scratch-copy control (20/20 controlled cases). That appears to be the missing invalidation; no repository patch or PR is included.
Recovery and limits
In the controlled client test, calling
ensure()again on the same controller leaves the restored listing unchanged. Another refresh reportsplugin-market/unknown-indexand retains the old listing. Re-reading the source list (reload()) or constructing a new controller restores the empty state. These are API-level checks; I did not test clicking a stale plugin's Install button or claim that deleting a source can be bypassed.Duplicate and fix checks
On 2026-10-26 I fully paginated 19 related public Discussion searches (1,261 unique discussions, 3,233 comments, 721 replies), including open and closed results. I found no report of this same last-source/late-response case. Nearby reports #10869, #10786, and #10538 concern update actions, third-party market lifecycle, or hung plugin operations instead. Public all-state Issue/PR searches returned no visible entries; internal or inaccessible PRs could not be checked. The fixed master source and its path history still retain the clearing branch above.
AI assistance
This report was prepared with an AI assistant. The stated results are actual isolated script runs; the full desktop UI was not driven or captured. No real user profile or repository source was modified.
All reactions