From 25318f2e4d4ec947b18cf22e0f97d2ca3dddb965 Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 10:40:28 +0200 Subject: [PATCH 01/15] Initial proposal of restyling the Unigraph examples' UI --- .../unigraph-static-example/index.astro | 7 ++++ .../unigraph/examples/domain-by-name.mdx | 25 +++++++---- docs/ensnode.io/src/styles/starlight.css | 41 ++++++++++++++++--- 3 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro new file mode 100644 index 000000000..02d91486e --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro @@ -0,0 +1,7 @@ +--- +--- + +
+ +
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 67a4834c8..95913c453 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -9,6 +9,10 @@ import { Tabs, TabItem } from "@astrojs/starlight/components"; import ResultDetails from "@components/molecules/ResultDetails.astro"; import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; +import UnigraphStaticExampleWrapper from "@components/molecules/unigraph-static-example/index.astro"; +import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; +import StaticExampleOutputSection from "@components/molecules/omnigraph-static-example/StaticExampleOutputSection.astro"; +import { stringifyJsonForDocs } from "@lib/examples/omnigraph/docs-utils"; export const unigraphSqlResultJson = [ { @@ -66,6 +70,8 @@ export const ensDbSdkResultJson = [ }, ]; +export const exampleSQLSnippet = `SELECT * FROM ensindexer_0.domains\nWHERE canonical_name = 'vitalik.eth';` + :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: @@ -76,20 +82,24 @@ Fetch a Domain by its canonical name. Because `canonical_name` is materialized a Canonical fields are populated on every Domain reachable from the canonical root, across both ENSv1 and ENSv2 — query them uniformly without branching by `type`. In SQL, these columns are `canonical_name`, `canonical_path`, `canonical_node`, and `canonical_depth`; in `ensdb-sdk`, the corresponding fields are `canonicalName`, `canonicalPath`, `canonicalNode`, and `canonicalDepth`. ::: + - + +
+
-```sql -SELECT * FROM ensindexer_0.domains -WHERE canonical_name = 'vitalik.eth'; -``` + - +
- + ```typescript @@ -107,3 +117,4 @@ console.log(vitalik);
+
diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index 7859a8810..0a320c7e2 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -452,15 +452,46 @@ ul.top-level details details > summary .group-label span { transform: none !important; } -/* Align "tablist" component to the left - * and remove the default full-width underline - */ +/* Unify the styling of Starlight tabs with our Omnigraph Static example tabs */ starlight-tabs ul[role="tablist"] { - padding-left: 0; border-bottom: none; + margin-top: 0; + padding-left: 20px; + padding-top: 12px; + + display: flex; + flex-direction: row; + gap: 16px; + + border-bottom: 1px solid rgba(0, 0, 0, 0.05); & a[role="tab"] { - padding-bottom: 8px; + padding: 8px 0 10px 0; + + font-size: 14px; + font-weight: 500; + + transition: color 0.2s ease-in-out; + + position: relative; + + display: inline-flex; + align-items: center; + gap: 0.375rem; + line-height: 1; + color: var(--sl-color-gray-3); + + box-shadow: none; + + &:is([aria-selected="true"]) { + color: var(--sl-color-text-accent); + box-shadow: inset 0 -2px 0 var(--sl-tab-color-border); + } + + & svg { + width: 16px; + height: 16px; + } } } From ba3f5fc841919c51e1eb3c389a82d94fa22fe729 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Wed, 3 Jun 2026 16:18:33 +0200 Subject: [PATCH 02/15] Introduce `SqlResutlTable` component Addresses use case of presenting SQL query results as a table on the UI. --- .../components/molecules/SqlResultTable.astro | 60 ++++++ .../unigraph/examples/account-domains.mdx | 3 +- .../unigraph/examples/domain-by-name.mdx | 9 +- .../unigraph/examples/indexing-status.mdx | 3 +- docs/ensnode.io/src/styles/starlight.css | 179 ++++++++++++++---- 5 files changed, 206 insertions(+), 48 deletions(-) create mode 100644 docs/ensnode.io/src/components/molecules/SqlResultTable.astro diff --git a/docs/ensnode.io/src/components/molecules/SqlResultTable.astro b/docs/ensnode.io/src/components/molecules/SqlResultTable.astro new file mode 100644 index 000000000..fab13aaf0 --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/SqlResultTable.astro @@ -0,0 +1,60 @@ +--- +/** + * Renders an array of row objects (or a single row object) as an HTML table + * with auto-detected column headers. + */ +interface Props { + rows: Record | Array>; +} + +const { rows } = Astro.props; + +const data = Array.isArray(rows) ? rows : [rows]; +const columns = data.length > 0 ? Object.keys(data[0]) : []; + +function formatCell(value: unknown): string { + if (value === null) return "NULL"; + if (typeof value === "object") return JSON.stringify(value, null, 2); + return String(value); +} +--- + +
+ + + + + {columns.map((col) => )} + + + + { + data.map((row, i) => ( + + + {columns.map((col) => { + const value = row[col]; + const text = formatCell(value); + const isComplex = value !== null && (typeof value === "object" || text.length > 80); + return ( + + ); + })} + + )) + } + +
#{col}
+ {i + 1} + + {isComplex ? ( +
+                      {text}
+                    
+ ) : value === null ? ( + {text} + ) : ( + {text} + )} +
+
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index 801fbe831..e69f43eda 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -7,6 +7,7 @@ sidebar: import { Tabs, TabItem } from "@astrojs/starlight/components"; import ResultDetails from "@components/molecules/ResultDetails.astro"; +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; @@ -37,7 +38,7 @@ WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' GROUP BY type; ``` - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 95913c453..6f657d0da 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -7,12 +7,11 @@ sidebar: import { Tabs, TabItem } from "@astrojs/starlight/components"; import ResultDetails from "@components/molecules/ResultDetails.astro"; +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; import UnigraphStaticExampleWrapper from "@components/molecules/unigraph-static-example/index.astro"; import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; -import StaticExampleOutputSection from "@components/molecules/omnigraph-static-example/StaticExampleOutputSection.astro"; -import { stringifyJsonForDocs } from "@lib/examples/omnigraph/docs-utils"; export const unigraphSqlResultJson = [ { @@ -91,11 +90,7 @@ Canonical fields are populated on every Domain reachable from the canonical root - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 085603ad4..a524ec584 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -7,6 +7,7 @@ sidebar: import { Tabs, TabItem } from "@astrojs/starlight/components"; import ResultDetails from "@components/molecules/ResultDetails.astro"; +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; @@ -136,7 +137,7 @@ WHERE ens_indexer_schema_name = 'ensindexer_0' AND key = 'indexing_metadata_context'; ``` - + diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index 0a320c7e2..e1a6c8e3e 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -130,22 +130,16 @@ } /* Docked + collapsed: show only the top-level topic icons */ - .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) - .sidebar-content - > :not(.starlight-sidebar-topics) { + .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) .sidebar-content> :not(.starlight-sidebar-topics) { display: none; } - .page[data-sidebar-docked] - nav.sidebar:not(:hover):not(:focus-within) - .starlight-sidebar-topics-icon - + div { + .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) .starlight-sidebar-topics-icon+div { display: none; } /* Docked + collapsed: Highlight only the icon of the current topic */ - .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) - a.starlight-sidebar-topics-current { + .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) a.starlight-sidebar-topics-current { background-color: transparent !important; } } @@ -205,7 +199,7 @@ a[rel="prev"]:hover { color: var(--sl-color-accent); } -.content-panel + .content-panel { +.content-panel+.content-panel { border-top: 0; padding-top: 0; } @@ -224,13 +218,13 @@ a[rel="prev"]:hover { --sl-color-white): keep links their base color on hover so only the underline-offset animates. */ .sl-markdown-content a:hover:not(:where(.not-content *)), -.sl-markdown-content a:hover:not(:where(.not-content *)) > span, +.sl-markdown-content a:hover:not(:where(.not-content *))>span, .omnigraph-required-table-content { color: var(--sl-color-text-accent); } -.sl-markdown-content > p a:not(:has(code), [role="tab"]), -.sl-markdown-content :is(ul, ol) > li a:not(:has(code), [role="tab"]), +.sl-markdown-content>p a:not(:has(code), [role="tab"]), +.sl-markdown-content :is(ul, ol)>li a:not(:has(code), [role="tab"]), .starlight-aside__content a, .omnigraph-required-table-content { text-decoration: underline; @@ -243,8 +237,8 @@ a[rel="prev"]:hover { } } -.sl-markdown-content > p a:has(code):not([role="tab"]), -.sl-markdown-content :is(ul, ol) > li a:has(code):not([role="tab"]) { +.sl-markdown-content>p a:has(code):not([role="tab"]), +.sl-markdown-content :is(ul, ol)>li a:has(code):not([role="tab"]) { text-decoration: underline; text-underline-offset: 4px; @@ -259,7 +253,7 @@ starlight-toc a:hover { color: var(--sl-color-text-accent); } -.sl-markdown-content :is(h1, h2, h3, h4, h5, h6) > a { +.sl-markdown-content :is(h1, h2, h3, h4, h5, h6)>a { color: var(--sl-color-white); display: inline; text-decoration: none; @@ -300,7 +294,7 @@ starlight-toc a:hover { justify-content: space-between; margin-top: 3rem; - & > a { + &>a { flex-basis: unset; flex-grow: unset; width: fit-content; @@ -318,7 +312,7 @@ starlight-toc a:hover { margin-left: auto; } - & > span { + &>span { font-size: 0.75rem; .link-title { @@ -326,7 +320,7 @@ starlight-toc a:hover { } } - & > svg { + &>svg { align-self: self-end; color: var(--pagination-arrow-color); font-size: 1.25rem; @@ -334,7 +328,7 @@ starlight-toc a:hover { } } - & > a:hover > svg { + &>a:hover>svg { color: var(--sl-color-white); } } @@ -347,8 +341,8 @@ starlight-toc a:hover { } #starlight__sidebar .starlight-sidebar-topics a, -#starlight__sidebar .top-level > li > a, -#starlight__sidebar .top-level > li > details > summary .group-label span, +#starlight__sidebar .top-level>li>a, +#starlight__sidebar .top-level>li>details>summary .group-label span, #starlight__sidebar a[aria-current="page"] { font-weight: 500; } @@ -358,8 +352,8 @@ starlight-toc a:hover { * * expandable items (in all states), including nested ones */ #starlight__sidebar a:not([aria-current="page"]):hover, -#starlight__sidebar details details > summary:hover, -#starlight__sidebar details > summary:hover { +#starlight__sidebar details details>summary:hover, +#starlight__sidebar details>summary:hover { background-color: rgba(128, 128, 128, 0.1); border-radius: 6px; } @@ -367,14 +361,14 @@ starlight-toc a:hover { /** Additional styling required for the * expandable items in the sidebar */ -#starlight__sidebar details details > summary:hover { +#starlight__sidebar details details>summary:hover { & span { color: var(--sl-color-white); } } -#starlight__sidebar details details > summary, -#starlight__sidebar details > summary { +#starlight__sidebar details details>summary, +#starlight__sidebar details>summary { transition: all 0.2s ease-in-out; &:hover { @@ -410,7 +404,7 @@ a.starlight-sidebar-topics-current .starlight-sidebar-topics-icon { * * not bolded * * the same color as the rest of the sidebar text */ -ul.top-level details details > summary .group-label span { +ul.top-level details details>summary .group-label span { @media (min-width: 50rem) { font-size: var(--sl-text-sm); } @@ -516,11 +510,9 @@ starlight-tabs ul[role="tablist"] { } & code { - background-color: color-mix( - in srgb, - var(--aside-color) var(--aside-code-strength, 12%), - transparent - ); + background-color: color-mix(in srgb, + var(--aside-color) var(--aside-code-strength, 12%), + transparent); border-radius: 4px; } } @@ -530,7 +522,8 @@ starlight-tabs ul[role="tablist"] { font-size: 16px; font-style: normal; font-weight: 500; - line-height: 20px; /* 125% */ + line-height: 20px; + /* 125% */ } .starlight-aside__content { @@ -538,7 +531,8 @@ starlight-tabs ul[role="tablist"] { font-size: 14px; font-style: normal; font-weight: 400; - line-height: 24px; /* 171.429% */ + line-height: 24px; + /* 171.429% */ margin-top: 10px; @@ -650,7 +644,8 @@ starlight-tabs ul[role="tablist"] { * hack since Starlight doesn't allow overriding icons directly. */ .starlight-sidebar-topics-icon svg { - display: none; /* Hide the default SVG icon */ + display: none; + /* Hide the default SVG icon */ } /* Default sidebar icon (parent) */ @@ -682,15 +677,19 @@ starlight-tabs ul[role="tablist"] { .starlight-sidebar-topics a[href*="/integrate"] .starlight-sidebar-topics-icon { --sidebar-icon: url("../assets/custom-sidebar-icons/integrate-with-ensv2.svg"); } + .starlight-sidebar-topics a[href*="/hosted-instances"] .starlight-sidebar-topics-icon { --sidebar-icon: url("../assets/custom-sidebar-icons/hosted-instances.svg"); } + .starlight-sidebar-topics a[href*="/self-host"] .starlight-sidebar-topics-icon { --sidebar-icon: url("../assets/custom-sidebar-icons/self-host-ensnode.svg"); } + .starlight-sidebar-topics a[href*="/services"] .starlight-sidebar-topics-icon { --sidebar-icon: url("../assets/custom-sidebar-icons/ensnode-services.svg"); } + .starlight-sidebar-topics a[href*="/reference"] .starlight-sidebar-topics-icon { --sidebar-icon: url("../assets/custom-sidebar-icons/reference.svg"); } @@ -717,7 +716,7 @@ starlight-tabs ul[role="tablist"] { /* Other elements are rounded accordingly */ .sl-markdown-content .expressive-code figcaption:is(.header), -.sl-markdown-content .expressive-code figcaption:is(.header) > span { +.sl-markdown-content .expressive-code figcaption:is(.header)>span { border-top-left-radius: 12px; border-top-right-radius: 12px; } @@ -727,12 +726,114 @@ starlight-tabs ul[role="tablist"] { border-bottom-right-radius: 12px; } -.sl-markdown-content div[role="tabpanel"] > .expressive-code:not(:has(figcaption:not(:empty))) pre { +.sl-markdown-content div[role="tabpanel"]>.expressive-code:not(:has(figcaption:not(:empty))) pre { border-radius: 12px; } /* Additional border for the "filename" tab in the code snippets */ -.sl-markdown-content .expressive-code figcaption:is(.header):has(.title:not(:empty)) > span { +.sl-markdown-content .expressive-code figcaption:is(.header):has(.title:not(:empty))>span { border-right: 1px solid var(--color-border); border-top: 1px solid var(--color-border); } + +/* SQL Result Table styles */ +.sql-result-table-wrapper { + overflow: auto; + max-height: 420px; + margin: 1rem 0; + border-radius: 12px; + border: 1px solid var(--sl-color-gray-5); +} + +.sql-result-table { + width: 100%; + border-collapse: separate; + border-spacing: 0; + font-size: 0.8125rem; + line-height: 1.4; + color: var(--sl-color-white); +} + +.sql-result-table th, +.sql-result-table td { + padding: 0.375rem 0.625rem; + text-align: left; + vertical-align: top; + border-bottom: 1px solid var(--sl-color-gray-5); + border-right: 1px solid var(--sl-color-gray-5); +} + +.sql-result-table th:last-child, +.sql-result-table td:last-child { + border-right: none; +} + +.sql-result-table th { + position: sticky; + top: 0; + z-index: 1; + background-color: var(--sl-color-gray-6); + font-weight: 600; + white-space: nowrap; + border-bottom: 1px solid var(--sl-color-gray-5); +} + +.sql-result-table td { + background-color: var(--sl-color-black); + white-space: nowrap; +} + +.sql-result-table tbody tr:hover td { + background-color: var(--color-gray-50); +} + +.sql-result-table tbody tr:last-child td { + border-bottom: none; +} + +.sql-result-table td code { + background: none; + padding: 0; + font-size: 0.75rem; + word-break: normal; + color: inherit; +} + +/* Row number column */ +.sql-result-rownum { + width: 2.25rem; + min-width: 2.25rem; + max-width: 2.25rem; + text-align: center !important; + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; +} + +.sql-result-rownum-label { + color: var(--sl-color-gray-3); + font-size: 0.75rem; +} + +.sql-result-cell-pre { + margin: 0; + background: none; + padding: 0; + font-size: 0.75rem; + line-height: 1.3; + color: inherit; + white-space: pre-wrap; + word-break: break-word; +} + +.sql-result-cell-pre code { + background: none; + padding: 0; + word-break: break-all; + white-space: pre-wrap; + color: inherit; +} + +.sql-result-null { + color: var(--sl-color-gray-3); + font-style: italic; +} From cf42d20a3d8c4cd75793107f6cf9d88f2262bebb Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 17:58:43 +0200 Subject: [PATCH 03/15] Extract the Unigraph example code into a generic component + minor style fixes of it --- .../molecules/UnigraphStaticExample.astro | 55 +++++++++++++ .../unigraph-static-example/index.astro | 7 -- .../unigraph/examples/domain-by-name.mdx | 59 +++++--------- docs/ensnode.io/src/styles/starlight.css | 77 +++++++++++-------- 4 files changed, 122 insertions(+), 76 deletions(-) create mode 100644 docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro delete mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro new file mode 100644 index 000000000..639e5ffef --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro @@ -0,0 +1,55 @@ +--- +import { Tabs, TabItem } from "@astrojs/starlight/components"; +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; +import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; +import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; +import StaticExampleNote from "@components/molecules/omnigraph-static-example/StaticExampleNote.astro"; + +interface unigraphExampleTabData { + codeSnippet: string; + result: Record | Array>; + resultNote?: string; +} + +interface Props { + sql: unigraphExampleTabData; + ensdbsdk: unigraphExampleTabData; +} + +const { sql, ensdbsdk } = Astro.props; + +const defaultResultNote = + "Output matches a SQL response snapshot; live output depends on your ENSNode instance."; +--- + +
+ + +
+ +
+ + + + + + {sql.resultNote ?? defaultResultNote} +
+ + +
+ +
+ + + + + + {ensdbsdk.resultNote ?? defaultResultNote} +
+
+
diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro deleted file mode 100644 index 02d91486e..000000000 --- a/docs/ensnode.io/src/components/molecules/unigraph-static-example/index.astro +++ /dev/null @@ -1,7 +0,0 @@ ---- ---- - -
- -
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 6f657d0da..2dea30be5 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -5,13 +5,7 @@ sidebar: label: Domain by Name --- -import { Tabs, TabItem } from "@astrojs/starlight/components"; -import ResultDetails from "@components/molecules/ResultDetails.astro"; -import SqlResultTable from "@components/molecules/SqlResultTable.astro"; -import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; -import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; -import UnigraphStaticExampleWrapper from "@components/molecules/unigraph-static-example/index.astro"; -import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; +import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; export const unigraphSqlResultJson = [ { @@ -71,6 +65,15 @@ export const ensDbSdkResultJson = [ export const exampleSQLSnippet = `SELECT * FROM ensindexer_0.domains\nWHERE canonical_name = 'vitalik.eth';` +export const exampleTSSnippet = `import { eq } from "drizzle-orm"; + +const [vitalik] = await ensDb +\t.select() +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); + +console.log(vitalik);` + :::caution[`unigraph` plugin required] Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) ::: @@ -81,35 +84,13 @@ Fetch a Domain by its canonical name. Because `canonical_name` is materialized a Canonical fields are populated on every Domain reachable from the canonical root, across both ENSv1 and ENSv2 — query them uniformly without branching by `type`. In SQL, these columns are `canonical_name`, `canonical_path`, `canonical_node`, and `canonical_depth`; in `ensdb-sdk`, the corresponding fields are `canonicalName`, `canonicalPath`, `canonicalNode`, and `canonicalDepth`. ::: - - - -
- -
- - - - - -
- - - - -```typescript -import { eq } from "drizzle-orm"; - -const [vitalik] = await ensDb - .select() - .from(ensIndexerSchema.domain) - .where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); - -console.log(vitalik); -``` - - - - -
-
+ diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index e1a6c8e3e..2cf74463a 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -130,16 +130,22 @@ } /* Docked + collapsed: show only the top-level topic icons */ - .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) .sidebar-content> :not(.starlight-sidebar-topics) { + .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) + .sidebar-content + > :not(.starlight-sidebar-topics) { display: none; } - .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) .starlight-sidebar-topics-icon+div { + .page[data-sidebar-docked] + nav.sidebar:not(:hover):not(:focus-within) + .starlight-sidebar-topics-icon + + div { display: none; } /* Docked + collapsed: Highlight only the icon of the current topic */ - .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) a.starlight-sidebar-topics-current { + .page[data-sidebar-docked] nav.sidebar:not(:hover):not(:focus-within) + a.starlight-sidebar-topics-current { background-color: transparent !important; } } @@ -199,7 +205,7 @@ a[rel="prev"]:hover { color: var(--sl-color-accent); } -.content-panel+.content-panel { +.content-panel + .content-panel { border-top: 0; padding-top: 0; } @@ -218,13 +224,13 @@ a[rel="prev"]:hover { --sl-color-white): keep links their base color on hover so only the underline-offset animates. */ .sl-markdown-content a:hover:not(:where(.not-content *)), -.sl-markdown-content a:hover:not(:where(.not-content *))>span, +.sl-markdown-content a:hover:not(:where(.not-content *)) > span, .omnigraph-required-table-content { color: var(--sl-color-text-accent); } -.sl-markdown-content>p a:not(:has(code), [role="tab"]), -.sl-markdown-content :is(ul, ol)>li a:not(:has(code), [role="tab"]), +.sl-markdown-content > p a:not(:has(code), [role="tab"]), +.sl-markdown-content :is(ul, ol) > li a:not(:has(code), [role="tab"]), .starlight-aside__content a, .omnigraph-required-table-content { text-decoration: underline; @@ -237,8 +243,8 @@ a[rel="prev"]:hover { } } -.sl-markdown-content>p a:has(code):not([role="tab"]), -.sl-markdown-content :is(ul, ol)>li a:has(code):not([role="tab"]) { +.sl-markdown-content > p a:has(code):not([role="tab"]), +.sl-markdown-content :is(ul, ol) > li a:has(code):not([role="tab"]) { text-decoration: underline; text-underline-offset: 4px; @@ -253,7 +259,7 @@ starlight-toc a:hover { color: var(--sl-color-text-accent); } -.sl-markdown-content :is(h1, h2, h3, h4, h5, h6)>a { +.sl-markdown-content :is(h1, h2, h3, h4, h5, h6) > a { color: var(--sl-color-white); display: inline; text-decoration: none; @@ -294,7 +300,7 @@ starlight-toc a:hover { justify-content: space-between; margin-top: 3rem; - &>a { + & > a { flex-basis: unset; flex-grow: unset; width: fit-content; @@ -312,7 +318,7 @@ starlight-toc a:hover { margin-left: auto; } - &>span { + & > span { font-size: 0.75rem; .link-title { @@ -320,7 +326,7 @@ starlight-toc a:hover { } } - &>svg { + & > svg { align-self: self-end; color: var(--pagination-arrow-color); font-size: 1.25rem; @@ -328,7 +334,7 @@ starlight-toc a:hover { } } - &>a:hover>svg { + & > a:hover > svg { color: var(--sl-color-white); } } @@ -341,8 +347,8 @@ starlight-toc a:hover { } #starlight__sidebar .starlight-sidebar-topics a, -#starlight__sidebar .top-level>li>a, -#starlight__sidebar .top-level>li>details>summary .group-label span, +#starlight__sidebar .top-level > li > a, +#starlight__sidebar .top-level > li > details > summary .group-label span, #starlight__sidebar a[aria-current="page"] { font-weight: 500; } @@ -352,8 +358,8 @@ starlight-toc a:hover { * * expandable items (in all states), including nested ones */ #starlight__sidebar a:not([aria-current="page"]):hover, -#starlight__sidebar details details>summary:hover, -#starlight__sidebar details>summary:hover { +#starlight__sidebar details details > summary:hover, +#starlight__sidebar details > summary:hover { background-color: rgba(128, 128, 128, 0.1); border-radius: 6px; } @@ -361,14 +367,14 @@ starlight-toc a:hover { /** Additional styling required for the * expandable items in the sidebar */ -#starlight__sidebar details details>summary:hover { +#starlight__sidebar details details > summary:hover { & span { color: var(--sl-color-white); } } -#starlight__sidebar details details>summary, -#starlight__sidebar details>summary { +#starlight__sidebar details details > summary, +#starlight__sidebar details > summary { transition: all 0.2s ease-in-out; &:hover { @@ -404,7 +410,7 @@ a.starlight-sidebar-topics-current .starlight-sidebar-topics-icon { * * not bolded * * the same color as the rest of the sidebar text */ -ul.top-level details details>summary .group-label span { +ul.top-level details details > summary .group-label span { @media (min-width: 50rem) { font-size: var(--sl-text-sm); } @@ -510,9 +516,11 @@ starlight-tabs ul[role="tablist"] { } & code { - background-color: color-mix(in srgb, - var(--aside-color) var(--aside-code-strength, 12%), - transparent); + background-color: color-mix( + in srgb, + var(--aside-color) var(--aside-code-strength, 12%), + transparent + ); border-radius: 4px; } } @@ -716,7 +724,7 @@ starlight-tabs ul[role="tablist"] { /* Other elements are rounded accordingly */ .sl-markdown-content .expressive-code figcaption:is(.header), -.sl-markdown-content .expressive-code figcaption:is(.header)>span { +.sl-markdown-content .expressive-code figcaption:is(.header) > span { border-top-left-radius: 12px; border-top-right-radius: 12px; } @@ -726,12 +734,12 @@ starlight-tabs ul[role="tablist"] { border-bottom-right-radius: 12px; } -.sl-markdown-content div[role="tabpanel"]>.expressive-code:not(:has(figcaption:not(:empty))) pre { +.sl-markdown-content div[role="tabpanel"] > .expressive-code:not(:has(figcaption:not(:empty))) pre { border-radius: 12px; } /* Additional border for the "filename" tab in the code snippets */ -.sl-markdown-content .expressive-code figcaption:is(.header):has(.title:not(:empty))>span { +.sl-markdown-content .expressive-code figcaption:is(.header):has(.title:not(:empty)) > span { border-right: 1px solid var(--color-border); border-top: 1px solid var(--color-border); } @@ -740,8 +748,9 @@ starlight-tabs ul[role="tablist"] { .sql-result-table-wrapper { overflow: auto; max-height: 420px; - margin: 1rem 0; - border-radius: 12px; + margin: 1rem 20px; + border-top-left-radius: 12px; + border-top-right-radius: 12px; border: 1px solid var(--sl-color-gray-5); } @@ -837,3 +846,11 @@ starlight-tabs ul[role="tablist"] { color: var(--sl-color-gray-3); font-style: italic; } + +/* + Additional global styles for the .static-example class + inside the Unigraph example +*/ +.static-example starlight-tabs .expressive-code .frame > pre { + border-radius: 12px; +} From f5f7b16c1637be4d1e6a686a5084ad1e246a2c42 Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 20:30:34 +0200 Subject: [PATCH 04/15] Apply the new UI component in all remaining examples --- .../molecules/UnigraphStaticExample.astro | 6 +- .../unigraph/examples/account-domains.mdx | 58 ++++++++----------- .../unigraph/examples/domain-by-name.mdx | 8 +-- .../unigraph/examples/indexing-status.mdx | 56 +++++++----------- docs/ensnode.io/src/styles/starlight.css | 3 +- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro index 639e5ffef..f76c6c5b4 100644 --- a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro @@ -6,15 +6,15 @@ import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; import StaticExampleNote from "@components/molecules/omnigraph-static-example/StaticExampleNote.astro"; -interface unigraphExampleTabData { +interface UnigraphExampleTabData { codeSnippet: string; result: Record | Array>; resultNote?: string; } interface Props { - sql: unigraphExampleTabData; - ensdbsdk: unigraphExampleTabData; + sql: UnigraphExampleTabData; + ensdbsdk: UnigraphExampleTabData; } const { sql, ensdbsdk } = Astro.props; diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index e69f43eda..4f87308e8 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -5,11 +5,7 @@ sidebar: label: Account Domains --- -import { Tabs, TabItem } from "@astrojs/starlight/components"; -import ResultDetails from "@components/molecules/ResultDetails.astro"; -import SqlResultTable from "@components/molecules/SqlResultTable.astro"; -import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; -import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; +import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; export const resultJson = [ { @@ -22,40 +18,34 @@ export const resultJson = [ } ]; -:::caution[`unigraph` plugin required] -Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) -::: - -Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. - - - - - -```sql -SELECT type, count(*) FROM ensindexer_0.domains +export const sqlExampleSnippet = `SELECT type, count(*) FROM ensindexer_0.domains WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' GROUP BY type; -``` - - +`; - - - - - -```typescript +export const tsExampleSnippet = ` import { count, eq } from "drizzle-orm"; const counts = await ensDb - .select({ type: ensIndexerSchema.domain.type, count: count() }) - .from(ensIndexerSchema.domain) - .where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) - .groupBy(ensIndexerSchema.domain.type); -``` +\t.select({ type: ensIndexerSchema.domain.type, count: count() }) +\t.from(ensIndexerSchema.domain) +\t.where(eq(ensIndexerSchema.domain.ownerId, "0x70997970c51812dc3a010c7d01b50e0d17dc79c8")) +\t.groupBy(ensIndexerSchema.domain.type); +` - +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` vs `ENSv2Domain`) — a single query spanning both protocol versions. See [Connect](/docs/integrate/unigraph/examples) for setup. - - + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 2dea30be5..b5aa61020 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -63,9 +63,9 @@ export const ensDbSdkResultJson = [ }, ]; -export const exampleSQLSnippet = `SELECT * FROM ensindexer_0.domains\nWHERE canonical_name = 'vitalik.eth';` +export const sqlExampleSnippet = `SELECT * FROM ensindexer_0.domains\nWHERE canonical_name = 'vitalik.eth';` -export const exampleTSSnippet = `import { eq } from "drizzle-orm"; +export const tsExampleSnippet = `import { eq } from "drizzle-orm"; const [vitalik] = await ensDb \t.select() @@ -86,11 +86,11 @@ Canonical fields are populated on every Domain reachable from the canonical root diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index a524ec584..268a5b4d7 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -5,11 +5,7 @@ sidebar: label: Indexing Status --- -import { Tabs, TabItem } from "@astrojs/starlight/components"; -import ResultDetails from "@components/molecules/ResultDetails.astro"; -import SqlResultTable from "@components/molecules/SqlResultTable.astro"; -import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; -import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; +import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; export const ensDbSdkResultJson = { strategy: "omnichain", @@ -119,42 +115,34 @@ export const unigraphSqlResultJson = { indexing_status_snapshot: ensDbSdkResultJson, }; -:::caution[`unigraph` plugin required] -Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) -::: - -Read the indexing status snapshot for an ENSIndexer instance from the shared `ensnode.metadata` table. See [Connect](/docs/integrate/unigraph/examples) for setup. - - - - - -```sql --- Indexing status snapshot for the `ensindexer_0` ENSIndexer Schema +export const sqlExampleSnippet = `-- Indexing status snapshot for the \`ensindexer_0\` ENSIndexer Schema SELECT value -> 'indexingStatus' as indexing_status_snapshot FROM "ensnode"."metadata" WHERE ens_indexer_schema_name = 'ensindexer_0' AND key = 'indexing_metadata_context'; -``` - - +`; - - - - - -```typescript -import { IndexingMetadataContextStatusCodes } from "@ensnode/ensdb-sdk"; +export const tsExampleSnippet = `import { IndexingMetadataContextStatusCodes } from "@ensnode/ensdb-sdk"; const indexingMetadataContext = await ensDbReader.getIndexingMetadataContext(); if (indexingMetadataContext.statusCode === IndexingMetadataContextStatusCodes.Initialized) { - const indexingStatusSnapshot = indexingMetadataContext.indexingStatus; - console.log(indexingStatusSnapshot); -} -``` +\tconst indexingStatusSnapshot = indexingMetadataContext.indexingStatus; +\tconsole.log(indexingStatusSnapshot); +}`; - +:::caution[`unigraph` plugin required] +Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` plugin activated in your ENSNode instance. [Learn more](/docs/services/ensindexer/usage/configuration) +::: + +Read the indexing status snapshot for an ENSIndexer instance from the shared `ensnode.metadata` table. See [Connect](/docs/integrate/unigraph/examples) for setup. - - + diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index 2cf74463a..4795328ec 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -749,8 +749,7 @@ starlight-tabs ul[role="tablist"] { overflow: auto; max-height: 420px; margin: 1rem 20px; - border-top-left-radius: 12px; - border-top-right-radius: 12px; + border-radius: 12px; border: 1px solid var(--sl-color-gray-5); } From 18053de0da5d905e26ce4557c2d3f9363601b787 Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 20:47:59 +0200 Subject: [PATCH 05/15] Apply AI agents' suggestions, pt.1 --- .../src/components/molecules/UnigraphStaticExample.astro | 6 +++--- .../docs/integrate/unigraph/examples/account-domains.mdx | 2 +- .../docs/integrate/unigraph/examples/domain-by-name.mdx | 2 +- .../docs/integrate/unigraph/examples/indexing-status.mdx | 2 +- docs/ensnode.io/src/styles/starlight.css | 7 +++++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro index f76c6c5b4..8f398ae3a 100644 --- a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro @@ -47,9 +47,9 @@ const defaultResultNote = - {ensdbsdk.resultNote ?? defaultResultNote} + + {ensdbsdk.resultNote ?? defaultResultNote} + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index 4f87308e8..607e41b7d 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -46,6 +46,6 @@ Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` v }} ensdbsdk={{ codeSnippet: tsExampleSnippet, - result: resultJson + result: resultJson, }} /> diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index b5aa61020..9f70fb57f 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -91,6 +91,6 @@ Canonical fields are populated on every Domain reachable from the canonical root }} ensdbsdk={{ codeSnippet: tsExampleSnippet, - result: ensDbSdkResultJson + result: ensDbSdkResultJson, }} /> diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 268a5b4d7..da13f128b 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -143,6 +143,6 @@ Read the indexing status snapshot for an ENSIndexer instance from the shared `en }} ensdbsdk={{ codeSnippet: tsExampleSnippet, - result: ensDbSdkResultJson + result: ensDbSdkResultJson, }} /> diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index 4795328ec..e8f00f0cd 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -454,7 +454,6 @@ ul.top-level details details > summary .group-label span { /* Unify the styling of Starlight tabs with our Omnigraph Static example tabs */ starlight-tabs ul[role="tablist"] { - border-bottom: none; margin-top: 0; padding-left: 20px; padding-top: 12px; @@ -483,9 +482,13 @@ starlight-tabs ul[role="tablist"] { box-shadow: none; + &:hover { + color: var(--sl-color-accent-high); + } + &:is([aria-selected="true"]) { color: var(--sl-color-text-accent); - box-shadow: inset 0 -2px 0 var(--sl-tab-color-border); + box-shadow: inset 0 -2px 0 var(--sl-color-text-accent); } & svg { From 941c89fe49719c2a724b2965a74369ae335cdc68 Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 23:13:55 +0200 Subject: [PATCH 06/15] Apply AI agents' suggestions, pt.2 --- docs/ensnode.io/src/components/molecules/SqlResultTable.astro | 4 ++-- .../docs/docs/integrate/unigraph/examples/account-domains.mdx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/SqlResultTable.astro b/docs/ensnode.io/src/components/molecules/SqlResultTable.astro index fab13aaf0..7e70219ed 100644 --- a/docs/ensnode.io/src/components/molecules/SqlResultTable.astro +++ b/docs/ensnode.io/src/components/molecules/SqlResultTable.astro @@ -23,8 +23,8 @@ function formatCell(value: unknown): string { - - {columns.map((col) => )} + + {columns.map((col) => )} diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index 607e41b7d..9bdfe8775 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -23,8 +23,7 @@ WHERE owner_id = '0x70997970c51812dc3a010c7d01b50e0d17dc79c8' GROUP BY type; `; -export const tsExampleSnippet = ` -import { count, eq } from "drizzle-orm"; +export const tsExampleSnippet = `import { count, eq } from "drizzle-orm"; const counts = await ensDb \t.select({ type: ensIndexerSchema.domain.type, count: count() }) From e46f3df3bafd07e35a2631a65bf39ea7d12c560d Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 23:34:41 +0200 Subject: [PATCH 07/15] Enable note customization for SQL tab in UnigraphStaticExample --- .../src/components/molecules/UnigraphStaticExample.astro | 2 +- .../docs/integrate/unigraph/examples/account-domains.mdx | 5 ++++- .../docs/integrate/unigraph/examples/domain-by-name.mdx | 6 ++++-- .../docs/integrate/unigraph/examples/indexing-status.mdx | 6 ++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro index 8f398ae3a..285cf192e 100644 --- a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro @@ -28,7 +28,7 @@ const defaultResultNote =
- +
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index 9bdfe8775..c84b910f7 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -6,6 +6,7 @@ sidebar: --- import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; export const resultJson = [ { @@ -47,4 +48,6 @@ Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` v codeSnippet: tsExampleSnippet, result: resultJson, }} - /> +> + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 4bef2f350..52c1b3f75 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -6,6 +6,7 @@ sidebar: --- import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; export const unigraphSqlResultJson = [ { @@ -92,5 +93,6 @@ Canonical fields are populated on every Domain reachable from the canonical root ensdbsdk={{ codeSnippet: tsExampleSnippet, result: ensDbSdkResultJson, - }} - /> + }}> + + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index da13f128b..67bfab6b4 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -6,6 +6,7 @@ sidebar: --- import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; export const ensDbSdkResultJson = { strategy: "omnichain", @@ -144,5 +145,6 @@ Read the indexing status snapshot for an ENSIndexer instance from the shared `en ensdbsdk={{ codeSnippet: tsExampleSnippet, result: ensDbSdkResultJson, - }} - /> + }}> + + From 56e5fc409d498acbc270f1eb5027ac3cd6c3850f Mon Sep 17 00:00:00 2001 From: y3drk Date: Wed, 3 Jun 2026 23:42:26 +0200 Subject: [PATCH 08/15] Apply AI agents' suggestions, pt.3 --- .../components/molecules/UnigraphStaticExample.astro | 11 +++++------ .../integrate/unigraph/examples/account-domains.mdx | 2 +- .../integrate/unigraph/examples/domain-by-name.mdx | 2 +- .../integrate/unigraph/examples/indexing-status.mdx | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro index 285cf192e..ae295f38e 100644 --- a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro @@ -1,7 +1,6 @@ --- import { Tabs, TabItem } from "@astrojs/starlight/components"; import SqlResultTable from "@components/molecules/SqlResultTable.astro"; -import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; import StaticExampleNote from "@components/molecules/omnigraph-static-example/StaticExampleNote.astro"; @@ -14,10 +13,10 @@ interface UnigraphExampleTabData { interface Props { sql: UnigraphExampleTabData; - ensdbsdk: UnigraphExampleTabData; + ensDbSdk: UnigraphExampleTabData; } -const { sql, ensdbsdk } = Astro.props; +const { sql, ensDbSdk } = Astro.props; const defaultResultNote = "Output matches a SQL response snapshot; live output depends on your ENSNode instance."; @@ -43,12 +42,12 @@ const defaultResultNote = - + - + - {ensdbsdk.resultNote ?? defaultResultNote} + {ensDbSdk.resultNote ?? defaultResultNote}
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index c84b910f7..bd105403a 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -44,7 +44,7 @@ Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` v codeSnippet: sqlExampleSnippet, result: resultJson, }} - ensdbsdk={{ + ensDbSdk={{ codeSnippet: tsExampleSnippet, result: resultJson, }} diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 52c1b3f75..d88e14843 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -90,7 +90,7 @@ Canonical fields are populated on every Domain reachable from the canonical root codeSnippet: sqlExampleSnippet, result: unigraphSqlResultJson, }} - ensdbsdk={{ + ensDbSdk={{ codeSnippet: tsExampleSnippet, result: ensDbSdkResultJson, }}> diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 67bfab6b4..7fca472c8 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -142,7 +142,7 @@ Read the indexing status snapshot for an ENSIndexer instance from the shared `en codeSnippet: sqlExampleSnippet, result: unigraphSqlResultJson, }} - ensdbsdk={{ + ensDbSdk={{ codeSnippet: tsExampleSnippet, result: ensDbSdkResultJson, }}> From daa5bbceab59054bd60f0b31aefa1ffa05121ca0 Mon Sep 17 00:00:00 2001 From: y3drk Date: Thu, 4 Jun 2026 15:59:08 +0200 Subject: [PATCH 09/15] Refactor UnigraphStaticExample component to make it more static + apply new ui in unigraph/examples/index --- .../molecules/UnigraphStaticExample.astro | 54 --------------- .../StaticExampleCodeSection.astro | 16 +++-- .../UnigraphExampleEnsDbSdkTab.astro | 7 ++ .../UnigraphExampleSQLTab.astro | 7 ++ .../UnigraphExampleWrapper.astro | 10 +++ .../UnigraphStaticExample.astro | 52 ++++++++++++++ .../unigraph/examples/account-domains.mdx | 4 +- .../unigraph/examples/domain-by-name.mdx | 4 +- .../integrate/unigraph/examples/index.mdx | 68 +++++++++++-------- .../unigraph/examples/indexing-status.mdx | 4 +- docs/ensnode.io/src/styles/starlight.css | 17 +++-- 11 files changed, 147 insertions(+), 96 deletions(-) delete mode 100644 docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro create mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro create mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro create mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro create mode 100644 docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro diff --git a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro deleted file mode 100644 index ae295f38e..000000000 --- a/docs/ensnode.io/src/components/molecules/UnigraphStaticExample.astro +++ /dev/null @@ -1,54 +0,0 @@ ---- -import { Tabs, TabItem } from "@astrojs/starlight/components"; -import SqlResultTable from "@components/molecules/SqlResultTable.astro"; -import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; -import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; -import StaticExampleNote from "@components/molecules/omnigraph-static-example/StaticExampleNote.astro"; - -interface UnigraphExampleTabData { - codeSnippet: string; - result: Record | Array>; - resultNote?: string; -} - -interface Props { - sql: UnigraphExampleTabData; - ensDbSdk: UnigraphExampleTabData; -} - -const { sql, ensDbSdk } = Astro.props; - -const defaultResultNote = - "Output matches a SQL response snapshot; live output depends on your ENSNode instance."; ---- - -
- - -
- -
- - - - - - {sql.resultNote ?? defaultResultNote} -
- - -
- -
- - - - - - - {ensDbSdk.resultNote ?? defaultResultNote} - -
-
-
diff --git a/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro b/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro index 9ce3c1782..64965b760 100644 --- a/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro +++ b/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro @@ -4,7 +4,7 @@ import { Code } from "@astrojs/starlight/components"; import { staticExampleCodeWrapClass, staticExampleSectionXClass } from "./constants"; interface Props { - badge: string; + badge?: string; headingId?: string; code: string; lang: string; @@ -18,11 +18,15 @@ const sectionClass = `border-b border-black/[0.05] pb-5 pt-3 dark:border-white/[ ---
-
- - {badge} - -
+ { + badge && ( +
+ + {badge} + +
+ ) + }
diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro new file mode 100644 index 000000000..ba09955ef --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro @@ -0,0 +1,7 @@ +--- +import { TabItem } from "@astrojs/starlight/components"; +--- + + + + diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro new file mode 100644 index 000000000..b52294c64 --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro @@ -0,0 +1,7 @@ +--- +import { TabItem } from "@astrojs/starlight/components"; +--- + + + + diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro new file mode 100644 index 000000000..54bbeded1 --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro @@ -0,0 +1,10 @@ +--- +import { Tabs } from "@astrojs/starlight/components"; +--- + +
+ + + +
diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro new file mode 100644 index 000000000..6da23a12f --- /dev/null +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro @@ -0,0 +1,52 @@ +--- +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; +import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; +import StaticExampleNote from "@components/molecules/omnigraph-static-example/StaticExampleNote.astro"; +import UnigraphExampleWrapper from "@components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro"; +import UnigraphExampleSQLTab from "./UnigraphExampleSQLTab.astro"; +import UnigraphExampleEnsDbSdkTab from "./UnigraphExampleEnsDbSdkTab.astro"; + +interface UnigraphExampleTabData { + codeSnippet: string; + result: Record | Array>; + resultNote?: string; +} + +interface Props { + sql: UnigraphExampleTabData; + ensDbSdk: UnigraphExampleTabData; +} + +const { sql, ensDbSdk } = Astro.props; + +const defaultResultNote = + "Output matches a SQL response snapshot; live output depends on your ENSNode instance."; +--- + + + +
+ +
+ + + + + + {sql.resultNote ?? defaultResultNote} +
+ + +
+ +
+ + + + + + + {ensDbSdk.resultNote ?? defaultResultNote} + +
+
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx index bd105403a..b05f6fe57 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/account-domains.mdx @@ -5,8 +5,9 @@ sidebar: label: Account Domains --- -import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; export const resultJson = [ { @@ -50,4 +51,5 @@ Count the Domains owned by an address, grouped by Domain `type` (`ENSv1Domain` v }} > + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index d88e14843..7c1da183a 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -5,8 +5,9 @@ sidebar: label: Domain by Name --- -import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsIndexerSchemaIntro from "@components/molecules/EnsIndexerSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; export const unigraphSqlResultJson = [ { @@ -95,4 +96,5 @@ Canonical fields are populated on every Domain reachable from the canonical root result: ensDbSdkResultJson, }}> + diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx index 6e4b40758..b1856bbe1 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx @@ -5,7 +5,24 @@ sidebar: label: Overview --- -import { LinkCard, Tabs, TabItem } from "@astrojs/starlight/components"; +import { LinkCard, Aside } from "@astrojs/starlight/components"; +import UnigraphExampleWrapper from "@components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro"; +import UnigraphExampleSQLTab from "@components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro"; +import UnigraphExampleEnsDbSdkTab from "@components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro"; +import StaticExampleCodeSection from "@components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro"; + +export const bashSQLConnectSnippet = `psql postgresql://user:password@host:5432/ensdb_devnet`; + +export const sqlDiscoverSnippet = `SELECT DISTINCT ens_indexer_schema_name +FROM ensnode.metadata;`; + +export const tsConnectCodeSnippet = `import { EnsDbReader } from "@ensnode/ensdb-sdk"; + +// Connect by providing a connection string and the ENSIndexer Schema Name to query +const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); +const { ensDb, ensIndexerSchema } = ensDbReader;`; + +export const bashSdkInstallSnippet = `npm install @ensnode/ensdb-sdk`; These examples show the same queries two ways: in **raw SQL** (any PostgreSQL client, any language) and with the typed **[`@ensnode/ensdb-sdk`](https://www.npmjs.com/package/@ensnode/ensdb-sdk)** for TypeScript projects. @@ -19,39 +36,32 @@ Performing SQL queries on the ENS Unigraph requires that you have the `unigraph` The Unigraph lives in [ENSDb](/docs/services/ensdb), a PostgreSQL database. Each ENSIndexer instance writes to its own **ENSIndexer Schema** (e.g. `ensindexer_0`); shared operational metadata lives in the `ensnode` schema. - - -```bash -psql postgresql://user:password@host:5432/ensdb_devnet -``` - -Discover the available ENSIndexer Schemas: - -```sql -SELECT DISTINCT ens_indexer_schema_name -FROM ensnode.metadata; -``` + + +
+ +
-
- -```bash -npm install @ensnode/ensdb-sdk -``` +

Discover the available ENSIndexer Schemas:

-:::note[ENSDb Reader] -The `EnsDbReader` object enables you to build custom queries against the Unigraph data model in ENSDb. Use the `ensDb` field to build queries with the Drizzle ORM, and the `ensIndexerSchema` field to reference database objects (i.e. the Unigraph tables) within the [ENSIndexer Schema](/docs/services/ensdb/concepts/glossary#ensindexer-schema) in a type-safe way. -::: + -```typescript -import { EnsDbReader } from "@ensnode/ensdb-sdk"; + + +
+ +
+ +
+ +
-// Connect by providing a connection string and the ENSIndexer Schema Name to query -const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); -const { ensDb, ensIndexerSchema } = ensDbReader; -``` + -
-
+ + ## Examples diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 7fca472c8..d3353a601 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -5,8 +5,9 @@ sidebar: label: Indexing Status --- -import UnigraphStaticExample from "@components/molecules/UnigraphStaticExample.astro"; +import UnigraphStaticExample from "@components/molecules/unigraph-static-example/UnigraphStaticExample.astro"; import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; +import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; export const ensDbSdkResultJson = { strategy: "omnichain", @@ -147,4 +148,5 @@ Read the indexing status snapshot for an ENSIndexer instance from the shared `en result: ensDbSdkResultJson, }}> + diff --git a/docs/ensnode.io/src/styles/starlight.css b/docs/ensnode.io/src/styles/starlight.css index e8f00f0cd..f67db9da5 100644 --- a/docs/ensnode.io/src/styles/starlight.css +++ b/docs/ensnode.io/src/styles/starlight.css @@ -849,10 +849,19 @@ starlight-tabs ul[role="tablist"] { font-style: italic; } -/* - Additional global styles for the .static-example class - inside the Unigraph example +/* + Additional global styles for the .static-example class + inside the Unigraph example */ -.static-example starlight-tabs .expressive-code .frame > pre { +.static-example starlight-tabs .expressive-code .frame > pre:not([data-language="bash"]) { border-radius: 12px; } + +/* + Make sure that code blocks inside asides are styled properly inside the static examples +*/ +.static-example starlight-tabs .starlight-aside :not(pre) > code { + margin-block: -0.125rem; + padding: 0.125rem 0.375rem; + font-size: var(--sl-text-code-sm); +} From 74f8e99cdfeb08cb949032d093f9a2998c589156 Mon Sep 17 00:00:00 2001 From: y3drk Date: Thu, 4 Jun 2026 16:04:36 +0200 Subject: [PATCH 10/15] Apply 06/04/26 Slack suggestion --> adjust the note title for ensDbSdk tab in unigraph examples --- docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro b/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro index 3ee233a85..dfbafa80d 100644 --- a/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro +++ b/docs/ensnode.io/src/components/molecules/EnsDbReaderIntro.astro @@ -2,7 +2,7 @@ import { Aside } from "@astrojs/starlight/components"; --- -
- {columns.map((col) => { const value = row[col]; const text = formatCell(value);
#{col}#{col}
{isComplex ? ( -
-                      {text}
-                    
+ // prettier-ignore +
{text}
) : value === null ? ( {text} ) : ( diff --git a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro index 6da23a12f..a4663d928 100644 --- a/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro +++ b/docs/ensnode.io/src/components/molecules/unigraph-static-example/UnigraphStaticExample.astro @@ -5,6 +5,7 @@ import StaticExampleNote from "@components/molecules/omnigraph-static-example/St import UnigraphExampleWrapper from "@components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro"; import UnigraphExampleSQLTab from "./UnigraphExampleSQLTab.astro"; import UnigraphExampleEnsDbSdkTab from "./UnigraphExampleEnsDbSdkTab.astro"; +import Pill from "@components/atoms/Pill.astro"; interface UnigraphExampleTabData { codeSnippet: string; @@ -20,7 +21,7 @@ interface Props { const { sql, ensDbSdk } = Astro.props; const defaultResultNote = - "Output matches a SQL response snapshot; live output depends on your ENSNode instance."; + "Output matches a result snapshot; live output depends on your ENSNode instance."; --- @@ -31,6 +32,10 @@ const defaultResultNote = +
+ Output +
+ {sql.resultNote ?? defaultResultNote} @@ -43,6 +48,10 @@ const defaultResultNote = +
+ Output +
+ diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx index 46ae8c2bd..b8124b574 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/domain-by-name.mdx @@ -13,27 +13,9 @@ export const unigraphSqlResultJson = [ { id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", type: "ENSv1Domain", - registry_id: - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", - subregistry_id: - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - token_id: null, - node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - label_hash: "0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc", - owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - root_registry_owner_id: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", - canonical: true, canonical_name: "vitalik.eth", - canonical_label_hash_path: [ - "0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0", - "0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc", - ], - canonical_path: [ - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ], - canonical_depth: 2, canonical_node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + owner_id: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", }, ]; @@ -41,36 +23,31 @@ export const ensDbSdkResultJson = [ { id: "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", type: "ENSv1Domain", - registryId: - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", - subregistryId: - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - tokenId: null, - node: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - labelHash: "0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc", - ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", - rootRegistryOwnerId: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", - canonical: true, canonicalName: "vitalik.eth", - canonicalLabelHashPath: [ - "0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0", - "0xaf2caa1c2ca1d027f1ac823b529d0a67cd144264b2789fa2ea4d63a67c7103cc", - ], - canonicalPath: [ - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae", - "1-0x00000000000c2e074ec69a0dfb2997ba6c7d2e1e-0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", - ], - canonicalDepth: 2, canonicalNode: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835", + ownerId: "0x220866b1a2219f40e72f5c628b65d54268ca3a9d", }, ]; -export const sqlExampleSnippet = `SELECT * FROM ensindexer_0.domains\nWHERE canonical_name = 'vitalik.eth';` +export const sqlExampleSnippet = `SELECT + id, + type, + canonical_name, + canonical_node, + owner_id +FROM ensindexer_0.domains +WHERE canonical_name = 'vitalik.eth';` export const tsExampleSnippet = `import { eq } from "drizzle-orm"; const [vitalik] = await ensDb -\t.select() +\t.select({ +\t\tid: ensIndexerSchema.domain.id, +\t\ttype: ensIndexerSchema.domain.type, +\t\tcanonicalName: ensIndexerSchema.domain.canonicalName, +\t\tcanonicalNode: ensIndexerSchema.domain.canonicalNode, +\t\townerId: ensIndexerSchema.domain.ownerId, +\t}) \t.from(ensIndexerSchema.domain) \t.where(eq(ensIndexerSchema.domain.canonicalName, "vitalik.eth")); diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx index 3f76d6cdf..c424eedcd 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/index.mdx @@ -6,6 +6,8 @@ sidebar: --- import { LinkCard, Aside } from "@astrojs/starlight/components"; +import Pill from "@components/atoms/Pill.astro"; +import SqlResultTable from "@components/molecules/SqlResultTable.astro"; import UnigraphExampleWrapper from "@components/molecules/unigraph-static-example/UnigraphExampleWrapper.astro"; import UnigraphExampleSQLTab from "@components/molecules/unigraph-static-example/UnigraphExampleSQLTab.astro"; import UnigraphExampleEnsDbSdkTab from "@components/molecules/unigraph-static-example/UnigraphExampleEnsDbSdkTab.astro"; @@ -16,11 +18,29 @@ export const bashSQLConnectSnippet = `psql postgresql://user:password@host:5432/ export const sqlDiscoverSnippet = `SELECT DISTINCT ens_indexer_schema_name FROM ensnode.metadata;`; +export const sqlDiscoverResultJson = [ + { ens_indexer_schema_name: "ensindexer_0" }, + { ens_indexer_schema_name: "ensindexer_1" }, +]; + export const tsConnectCodeSnippet = `import { EnsDbReader } from "@ensnode/ensdb-sdk"; // Connect by providing a connection string and the ENSIndexer Schema Name to query const ensDbReader = new EnsDbReader(ensDbConnectionString, ensIndexerSchemaName); -const { ensDb, ensIndexerSchema } = ensDbReader;`; +const { ensDb, ensIndexerSchema, ensNodeSchema } = ensDbReader;`; + +export const tsDiscoverCodeSnippet = `const availableEnsDbWriterSchemas = await ensDb + .selectDistinct({ + ensIndexerSchemaName: ensNodeSchema.metadata.ensIndexerSchemaName, + }) + .from(ensNodeSchema.metadata); + +console.log(availableEnsDbWriterSchemas);`; + +export const tsDiscoverResultJson = [ + { ensIndexerSchemaName: "ensindexer_0" }, + { ensIndexerSchemaName: "ensindexer_1" }, +]; export const bashSdkInstallSnippet = `npm install @ensnode/ensdb-sdk`; @@ -38,29 +58,46 @@ The Unigraph lives in [ENSDb](/docs/services/ensdb), a PostgreSQL database. Each -
- -
+

Connect to your ENSDb instance:

+ +

Discover the available ENSDb Writer Schemas:

+
+ Output +
+ + +
-
- -
- +

Install ENSDb SDK from NPM registry:

+ + +
+

Connect to your ENSDb instance:

+ +

Discover the available ENSDb Writer Schemas:

+ + + +
+ Output +
+ +
diff --git a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx index 0c1dee1d7..000984ac8 100644 --- a/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx +++ b/docs/ensnode.io/src/content/docs/docs/integrate/unigraph/examples/indexing-status.mdx @@ -10,116 +10,118 @@ import EnsNodeSchemaIntro from "@components/molecules/EnsNodeSchemaIntro.astro"; import EnsDbReaderIntro from "@components/molecules/EnsDbReaderIntro.astro"; export const ensDbSdkResultJson = { - strategy: "omnichain", - snapshotTime: 1779795066, - omnichainSnapshot: { - chains: { - 1: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 3327417, - timestamp: 1489165544, + indexingStatus: { + strategy: "omnichain", + snapshotTime: 1779795066, + omnichainSnapshot: { + chains: { + 1: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 3327417, + timestamp: 1489165544, + }, }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 25171597, - timestamp: 1779703391, - }, - latestIndexedBlock: { - number: 21224717, - timestamp: 1732054691, - }, - }, - 10: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 110393959, - timestamp: 1696386695, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 25171597, + timestamp: 1779703391, }, - }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 152052671, - timestamp: 1779704119, - }, - latestIndexedBlock: { - number: 128226309, - timestamp: 1732051395, - }, - }, - 8453: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 17522624, - timestamp: 1721834595, + latestIndexedBlock: { + number: 21224717, + timestamp: 1732054691, }, }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 46457386, - timestamp: 1779704119, - }, - latestIndexedBlock: { - number: 22632818, - timestamp: 1732054983, - }, - }, - 42161: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 349263357, - timestamp: 1750406457, + 10: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 110393959, + timestamp: 1696386695, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 152052671, + timestamp: 1779704119, + }, + latestIndexedBlock: { + number: 128226309, + timestamp: 1732051395, }, }, - chainStatus: "chain-queued", - }, - 59144: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 6682888, - timestamp: 1720768992, + 8453: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 17522624, + timestamp: 1721834595, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 46457386, + timestamp: 1779704119, + }, + latestIndexedBlock: { + number: 22632818, + timestamp: 1732054983, }, }, - chainStatus: "chain-backfill", - backfillEndBlock: { - number: 30774477, - timestamp: 1779703911, + 42161: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 349263357, + timestamp: 1750406457, + }, + }, + chainStatus: "chain-queued", }, - latestIndexedBlock: { - number: 12280006, - timestamp: 1732054967, + 59144: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 6682888, + timestamp: 1720768992, + }, + }, + chainStatus: "chain-backfill", + backfillEndBlock: { + number: 30774477, + timestamp: 1779703911, + }, + latestIndexedBlock: { + number: 12280006, + timestamp: 1732054967, + }, }, - }, - 534352: { - config: { - rangeType: "left-bounded", - startBlock: { - number: 16604272, - timestamp: 1750406415, + 534352: { + config: { + rangeType: "left-bounded", + startBlock: { + number: 16604272, + timestamp: 1750406415, + }, }, + chainStatus: "chain-queued", }, - chainStatus: "chain-queued", }, + omnichainStatus: "omnichain-backfill", + omnichainIndexingCursor: 1732054983, }, - omnichainStatus: "omnichain-backfill", - omnichainIndexingCursor: 1732054983, - }, - slowestChainIndexingCursor: 1732054983, -}; + slowestChainIndexingCursor: 1732054983, + } +} export const unigraphSqlResultJson = { - indexing_status_snapshot: ensDbSdkResultJson, + indexing_status_snapshot: ensDbSdkResultJson.indexingStatus, }; export const sqlExampleSnippet = `-- Indexing status snapshot for the \`ensindexer_0\` ENSIndexer Schema SELECT value -> 'indexingStatus' as indexing_status_snapshot -FROM "ensnode"."metadata" +FROM ensnode.metadata WHERE ens_indexer_schema_name = 'ensindexer_0' AND key = 'indexing_metadata_context'; `; @@ -128,8 +130,8 @@ export const tsExampleSnippet = `import { IndexingMetadataContextStatusCodes } f const indexingMetadataContext = await ensDbReader.getIndexingMetadataContext(); if (indexingMetadataContext.statusCode === IndexingMetadataContextStatusCodes.Initialized) { -\tconst indexingStatusSnapshot = indexingMetadataContext.indexingStatus; -\tconsole.log(indexingStatusSnapshot); +\tconst { indexingStatus } = indexingMetadataContext; +\tconsole.log({ indexingStatus }); }`; :::caution[`unigraph` plugin required] From 0e2665a11d57c8709d8af60d022cde3103efbe99 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Thu, 4 Jun 2026 18:41:35 +0200 Subject: [PATCH 12/15] Unify usage of the badge pill component --- docs/ensnode.io/src/components/atoms/Pill.astro | 3 ++- .../StaticExampleCodeSection.astro | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/ensnode.io/src/components/atoms/Pill.astro b/docs/ensnode.io/src/components/atoms/Pill.astro index d14c53ef8..e006883c4 100644 --- a/docs/ensnode.io/src/components/atoms/Pill.astro +++ b/docs/ensnode.io/src/components/atoms/Pill.astro @@ -1,8 +1,9 @@ --- +const { id } = Astro.props; const badgeClass = "inline-flex items-center rounded-full bg-[var(--sl-color-gray-5)] px-2.5 py-0.5 text-[0.7rem] font-medium tracking-wide text-[var(--sl-color-gray-2)] dark:bg-[var(--sl-color-gray-6)]"; --- - + diff --git a/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro b/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro index 64965b760..28f6249ef 100644 --- a/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro +++ b/docs/ensnode.io/src/components/molecules/omnigraph-static-example/StaticExampleCodeSection.astro @@ -2,6 +2,7 @@ import { Code } from "@astrojs/starlight/components"; import { staticExampleCodeWrapClass, staticExampleSectionXClass } from "./constants"; +import Pill from "@components/atoms/Pill.astro"; interface Props { badge?: string; @@ -12,8 +13,6 @@ interface Props { const { badge, headingId, code, lang } = Astro.props; -const badgeClass = - "inline-flex items-center rounded-full bg-[var(--sl-color-gray-5)] px-2.5 py-0.5 text-[0.7rem] font-medium tracking-wide text-[var(--sl-color-gray-2)] dark:bg-[var(--sl-color-gray-6)]"; const sectionClass = `border-b border-black/[0.05] pb-5 pt-3 dark:border-white/[0.06] ${staticExampleSectionXClass}`; --- @@ -21,9 +20,7 @@ const sectionClass = `border-b border-black/[0.05] pb-5 pt-3 dark:border-white/[ { badge && (
- - {badge} - + {badge}
) } From 53dc8bfc2aeefb2ec79094f039e471680a30a42a Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Thu, 4 Jun 2026 18:48:13 +0200 Subject: [PATCH 13/15] Apply AI PR feedback --- .../src/components/molecules/EnsDbWriterSchemaIntro.astro | 2 +- .../src/components/molecules/EnsNodeSchemaIntro.astro | 2 +- .../omnigraph-static-example/StaticExampleCodeSection.astro | 2 +- .../docs/docs/integrate/unigraph/examples/account-domains.mdx | 2 +- .../docs/docs/integrate/unigraph/examples/domain-by-name.mdx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ensnode.io/src/components/molecules/EnsDbWriterSchemaIntro.astro b/docs/ensnode.io/src/components/molecules/EnsDbWriterSchemaIntro.astro index 997f1db2c..bd81c099c 100644 --- a/docs/ensnode.io/src/components/molecules/EnsDbWriterSchemaIntro.astro +++ b/docs/ensnode.io/src/components/molecules/EnsDbWriterSchemaIntro.astro @@ -6,7 +6,7 @@ const { ensDbWriterSchemaName = "ensindexer_0" } = Astro.props;
+ {i + 1} - +