Optimize $backend function call

This commit is contained in:
Max 2024-08-04 11:40:15 +08:00
parent 8e47849e93
commit d170ab6e53
9 changed files with 140 additions and 79 deletions

File diff suppressed because one or more lines are too long

View file

@ -12,7 +12,7 @@ func TestCompile(t *testing.T) {
defer clean() defer clean()
page := testPage(t) page := testPage(t)
html, warnings, err := page.Compile(nil, &core.BuildOption{KeepPageTag: false}) html, _, warnings, err := page.Compile(nil, &core.BuildOption{KeepPageTag: false})
if err != nil { if err != nil {
t.Fatalf("Compile error: %v", err) t.Fatalf("Compile error: %v", err)
} }

View file

@ -1,6 +1,8 @@
package api package api
import ( import (
"path/filepath"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/yaoapp/gou/process" "github.com/yaoapp/gou/process"
"github.com/yaoapp/kun/exception" "github.com/yaoapp/kun/exception"
@ -36,6 +38,17 @@ func Run(process *process.Process) interface{} {
return nil return nil
} }
if payload["page"] == nil {
exception.New("The page is required", 400).Throw()
return nil
}
page, ok := payload["page"].(string)
if !ok {
exception.New("The page must be a string", 400).Throw()
return nil
}
args := []interface{}{} args := []interface{}{}
if payload["args"] != nil { if payload["args"] != nil {
args, ok = payload["args"].([]interface{}) args, ok = payload["args"].([]interface{})
@ -45,7 +58,7 @@ func Run(process *process.Process) interface{} {
} }
} }
ctx.Request.URL.Path = route ctx.Request.URL.Path = page
r, _, err := NewRequestContext(ctx) r, _, err := NewRequestContext(ctx)
if err != nil { if err != nil {
exception.Err(err, 500).Throw() exception.Err(err, 500).Throw()
@ -61,7 +74,7 @@ func Run(process *process.Process) interface{} {
c, _, err = r.MakeCache() c, _, err = r.MakeCache()
if err != nil { if err != nil {
log.Error("[SUI] Can't make cache, %s %s error: %s", route, method, err.Error()) log.Error("[SUI] Can't make cache, %s %s error: %s", route, method, err.Error())
exception.New("Can't make cache, please the route and method is correct, get more information from the log.", 500).Throw() exception.New("Can't make cache, the route and method is correct, get more information from the log.", 500).Throw()
return nil return nil
} }
} }
@ -78,12 +91,20 @@ func Run(process *process.Process) interface{} {
return nil return nil
} }
if c.Script == nil { // Load the script
exception.New("Script not found", 500).Throw() file := filepath.Join("/public", route)
script, err := core.LoadScript(file, r.Request.DisableCache())
if err != nil {
exception.New("Can't load the script (%s), get more information from the log.", 500, route).Throw()
return nil return nil
} }
scriptCtx, err := c.Script.NewContext(process.Sid, nil) if script == nil {
exception.New("Script not found (%s)", 404, route)
return nil
}
scriptCtx, err := script.NewContext(process.Sid, nil)
if err != nil { if err != nil {
exception.Err(err, 500).Throw() exception.Err(err, 500).Throw()
return nil return nil

View file

@ -58,6 +58,9 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
body := doc.Find("body") body := doc.Find("body")
body.SetAttr("s:ns", namespace) body.SetAttr("s:ns", namespace)
body.SetAttr("s:public", option.PublicRoot) // Save public root
body.SetAttr("s:assets", option.AssetRoot)
// Bind the Page events // Bind the Page events
if !option.JitMode { if !option.JitMode {
page.BindEvent(ctx, doc.Selection, "__page", true) page.BindEvent(ctx, doc.Selection, "__page", true)
@ -218,6 +221,9 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op
// Pass the component props // Pass the component props
first := body.Children().First() first := body.Children().First()
first.SetAttr("s:public", option.PublicRoot) // Save public root
first.SetAttr("s:assets", option.AssetRoot)
// page.copyProps(ctx, sel, first, attrs...) // page.copyProps(ctx, sel, first, attrs...)
page.parseProps(sel, first, attrs...) page.parseProps(sel, first, attrs...)
page.copySlots(sel, first) page.copySlots(sel, first)

View file

@ -19,11 +19,11 @@ var importAssetsRe = regexp.MustCompile(`import\s*\t*\n*\s*['"]@assets\/([^'"]+)
var AssetsRe = regexp.MustCompile(`[` + quoteRe + `]@assets\/([^` + quoteRe + `]+)[` + quoteRe + `]`) // '@assets/foo.js' or "@assets/foo.js" or `@assets/foo` var AssetsRe = regexp.MustCompile(`[` + quoteRe + `]@assets\/([^` + quoteRe + `]+)[` + quoteRe + `]`) // '@assets/foo.js' or "@assets/foo.js" or `@assets/foo`
// Compile the page // Compile the page
func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, []string, error) { func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, string, []string, error) {
doc, warnings, err := page.Build(ctx, option) doc, warnings, err := page.Build(ctx, option)
if err != nil { if err != nil {
return "", warnings, fmt.Errorf("Page build error: %s", err.Error()) return "", "", warnings, fmt.Errorf("Page build error: %s", err.Error())
} }
if warnings != nil && len(warnings) > 0 { if warnings != nil && len(warnings) > 0 {
@ -62,9 +62,11 @@ func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, []str
page.Config = page.GetConfig() page.Config = page.GetConfig()
// Config Data // Config Data
config := ""
if page.Config != nil { if page.Config != nil {
config = page.ExportConfig()
body.AppendHtml("\n\n" + `<script name="config" type="json">` + "\n" + body.AppendHtml("\n\n" + `<script name="config" type="json">` + "\n" +
page.ExportConfig() + config +
"\n</script>\n\n", "\n</script>\n\n",
) )
} }
@ -94,11 +96,11 @@ func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, []str
page.ReplaceDocument(doc) page.ReplaceDocument(doc)
html, err := doc.Html() html, err := doc.Html()
if err != nil { if err != nil {
return "", warnings, fmt.Errorf("Generate html error: %s", err.Error()) return "", "", warnings, fmt.Errorf("Generate html error: %s", err.Error())
} }
// @todo: Minify the html // @todo: Minify the html
return html, warnings, nil return html, config, warnings, nil
} }
// CompileAsComponent compile the page as component // CompileAsComponent compile the page as component

View file

@ -74,6 +74,8 @@ var allowUsePropAttrs = map[string]bool{
"s:event": true, "s:event": true,
"s:event-cn": true, "s:event-cn": true,
"s:render": true, "s:render": true,
"s:public": true,
"s:assets": true,
} }
var keepAttrs = map[string]bool{ var keepAttrs = map[string]bool{
@ -83,6 +85,8 @@ var keepAttrs = map[string]bool{
"s:event": true, "s:event": true,
"s:event-cn": true, "s:event-cn": true,
"s:render": true, "s:render": true,
"s:public": true,
"s:assets": true,
} }
// NewTemplateParser create a new template parser // NewTemplateParser create a new template parser

View file

@ -221,6 +221,7 @@ function __sui_store(elm) {
async function __sui_backend_call( async function __sui_backend_call(
route: string, route: string,
page: string,
method: string, method: string,
...args: any ...args: any
): Promise<any> { ): Promise<any> {
@ -229,7 +230,7 @@ async function __sui_backend_call(
"Content-Type": "application/json", "Content-Type": "application/json",
Cookie: document.cookie, Cookie: document.cookie,
}; };
const payload = { method, args }; const payload = { method, args, page };
try { try {
const body = JSON.stringify(payload); const body = JSON.stringify(payload);
const response = await fetch(url, { method: "POST", headers, body: body }); const response = await fetch(url, { method: "POST", headers, body: body });

View file

@ -177,18 +177,24 @@ class __Render {
} }
function $Backend(route?: string) { function $Backend(route?: string) {
route = route || window.location.pathname; const page = window.location.pathname;
return new __Backend(route); const root = document.body.getAttribute("s:public") || "/";
route = route || page;
const re = new RegExp("^" + root);
route = root + route.replace(re, "");
return new __Backend(route, page);
} }
class __Backend { class __Backend {
route = ""; route = "";
constructor(route) { page = "";
constructor(route: string, page: string) {
this.route = route; this.route = route;
this.page = page;
} }
async Call(method: string, ...args: any): Promise<any> { async Call(method: string, ...args: any): Promise<any> {
// @ts-ignore // @ts-ignore
return await __sui_backend_call(this.route, method, ...args); return await __sui_backend_call(this.route, this.page, method, ...args);
} }
} }

View file

@ -398,7 +398,7 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp
} }
page.Root = root page.Root = root
html, warnings, err := page.Page.Compile(ctx, option) html, config, warnings, err := page.Page.Compile(ctx, option)
if err != nil { if err != nil {
return warnings, fmt.Errorf("Compile the page %s error: %s", page.Route, err.Error()) return warnings, fmt.Errorf("Compile the page %s error: %s", page.Route, err.Error())
} }
@ -421,6 +421,12 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp
return warnings, err return warnings, err
} }
// Save the config file
err = page.writeConfig([]byte(config), option.Data)
if err != nil {
return warnings, err
}
// Jit Components // Jit Components
if globalCtx == nil { if globalCtx == nil {
jitComponents, err := page.tmpl.GlobRoutes(ctx.GetJitComponents(), true) jitComponents, err := page.tmpl.GlobRoutes(ctx.GetJitComponents(), true)
@ -528,7 +534,7 @@ func (page *Page) Trans(globalCtx *core.GlobalBuildContext, option *core.BuildOp
warnings := []string{} warnings := []string{}
ctx := core.NewBuildContext(globalCtx) ctx := core.NewBuildContext(globalCtx)
_, messages, err := page.Page.Compile(ctx, option) _, _, messages, err := page.Page.Compile(ctx, option)
if err != nil { if err != nil {
return warnings, err return warnings, err
} }
@ -768,6 +774,21 @@ func (page *Page) writeHTML(html []byte, data map[string]interface{}) error {
return nil return nil
} }
// writeHTMLTo write the html to file
func (page *Page) writeConfig(config []byte, data map[string]interface{}) error {
configFile := fmt.Sprintf("%s.cfg", page.publicFile(data))
configFileAbs := filepath.Join(application.App.Root(), configFile)
dir := filepath.Dir(configFileAbs)
if exist, _ := os.Stat(dir); exist == nil {
os.MkdirAll(dir, os.ModePerm)
}
err := os.WriteFile(configFileAbs, config, 0644)
if err != nil {
return err
}
return nil
}
// writeHTMLTo write the html to file // writeHTMLTo write the html to file
func (page *Page) writeJitHTML(html []byte, data map[string]interface{}) error { func (page *Page) writeJitHTML(html []byte, data map[string]interface{}) error {
htmlFile := fmt.Sprintf("%s.jit", page.publicFile(data)) htmlFile := fmt.Sprintf("%s.jit", page.publicFile(data))