Skip to content

feat: show a document type's GroveDB layout, computed by Drive - #3

Merged
QuantumExplorer merged 4 commits into
mainfrom
feat/document-type-layout
Sep 29, 2026
Merged

QuantumExplorer merged 4 commits into
mainfrom
feat/document-type-layout

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Basic explanation

What this does: Select a document type and click GroveDB layout in the inspector. A panel opens with every tree and element Drive writes for that type: the documents by id, and for each index the tree per indexed property and per value, down to where the index ends. Each layer shows what kind of tree it is (plain, counting, summing, ranked), the indexes that use it, and a ↗ link to that kind of layer in the GroveDB structure viewer.

Value: You can see what an index costs in storage and what it can prove, for your own contract, without reading Drive. The structure viewer describes every document type at once, with templates ("an index property: one of 8 tree kinds"). This panel gives the concrete answer for one type and links back to the general description.

Where the layout comes from: Drive computes it, with the same rules it uses when it inserts documents (documentTypeLayout, added by dashpay/platform#5153). A Drive test compares it with what Drive really writes. The visualizer only draws it, so it cannot drift from Drive.

Needs an SDK release: dashpay/platform#5153 is merged (c795f81ce9), after 4.2.0-beta.6 was cut, so documentTypeLayout arrives with the next 4.2 release. It is not in @dashevo/evo-sdk 4.2.0-beta.4, which this repo pins. The panel checks whether the function exists. Until the dependency is bumped to a release that includes #5153, it says so instead of showing a layout. So this can merge before that release, and it starts working with a plain version bump.

Before and after

The marketplace example's listing type.

  • Before: the diagram shows the indexes (byShop, byCategoryPrice, newListings, ...) and their keywords. How they are stored is in the insert code only.
  • After: the panel shows (colours stand for plain / count / sum / ranked / value):
listing                                   Tree
├─ [0] PrimaryKey                         CountTree
│  └─ ‹document id›                       Item
├─ $createdAt#86400#3600                  Tree       newListings
│  └─ ‹$createdAt window: 1d every 1h›    CountTree  newListings
│     └─ [0] Members                      CountTree  newListings
│        └─ ‹document id›                 Reference
├─ category                               Tree       byCategoryPrice
│  └─ ‹category value›                    Tree       byCategoryPrice
│     └─ price                            Tree       byCategoryPrice
│        └─ ‹price value›                 Tree       byCategoryPrice
│           └─ [0] Members                Tree       byCategoryPrice
│              └─ ‹document id›           Reference
└─ shopId                                 Tree       byShop
   └─ ‹shopId value›                      Tree       byShop
      └─ $createdAt                       Tree       byShop
         └─ ‹$createdAt value›            CountTree  byShop
            └─ [0] Members                CountTree  byShop
               └─ ‹document id›           Reference

19 layers · 5 counted or summed · 0 ranked · 0 wrapped to contribute nothing

A ranked, summed indexOnly type (Yappr likes tip) shows ProvableCountProvableSumIndexedTree ranked by count, sum. A unique index (DPNS domain) shows its [0] as a Reference, with "or, when an indexed value of the document is null:" and the tree Drive writes instead.

With the SDK this repo pins today (4.2.0-beta.4), the panel says:

This build of the visualizer uses an @dashevo/evo-sdk without documentTypeLayout (added by dashpay/platform#5153). It appears with the next SDK release.

What was done?

  • src/components/LayoutPanel.tsx (new): the panel. It draws a tree you can collapse. Each row shows:
    • the key, with a tooltip saying what it stands for;
    • the element, coloured by kind;
    • the wrapper, ranked axes and indexes;
    • Drive's notes (skipIfAbsent, preallocated, time window overlap, ...);
    • a unique index's null fallback;
    • the ↗ link.
  • src/sdk/layout.ts (new): loads the SDK chunk on first use and calls documentTypeLayout, if the SDK has it. It turns a pasted bare map of schemas into a contract the SDK accepts, with placeholder id and owner (the layout does not depend on them).
  • src/model/layout.ts (new): the layout types, the key text (‹shopId value›, ‹$createdAt window: 1d every 1h›), the kind colours, the structure viewer links and the summary line.
  • src/App.tsx, src/components/InspectorPanel.tsx:
    • The app keeps the contract JSON of whatever is loaded: a network contract, an example, a ?url= link, a paste, or both sides of a compare.
    • The inspector's button opens the panel. In compare mode it uses the head version, or the base when the type was removed.
  • README: a How a document type is stored section.
  • Also on this branch, ed88d6a (docs). It fixes the README line about what the example check runs, and was left out of feat: compare two contract versions, judged by the update rules (and ?url= links) #2 when feat: compare two contract versions, judged by the update rules (and ?url= links) #2 merged.

How Has This Been Tested?

  • npx vitest run: 87 passed. The new src/model/layout.test.ts runs against layouts that the SDK built from the merged #5153 (c795f81ce9) computed for three examples (src/model/fixtures/document-type-layouts.json): marketplace listing, Yappr likes tip, DPNS domain.
  • tsc clean, npm run build clean.
  • In the browser:
    • With the SDK built from #5153 (swapped into node_modules locally, not committed), the panel draws marketplace listing and Yappr tip, and each ↗ opens the matching node in the structure viewer.
    • With the pinned 4.2.0-beta.4, the panel shows the "appears with the next SDK release" message.

🤖 Generated with Claude Code

QuantumExplorer and others added 2 commits September 29, 2026 02:22
@dashevo/evo-sdk is built without dpp's validation feature, so
DataContract.fromJSON(json, true, 14) runs the contract parser but not the
document meta-schema or the parser checks gated behind that feature. The
README, the examples registry and the validation script claimed more.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A "GroveDB layout" button in the inspector opens every tree and element
Drive writes for the selected document type: the documents by id (and
revisions), and for each index the property and value trees down to the
[0] where it ends, with each layer's element (count, sum, ranked, ...),
its zero-contribution wrapper, the indexes that use it, conditions (the
null fallback of a unique index, skipIfAbsent, preallocated, time window
overlap) and a link to that kind of layer in the GroveDB structure viewer.

The layout comes from documentTypeLayout in @dashevo/evo-sdk
(dashpay/platform#5153), so it follows Drive's own rules. It is
feature-detected: with an SDK that predates it, the panel says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 9a651c36-d71c-4340-b113-d8dce8891b86


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

dashpay/platform#5153 merged with a review fix: a unique index's null
fallback no longer repeats the terminal's indexes and notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in the inspector's JSON view (#5). The conflicts were both-sides
additions: EntityView takes both onShowLayout and version, the README
lists both layout.ts and jsonTokens.ts, and styles.css keeps both blocks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@QuantumExplorer
QuantumExplorer merged commit 8618215 into main Sep 29, 2026
3 checks passed
QuantumExplorer added a commit that referenced this pull request Sep 29, 2026
Main is #3's squash (8618215), whose tree is identical to #3's last head
(1631a85), already merged here. Keeping this branch's tree resolves the
conflicts the squash created.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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