Skip to content

best-practices: Visualizations (factory pattern + per-instance settings) - #5

Merged
topkoa merged 2 commits into
docs/client-runtime-sectionfrom
docs/best-practices-visualizations
Jul 6, 2026
Merged

best-practices: Visualizations (factory pattern + per-instance settings)#5
topkoa merged 2 commits into
docs/client-runtime-sectionfrom
docs/best-practices-visualizations

Conversation

@topkoa

@topkoa topkoa commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a Visualizations section to the best-practices guide for type: "visualization" plugins — the factory pattern for splitscreen compatibility, and the per-instance settings-communication pattern (including the concrete failure modes the recent fixes addressed). Traced against the Host's actual renderer contract and the June–July settings/splitscreen commits, not written from memory.

Why a factory (rule 15)

window.feedBackViz_<id> must be a factory function returning a fresh renderer per call. Splitscreen creates one highway per panel and calls the factory once per panel, so N panels get N independent renderers. A singleton would have every panel fight over one WebGL context / canvas / mesh set — the classic splitscreen bug. Includes the renderer interface (draw required; init/resize/destroy/contextType/readyPromise optional) and the Host lifecycle.

Settings communication (rule 19) — the recent-fixes part

Forward pattern: declare a settings array on the visualization capability and implement applySetting(key, value) on the renderer instance. The Host validates the descriptors, owns persistence, and calls applySetting on each specific per-panel instance — inherently per-panel, no shared global keys, no canvas→panel lookup to get wrong.

Documents the actual failure modes recent commits fixed:

  • Apply live, never location.reload() (it drops the user out of settings).
  • No cross-setting leakage — back-fill a migrated setting once on load, don't mirror on every read (a real "moving one dropdown retinted the other" bug).
  • Scope keys deliberately — only genuine per-panel controls get per-panel storage; shared assets/palette stay global so a stale per-panel override can't shadow a global edit.
  • Fan out to all panels; settings.html loads before the renderer (guard setter calls).

Plus: per-instance resource ownership + destroy() cleanup (16), read-only per-frame bundle / allocation-free draw() (17), self-detect canvas size drift (18), and fail-safe auto-revert (20). Checklist gains a Visualizations block; Shipping section renumbered to 21–25.

Scope & stacking

Docs only (spec/best-practices.md + CHANGELOG.md). No version bump. Framed the concrete API names (feedBackViz_<id>, applySetting) as the current Host contract, principles as stable.

Stacked on #3 (base docs/best-practices-performance) since it extends the same file — the section sits right after "Client screen & the shared main thread." Full stack is now #2#4#3#5. mkdocs build --strict and check_versions.py pass; headings contiguous 1–25.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22f784bc-c361-45a2-a1d7-bb0ff7f73e52

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/best-practices-visualizations

Comment @coderabbitai help to get the list of available commands.

topkoa and others added 2 commits July 6, 2026 00:25
Add a "Visualizations" section to the best-practices guide for
type: "visualization" plugins, ground-truthed against the Host's renderer
contract and the recent splitscreen/settings fixes.

- Factory pattern (rule 15): window.feedBackViz_<id> MUST be a factory function
  returning a fresh renderer per call — this is what makes splitscreen's N
  simultaneous panels work; a singleton shares one context/canvas/meshes across
  panels and collides. Includes the renderer interface (draw required;
  init/resize/destroy/contextType/readyPromise optional) and lifecycle.
- Per-instance resources + destroy() cleanup (16); read-only per-frame bundle,
  allocation-free draw() (17); self-detect canvas size drift (18).
- Settings communication (19): declare `settings` on the visualization
  capability and implement applySetting(key, value) on the instance — the Host
  applies each change to the specific per-panel instance (inherently per-panel).
  Documents the concrete failure modes recent fixes addressed: apply-live-never-
  reload, no cross-setting leakage (backfill once, don't mirror on read),
  deliberate per-panel vs global key scoping, fan-out to all panels, and the
  settings panel loading before the renderer.
- Fail-safe auto-revert (20): guard draw() or the Host reverts to default after
  repeated throws.

Renumber the Shipping section to 21-25 and add a Visualizations checklist block.
Docs only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: K. O. A. <topkoa@gmail.com>
… (rule 19)

Rule 19 said "the Host owns persistence" but never addressed localStorage. Make
it explicit: prefer Host-owned persistence (declare the setting, apply live, let
the Host store/replay) and do not hand-roll settings into localStorage — that is
what keeps export/import and backups whole and stops per-panel copies drifting.
For a self-managed viz that predates the contract, add the quota-safe rule from
the fixes: localStorage is synchronous and can throw (quota / private mode), so
stage the value in an in-memory fallback before setItem and prefer it on read,
and never touch localStorage on a per-frame path. Add a matching checklist item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: K. O. A. <topkoa@gmail.com>
@topkoa
topkoa force-pushed the docs/best-practices-visualizations branch from e792ad2 to b2040e8 Compare July 6, 2026 04:25
Base automatically changed from docs/best-practices-performance to docs/client-runtime-section July 6, 2026 04:42
@topkoa
topkoa merged commit 264781a into docs/client-runtime-section Jul 6, 2026
8 checks passed
@topkoa
topkoa deleted the docs/best-practices-visualizations branch July 6, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant