Repository navigation
Clear plugin visuals the moment the market switches - #293
Merged
Merged
Conversation
A symbol or timeframe switch empties the bar series while the new market loads. Two kinds of plugin data survived into that gap and, with no bars on the axis, every time-keyed entry mapped to the same slot - the old market's cells stacked in one column at the right edge until the new bars landed: - a chart-type data engine suspended mid-fetch pushed its cache back when the fetch resolved, and a stopped engine could push the old market's cells onto the new one after the reload; - native indicators kept running and kept their layer payloads until the post-load restart. The host handed to a chart-type engine now forwards pushes only from the chart's current, unsuspended engine. Each native indicator start gets its own context, revoked once the instance is stopped (its own teardown inside stop() still lands). An identity switch stops running natives and blanks their channels in the same breath as the series clear; the post-load restart rebuilds them as before. Co-authored-by: Cursor <cursoragent@cursor.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 751c2ead-e5ad-492e-999e-f09bc9a57181) |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Background
Switching the symbol or timeframe on a chart with plugin-drawn data (a chart type with a data engine, or a native indicator that paints its own renderer layer) could stack the old market's visuals in a single column at the right edge until the new bars arrived. While the new market loads, the bar series is empty, and an empty axis maps every timestamp to the same logical slot.
Two paths put old data there during that gap:
Summary
pushData/pushPendingonly from the chart's current, unsuspended engine. A suspended engine's re-push onresume()still lands.stop()(a layer-backed native clearing its channel) still land; anything after is dropped. This covers removal, destroy and every restart.SeriesDataEngineandNativeIndicatorcontract comments say what the chart now enforces. No public API change.End-to-end verification
Exercised in Chromium (Playwright) with the built package linked into a downstream extension's playground, which registers a chart type with a data engine and two layer-backed native indicators, on live data. Candle responses were delayed to widen the loading gap, and engine responses were delayed to keep a fetch in flight across the switch. Each frame was probed for the layer payloads in the scene and the painted extent of every layer canvas.
Checklist
npm run typecheck,npm run lint,npm test, andnpm run buildall passdocs/has been added / updated (for public interface or feature changes)CHANGELOG.mdhas an entry under[Unreleased](for user-visible changes)Future work
docs/contributing/plugin-sdk.mddescribes the engine lifecycle accurately but does not mention that late pushes are dropped; one sentence there would document the guarantee for plugin authors.Note
Medium Risk
Changes market-switch and plugin lifecycle in the orchestrator; incorrect gating could hide legitimate plugin updates, but behavior is covered by new tests and matches documented SDK contracts.
Overview
Plugin-drawn layers no longer linger or get corrupted when you change symbol or timeframe. While the new market loads with an empty bar axis, time-keyed plugin payloads used to stack in one column at the right edge; fetches that finished after suspend or after a rebuild could still paint the old market.
On an identity switch the orchestrator now stops running native indicators synchronously, blanks their renderer channels, and routes chart-type
pushData/pushPendingonly from the chart’s current, unsuspended engine (late work from suspended or replaced engines is dropped). Each native start gets a revocable context: teardown insidestop()can still clear a layer, but any lateremit/pushDatais ignored. Contract comments in the chart-type registry and native-indicator types describe this host behavior; no public API change. Tests cover late pushes after remove, style suspend, andsetMarket.Reviewed by Cursor Bugbot for commit 31a31b2. Bugbot is set up for automated code reviews on this repo. Configure here.