尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Interactive 3D visualizer of the Constellation Network ($DAG)
翻译准备中
正在加载完整 README。 以下为已保存的摘录。
DAG Visualizer — live 3D map of the Constellation Network
An interactive, real-time 3D map of the Constellation Network ($DAG) built with
Three.js. It visualizes the network's fundamentals so anyone
can understand how it works and why it's powerful.查看完整 README ↗Live at dagvisualizer.io
An interactive, real-time 3D map of the Constellation Network ($DAG) built with Three.js. It visualizes the network's fundamentals so anyone can understand how it works and why it's powerful.
/trends) shows the network's measured history as the scene itself —
one chart plane per network, receding into depth, with a shared time cursor reading every
chain at the same moment and a scrubbable timeline along the bottom. Brush a range and its
card states the span; click an instant and its card reads every network at that moment. On
touch, flick a card up or down to turn the deck and left or right to step the measure.
Daily, hourly and 5-minute buckets, all
reaching the same mid-2025 floor (TIER_SINCE in src/data/trendWindow.ts), summed from
the chain's own records into an Upstash Redis timeseries by a 15-minute cron (the other
three views need no backend at all; only this history does).Three depths, one subject — the observation ladder. Everything the site shows is the same network at one of three depths: the 3D scene is the live instrument (what is happening right now), the measured history is what the chain's own records say happened, and the raw data layer is the record-level microscope (the snapshots themselves, back to genesis). The middle depth is the History view's chart planes, and its RAW toggle steps down to the records for the span on screen. Each step down is one deliberate gesture that carries its context with it — zoom a chart into a range and you can hand that exact range to the snapshot search. The depths complement each other on purpose: history grows coarser the further back you look, precisely where the record microscope stays exact.
The HUD is four fixed zones over the canvas, each with one role that holds in every view, so switching views never relearns the screen:
Cards tell the story, not a static record. A card is its subject as seen from the current scene: the same facts, redistributed to lead with what the context makes relevant. Select a node in the Snapshots view and its card head states the relation to the pinned snapshot ("signed", with the layer chip) while the status steps down to a body row; committed ancestor cards absorb the facts they state better (a node under a committed country drops its Country line — the country card's title says it); and the in-scene callout label follows whichever card you expand, exactly as the camera does. Nothing is duplicated, nothing is lost — the presentation follows the story's state.
The four live views are complementary projections of the same network — each answers an orthogonal question and owns one "signature" detail card, so the views never overlap:
| View | Question | Explore tool (left rail) | Signature (detail) slot |
|---|---|---|---|
| Hypergraph | who / what — architecture + economic weight | Network breakdown (networks → compositions → nodes, with a measure heading) | Node card; structure counts live in the bottom vitals band |
| Node geography | where — footprint & decentralization | Country breakdown (countries → city · provider cohorts → nodes) | Node card (state, roles, location) + country / provider cards |
| Snapshots | when — how the ledger advances + cost | Snapshot breakdown (global ticks → networks in a tick → their snapshots → signers) | Snapshot card (DAG position, anchors, fees) |
| History | how it changed — the measured past | Network breakdown (one chart plane per network plus the unlisted channels, the measure as its heading) | Range card (a brushed span) over the Moment card (every network read at one instant) |
Visual uniformity is enforced with shared design tokens in one stylesheet (app/globals.css):
one spacing scale, one panel radius, one "selected" treatment (--sel-bg / --sel-border),
and one CardHead header component on every card. The design tokens (colour lanes + type
scale) live in that one stylesheet, and the running app is their reference.
globals.css is the single source of truth for colour — even in the 3D scene. The Three.js
engine doesn't hardcode structural colours; at start-up it reads the CSS design tokens
(--primary, --core, --background) and threads them into every scene module,
so the WebGL views and the HTML HUD always match.
A Next.js 16 app (React + TypeScript, Turbopack) driving a vanilla Three.js engine. Needs Node ≥ 20.9.
npm install
npm run dev # http://localhost:3000
Vercel is the intended host (any Node host works — npm run build / npm start).
The /api/metagraphs and /api/geo routes run server-side (the
Node server reaches the no-CORS metagraph cluster endpoints a browser can't). The browser
polls the app's own edge-cached /api/live* routes for snapshots and node lists, and those
read the Constellation block explorer once for every open tab. No CDN dependencies.
/api/metagraphs caches its live fetch for 5 min (unstable_cache) with a maxDuration
budget and a concurrent cluster fan-out, answering an honest 503 if the upstreams are down
(the client keeps its last good pull). The trends backend additionally needs the Upstash
Redis marketplace integration and a CRON_SECRET env var: a 15-minute Vercel Cron samples
the chain into tiered timeseries. Crons fire on the production deployment only — a PR
preview renders the /trends charts read-only from the shared store and cannot write to it
(the sampler fails closed without its secret). Real-user metrics come from Vercel Speed
Insights + Analytics, and
the social card is a frame of the intro tour, app/opengraph-image.png. See CLAUDE.md →
Deploying (Vercel) for the full checklist (incl. the Pro-only extras to enable as
traffic grows).
Browser ──poll──> /api/live* (edge-cached) ──> Constellation block explorer + L0/L1
│ │ one upstream read serves every open tab
│ │ events
│ v
│ NetworkData ──┬─► Engine (vanilla Three.js, 60fps, never re-rendered by React)
│ └─► Zustand store ──► React panels (header, ribbon, filter, inspector…)
│
└── Next routes (server-side): /api/metagraphs (live cluster fetch + geo, ISR)
/api/geo (validator geo seed)
/api/snapshot, /api/network (the raw records)
/api/trends (tiered history out of Upstash Redis)
Vercel Cron ──15 min──> /api/trends/sample ──> Upstash Redis (5m/1h/1d buckets) ──> /trends
The codebase is held together by a small set of rules — six of them are executable (vitest fails if they're broken), the rest are conventions the code and docs follow everywhere. If you contribute (human or AI), these are the contract:
1. The engine is three layers with one-way dependencies (enforced:
src/engine/layerBoundaries.test.ts; domainExportCoverage.test.ts requires every domain
export to be covered by its colocated test; the scene-view contract tests keep scene modules
mode-agnostic and views on the shared SceneView shape). domain/ is pure logic and data —
layout math, simulations, decision tables, camera framings; it may use THREE's math classes
but never the scene, React, or store values, so every behaviour is unit-testable in
isolation. scene/ owns meshes and GPU writes; it reads domain, never the store. The engine
layer — Engine.ts and a named allow-list of its siblings in src/engine/ — is the single
bridge: it subscribes to the store and translates state into scene commands.
New logic goes into domain/ with a test; the scene stays a dumb adapter.
2. Selections have one write path (enforced: components/selectionBoundary.test.ts).
Every interactive surface — a 3D raycast click, an explorer row, a strip bar, a picker row, a
card's Clear-selection × — expresses intent through the same pure decision table
(src/engine/domain/pickActions.ts, where the per-view semantics and ordering rules live,
tested) and applies it through one executor (src/store/applyClickActions.ts). Components
never call selection setters directly, so the scene and the panels can't drift apart. The
rule is write-based: read-only cards cost nothing.
3. Colours have one source of truth (enforced: src/engine/noHardcodedColors.test.ts).
The CSS design tokens in app/globals.css are canonical; the 3D engine reads them at boot
(sceneColors.ts) and no scene file may contain a raw hex colour outside a tiny documented
allowlist. Two colour lanes never mix: structural cyan is the sole affordance/accent signal,
and per-metagraph identity hues (generated deterministically in src/palette/) appear only
on subject marks — a metagraph is the same colour in the 3D scene, the filter picker, the
rail threads, and the cards, by construction.
4. Per-view behaviour is an allow-list, not scattered ifs. domain/viewPolicy.ts has one
row per view declaring what it turns on (canvas, sims, pickable pools, camera floors); a new
view is inert until its row opts in. The same idea repeats at smaller scales: the camera has
one home (domain/cameraRig.ts, including the global zoom lever), and the click semantics
one table.
5. The render loop allocates nothing (enforced: src/engine/noFrameAllocations.test.ts).
Per-frame code reuses construction-time scratch objects; simulations communicate through
ring-buffer events their owning adapter drains — never by mutating another view's objects.
6. The scene↔HUD hover pairing is sacrosanct. Hovering a row glows the 3D object and
hovering the 3D object washes the row, through shared store channels (hoverFilter,
hoverNodeId, hoverSnapOrd, hoverMetaSnap, hoverCountry, hoverCohort) — previews never
commit anything.
7. Honesty over decoration. Every bar, tile, count and border comes from live data; absent data reads as an instrument state (NO SIGNAL, acquiring), never as fabricated numbers.
| Path | Purpose |
|---|---|
app/ | Next App Router — page.tsx (mounts panels + canvas), [view]/ (the routed views: /hypergraph, /geography, /snapshots, /trends, /soon), about/ (the doc overlay), globals.css, api/* (server-side data routes) |
components/ | React panels (SceneCanvas, TopBar (heartbeat/pulse strip + filter + view switch + presentation), ExploreRail, Inspector, ContextCard, Tooltip, FollowController, …); CardHead (the shared card header), BottomStream + VitalsBand (the bottom per-view instrument band) + useSnapshotFeed (shared live feed), TrendStack (History's DOM chart planes), Blueprint (scaffolded-view schematics); components/explorer/ is the ONE explorer card every view's tool (GeoExplore, HyperExplore, LedgerPanel, TrendExplore) describes itself to; components/inspector/ holds the inspector cards; components/docs/ the About overlay and the one chart |
src/store/store.ts | Zustand store (the React↔engine command/state bridge) |
src/data/ | api.ts (the live NetworkData singleton), network.ts (its accessors), follow.ts, types.ts, and the pure row builders and rules — the explorer's levels, the raw log's merge and search, the History windows and series |
src/net/ | The three networks (?net=), the catalog's address lineage and network retirement |
src/util/ | Shared formatters — hex (colour), fmtDag (fee) — and localTime.ts (day-only labels are UTC days; clock times are local with a zone tag) |
src/engine/ | Engine.ts (imperative Three.js engine: render loop, morph, camera focus, DoF, picking) with CalloutSync.ts and TrendStackSync.ts beside it — together the one store bridge — over domain/ (pure, unit-tested layout/sim/policy logic) and (the Three.js adapters: globe, base rings, packet arcs, hyper furniture, ledger chamber, node meshes) |
Built as an educational visualization. Data is read-only from public endpoints.
scene/