
;; Live GraphQL parse island — parses input and shows AST + serialized output
(defisland
  ()
  (let
    ((input (signal "{\n  user(id: 1) {\n    name\n    email\n  }\n}"))
      (ast-output (signal ""))
      (ser-output (signal "")))
    (define
      do-parse!
      (fn
        (e)
        (let
          ((src (deref input)))
          (when
            (not (empty? src))
            (let
              ((doc (gql-parse src)))
              (do
                (set-signal! ast-output (sx-serialize doc))
                (set-signal! ser-output (gql-serialize doc))))))))
    (div
      (~tw :tokens "flex flex-col gap-3")
      (textarea
        :rows "5"
        (~tw
          :tokens "w-full font-mono text-sm p-3 border border-gray-300 rounded-lg focus:border-violet-500 focus:ring-1 focus:ring-violet-500 outline-none")
        :placeholder "{ user(id: 1) { name email } }"
        :value (deref input)
        :on-input (fn (e) (set-signal! input (get-prop e "target.value"))))
      (button
        (~tw
          :tokens "self-start px-4 py-2 bg-violet-600 text-white rounded-lg hover:bg-violet-700 transition-colors")
        :on-click do-parse!
        "Parse")
      (when
        (not (empty? (deref ast-output)))
        (div
          (~tw :tokens "space-y-4")
          (div
            (h4
              (~tw
                :tokens "text-xs font-semibold uppercase tracking-wider text-gray-500 mb-2")
              "AST")
            (pre
              (~tw
                :tokens "bg-gray-900 text-green-400 p-4 rounded-lg text-sm overflow-x-auto")
              (deref ast-output)))
          (div
            (h4
              (~tw
                :tokens "text-xs font-semibold uppercase tracking-wider text-gray-500 mb-2")
              "Serialized")
            (pre
              (~tw
                :tokens "bg-gray-900 text-amber-400 p-4 rounded-lg text-sm overflow-x-auto")
              (deref ser-output))))))))
