Skip to content

Commit

Permalink
chore: experimental render proxy example for versioned realms (#3341)
Browse files Browse the repository at this point in the history
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.

---------

Co-authored-by: Nathan Toups <[email protected]>
Co-authored-by: Leon Hudak <[email protected]>
Co-authored-by: Morgan <[email protected]>
  • Loading branch information
4 people authored Dec 20, 2024
1 parent f664c62 commit ea598bc
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 0 deletions.
20 changes: 20 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/example.gno
Original file line number Diff line number Diff line change
@@ -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.
`
}
1 change: 1 addition & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/r/x/jeronimo_render_proxy
52 changes: 52 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/home.gno
Original file line number Diff line number Diff line change
@@ -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)
}
16 changes: 16 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/v1/v1.gno
Original file line number Diff line number Diff line change
@@ -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("") + ")"
}
10 changes: 10 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/v1/z_filetest.gno
Original file line number Diff line number Diff line change
@@ -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)
16 changes: 16 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/v2/v2.gno
Original file line number Diff line number Diff line change
@@ -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("") + ")"
}
10 changes: 10 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/v2/z_filetest.gno
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 10 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/z_a_filetest.gno
Original file line number Diff line number Diff line change
@@ -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
15 changes: 15 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/z_b_filetest.gno
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions examples/gno.land/r/x/jeronimo_render_proxy/home/z_c_filetest.gno
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit ea598bc

Please sign in to comment.