Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions docs/binance-chart-storage-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,41 @@ behavior. Landing-to-trading SPA navigation does not re-run the storage installe
only a fresh matching page starts early interception. It never places orders, changes leverage, reads credentials, changes
the proxy, clears databases or replaces global storage methods.

Only the pinned TradingView module `70940` mirror destination expression changes.
The complete original factory must match before first execution. Late injection,
source drift and a missing capture after a 30-second timer retire interception
and leave native registration intact. Metadata does not guarantee early injection
on every extension configuration; rejection remains a supported outcome.
Two complete pinned factories are intercepted before their first execution:
`70940` changes only the mirror destination expression, while `76535` restricts
the native save extractor's input to each chart's current MainSeries symbols.
One queue observer owns both targets. Capture, source rejection and deadline
outcomes are independent; one changed upstream module does not cancel a matching
other module. Late injection leaves both native. Metadata does not guarantee
early injection on every extension configuration; rejection remains explicit.

### Drawing ownership

Native loading puts historical symbols' drawings into every chart that shares
their ownerSource. A different symbol's tab can therefore retain an old invisible
copy of drawings that another page has edited or deleted. The native extractor
previously wrote all those groups back on every save, restoring deleted drawings.

Before native drawing-ID deduplication, the scoped snapshot retains only drawings
belonging to the current MainSeries symbols of their own chart. All indicator
panes inherit that chart's symbol set. Other sources and drawing properties stay
unchanged. Native extraction still produces an explicit empty array for a current
symbol with no drawings, while unrelated symbols are not written. A whole chart
containing drawings without any MainSeries is rejected before storage writes;
an indicator pane without its own MainSeries is valid. The patch does not delete
historical keys, replace save events or serialize charts through a new API.

All concurrently open trading tabs need the new version; an old tab can still
write its stale hidden copies. Same-symbol concurrent editors and source-only
cross-database interruptions remain separate conflicts, not solved by ownership
filtering. No trading action is needed to validate the fix.

Each accepted mirror uses one IndexedDB read/write transaction and compares the
destination values before writing. Equal JSON trees must retain signed zero,
property order and dense array structure. Missing keys remain distinct from stored
null. Ordinary saves, source reads, Basic chart settings and `clear()` retain
their native implementations. No record cache persists between batches.
null. Ordinary saves retain their native write sequence after drawing ownership
filtering; source reads, Basic chart settings and `clear()` remain native. No
record cache persists between batches.

Input admission defaults to 512 entries, 4 MiB per batch and 16 pending batches
with 64 MiB of copied input. Unsupported values, capacity limits, initialization
Expand All @@ -46,11 +70,14 @@ through its Promise boundary. Subsequent calls resume native handling.
## Lifecycle and diagnostics

`self.__BINANCE_CHART_STORAGE__.snapshot()` returns fixed aggregate counters and
startup status. `stop()` drains the current instance's accepted work, including
startup status and an independent `drawingScope` status. `stop()` drains the current instance's accepted mirror work, including
every member of an early-rejecting native Promise array. Calls arriving during
drain wait for that finite fence, then run their native expression. After stop,
native arrays and errors pass through synchronously and statistics freeze.
The public interface exposes no stored keys, values or storage methods.
Stopping mirror optimization does not remove drawing ownership protection. If
that factory has not been captured, its original bounded startup observation
continues; pagehide terminates outstanding observations for both targets.

`acceptedBatches` counts created optimized transactions. `committedTransactions`
counts real completion events, while `committedWrites` and `skippedWrites` count
Expand Down Expand Up @@ -79,6 +106,7 @@ to accept an unknown module. The generation command accepts an explicit output:

```sh
node experiments/binance-chart-storage/generate-mirror-module.js /path/to/verified/TradingView.99bc5074.js src/binance-orderbook-trade/chart-storage/mirror-module.js
node scripts/generate-chart-drawing-save-module.mjs /path/to/verified/36648.dd8ae7dc.js
```

## Validation and release
Expand Down
46 changes: 46 additions & 0 deletions docs/binance-futures-blank-page-diagnosis.md
Original file line number Diff line number Diff line change
Expand Up @@ -930,3 +930,49 @@ After stop, another interval change committed four native transactions and four
writes while optimizer statistics stayed frozen. Chart data readiness was true
throughout all three stages. The browser was closed. Evidence is retained in
`/var/folders/99/d7dxx5j94_x8n09snmknq0x80000gn/T/binance-chart-storage-smoke-30Xntg/`.

### Deleted drawings restored by other symbols: 2026-10-07 (Beijing)

After v2.7.218, the user reported that removing all 20 MUBARAKUSDT drawings and
waiting one, five or more than ten minutes still restored them after reload.
Other trading tabs were open, each on a different symbol. Read-only inspection
found 20 matching MUBARAK records in both chart databases. The MUBARAK serializer
contained 893 drawings across 99 symbols; the GRIFFAIN serializer retained the
same 20 MUBARAK drawing IDs as hidden sources, with shared ownerSource `ZmamTt`.
The current page's two stored symbol keys and drawing symbols were uppercase,
ruling out the separately reproduced mixed-case-key candidate for this incident.
No user drawing was deleted and no user page was refreshed during diagnosis.
The aggregate evidence is `/tmp/binance-drawing-ownership-VuHzpW/incident.json`.

Native `zt` loads all historical symbol groups by ownerSource. Native `kt` then
extracts all LineTool sources, including other symbols' invisible copies, and
`xt` writes every group. Consequently, a different-symbol tab can overwrite an
already committed deletion during its next save. Exact host callbacks and real
IndexedDB reproduced 20 -> 0 -> 20 with both native and v2.7.218 writers. No
interrupted save, duplicate-symbol tab or mirror-transaction failure was needed.

Version 2.7.219 scopes the input of the native `kt` extractor to each chart's
current MainSeries symbols, before global drawing-ID deduplication. Indicator
panes inherit their own chart's symbols. The original extractor still writes an
empty active-symbol array after deletion and preserves other symbols' database
records. The complete pinned 76535 factory differs only at that input expression;
its event handlers, source persistence sequence and load path remain native.
Drawing protection has its own capture status and remains active after mirror
optimization stops. Existing old-version tabs retain their old write behavior
until they load the new version.

The repaired real-IDB scenario stays at 20 -> 0 -> 0. Eleven deletion scenarios
also cover multi-chart ownership before deduplication, indicator-pane drawings,
current empty arrays, preservation of a newer unrelated-symbol record and invalid
whole-chart ownership rejection before writes. A separate source-only cross-db
interruption still permits native stale overwrite and is explicitly not this
incident's root cause. All 2,167 Node/DOM and 143 chart-storage browser tests, test
lint, build, syntax checks and independent source review passed.

The complete v2.7.219 artifact passed anonymous Chrome verification with zero
page errors, ready charts, five optimized transactions and four native commits
after stop. Drawing protection remained active throughout. Screenshots were
inspected and the anonymous browser was closed. This smoke did not create/delete
drawings; deletion and reload integrity were exercised by the exact host/IDB
scenarios. Its report is in
`/var/folders/99/d7dxx5j94_x8n09snmknq0x80000gn/T/binance-chart-storage-smoke-R0V9Km/`.
6 changes: 4 additions & 2 deletions docs/binance-orderbook-trade-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ scripts/binance-orderbook-trade.user.js
### Chart mirror storage

`chart-storage/install.js` runs before the orderbook business initializer. This
module batches the pinned TradingView mirror destination writes and skips
unchanged records. It is included in the existing orderbook installer, with no
module restricts native drawing saves to each chart's current symbols, batches
the pinned TradingView mirror destination writes and skips unchanged records.
This prevents different-symbol tabs from writing back stale hidden drawings.
It is included in the existing orderbook installer, with no
separate script. Its top-frame guard applies only to storage interception;
source drift or late injection must leave the orderbook panel functional.
See [the storage contract](binance-chart-storage-development.md) for native
Expand Down
Loading
Loading