-
-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Is there a way we can hard monkey patch os.FileRead?
Options to do this could be:
// Manually force-register a fake package
packages["os"] = &compiler.Archive{
ImportPath: "os",
// You would need to populate this with the compiled
// declarations of your custom ReadFile
}or update main in complie.go:
// 1. Define your mock OS archive globally or fetch it once
var mockOSArchive *compiler.Archive
// ... inside main ...
importContext := &compiler.ImportContext{
Packages: make(map[string]*types.Package),
Import: func(path string) (*compiler.Archive, error) {
// HIJACK: If anything asks for "os", give them our fake one
if path == "os" && mockOSArchive != nil {
return mockOSArchive, nil
}
if pkg, found := packages[path]; found {
return pkg, nil
}
pkgsToLoad[path] = struct{}{}
return &compiler.Archive{}, nil
},
}Dropping this here since @hatemhosny - will think this is useful.
import { compile, format } from 'https://cdn.jsdelivr.net/npm/@live-codes/go2js';
import { vol } from "https://cdn.jsdelivr.net/npm/memfs@4.6.0/+esm";
// ---------------------------
// 1. Load JSON into memfs
// ---------------------------
vol.fromJSON({
"/etc/hello.txt": "Hello from the JSON VFS!",
"/data/config.json": JSON.stringify({ version: "1.0", status: "ready" })
});
// ---------------------------
// 2. Expose VFS to Go
// ---------------------------
window.VFS = {
readFile: (path) => vol.readFileSync(path, "utf8"),
writeFile: (path, data) => vol.writeFileSync(path, data, "utf8"),
stat: (path) => vol.statSync(path),
readDir: (path) => vol.readdirSync(path),
mkdirAll: (path) => vol.mkdirSync(path, { recursive: true }),
remove: (path) => vol.unlinkSync(path),
// Simple open/read/close
open: (path) => vol.openSync(path, "r"),
read: (fd, len) => {
const buf = new Uint8Array(len);
const bytes = vol.readSync(fd, buf, 0, len, null);
return new TextDecoder().decode(buf.slice(0, bytes));
}
,
close: (fd) => vol.closeSync(fd)
};
// ---------------------------
// 3. Go code (os-compatible API)
// ---------------------------
const goCode = `
package main
import (
"fmt"
"io"
"os"
"syscall/js"
"time"
)
// ---- vfs/os-compatible types ----
type File struct{ fd int }
type fileInfo struct {
name string
size int64
mode os.FileMode
isDir bool
mtime time.Time
}
func (fi fileInfo) Name() string { return fi.name }
func (fi fileInfo) Size() int64 { return fi.size }
func (fi fileInfo) Mode() os.FileMode { return fi.mode }
func (fi fileInfo) ModTime() time.Time { return fi.mtime }
func (fi fileInfo) IsDir() bool { return fi.isDir }
func (fi fileInfo) Sys() interface{} { return nil }
// ---- VFS API ----
func ReadFile(path string) ([]byte, error) {
val := js.Global().Get("VFS").Call("readFile", path)
return []byte(val.String()), nil
}
func WriteFile(path string, data string) error {
js.Global().Get("VFS").Call("writeFile", path, data)
return nil
}
func Stat(path string) (os.FileInfo, error) {
st := js.Global().Get("VFS").Call("stat", path)
return fileInfo{
name: st.Get("name").String(),
size: int64(st.Get("size").Int()),
mode: os.FileMode(st.Get("mode").Int()),
isDir: st.Get("isDirectory").Bool(),
mtime: time.Unix(0, int64(st.Get("mtimeMs").Int())*int64(time.Millisecond)),
}, nil
}
func ReadDir(path string) ([]os.DirEntry, error) {
arr := js.Global().Get("VFS").Call("readDir", path)
out := make([]os.DirEntry, 0, arr.Length())
for i := 0; i < arr.Length(); i++ {
name := arr.Index(i).String()
out = append(out, dirEntry{name: name})
}
return out, nil
}
type dirEntry struct{ name string }
func (d dirEntry) Name() string { return d.name }
func (d dirEntry) IsDir() bool { return false }
func (d dirEntry) Type() os.FileMode { return 0 }
func (d dirEntry) Info() (os.FileInfo, error) { return nil, nil }
func Open(path string) (*File, error) {
fd := js.Global().Get("VFS").Call("open", path).Int()
return &File{fd: fd}, nil
}
func (f *File) Read(p []byte) (int, error) {
s := js.Global().Get("VFS").Call("read", f.fd, len(p)).String()
n := copy(p, []byte(s))
if n == 0 {
return 0, io.EOF
}
return n, nil
}
func (f *File) Close() error {
js.Global().Get("VFS").Call("close", f.fd)
return nil
}
// ---- main ----
func main() {
data, _ := ReadFile("/etc/hello.txt")
fmt.Println("ReadFile:", string(data))
f, _ := Open("/etc/hello.txt")
buf := make([]byte, 128)
n, _ := f.Read(buf)
fmt.Println("Open+Read:", string(buf[:n]))
f.Close()
}
`;
// ---------------------------
// 4. Compile & run
// ---------------------------
format(goCode)
.then((formatted) => compile(formatted))
.then((js) => eval(js))
.catch(console.error);Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels