sing-box/script/modules/sgstore/module.go
2025-02-02 17:27:29 +08:00

76 lines
1.8 KiB
Go

package sgstore
import (
"context"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/script/jsc"
"github.com/sagernet/sing/service"
"github.com/dop251/goja"
)
type SurgePersistentStore struct {
vm *goja.Runtime
cacheFile adapter.CacheFile
data map[string]string
tag string
}
func Enable(vm *goja.Runtime, ctx context.Context) {
object := vm.NewObject()
cacheFile := service.FromContext[adapter.CacheFile](ctx)
tag := vm.Get("$script").(*goja.Object).Get("name").String()
store := &SurgePersistentStore{
vm: vm,
cacheFile: cacheFile,
tag: tag,
}
if cacheFile == nil {
store.data = make(map[string]string)
}
object.Set("read", store.js_read)
object.Set("write", store.js_write)
vm.Set("$persistentStore", object)
}
func (s *SurgePersistentStore) js_read(call goja.FunctionCall) goja.Value {
if len(call.Arguments) > 1 {
panic(s.vm.NewTypeError("invalid arguments"))
}
key := jsc.AssertString(s.vm, call.Argument(0), "key", true)
if key == "" {
key = s.tag
}
var value string
if s.cacheFile != nil {
value = s.cacheFile.SurgePersistentStoreRead(key)
} else {
value = s.data[key]
}
if value == "" {
return goja.Null()
} else {
return s.vm.ToValue(value)
}
}
func (s *SurgePersistentStore) js_write(call goja.FunctionCall) goja.Value {
if len(call.Arguments) == 0 || len(call.Arguments) > 2 {
panic(s.vm.NewTypeError("invalid arguments"))
}
data := jsc.AssertString(s.vm, call.Argument(0), "data", true)
key := jsc.AssertString(s.vm, call.Argument(1), "key", true)
if key == "" {
key = s.tag
}
if s.cacheFile != nil {
err := s.cacheFile.SurgePersistentStoreWrite(key, data)
if err != nil {
panic(s.vm.NewGoError(err))
}
} else {
s.data[key] = data
}
return goja.Undefined()
}