// Copyright 2017-2026 @pezkuwi/app-js authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { Log } from './types.js'; import React from 'react'; import { styled } from '@pezkuwi/react-components'; import { isError, isNull, isUndefined } from '@pezkuwi/util'; interface Props { children?: React.ReactNode; className?: string; logs: Log[]; } const format = (value: unknown): string => { if (isError(value)) { return value.stack ? value.stack : value.toString(); } else if (isUndefined(value)) { return 'undefined'; } else if (isNull(value)) { return 'null'; } else if (Array.isArray(value)) { return `[${value.map(format).join(', ')}]`; } else if (value instanceof Map) { return `{${[...value.entries()] .map(([k, v]) => `${(k as string).toString()}: ${format(v)}`) .join(', ')}}`; } // This _could_ fail as well, hence the catch below return (value as string).toString(); }; const renderEntry = ({ args, type }: Log, index: number): React.ReactNode => { try { return (
{args.map(format).join(' ')}
); } catch (error) { // e.g. this would hit here - // console.log(api.createType('ProxyType').__proto__) return (
Internal error: {(error as Error).stack || (error as Error).message}
); } }; function Output ({ children, className = '', logs }: Props): React.ReactElement { return (
            {logs.map(renderEntry)}
          
{children}
); } const StyledArticle = styled.article` background-color: #4e4e4e; color: #ffffff; display: flex; flex-direction: column; flex-grow: 1; font: var(--font-mono); font-variant-ligatures: common-ligatures; line-height: 18px; padding: 50px 10px 10px; position: relative; width: 40%; .logs-wrapper { display: flex; flex: 1; min-height: 0; } .logs-container { flex: 1; overflow: auto; } .logs-content { height: auto; } .js--Log { animation: fadein 0.2s; margin: 0 0 5px 0; word-break: break-all; &.error { color: #f88; } } `; export default React.memo(Output);