Skip to content

Commit b92c454

Browse files
authored
Merge pull request #20 from omniviewdev/fix/runtime-types
fix(types): runtime types passing as number[][] instead of any due to json optimization
2 parents 2cd1ace + f8042aa commit b92c454

10 files changed

Lines changed: 263 additions & 162 deletions

File tree

backend/pkg/plugin/resource/client.go

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ import (
77
"github.com/omniviewdev/plugin-sdk/pkg/types"
88
)
99

10-
// Client is a thin wrapper that exposes only the Service interface for Wails binding.
11-
// The controller has lifecycle methods (OnPluginStart, etc.) that must not be exposed
12-
// to the frontend — this is a Wails constraint, not a design choice.
10+
// NOTE: Client intentionally does NOT implement Service. It is the Wails-bound
11+
// frontend API layer that converts between SDK types (json.RawMessage) and
12+
// frontend-friendly types (interface{} → "any" in TypeScript).
13+
14+
// Client is a thin Wails-bound wrapper around the Controller.
15+
// It converts SDK types (json.RawMessage) to frontend-friendly types (interface{})
16+
// so that Wails generates "any" in TypeScript instead of "number[]".
1317
type Client struct {
1418
controller Controller
1519
}
@@ -18,37 +22,69 @@ func NewClient(controller Controller) *Client {
1822
return &Client{controller: controller}
1923
}
2024

21-
// compile-time assertion
22-
var _ Service = (*Client)(nil)
25+
// Client no longer satisfies Service — it uses frontend-facing types
26+
// (interface{} instead of json.RawMessage) so Wails generates correct TS.
2327

2428
func (c *Client) ListPlugins() ([]string, error) {
2529
return c.controller.ListPlugins()
2630
}
2731

28-
// CRUD
32+
// CRUD — converts between SDK types and frontend-facing types
2933

30-
func (c *Client) Get(pluginID, connectionID, key string, input resource.GetInput) (*resource.GetResult, error) {
31-
return c.controller.Get(pluginID, connectionID, key, input)
34+
func (c *Client) Get(pluginID, connectionID, key string, input resource.GetInput) (*ClientResult, error) {
35+
result, err := c.controller.Get(pluginID, connectionID, key, input)
36+
if err != nil {
37+
return nil, err
38+
}
39+
return toClientResult(result), nil
3240
}
3341

34-
func (c *Client) List(pluginID, connectionID, key string, input resource.ListInput) (*resource.ListResult, error) {
35-
return c.controller.List(pluginID, connectionID, key, input)
42+
func (c *Client) List(pluginID, connectionID, key string, input resource.ListInput) (*ClientListResult, error) {
43+
result, err := c.controller.List(pluginID, connectionID, key, input)
44+
if err != nil {
45+
return nil, err
46+
}
47+
return toClientListResult(result), nil
3648
}
3749

38-
func (c *Client) Find(pluginID, connectionID, key string, input resource.FindInput) (*resource.FindResult, error) {
39-
return c.controller.Find(pluginID, connectionID, key, input)
50+
func (c *Client) Find(pluginID, connectionID, key string, input resource.FindInput) (*ClientListResult, error) {
51+
result, err := c.controller.Find(pluginID, connectionID, key, input)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return findToClientListResult(result), nil
4056
}
4157

42-
func (c *Client) Create(pluginID, connectionID, key string, input resource.CreateInput) (*resource.CreateResult, error) {
43-
return c.controller.Create(pluginID, connectionID, key, input)
58+
func (c *Client) Create(pluginID, connectionID, key string, input ClientCreateInput) (*ClientResult, error) {
59+
sdkInput, err := toSDKCreateInput(input)
60+
if err != nil {
61+
return nil, err
62+
}
63+
result, err := c.controller.Create(pluginID, connectionID, key, sdkInput)
64+
if err != nil {
65+
return nil, err
66+
}
67+
return createToClientResult(result), nil
4468
}
4569

46-
func (c *Client) Update(pluginID, connectionID, key string, input resource.UpdateInput) (*resource.UpdateResult, error) {
47-
return c.controller.Update(pluginID, connectionID, key, input)
70+
func (c *Client) Update(pluginID, connectionID, key string, input ClientUpdateInput) (*ClientResult, error) {
71+
sdkInput, err := toSDKUpdateInput(input)
72+
if err != nil {
73+
return nil, err
74+
}
75+
result, err := c.controller.Update(pluginID, connectionID, key, sdkInput)
76+
if err != nil {
77+
return nil, err
78+
}
79+
return updateToClientResult(result), nil
4880
}
4981

50-
func (c *Client) Delete(pluginID, connectionID, key string, input resource.DeleteInput) (*resource.DeleteResult, error) {
51-
return c.controller.Delete(pluginID, connectionID, key, input)
82+
func (c *Client) Delete(pluginID, connectionID, key string, input resource.DeleteInput) (*ClientResult, error) {
83+
result, err := c.controller.Delete(pluginID, connectionID, key, input)
84+
if err != nil {
85+
return nil, err
86+
}
87+
return deleteToClientResult(result), nil
5288
}
5389

5490
// Connection lifecycle
@@ -171,8 +207,12 @@ func (c *Client) GetFilterFields(pluginID, connectionID, key string) ([]resource
171207
return c.controller.GetFilterFields(pluginID, connectionID, key)
172208
}
173209

174-
func (c *Client) GetResourceSchema(pluginID, connectionID, key string) (json.RawMessage, error) {
175-
return c.controller.GetResourceSchema(pluginID, connectionID, key)
210+
func (c *Client) GetResourceSchema(pluginID, connectionID, key string) (interface{}, error) {
211+
raw, err := c.controller.GetResourceSchema(pluginID, connectionID, key)
212+
if err != nil {
213+
return nil, err
214+
}
215+
return interface{}(raw), nil
176216
}
177217

178218
// Actions
@@ -207,8 +247,12 @@ func (c *Client) ResolveRelationships(pluginID, connectionID, key, id, namespace
207247

208248
// Health
209249

210-
func (c *Client) GetHealth(pluginID, connectionID, key string, data json.RawMessage) (*resource.ResourceHealth, error) {
211-
return c.controller.GetHealth(pluginID, connectionID, key, data)
250+
func (c *Client) GetHealth(pluginID, connectionID, key string, data interface{}) (*resource.ResourceHealth, error) {
251+
raw, err := json.Marshal(data)
252+
if err != nil {
253+
return nil, err
254+
}
255+
return c.controller.GetHealth(pluginID, connectionID, key, json.RawMessage(raw))
212256
}
213257

214258
func (c *Client) GetResourceEvents(pluginID, connectionID, key, id, namespace string, limit int32) ([]resource.ResourceEvent, error) {
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package resource
2+
3+
import (
4+
"encoding/json"
5+
6+
resource "github.com/omniviewdev/plugin-sdk/pkg/v1/resource"
7+
)
8+
9+
// --- Result types (SDK → frontend) ---
10+
// These replace json.RawMessage fields with interface{} so Wails generates
11+
// "any" in TypeScript instead of "number[]".
12+
13+
// ClientResult wraps a single-resource SDK result for the frontend.
14+
type ClientResult struct {
15+
Result interface{} `json:"result"`
16+
Success bool `json:"success"`
17+
}
18+
19+
// ClientListResult wraps a multi-resource SDK result for the frontend.
20+
type ClientListResult struct {
21+
Result []interface{} `json:"result"`
22+
Success bool `json:"success"`
23+
TotalCount int `json:"totalCount"`
24+
NextCursor string `json:"nextCursor,omitempty"`
25+
}
26+
27+
// --- Input types (frontend → SDK) ---
28+
29+
// ClientCreateInput accepts interface{} from the frontend instead of json.RawMessage.
30+
type ClientCreateInput struct {
31+
Input interface{} `json:"input"`
32+
Namespace string `json:"namespace"`
33+
}
34+
35+
// ClientUpdateInput accepts interface{} from the frontend instead of json.RawMessage.
36+
type ClientUpdateInput struct {
37+
Input interface{} `json:"input"`
38+
ID string `json:"id"`
39+
Namespace string `json:"namespace"`
40+
}
41+
42+
// --- Converters: zero-copy for results, one marshal for inputs ---
43+
44+
func toClientResult(r *resource.GetResult) *ClientResult {
45+
if r == nil {
46+
return nil
47+
}
48+
return &ClientResult{Result: r.Result, Success: r.Success}
49+
}
50+
51+
func createToClientResult(r *resource.CreateResult) *ClientResult {
52+
if r == nil {
53+
return nil
54+
}
55+
return &ClientResult{Result: r.Result, Success: r.Success}
56+
}
57+
58+
func updateToClientResult(r *resource.UpdateResult) *ClientResult {
59+
if r == nil {
60+
return nil
61+
}
62+
return &ClientResult{Result: r.Result, Success: r.Success}
63+
}
64+
65+
func deleteToClientResult(r *resource.DeleteResult) *ClientResult {
66+
if r == nil {
67+
return nil
68+
}
69+
return &ClientResult{Result: r.Result, Success: r.Success}
70+
}
71+
72+
func toClientListResult(r *resource.ListResult) *ClientListResult {
73+
if r == nil {
74+
return nil
75+
}
76+
items := make([]interface{}, len(r.Result))
77+
for i, raw := range r.Result {
78+
items[i] = raw
79+
}
80+
return &ClientListResult{
81+
Result: items,
82+
Success: r.Success,
83+
TotalCount: r.TotalCount,
84+
NextCursor: r.NextCursor,
85+
}
86+
}
87+
88+
func findToClientListResult(r *resource.FindResult) *ClientListResult {
89+
if r == nil {
90+
return nil
91+
}
92+
items := make([]interface{}, len(r.Result))
93+
for i, raw := range r.Result {
94+
items[i] = raw
95+
}
96+
return &ClientListResult{
97+
Result: items,
98+
Success: r.Success,
99+
TotalCount: r.TotalCount,
100+
NextCursor: r.NextCursor,
101+
}
102+
}
103+
104+
func toSDKCreateInput(c ClientCreateInput) (resource.CreateInput, error) {
105+
raw, err := json.Marshal(c.Input)
106+
if err != nil {
107+
return resource.CreateInput{}, err
108+
}
109+
return resource.CreateInput{Input: raw, Namespace: c.Namespace}, nil
110+
}
111+
112+
func toSDKUpdateInput(c ClientUpdateInput) (resource.UpdateInput, error) {
113+
raw, err := json.Marshal(c.Input)
114+
if err != nil {
115+
return resource.UpdateInput{}, err
116+
}
117+
return resource.UpdateInput{Input: raw, ID: c.ID, Namespace: c.Namespace}, nil
118+
}

main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,16 @@ func main() {
102102
settingsController := settings.NewController(log, settingsProvider)
103103
settingsClient := settings.NewClient(settingsController)
104104

105-
execController := exec.NewController(log, settingsProvider, resourceClient)
105+
execController := exec.NewController(log, settingsProvider, resourceController)
106106
execClient := exec.NewClient(execController)
107107

108-
networkerController := networker.NewController(log, settingsProvider, resourceClient)
108+
networkerController := networker.NewController(log, settingsProvider, resourceController)
109109
networkerClient := networker.NewClient(networkerController)
110110

111-
logsController := pluginlogs.NewController(log, settingsProvider, resourceClient)
111+
logsController := pluginlogs.NewController(log, settingsProvider, resourceController)
112112
logsClient := pluginlogs.NewClient(logsController)
113113

114-
metricController := pluginmetric.NewController(log, settingsProvider, resourceClient)
114+
metricController := pluginmetric.NewController(log, settingsProvider, resourceController)
115115
metricClient := pluginmetric.NewClient(metricController)
116116

117117
dataController := data.NewController(log)

packages/omniviewdev-providers/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@omniviewdev/providers",
3-
"version": "0.1.9",
3+
"version": "0.2.1",
44
"description": "Package to interact with the various providers in Omniview via the UI.",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",

packages/omniviewdev-runtime/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"author": "Omniview",
33
"license": "AGPL-3.0-only",
44
"name": "@omniviewdev/runtime",
5-
"version": "0.1.9",
5+
"version": "0.2.1",
66
"description": "Runtime shared library for Omniview",
77
"sideEffects": false,
88
"type": "module",

0 commit comments

Comments
 (0)