yao/sandbox/v2/jsapi/node.go
Max ce0a97c0af feat(sandbox/v2): refactor benchmarks and tests to use TaiID
- Updated benchmark functions to utilize TaiID instead of pool names for improved consistency and accuracy in tests.
- Refactored test cases across various files to ensure compatibility with the new TaiID structure.
- Enhanced setup functions to accept pointers to poolConfig for better memory management.
- Removed deprecated config struct and adjusted related documentation to reflect the changes in the sandbox architecture.

Made-with: Cursor
2026-03-09 02:50:28 +08:00

142 lines
3.7 KiB
Go

package jsapi
import (
"encoding/json"
"time"
"github.com/yaoapp/yao/tai/registry"
"rogchap.com/v8go"
)
// sbGetNode: `sandbox.GetNode(taiID)` → NodeInfo | null
func sbGetNode(info *v8go.FunctionCallbackInfo) *v8go.Value {
iso := info.Context().Isolate()
args := info.Args()
if len(args) < 1 || !args[0].IsString() {
return throwError(info, "GetNode requires taiID (string)")
}
reg := registry.Global()
if reg == nil {
return throwError(info, "registry not initialized")
}
snap, ok := reg.Get(args[0].String())
if !ok {
return v8go.Null(iso)
}
val, err := snapshotToJS(info.Context(), snap)
if err != nil {
return throwError(info, err.Error())
}
return val
}
// sbNodes: `sandbox.Nodes()` → NodeInfo[]
func sbNodes(info *v8go.FunctionCallbackInfo) *v8go.Value {
v8ctx := info.Context()
reg := registry.Global()
if reg == nil {
return throwError(info, "registry not initialized")
}
snaps := reg.List()
return snapshotsToJSArray(v8ctx, snaps)
}
// sbNodesByTeam: `sandbox.NodesByTeam(teamID)` → NodeInfo[]
func sbNodesByTeam(info *v8go.FunctionCallbackInfo) *v8go.Value {
v8ctx := info.Context()
args := info.Args()
if len(args) < 1 || !args[0].IsString() {
return throwError(info, "NodesByTeam requires teamID (string)")
}
reg := registry.Global()
if reg == nil {
return throwError(info, "registry not initialized")
}
snaps := reg.ListByTeam(args[0].String())
return snapshotsToJSArray(v8ctx, snaps)
}
// snapshotToJS converts a NodeSnapshot to a JS NodeInfo object.
// Auth and YaoBase are excluded for security.
func snapshotToJS(v8ctx *v8go.Context, snap *registry.NodeSnapshot) (*v8go.Value, error) {
ports := make(map[string]interface{}, len(snap.Ports))
for k, v := range snap.Ports {
ports[k] = v
}
caps := make(map[string]interface{}, len(snap.Capabilities))
for k, v := range snap.Capabilities {
caps[k] = v
}
data, err := json.Marshal(map[string]interface{}{
"tai_id": snap.TaiID,
"machine_id": snap.MachineID,
"version": snap.Version,
"mode": snap.Mode,
"addr": snap.Addr,
"status": snap.Status,
"pool": snap.PoolName,
"connected_at": snap.ConnectedAt.Format(time.RFC3339),
"last_ping": snap.LastPing.Format(time.RFC3339),
"ports": ports,
"capabilities": caps,
"system": map[string]interface{}{
"os": snap.System.OS,
"arch": snap.System.Arch,
"hostname": snap.System.Hostname,
"num_cpu": snap.System.NumCPU,
"total_mem": snap.System.TotalMem,
},
})
if err != nil {
return nil, err
}
return v8go.JSONParse(v8ctx, string(data))
}
func snapshotsToJSArray(v8ctx *v8go.Context, snaps []registry.NodeSnapshot) *v8go.Value {
items := make([]interface{}, 0, len(snaps))
for i := range snaps {
snap := &snaps[i]
ports := make(map[string]interface{}, len(snap.Ports))
for k, v := range snap.Ports {
ports[k] = v
}
caps := make(map[string]interface{}, len(snap.Capabilities))
for k, v := range snap.Capabilities {
caps[k] = v
}
items = append(items, map[string]interface{}{
"tai_id": snap.TaiID,
"machine_id": snap.MachineID,
"version": snap.Version,
"mode": snap.Mode,
"addr": snap.Addr,
"status": snap.Status,
"pool": snap.PoolName,
"connected_at": snap.ConnectedAt.Format(time.RFC3339),
"last_ping": snap.LastPing.Format(time.RFC3339),
"ports": ports,
"capabilities": caps,
"system": map[string]interface{}{
"os": snap.System.OS,
"arch": snap.System.Arch,
"hostname": snap.System.Hostname,
"num_cpu": snap.System.NumCPU,
"total_mem": snap.System.TotalMem,
},
})
}
data, _ := json.Marshal(items)
val, _ := v8go.JSONParse(v8ctx, string(data))
return val
}