Transaction
E8B7F1C00F4E87…00E13DA2F482
Block 26,126 · index 0 · indexed
Summary
- Hash
- E8B7F1C00F4E87B43B90F9F015DD146A2D12B520A74C9364DC6800E13DA2F482
- Block
- 26,126
- Size
- 5875 bytes
- Gas used
- 10,276,855 / 12,332,286
- Fee
- 1000000 ugnot
- Memo
- gnopublish
- Status
- success
Messages
Arguments · 9
- #1toposortdemo
- #2README.md
- #3# Topological Sort > ⚠️ **Experimental — generated with no human supervision** by the daily MCP pipeline to exercise gno tooling. Not audited. See [r/moul/x/daily](https://github.com/moul/gno-contracts/blob/main/r/moul/x/daily/README.md). --- Shows a small build graph resolved into a safe install order — and a deliberately broken one, to show how a cycle is reported. Demo of the [`p/moul/x/daily/toposort`](https://github.com/moul/gno-contracts/tree/main/p/moul/x/daily/toposort/v0) library — the graph, the ordering and the cycle detection all come from the package; this realm holds no logic of its own. Stateless and read-only, so `Render` is fully deterministic. ``` /r/moul/x/daily/toposortdemo/v0 → the build graph, resolved into an order /r/moul/x/daily/toposortdemo/v0:cycle → a cyclic graph and its failure report ``` The interesting part is that the ordering is **unique**: ties are broken lexicographically, so this graph will always resolve to the same list. The cycle page shows the other half of the contract — the nodes that could not be ordered are named rather than silently dropped. Built for gno 0.9. <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:**  > 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4gnomod.toml
- #5module = "gno.land/r/moul/x/daily/toposortdemo/v0" gno = "0.9"
- #6toposortdemo.gno
- #7// Package toposortdemo is a small gnoweb demo of the dependency ordering // provided by the [p/moul/x/daily/toposort](/p/moul/x/daily/toposort/v0) // library: it shows a build graph resolved into a safe install order, and a // deliberately broken graph to show how a cycle is reported. // // It contains no ordering logic of its own — the graph, the sort and the cycle // detection all come from the library. Stateless and read-only, so Render is // fully deterministic. package toposortdemo import ( "strconv" "strings" "gno.land/p/moul/x/daily/toposort/v0" ) // buildGraph is a small, realistic dependency graph: a realm on top of a couple // of libraries, themselves on a shared core. func buildGraph() *toposort.Graph { return toposort.FromPairs([][2]string{ {"realm", "ui"}, {"realm", "storage"}, {"ui", "markdown"}, {"storage", "avl"}, {"markdown", "strings"}, {"avl", "strings"}, }) } // cyclicGraph is broken on purpose: auth and session need each other. func cyclicGraph() *toposort.Graph { return toposort.FromPairs([][2]string{ {"server", "auth"}, {"auth", "session"}, {"session", "auth"}, }) } // Render renders the demo for gnoweb. // // Render("") / Render("/") -> the build graph, resolved // Render("/cycle") -> the broken graph and its report func Render(path string) string { var b strings.Builder b.WriteString("# Topological Sort\n\n") b.WriteString("Ordering a dependency graph so nothing is built before what it needs, ") b.WriteString("demoing the [`p/moul/x/daily/toposort`](/p/moul/x/daily/toposort/v0) library.\n\n") if parseArg(path) == "cycle" { return b.String() + renderCycle() } g := buildGraph() b.WriteString("## The graph\n\n```\n") b.WriteString(g.String()) b.WriteString("```\n\n") order, err := g.Sort() if err != nil { b.WriteString("_Unexpectedly cyclic._\n") return b.String() } b.WriteString("## Install order\n\n") for i, n := range order { b.WriteString(strconv.Itoa(i + 1)) b.WriteString(". `") b.WriteString(n) b.WriteString("`\n") } b.WriteString("\nTies are broken lexicographically, so this ordering is the ") b.WriteString("*only* one the library will ever produce for this graph.\n\n") b.WriteString("> See [`/cycle`](/r/moul/x/daily/toposortdemo/v0:cycle) for what happens ") b.WriteString("when the graph is not a DAG.\n") return b.String() } // renderCycle shows the failure mode. func renderCycle() string { g := cyclicGraph() var b strings.Builder b.WriteString("## A graph with a cycle\n\n```\n") b.WriteString(g.String()) b.WriteString("```\n\n") order, err := g.Sort() if err == nil { b.WriteString("_Unexpectedly acyclic._\n") return b.String() } b.WriteString("`Sort` returns an error: **") b.WriteString(err.Error()) b.WriteString("**\n\n") b.WriteString("Ordered before giving up: ") if len(order) == 0 { b.WriteString("_nothing_") } else { b.WriteString("`" + strings.Join(order, "`, `") + "`") } b.WriteString("\n\nStuck on the cycle: `") b.WriteString(strings.Join(g.CycleNodes(), "`, `")) b.WriteString("`\n\n> The nodes still stuck are named rather than silently dropped, ") b.WriteString("so a caller can report exactly which dependencies are tangled.\n") return b.String() } // parseArg extracts the first path segment. func parseArg(path string) string { s := strings.TrimSpace(path) s = strings.TrimPrefix(s, "/") if i := strings.IndexByte(s, '/'); i >= 0 { s = s[:i] } return s }
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]