From 76853d4beb3d543c1ceb1166966b334cb0c9ee1b Mon Sep 17 00:00:00 2001 From: CharlesKWON Date: Mon, 15 Jun 2026 21:42:00 +0900 Subject: [PATCH] feat(rtl): nodebridge decodes JS arrays/objects to native PRG values jsValToValue now recursively converts JS arrays/objects (the "json" wire type) into native hbrt arrays/hashes, so PRG can Len()/index/hb_HGetDef the results of npm methods (e.g. os.cpus()[1]:model). Strings/numbers/booleans/ buffers unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- hbrtl_ext/nodebridge/nodebridge.go | 36 +++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/hbrtl_ext/nodebridge/nodebridge.go b/hbrtl_ext/nodebridge/nodebridge.go index 4dd3d51..9c33fb9 100644 --- a/hbrtl_ext/nodebridge/nodebridge.go +++ b/hbrtl_ext/nodebridge/nodebridge.go @@ -370,7 +370,13 @@ func jsValToValue(val map[string]interface{}) hbrt.Value { t := str(val["t"]) v := str(val["v"]) switch t { - case "string", "buffer", "json": + case "string", "buffer": + return hbrt.MakeString(v) + case "json": // JS array/object → 네이티브 PRG 배열/해시로 디코드 + var parsed interface{} + if err := json.Unmarshal([]byte(v), &parsed); err == nil { + return jsonToValue(parsed) + } return hbrt.MakeString(v) case "number": if f, err := strconv.ParseFloat(v, 64); err == nil { @@ -384,6 +390,34 @@ func jsValToValue(val map[string]interface{}) hbrt.Value { } } +// jsonToValue: 디코드된 JSON 값을 네이티브 hbrt.Value(배열/해시/스칼라)로. +func jsonToValue(x interface{}) hbrt.Value { + switch v := x.(type) { + case nil: + return hbrt.MakeNil() + case bool: + return hbrt.MakeBool(v) + case float64: + return hbrt.MakeDoubleAuto(v) + case string: + return hbrt.MakeString(v) + case []interface{}: + items := make([]hbrt.Value, len(v)) + for i, e := range v { + items[i] = jsonToValue(e) + } + return hbrt.MakeArrayFrom(items) + case map[string]interface{}: + pairs := make([]hbrt.Value, 0, len(v)*2) + for k, e := range v { + pairs = append(pairs, hbrt.MakeString(k), jsonToValue(e)) + } + return hbrt.MakeHashFrom(hbrt.HashFromPairs(pairs)) + default: + return hbrt.MakeNil() + } +} + func str(v interface{}) string { if s, ok := v.(string); ok { return s