at main 2.7 kB view raw
1package module 2 3import ( 4 "bytes" 5 "embed" 6 "errors" 7 "fmt" 8 "image" 9 "image/jpeg" 10 "image/png" 11 "path" 12 "strings" 13 14 "github.com/dop251/goja" 15 "github.com/dop251/goja_nodejs/require" 16 "tangled.org/cdbrdr.com/scrn/internal/transform" 17) 18 19var ( 20 ErrImgSrcUnknown = errors.New("img src unknown") 21) 22 23//go:generate esbuild scrn/*.jsx --jsx=automatic --jsx-factory=h --jsx-fragment=b --jsx-import-source=react --format=cjs --minify --outdir=scrn 24//go:generate esbuild jsx/jsx-runtime.js --outfile=jsx/jsx-runtime.min.js --format=cjs --minify 25 26//go:embed scrn/* jsx/* 27var f embed.FS 28 29func LoadImgSrc(p string) (image.Image, error) { 30 content, err := f.ReadFile(p) 31 if err != nil { 32 return nil, err 33 } 34 35 if strings.HasSuffix(p, ".png") { 36 img, err := png.Decode(bytes.NewBuffer(content)) 37 if err != nil { 38 return nil, err 39 } 40 41 return img, nil 42 } else if strings.HasSuffix(p, ".jpg") { 43 img, err := jpeg.Decode(bytes.NewBuffer(content)) 44 if err != nil { 45 return nil, err 46 } 47 48 return img, nil 49 } 50 51 return nil, ErrImgSrcUnknown 52} 53 54func LoadModule(p string) ([]byte, error) { 55 ext := path.Ext(p) 56 57 tryPaths := []string{} 58 if ext == "" { 59 tryPaths = append(tryPaths, fmt.Sprintf("%s.js", p)) 60 tryPaths = append(tryPaths, fmt.Sprintf("%s.jsx", p)) 61 } 62 63 if len(tryPaths) == 0 { 64 tryPaths = append(tryPaths, p) 65 } 66 67 for _, pth := range tryPaths { 68 content, err := f.ReadFile(pth) 69 if err != nil { 70 continue 71 } 72 73 if strings.HasSuffix(pth, ".jsx") { 74 code, errs := transform.Transform(path.Base(pth), string(content), transform.FormatCommonJS) 75 if len(errs) > 0 { 76 continue 77 } 78 79 return code, nil 80 } else { 81 return content, nil 82 } 83 } 84 85 return nil, require.ModuleFileDoesNotExistError 86} 87 88func LoadJSXRuntime() ([]byte, error) { 89 // First try pre-transformed 90 if code, err := f.ReadFile("jsx/jsx-runtime.min.js"); err == nil { 91 return code, nil 92 } 93 94 // Then load original source and transform it 95 content, err := f.ReadFile("jsx/jsx-runtime.js") 96 if err != nil { 97 return nil, require.ModuleFileDoesNotExistError 98 } 99 100 code, errs := transform.Transform("jsx-runtime.js", string(content), transform.FormatCommonJS) 101 if len(errs) > 0 { 102 return nil, require.ModuleFileDoesNotExistError 103 } 104 105 return code, nil 106} 107 108func Enable(runtime *goja.Runtime) *require.RequireModule { 109 registry := require.NewRegistryWithLoader(func(p string) ([]byte, error) { 110 if strings.HasSuffix(p, "node_modules/react/jsx-runtime") { 111 return LoadJSXRuntime() 112 } 113 if strings.HasPrefix(p, "node_modules/scrn/") { 114 return LoadModule(strings.TrimPrefix(p, "node_modules/")) 115 } 116 117 return nil, require.ModuleFileDoesNotExistError 118 }) 119 120 return registry.Enable(runtime) 121}