update
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled

This commit is contained in:
2025-12-08 16:16:23 +01:00
commit c251f174ed
1349 changed files with 194301 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/artwork/artwork.proto
package artwork
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetArtworkUrlRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Size int32 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` // Optional, 0 means original size
}
func (x *GetArtworkUrlRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetArtworkUrlRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *GetArtworkUrlRequest) GetSize() int32 {
if x != nil {
return x.Size
}
return 0
}
type GetArtworkUrlResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
}
func (x *GetArtworkUrlResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetArtworkUrlResponse) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
// go:plugin type=host version=1
type ArtworkService interface {
GetArtistUrl(context.Context, *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error)
GetAlbumUrl(context.Context, *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error)
GetTrackUrl(context.Context, *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error)
}

View File

@@ -0,0 +1,21 @@
syntax = "proto3";
package artwork;
option go_package = "github.com/navidrome/navidrome/plugins/host/artwork;artwork";
// go:plugin type=host version=1
service ArtworkService {
rpc GetArtistUrl(GetArtworkUrlRequest) returns (GetArtworkUrlResponse);
rpc GetAlbumUrl(GetArtworkUrlRequest) returns (GetArtworkUrlResponse);
rpc GetTrackUrl(GetArtworkUrlRequest) returns (GetArtworkUrlResponse);
}
message GetArtworkUrlRequest {
string id = 1;
int32 size = 2; // Optional, 0 means original size
}
message GetArtworkUrlResponse {
string url = 1;
}

View File

@@ -0,0 +1,130 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/artwork/artwork.proto
package artwork
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _artworkService struct {
ArtworkService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions ArtworkService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _artworkService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetArtistUrl), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_artist_url")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetAlbumUrl), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_album_url")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetTrackUrl), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_track_url")
_, err := envBuilder.Instantiate(ctx)
return err
}
func (h _artworkService) _GetArtistUrl(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetArtworkUrlRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetArtistUrl(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _artworkService) _GetAlbumUrl(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetArtworkUrlRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetAlbumUrl(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _artworkService) _GetTrackUrl(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetArtworkUrlRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetTrackUrl(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,90 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/artwork/artwork.proto
package artwork
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type artworkService struct{}
func NewArtworkService() ArtworkService {
return artworkService{}
}
//go:wasmimport env get_artist_url
func _get_artist_url(ptr uint32, size uint32) uint64
func (h artworkService) GetArtistUrl(ctx context.Context, request *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_artist_url(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetArtworkUrlResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_album_url
func _get_album_url(ptr uint32, size uint32) uint64
func (h artworkService) GetAlbumUrl(ctx context.Context, request *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_album_url(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetArtworkUrlResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_track_url
func _get_track_url(ptr uint32, size uint32) uint64
func (h artworkService) GetTrackUrl(ctx context.Context, request *GetArtworkUrlRequest) (*GetArtworkUrlResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_track_url(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetArtworkUrlResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package artwork
func NewArtworkService() ArtworkService {
panic("not implemented")
}

View File

@@ -0,0 +1,425 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/artwork/artwork.proto
package artwork
import (
fmt "fmt"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
bits "math/bits"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
func (m *GetArtworkUrlRequest) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GetArtworkUrlRequest) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *GetArtworkUrlRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if m.Size != 0 {
i = encodeVarint(dAtA, i, uint64(m.Size))
i--
dAtA[i] = 0x10
}
if len(m.Id) > 0 {
i -= len(m.Id)
copy(dAtA[i:], m.Id)
i = encodeVarint(dAtA, i, uint64(len(m.Id)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *GetArtworkUrlResponse) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GetArtworkUrlResponse) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *GetArtworkUrlResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarint(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarint(dAtA []byte, offset int, v uint64) int {
offset -= sov(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GetArtworkUrlRequest) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Id)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
if m.Size != 0 {
n += 1 + sov(uint64(m.Size))
}
n += len(m.unknownFields)
return n
}
func (m *GetArtworkUrlResponse) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Url)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func sov(x uint64) (n int) {
return (bits.Len64(x|1) + 6) / 7
}
func soz(x uint64) (n int) {
return sov(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GetArtworkUrlRequest) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GetArtworkUrlRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GetArtworkUrlRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Id = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Size", wireType)
}
m.Size = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Size |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GetArtworkUrlResponse) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GetArtworkUrlResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GetArtworkUrlResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skip(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLength
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLength
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflow = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group")
)

420
plugins/host/cache/cache.pb.go vendored Normal file
View File

@@ -0,0 +1,420 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/cache/cache.proto
package cache
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Request to store a string value
type SetStringRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // String value to store
TtlSeconds int64 `protobuf:"varint,3,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` // TTL in seconds, 0 means use default
}
func (x *SetStringRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SetStringRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *SetStringRequest) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *SetStringRequest) GetTtlSeconds() int64 {
if x != nil {
return x.TtlSeconds
}
return 0
}
// Request to store an integer value
type SetIntRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` // Integer value to store
TtlSeconds int64 `protobuf:"varint,3,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` // TTL in seconds, 0 means use default
}
func (x *SetIntRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SetIntRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *SetIntRequest) GetValue() int64 {
if x != nil {
return x.Value
}
return 0
}
func (x *SetIntRequest) GetTtlSeconds() int64 {
if x != nil {
return x.TtlSeconds
}
return 0
}
// Request to store a float value
type SetFloatRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
Value float64 `protobuf:"fixed64,2,opt,name=value,proto3" json:"value,omitempty"` // Float value to store
TtlSeconds int64 `protobuf:"varint,3,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` // TTL in seconds, 0 means use default
}
func (x *SetFloatRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SetFloatRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *SetFloatRequest) GetValue() float64 {
if x != nil {
return x.Value
}
return 0
}
func (x *SetFloatRequest) GetTtlSeconds() int64 {
if x != nil {
return x.TtlSeconds
}
return 0
}
// Request to store a byte slice value
type SetBytesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // Byte slice value to store
TtlSeconds int64 `protobuf:"varint,3,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` // TTL in seconds, 0 means use default
}
func (x *SetBytesRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SetBytesRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *SetBytesRequest) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
func (x *SetBytesRequest) GetTtlSeconds() int64 {
if x != nil {
return x.TtlSeconds
}
return 0
}
// Response after setting a value
type SetResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` // Whether the operation was successful
}
func (x *SetResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SetResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
// Request to get a value
type GetRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
}
func (x *GetRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
// Response containing a string value
type GetStringResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Whether the key exists
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // The string value (if exists is true)
}
func (x *GetStringResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetStringResponse) GetExists() bool {
if x != nil {
return x.Exists
}
return false
}
func (x *GetStringResponse) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
// Response containing an integer value
type GetIntResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Whether the key exists
Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` // The integer value (if exists is true)
}
func (x *GetIntResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetIntResponse) GetExists() bool {
if x != nil {
return x.Exists
}
return false
}
func (x *GetIntResponse) GetValue() int64 {
if x != nil {
return x.Value
}
return 0
}
// Response containing a float value
type GetFloatResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Whether the key exists
Value float64 `protobuf:"fixed64,2,opt,name=value,proto3" json:"value,omitempty"` // The float value (if exists is true)
}
func (x *GetFloatResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetFloatResponse) GetExists() bool {
if x != nil {
return x.Exists
}
return false
}
func (x *GetFloatResponse) GetValue() float64 {
if x != nil {
return x.Value
}
return 0
}
// Response containing a byte slice value
type GetBytesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Whether the key exists
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` // The byte slice value (if exists is true)
}
func (x *GetBytesResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetBytesResponse) GetExists() bool {
if x != nil {
return x.Exists
}
return false
}
func (x *GetBytesResponse) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
// Request to remove a value
type RemoveRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
}
func (x *RemoveRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *RemoveRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
// Response after removing a value
type RemoveResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` // Whether the operation was successful
}
func (x *RemoveResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *RemoveResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
// Request to check if a key exists
type HasRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Cache key
}
func (x *HasRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *HasRequest) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
// Response indicating if a key exists
type HasResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Whether the key exists
}
func (x *HasResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *HasResponse) GetExists() bool {
if x != nil {
return x.Exists
}
return false
}
// go:plugin type=host version=1
type CacheService interface {
// Set a string value in the cache
SetString(context.Context, *SetStringRequest) (*SetResponse, error)
// Get a string value from the cache
GetString(context.Context, *GetRequest) (*GetStringResponse, error)
// Set an integer value in the cache
SetInt(context.Context, *SetIntRequest) (*SetResponse, error)
// Get an integer value from the cache
GetInt(context.Context, *GetRequest) (*GetIntResponse, error)
// Set a float value in the cache
SetFloat(context.Context, *SetFloatRequest) (*SetResponse, error)
// Get a float value from the cache
GetFloat(context.Context, *GetRequest) (*GetFloatResponse, error)
// Set a byte slice value in the cache
SetBytes(context.Context, *SetBytesRequest) (*SetResponse, error)
// Get a byte slice value from the cache
GetBytes(context.Context, *GetRequest) (*GetBytesResponse, error)
// Remove a value from the cache
Remove(context.Context, *RemoveRequest) (*RemoveResponse, error)
// Check if a key exists in the cache
Has(context.Context, *HasRequest) (*HasResponse, error)
}

120
plugins/host/cache/cache.proto vendored Normal file
View File

@@ -0,0 +1,120 @@
syntax = "proto3";
package cache;
option go_package = "github.com/navidrome/navidrome/plugins/host/cache;cache";
// go:plugin type=host version=1
service CacheService {
// Set a string value in the cache
rpc SetString(SetStringRequest) returns (SetResponse);
// Get a string value from the cache
rpc GetString(GetRequest) returns (GetStringResponse);
// Set an integer value in the cache
rpc SetInt(SetIntRequest) returns (SetResponse);
// Get an integer value from the cache
rpc GetInt(GetRequest) returns (GetIntResponse);
// Set a float value in the cache
rpc SetFloat(SetFloatRequest) returns (SetResponse);
// Get a float value from the cache
rpc GetFloat(GetRequest) returns (GetFloatResponse);
// Set a byte slice value in the cache
rpc SetBytes(SetBytesRequest) returns (SetResponse);
// Get a byte slice value from the cache
rpc GetBytes(GetRequest) returns (GetBytesResponse);
// Remove a value from the cache
rpc Remove(RemoveRequest) returns (RemoveResponse);
// Check if a key exists in the cache
rpc Has(HasRequest) returns (HasResponse);
}
// Request to store a string value
message SetStringRequest {
string key = 1; // Cache key
string value = 2; // String value to store
int64 ttl_seconds = 3; // TTL in seconds, 0 means use default
}
// Request to store an integer value
message SetIntRequest {
string key = 1; // Cache key
int64 value = 2; // Integer value to store
int64 ttl_seconds = 3; // TTL in seconds, 0 means use default
}
// Request to store a float value
message SetFloatRequest {
string key = 1; // Cache key
double value = 2; // Float value to store
int64 ttl_seconds = 3; // TTL in seconds, 0 means use default
}
// Request to store a byte slice value
message SetBytesRequest {
string key = 1; // Cache key
bytes value = 2; // Byte slice value to store
int64 ttl_seconds = 3; // TTL in seconds, 0 means use default
}
// Response after setting a value
message SetResponse {
bool success = 1; // Whether the operation was successful
}
// Request to get a value
message GetRequest {
string key = 1; // Cache key
}
// Response containing a string value
message GetStringResponse {
bool exists = 1; // Whether the key exists
string value = 2; // The string value (if exists is true)
}
// Response containing an integer value
message GetIntResponse {
bool exists = 1; // Whether the key exists
int64 value = 2; // The integer value (if exists is true)
}
// Response containing a float value
message GetFloatResponse {
bool exists = 1; // Whether the key exists
double value = 2; // The float value (if exists is true)
}
// Response containing a byte slice value
message GetBytesResponse {
bool exists = 1; // Whether the key exists
bytes value = 2; // The byte slice value (if exists is true)
}
// Request to remove a value
message RemoveRequest {
string key = 1; // Cache key
}
// Response after removing a value
message RemoveResponse {
bool success = 1; // Whether the operation was successful
}
// Request to check if a key exists
message HasRequest {
string key = 1; // Cache key
}
// Response indicating if a key exists
message HasResponse {
bool exists = 1; // Whether the key exists
}

374
plugins/host/cache/cache_host.pb.go vendored Normal file
View File

@@ -0,0 +1,374 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/cache/cache.proto
package cache
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _cacheService struct {
CacheService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions CacheService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _cacheService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SetString), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("set_string")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetString), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_string")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SetInt), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("set_int")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetInt), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_int")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SetFloat), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("set_float")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetFloat), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_float")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SetBytes), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("set_bytes")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetBytes), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_bytes")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Remove), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("remove")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Has), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("has")
_, err := envBuilder.Instantiate(ctx)
return err
}
// Set a string value in the cache
func (h _cacheService) _SetString(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SetStringRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SetString(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Get a string value from the cache
func (h _cacheService) _GetString(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetString(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Set an integer value in the cache
func (h _cacheService) _SetInt(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SetIntRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SetInt(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Get an integer value from the cache
func (h _cacheService) _GetInt(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetInt(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Set a float value in the cache
func (h _cacheService) _SetFloat(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SetFloatRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SetFloat(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Get a float value from the cache
func (h _cacheService) _GetFloat(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetFloat(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Set a byte slice value in the cache
func (h _cacheService) _SetBytes(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SetBytesRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SetBytes(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Get a byte slice value from the cache
func (h _cacheService) _GetBytes(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetBytes(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Remove a value from the cache
func (h _cacheService) _Remove(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(RemoveRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Remove(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Check if a key exists in the cache
func (h _cacheService) _Has(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HasRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Has(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

251
plugins/host/cache/cache_plugin.pb.go vendored Normal file
View File

@@ -0,0 +1,251 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/cache/cache.proto
package cache
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type cacheService struct{}
func NewCacheService() CacheService {
return cacheService{}
}
//go:wasmimport env set_string
func _set_string(ptr uint32, size uint32) uint64
func (h cacheService) SetString(ctx context.Context, request *SetStringRequest) (*SetResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _set_string(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SetResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_string
func _get_string(ptr uint32, size uint32) uint64
func (h cacheService) GetString(ctx context.Context, request *GetRequest) (*GetStringResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_string(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetStringResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env set_int
func _set_int(ptr uint32, size uint32) uint64
func (h cacheService) SetInt(ctx context.Context, request *SetIntRequest) (*SetResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _set_int(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SetResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_int
func _get_int(ptr uint32, size uint32) uint64
func (h cacheService) GetInt(ctx context.Context, request *GetRequest) (*GetIntResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_int(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetIntResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env set_float
func _set_float(ptr uint32, size uint32) uint64
func (h cacheService) SetFloat(ctx context.Context, request *SetFloatRequest) (*SetResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _set_float(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SetResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_float
func _get_float(ptr uint32, size uint32) uint64
func (h cacheService) GetFloat(ctx context.Context, request *GetRequest) (*GetFloatResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_float(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetFloatResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env set_bytes
func _set_bytes(ptr uint32, size uint32) uint64
func (h cacheService) SetBytes(ctx context.Context, request *SetBytesRequest) (*SetResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _set_bytes(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SetResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env get_bytes
func _get_bytes(ptr uint32, size uint32) uint64
func (h cacheService) GetBytes(ctx context.Context, request *GetRequest) (*GetBytesResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_bytes(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetBytesResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env remove
func _remove(ptr uint32, size uint32) uint64
func (h cacheService) Remove(ctx context.Context, request *RemoveRequest) (*RemoveResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _remove(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(RemoveResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env has
func _has(ptr uint32, size uint32) uint64
func (h cacheService) Has(ctx context.Context, request *HasRequest) (*HasResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _has(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HasResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package cache
func NewCacheService() CacheService {
panic("not implemented")
}

2352
plugins/host/cache/cache_vtproto.pb.go vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/config/config.proto
package config
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetPluginConfigRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetPluginConfigRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
type GetPluginConfigResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Config map[string]string `protobuf:"bytes,1,rep,name=config,proto3" json:"config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *GetPluginConfigResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *GetPluginConfigResponse) GetConfig() map[string]string {
if x != nil {
return x.Config
}
return nil
}
// go:plugin type=host version=1
type ConfigService interface {
GetPluginConfig(context.Context, *GetPluginConfigRequest) (*GetPluginConfigResponse, error)
}

View File

@@ -0,0 +1,18 @@
syntax = "proto3";
package config;
option go_package = "github.com/navidrome/navidrome/plugins/host/config;config";
// go:plugin type=host version=1
service ConfigService {
rpc GetPluginConfig(GetPluginConfigRequest) returns (GetPluginConfigResponse);
}
message GetPluginConfigRequest {
// No fields needed; plugin name is inferred from context
}
message GetPluginConfigResponse {
map<string, string> config = 1;
}

View File

@@ -0,0 +1,66 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/config/config.proto
package config
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _configService struct {
ConfigService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions ConfigService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _configService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._GetPluginConfig), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get_plugin_config")
_, err := envBuilder.Instantiate(ctx)
return err
}
func (h _configService) _GetPluginConfig(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(GetPluginConfigRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.GetPluginConfig(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,44 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/config/config.proto
package config
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type configService struct{}
func NewConfigService() ConfigService {
return configService{}
}
//go:wasmimport env get_plugin_config
func _get_plugin_config(ptr uint32, size uint32) uint64
func (h configService) GetPluginConfig(ctx context.Context, request *GetPluginConfigRequest) (*GetPluginConfigResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get_plugin_config(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(GetPluginConfigResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package config
func NewConfigService() ConfigService {
panic("not implemented")
}

View File

@@ -0,0 +1,466 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/config/config.proto
package config
import (
fmt "fmt"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
bits "math/bits"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
func (m *GetPluginConfigRequest) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GetPluginConfigRequest) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *GetPluginConfigRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
return len(dAtA) - i, nil
}
func (m *GetPluginConfigResponse) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GetPluginConfigResponse) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *GetPluginConfigResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Config) > 0 {
for k := range m.Config {
v := m.Config[k]
baseI := i
i -= len(v)
copy(dAtA[i:], v)
i = encodeVarint(dAtA, i, uint64(len(v)))
i--
dAtA[i] = 0x12
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarint(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarint(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarint(dAtA []byte, offset int, v uint64) int {
offset -= sov(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GetPluginConfigRequest) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
n += len(m.unknownFields)
return n
}
func (m *GetPluginConfigResponse) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Config) > 0 {
for k, v := range m.Config {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v)))
n += mapEntrySize + 1 + sov(uint64(mapEntrySize))
}
}
n += len(m.unknownFields)
return n
}
func sov(x uint64) (n int) {
return (bits.Len64(x|1) + 6) / 7
}
func soz(x uint64) (n int) {
return sov(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GetPluginConfigRequest) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GetPluginConfigRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GetPluginConfigRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GetPluginConfigResponse) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GetPluginConfigResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GetPluginConfigResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Config == nil {
m.Config = make(map[string]string)
}
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLength
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLength
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLength
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue < 0 {
return ErrInvalidLength
}
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Config[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skip(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLength
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLength
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflow = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,117 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/http/http.proto
package http
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type HttpRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
TimeoutMs int32 `protobuf:"varint,3,opt,name=timeout_ms,json=timeoutMs,proto3" json:"timeout_ms,omitempty"`
Body []byte `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"` // Ignored for GET/DELETE/HEAD/OPTIONS
}
func (x *HttpRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *HttpRequest) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *HttpRequest) GetHeaders() map[string]string {
if x != nil {
return x.Headers
}
return nil
}
func (x *HttpRequest) GetTimeoutMs() int32 {
if x != nil {
return x.TimeoutMs
}
return 0
}
func (x *HttpRequest) GetBody() []byte {
if x != nil {
return x.Body
}
return nil
}
type HttpResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` // Non-empty if network/protocol error
}
func (x *HttpResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *HttpResponse) GetStatus() int32 {
if x != nil {
return x.Status
}
return 0
}
func (x *HttpResponse) GetBody() []byte {
if x != nil {
return x.Body
}
return nil
}
func (x *HttpResponse) GetHeaders() map[string]string {
if x != nil {
return x.Headers
}
return nil
}
func (x *HttpResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
// go:plugin type=host version=1
type HttpService interface {
Get(context.Context, *HttpRequest) (*HttpResponse, error)
Post(context.Context, *HttpRequest) (*HttpResponse, error)
Put(context.Context, *HttpRequest) (*HttpResponse, error)
Delete(context.Context, *HttpRequest) (*HttpResponse, error)
Patch(context.Context, *HttpRequest) (*HttpResponse, error)
Head(context.Context, *HttpRequest) (*HttpResponse, error)
Options(context.Context, *HttpRequest) (*HttpResponse, error)
}

View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package http;
option go_package = "github.com/navidrome/navidrome/plugins/host/http;http";
// go:plugin type=host version=1
service HttpService {
rpc Get(HttpRequest) returns (HttpResponse);
rpc Post(HttpRequest) returns (HttpResponse);
rpc Put(HttpRequest) returns (HttpResponse);
rpc Delete(HttpRequest) returns (HttpResponse);
rpc Patch(HttpRequest) returns (HttpResponse);
rpc Head(HttpRequest) returns (HttpResponse);
rpc Options(HttpRequest) returns (HttpResponse);
}
message HttpRequest {
string url = 1;
map<string, string> headers = 2;
int32 timeout_ms = 3;
bytes body = 4; // Ignored for GET/DELETE/HEAD/OPTIONS
}
message HttpResponse {
int32 status = 1;
bytes body = 2;
map<string, string> headers = 3;
string error = 4; // Non-empty if network/protocol error
}

View File

@@ -0,0 +1,258 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/http/http.proto
package http
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _httpService struct {
HttpService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions HttpService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _httpService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Get), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("get")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Post), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("post")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Put), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("put")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Delete), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("delete")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Patch), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("patch")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Head), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("head")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Options), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("options")
_, err := envBuilder.Instantiate(ctx)
return err
}
func (h _httpService) _Get(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Get(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Post(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Post(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Put(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Put(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Delete(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Delete(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Patch(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Patch(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Head(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Head(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
func (h _httpService) _Options(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(HttpRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Options(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,182 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/http/http.proto
package http
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type httpService struct{}
func NewHttpService() HttpService {
return httpService{}
}
//go:wasmimport env get
func _get(ptr uint32, size uint32) uint64
func (h httpService) Get(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _get(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env post
func _post(ptr uint32, size uint32) uint64
func (h httpService) Post(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _post(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env put
func _put(ptr uint32, size uint32) uint64
func (h httpService) Put(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _put(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env delete
func _delete(ptr uint32, size uint32) uint64
func (h httpService) Delete(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _delete(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env patch
func _patch(ptr uint32, size uint32) uint64
func (h httpService) Patch(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _patch(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env head
func _head(ptr uint32, size uint32) uint64
func (h httpService) Head(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _head(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env options
func _options(ptr uint32, size uint32) uint64
func (h httpService) Options(ctx context.Context, request *HttpRequest) (*HttpResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _options(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(HttpResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package http
func NewHttpService() HttpService {
panic("not implemented")
}

View File

@@ -0,0 +1,850 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/http/http.proto
package http
import (
fmt "fmt"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
bits "math/bits"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
func (m *HttpRequest) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *HttpRequest) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *HttpRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Body) > 0 {
i -= len(m.Body)
copy(dAtA[i:], m.Body)
i = encodeVarint(dAtA, i, uint64(len(m.Body)))
i--
dAtA[i] = 0x22
}
if m.TimeoutMs != 0 {
i = encodeVarint(dAtA, i, uint64(m.TimeoutMs))
i--
dAtA[i] = 0x18
}
if len(m.Headers) > 0 {
for k := range m.Headers {
v := m.Headers[k]
baseI := i
i -= len(v)
copy(dAtA[i:], v)
i = encodeVarint(dAtA, i, uint64(len(v)))
i--
dAtA[i] = 0x12
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarint(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarint(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x12
}
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarint(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *HttpResponse) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *HttpResponse) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *HttpResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Error) > 0 {
i -= len(m.Error)
copy(dAtA[i:], m.Error)
i = encodeVarint(dAtA, i, uint64(len(m.Error)))
i--
dAtA[i] = 0x22
}
if len(m.Headers) > 0 {
for k := range m.Headers {
v := m.Headers[k]
baseI := i
i -= len(v)
copy(dAtA[i:], v)
i = encodeVarint(dAtA, i, uint64(len(v)))
i--
dAtA[i] = 0x12
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarint(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarint(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0x1a
}
}
if len(m.Body) > 0 {
i -= len(m.Body)
copy(dAtA[i:], m.Body)
i = encodeVarint(dAtA, i, uint64(len(m.Body)))
i--
dAtA[i] = 0x12
}
if m.Status != 0 {
i = encodeVarint(dAtA, i, uint64(m.Status))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarint(dAtA []byte, offset int, v uint64) int {
offset -= sov(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *HttpRequest) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Url)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
if len(m.Headers) > 0 {
for k, v := range m.Headers {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v)))
n += mapEntrySize + 1 + sov(uint64(mapEntrySize))
}
}
if m.TimeoutMs != 0 {
n += 1 + sov(uint64(m.TimeoutMs))
}
l = len(m.Body)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func (m *HttpResponse) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Status != 0 {
n += 1 + sov(uint64(m.Status))
}
l = len(m.Body)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
if len(m.Headers) > 0 {
for k, v := range m.Headers {
_ = k
_ = v
mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v)))
n += mapEntrySize + 1 + sov(uint64(mapEntrySize))
}
}
l = len(m.Error)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func sov(x uint64) (n int) {
return (bits.Len64(x|1) + 6) / 7
}
func soz(x uint64) (n int) {
return sov(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *HttpRequest) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: HttpRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: HttpRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Headers == nil {
m.Headers = make(map[string]string)
}
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLength
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLength
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLength
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue < 0 {
return ErrInvalidLength
}
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Headers[mapkey] = mapvalue
iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field TimeoutMs", wireType)
}
m.TimeoutMs = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.TimeoutMs |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Body = append(m.Body[:0], dAtA[iNdEx:postIndex]...)
if m.Body == nil {
m.Body = []byte{}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *HttpResponse) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: HttpResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: HttpResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType)
}
m.Status = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Status |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Body", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Body = append(m.Body[:0], dAtA[iNdEx:postIndex]...)
if m.Body == nil {
m.Body = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Headers == nil {
m.Headers = make(map[string]string)
}
var mapkey string
var mapvalue string
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLength
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLength
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var stringLenmapvalue uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapvalue |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapvalue := int(stringLenmapvalue)
if intStringLenmapvalue < 0 {
return ErrInvalidLength
}
postStringIndexmapvalue := iNdEx + intStringLenmapvalue
if postStringIndexmapvalue < 0 {
return ErrInvalidLength
}
if postStringIndexmapvalue > l {
return io.ErrUnexpectedEOF
}
mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
iNdEx = postStringIndexmapvalue
} else {
iNdEx = entryPreIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Headers[mapkey] = mapvalue
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skip(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLength
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLength
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflow = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,212 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/scheduler/scheduler.proto
package scheduler
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ScheduleOneTimeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
DelaySeconds int32 `protobuf:"varint,1,opt,name=delay_seconds,json=delaySeconds,proto3" json:"delay_seconds,omitempty"` // Delay in seconds
Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` // Serialized data to pass to the callback
ScheduleId string `protobuf:"bytes,3,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` // Optional custom ID (if not provided, one will be generated)
}
func (x *ScheduleOneTimeRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *ScheduleOneTimeRequest) GetDelaySeconds() int32 {
if x != nil {
return x.DelaySeconds
}
return 0
}
func (x *ScheduleOneTimeRequest) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
func (x *ScheduleOneTimeRequest) GetScheduleId() string {
if x != nil {
return x.ScheduleId
}
return ""
}
type ScheduleRecurringRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
CronExpression string `protobuf:"bytes,1,opt,name=cron_expression,json=cronExpression,proto3" json:"cron_expression,omitempty"` // Cron expression (e.g. "0 0 * * *" for daily at midnight)
Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` // Serialized data to pass to the callback
ScheduleId string `protobuf:"bytes,3,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` // Optional custom ID (if not provided, one will be generated)
}
func (x *ScheduleRecurringRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *ScheduleRecurringRequest) GetCronExpression() string {
if x != nil {
return x.CronExpression
}
return ""
}
func (x *ScheduleRecurringRequest) GetPayload() []byte {
if x != nil {
return x.Payload
}
return nil
}
func (x *ScheduleRecurringRequest) GetScheduleId() string {
if x != nil {
return x.ScheduleId
}
return ""
}
type ScheduleResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ScheduleId string `protobuf:"bytes,1,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` // ID to reference this scheduled job
}
func (x *ScheduleResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *ScheduleResponse) GetScheduleId() string {
if x != nil {
return x.ScheduleId
}
return ""
}
type CancelRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ScheduleId string `protobuf:"bytes,1,opt,name=schedule_id,json=scheduleId,proto3" json:"schedule_id,omitempty"` // ID of the schedule to cancel
}
func (x *CancelRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CancelRequest) GetScheduleId() string {
if x != nil {
return x.ScheduleId
}
return ""
}
type CancelResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` // Whether cancellation was successful
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` // Error message if cancellation failed
}
func (x *CancelResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CancelResponse) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *CancelResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
type TimeNowRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *TimeNowRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
type TimeNowResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Rfc3339Nano string `protobuf:"bytes,1,opt,name=rfc3339_nano,json=rfc3339Nano,proto3" json:"rfc3339_nano,omitempty"` // Current time in RFC3339Nano format
UnixMilli int64 `protobuf:"varint,2,opt,name=unix_milli,json=unixMilli,proto3" json:"unix_milli,omitempty"` // Current time as Unix milliseconds timestamp
LocalTimeZone string `protobuf:"bytes,3,opt,name=local_time_zone,json=localTimeZone,proto3" json:"local_time_zone,omitempty"` // Local timezone name (e.g., "America/New_York", "UTC")
}
func (x *TimeNowResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *TimeNowResponse) GetRfc3339Nano() string {
if x != nil {
return x.Rfc3339Nano
}
return ""
}
func (x *TimeNowResponse) GetUnixMilli() int64 {
if x != nil {
return x.UnixMilli
}
return 0
}
func (x *TimeNowResponse) GetLocalTimeZone() string {
if x != nil {
return x.LocalTimeZone
}
return ""
}
// go:plugin type=host version=1
type SchedulerService interface {
// One-time event scheduling
ScheduleOneTime(context.Context, *ScheduleOneTimeRequest) (*ScheduleResponse, error)
// Recurring event scheduling
ScheduleRecurring(context.Context, *ScheduleRecurringRequest) (*ScheduleResponse, error)
// Cancel any scheduled job
CancelSchedule(context.Context, *CancelRequest) (*CancelResponse, error)
// Get current time in multiple formats
TimeNow(context.Context, *TimeNowRequest) (*TimeNowResponse, error)
}

View File

@@ -0,0 +1,55 @@
syntax = "proto3";
package scheduler;
option go_package = "github.com/navidrome/navidrome/plugins/host/scheduler;scheduler";
// go:plugin type=host version=1
service SchedulerService {
// One-time event scheduling
rpc ScheduleOneTime(ScheduleOneTimeRequest) returns (ScheduleResponse);
// Recurring event scheduling
rpc ScheduleRecurring(ScheduleRecurringRequest) returns (ScheduleResponse);
// Cancel any scheduled job
rpc CancelSchedule(CancelRequest) returns (CancelResponse);
// Get current time in multiple formats
rpc TimeNow(TimeNowRequest) returns (TimeNowResponse);
}
message ScheduleOneTimeRequest {
int32 delay_seconds = 1; // Delay in seconds
bytes payload = 2; // Serialized data to pass to the callback
string schedule_id = 3; // Optional custom ID (if not provided, one will be generated)
}
message ScheduleRecurringRequest {
string cron_expression = 1; // Cron expression (e.g. "0 0 * * *" for daily at midnight)
bytes payload = 2; // Serialized data to pass to the callback
string schedule_id = 3; // Optional custom ID (if not provided, one will be generated)
}
message ScheduleResponse {
string schedule_id = 1; // ID to reference this scheduled job
}
message CancelRequest {
string schedule_id = 1; // ID of the schedule to cancel
}
message CancelResponse {
bool success = 1; // Whether cancellation was successful
string error = 2; // Error message if cancellation failed
}
message TimeNowRequest {
// Empty request - no parameters needed
}
message TimeNowResponse {
string rfc3339_nano = 1; // Current time in RFC3339Nano format
int64 unix_milli = 2; // Current time as Unix milliseconds timestamp
string local_time_zone = 3; // Local timezone name (e.g., "America/New_York", "UTC")
}

View File

@@ -0,0 +1,170 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/scheduler/scheduler.proto
package scheduler
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _schedulerService struct {
SchedulerService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions SchedulerService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _schedulerService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._ScheduleOneTime), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("schedule_one_time")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._ScheduleRecurring), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("schedule_recurring")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._CancelSchedule), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("cancel_schedule")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._TimeNow), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("time_now")
_, err := envBuilder.Instantiate(ctx)
return err
}
// One-time event scheduling
func (h _schedulerService) _ScheduleOneTime(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(ScheduleOneTimeRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.ScheduleOneTime(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Recurring event scheduling
func (h _schedulerService) _ScheduleRecurring(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(ScheduleRecurringRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.ScheduleRecurring(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Cancel any scheduled job
func (h _schedulerService) _CancelSchedule(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(CancelRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.CancelSchedule(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Get current time in multiple formats
func (h _schedulerService) _TimeNow(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(TimeNowRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.TimeNow(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,113 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/scheduler/scheduler.proto
package scheduler
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type schedulerService struct{}
func NewSchedulerService() SchedulerService {
return schedulerService{}
}
//go:wasmimport env schedule_one_time
func _schedule_one_time(ptr uint32, size uint32) uint64
func (h schedulerService) ScheduleOneTime(ctx context.Context, request *ScheduleOneTimeRequest) (*ScheduleResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _schedule_one_time(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(ScheduleResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env schedule_recurring
func _schedule_recurring(ptr uint32, size uint32) uint64
func (h schedulerService) ScheduleRecurring(ctx context.Context, request *ScheduleRecurringRequest) (*ScheduleResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _schedule_recurring(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(ScheduleResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env cancel_schedule
func _cancel_schedule(ptr uint32, size uint32) uint64
func (h schedulerService) CancelSchedule(ctx context.Context, request *CancelRequest) (*CancelResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _cancel_schedule(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(CancelResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env time_now
func _time_now(ptr uint32, size uint32) uint64
func (h schedulerService) TimeNow(ctx context.Context, request *TimeNowRequest) (*TimeNowResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _time_now(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(TimeNowResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package scheduler
func NewSchedulerService() SchedulerService {
panic("not implemented")
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/subsonicapi/subsonicapi.proto
package subsonicapi
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CallRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
}
func (x *CallRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CallRequest) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
type CallResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Json string `protobuf:"bytes,1,opt,name=json,proto3" json:"json,omitempty"`
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` // Non-empty if operation failed
}
func (x *CallResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CallResponse) GetJson() string {
if x != nil {
return x.Json
}
return ""
}
func (x *CallResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
// go:plugin type=host version=1
type SubsonicAPIService interface {
Call(context.Context, *CallRequest) (*CallResponse, error)
}

View File

@@ -0,0 +1,19 @@
syntax = "proto3";
package subsonicapi;
option go_package = "github.com/navidrome/navidrome/plugins/host/subsonicapi;subsonicapi";
// go:plugin type=host version=1
service SubsonicAPIService {
rpc Call(CallRequest) returns (CallResponse);
}
message CallRequest {
string url = 1;
}
message CallResponse {
string json = 1;
string error = 2; // Non-empty if operation failed
}

View File

@@ -0,0 +1,66 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/subsonicapi/subsonicapi.proto
package subsonicapi
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _subsonicAPIService struct {
SubsonicAPIService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions SubsonicAPIService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _subsonicAPIService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Call), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("call")
_, err := envBuilder.Instantiate(ctx)
return err
}
func (h _subsonicAPIService) _Call(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(CallRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Call(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,44 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/subsonicapi/subsonicapi.proto
package subsonicapi
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type subsonicAPIService struct{}
func NewSubsonicAPIService() SubsonicAPIService {
return subsonicAPIService{}
}
//go:wasmimport env call
func _call(ptr uint32, size uint32) uint64
func (h subsonicAPIService) Call(ctx context.Context, request *CallRequest) (*CallResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _call(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(CallResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,441 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/subsonicapi/subsonicapi.proto
package subsonicapi
import (
fmt "fmt"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
bits "math/bits"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
func (m *CallRequest) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CallRequest) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *CallRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarint(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *CallResponse) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
}
size := m.SizeVT()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CallResponse) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *CallResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
if m == nil {
return 0, nil
}
i := len(dAtA)
_ = i
var l int
_ = l
if m.unknownFields != nil {
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if len(m.Error) > 0 {
i -= len(m.Error)
copy(dAtA[i:], m.Error)
i = encodeVarint(dAtA, i, uint64(len(m.Error)))
i--
dAtA[i] = 0x12
}
if len(m.Json) > 0 {
i -= len(m.Json)
copy(dAtA[i:], m.Json)
i = encodeVarint(dAtA, i, uint64(len(m.Json)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarint(dAtA []byte, offset int, v uint64) int {
offset -= sov(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *CallRequest) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Url)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func (m *CallResponse) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Json)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
l = len(m.Error)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func sov(x uint64) (n int) {
return (bits.Len64(x|1) + 6) / 7
}
func soz(x uint64) (n int) {
return sov(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *CallRequest) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CallRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CallRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *CallResponse) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CallResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CallResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Json", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Json = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLength
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skip(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflow
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLength
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroup
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLength
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflow = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,240 @@
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/websocket/websocket.proto
package websocket
import (
context "context"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ConnectRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
ConnectionId string `protobuf:"bytes,3,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
}
func (x *ConnectRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *ConnectRequest) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *ConnectRequest) GetHeaders() map[string]string {
if x != nil {
return x.Headers
}
return nil
}
func (x *ConnectRequest) GetConnectionId() string {
if x != nil {
return x.ConnectionId
}
return ""
}
type ConnectResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *ConnectResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *ConnectResponse) GetConnectionId() string {
if x != nil {
return x.ConnectionId
}
return ""
}
func (x *ConnectResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
type SendTextRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *SendTextRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SendTextRequest) GetConnectionId() string {
if x != nil {
return x.ConnectionId
}
return ""
}
func (x *SendTextRequest) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
type SendTextResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *SendTextResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SendTextResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
type SendBinaryRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *SendBinaryRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SendBinaryRequest) GetConnectionId() string {
if x != nil {
return x.ConnectionId
}
return ""
}
func (x *SendBinaryRequest) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
type SendBinaryResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *SendBinaryResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *SendBinaryResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
type CloseRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty"`
Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"`
}
func (x *CloseRequest) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CloseRequest) GetConnectionId() string {
if x != nil {
return x.ConnectionId
}
return ""
}
func (x *CloseRequest) GetCode() int32 {
if x != nil {
return x.Code
}
return 0
}
func (x *CloseRequest) GetReason() string {
if x != nil {
return x.Reason
}
return ""
}
type CloseResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *CloseResponse) ProtoReflect() protoreflect.Message {
panic(`not implemented`)
}
func (x *CloseResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
// go:plugin type=host version=1
type WebSocketService interface {
// Connect to a WebSocket endpoint
Connect(context.Context, *ConnectRequest) (*ConnectResponse, error)
// Send a text message
SendText(context.Context, *SendTextRequest) (*SendTextResponse, error)
// Send binary data
SendBinary(context.Context, *SendBinaryRequest) (*SendBinaryResponse, error)
// Close a connection
Close(context.Context, *CloseRequest) (*CloseResponse, error)
}

View File

@@ -0,0 +1,57 @@
syntax = "proto3";
package websocket;
option go_package = "github.com/navidrome/navidrome/plugins/host/websocket";
// go:plugin type=host version=1
service WebSocketService {
// Connect to a WebSocket endpoint
rpc Connect(ConnectRequest) returns (ConnectResponse);
// Send a text message
rpc SendText(SendTextRequest) returns (SendTextResponse);
// Send binary data
rpc SendBinary(SendBinaryRequest) returns (SendBinaryResponse);
// Close a connection
rpc Close(CloseRequest) returns (CloseResponse);
}
message ConnectRequest {
string url = 1;
map<string, string> headers = 2;
string connection_id = 3;
}
message ConnectResponse {
string connection_id = 1;
string error = 2;
}
message SendTextRequest {
string connection_id = 1;
string message = 2;
}
message SendTextResponse {
string error = 1;
}
message SendBinaryRequest {
string connection_id = 1;
bytes data = 2;
}
message SendBinaryResponse {
string error = 1;
}
message CloseRequest {
string connection_id = 1;
int32 code = 2;
string reason = 3;
}
message CloseResponse {
string error = 1;
}

View File

@@ -0,0 +1,170 @@
//go:build !wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/websocket/websocket.proto
package websocket
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
wazero "github.com/tetratelabs/wazero"
api "github.com/tetratelabs/wazero/api"
)
const (
i32 = api.ValueTypeI32
i64 = api.ValueTypeI64
)
type _webSocketService struct {
WebSocketService
}
// Instantiate a Go-defined module named "env" that exports host functions.
func Instantiate(ctx context.Context, r wazero.Runtime, hostFunctions WebSocketService) error {
envBuilder := r.NewHostModuleBuilder("env")
h := _webSocketService{hostFunctions}
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Connect), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("connect")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SendText), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("send_text")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._SendBinary), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("send_binary")
envBuilder.NewFunctionBuilder().
WithGoModuleFunction(api.GoModuleFunc(h._Close), []api.ValueType{i32, i32}, []api.ValueType{i64}).
WithParameterNames("offset", "size").
Export("close")
_, err := envBuilder.Instantiate(ctx)
return err
}
// Connect to a WebSocket endpoint
func (h _webSocketService) _Connect(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(ConnectRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Connect(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Send a text message
func (h _webSocketService) _SendText(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SendTextRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SendText(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Send binary data
func (h _webSocketService) _SendBinary(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(SendBinaryRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.SendBinary(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}
// Close a connection
func (h _webSocketService) _Close(ctx context.Context, m api.Module, stack []uint64) {
offset, size := uint32(stack[0]), uint32(stack[1])
buf, err := wasm.ReadMemory(m.Memory(), offset, size)
if err != nil {
panic(err)
}
request := new(CloseRequest)
err = request.UnmarshalVT(buf)
if err != nil {
panic(err)
}
resp, err := h.Close(ctx, request)
if err != nil {
panic(err)
}
buf, err = resp.MarshalVT()
if err != nil {
panic(err)
}
ptr, err := wasm.WriteMemory(ctx, m, buf)
if err != nil {
panic(err)
}
ptrLen := (ptr << uint64(32)) | uint64(len(buf))
stack[0] = ptrLen
}

View File

@@ -0,0 +1,113 @@
//go:build wasip1
// Code generated by protoc-gen-go-plugin. DO NOT EDIT.
// versions:
// protoc-gen-go-plugin v0.1.0
// protoc v5.29.3
// source: host/websocket/websocket.proto
package websocket
import (
context "context"
wasm "github.com/knqyf263/go-plugin/wasm"
_ "unsafe"
)
type webSocketService struct{}
func NewWebSocketService() WebSocketService {
return webSocketService{}
}
//go:wasmimport env connect
func _connect(ptr uint32, size uint32) uint64
func (h webSocketService) Connect(ctx context.Context, request *ConnectRequest) (*ConnectResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _connect(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(ConnectResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env send_text
func _send_text(ptr uint32, size uint32) uint64
func (h webSocketService) SendText(ctx context.Context, request *SendTextRequest) (*SendTextResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _send_text(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SendTextResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env send_binary
func _send_binary(ptr uint32, size uint32) uint64
func (h webSocketService) SendBinary(ctx context.Context, request *SendBinaryRequest) (*SendBinaryResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _send_binary(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(SendBinaryResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}
//go:wasmimport env close
func _close(ptr uint32, size uint32) uint64
func (h webSocketService) Close(ctx context.Context, request *CloseRequest) (*CloseResponse, error) {
buf, err := request.MarshalVT()
if err != nil {
return nil, err
}
ptr, size := wasm.ByteToPtr(buf)
ptrSize := _close(ptr, size)
wasm.Free(ptr)
ptr = uint32(ptrSize >> 32)
size = uint32(ptrSize)
buf = wasm.PtrToByte(ptr, size)
response := new(CloseResponse)
if err = response.UnmarshalVT(buf); err != nil {
return nil, err
}
return response, nil
}

View File

@@ -0,0 +1,7 @@
//go:build !wasip1
package websocket
func NewWebSocketService() WebSocketService {
panic("not implemented")
}

File diff suppressed because it is too large Load Diff