diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/example.gno b/examples/gno.land/r/x/jeronimo_render_proxy/example.gno new file mode 100644 index 00000000000..7b3da098232 --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/example.gno @@ -0,0 +1,20 @@ +package example + +func Render(string) string { + return `# Render Proxy + +This example shows how proxying render calls can be used to allow updating realms to new +versions while keeping the same realm path. The idea is to have a simple "parent" realm +that only keeps track of the latest realm version and forwards all render calls to it. + +By only focusing on the 'Render()' function the proxy realm keeps its public functions +stable allowing each version to update their public functions and exposed types without +needing to also update the proxy realm. + +Any interaction or transaction must be sent to the latest, or target, realm version while +render calls are sent to the proxy realm. + +Each realm version registers itself on deployment as the latest available version, and +its allowed to do so because each versioned realm path shares the proxy realm path. +` +} diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/gno.mod b/examples/gno.land/r/x/jeronimo_render_proxy/gno.mod new file mode 100644 index 00000000000..9236b28f5ad --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/gno.mod @@ -0,0 +1 @@ +module gno.land/r/x/jeronimo_render_proxy diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno new file mode 100644 index 00000000000..c73e99cc583 --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno @@ -0,0 +1,52 @@ +package home + +import ( + "std" + "strings" +) + +// RenderFn defines the type for the render function of realms. +type RenderFn func(string) string + +var current = struct { + realmPath string + renderFn RenderFn +}{} + +// CurrentRealmPath returns the path of the realm that is currently registered. +func CurrentRealmPath() string { + return current.realmPath +} + +// Register registers a render function of a realm. +func Register(fn RenderFn) { + if fn == nil { + panic("render function must not be nil") + } + + proxyPath := std.CurrentRealm().PkgPath() + callerPath := std.PrevRealm().PkgPath() + if !strings.HasPrefix(callerPath, proxyPath+"/") { + panic("caller realm path must start with " + proxyPath) + } + + current.renderFn = fn + current.realmPath = callerPath +} + +// URL returns a URL that links to the proxy realm. +func URL(renderPath string) string { + url := "http://" + std.CurrentRealm().PkgPath() + if renderPath != "" { + url += ":" + renderPath + } + return url +} + +// Render renders the rendered Markdown of the realm that is currently registered. +func Render(path string) string { + if current.renderFn == nil { + panic("no realm has been registered") + } + return current.renderFn(path) +} diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno new file mode 100644 index 00000000000..8698998577c --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno @@ -0,0 +1,16 @@ +package v1 + +import "gno.land/r/x/jeronimo_render_proxy/home" + +func init() { + // Register the private render function with the render proxy + home.Register(render) +} + +func render(string) string { + return "Rendered by v1" +} + +func Render(string) string { + return "[Home](" + home.URL("") + ")" +} diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno new file mode 100644 index 00000000000..cebe2aeb5ba --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno @@ -0,0 +1,10 @@ +package main + +import "gno.land/r/x/jeronimo_render_proxy/home/v1" + +func main() { + println(v1.Render("")) +} + +// Output: +// [Home](http://gno.land/r/x/jeronimo_render_proxy/home) diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno new file mode 100644 index 00000000000..031f8568441 --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno @@ -0,0 +1,16 @@ +package v2 + +import "gno.land/r/x/jeronimo_render_proxy/home" + +func init() { + // Register the private render function with the render proxy + home.Register(render) +} + +func render(string) string { + return "Rendered by v2" +} + +func Render(string) string { + return "[Home](" + home.URL("") + ")" +} diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno new file mode 100644 index 00000000000..feff15533ee --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno @@ -0,0 +1,10 @@ +package main + +import "gno.land/r/x/jeronimo_render_proxy/home/v2" + +func main() { + println(v2.Render("")) +} + +// Output: +// [Home](http://gno.land/r/x/jeronimo_render_proxy/home) diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/z_a_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_a_filetest.gno new file mode 100644 index 00000000000..c7d4d7febd2 --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_a_filetest.gno @@ -0,0 +1,10 @@ +package main + +import "gno.land/r/x/jeronimo_render_proxy/home" + +func main() { + home.Render("") +} + +// Error: +// no realm has been registered diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/z_b_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_b_filetest.gno new file mode 100644 index 00000000000..6ebdace67b4 --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_b_filetest.gno @@ -0,0 +1,15 @@ +package main + +import ( + "gno.land/r/x/jeronimo_render_proxy/home" + _ "gno.land/r/x/jeronimo_render_proxy/home/v1" +) + +func main() { + println(home.CurrentRealmPath()) + println(home.Render("")) +} + +// Output: +// gno.land/r/x/jeronimo_render_proxy/home/v1 +// Rendered by v1 diff --git a/examples/gno.land/r/x/jeronimo_render_proxy/home/z_c_filetest.gno b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_c_filetest.gno new file mode 100644 index 00000000000..f85b13bc5dd --- /dev/null +++ b/examples/gno.land/r/x/jeronimo_render_proxy/home/z_c_filetest.gno @@ -0,0 +1,16 @@ +package main + +import ( + "gno.land/r/x/jeronimo_render_proxy/home" + _ "gno.land/r/x/jeronimo_render_proxy/home/v1" + _ "gno.land/r/x/jeronimo_render_proxy/home/v2" +) + +func main() { + println(home.CurrentRealmPath()) + println(home.Render("")) +} + +// Output: +// gno.land/r/x/jeronimo_render_proxy/home/v2 +// Rendered by v2