samdenty / console-feed Goto Github PK
View Code? Open in Web Editor NEWCaptures console.log's into a React Component π₯
Home Page: https://stackblitz.com/~/github.com/samdenty/console-feed
License: MIT License
Captures console.log's into a React Component π₯
Home Page: https://stackblitz.com/~/github.com/samdenty/console-feed
License: MIT License
Is react-native
support planned? This component could be useful with other renderers such as react-native
or react-blessed
.
I am using console-feed with an online code editor like code sandbox but I am having trouble with console logs generated by the user (I am not using it with code sandbox but an editor I am writing myself).
Update:
I was able to get this working but I had to use a different pattern than the basic usage suggested on your readme. The pattern on the readme worked for console logs if they had been saved with the code base and loaded when the component with the console-feed was mounted, but not dynamic console logs the user wrote. I used an unhook, rehook pattern for every update the user made to their code to capture each new console log. This can be closed and sorry for the trouble.
There is an issue related to recent changes: #52 by @RealPeha
With empty log
console.log();
console.log("a");
console.log("b");
console.log("c");
// Output
// (4)
https://codesandbox.io/s/console-feed-forked-ugjmf?file=/src/demo/index.js
Sidenote: This behavior should probably be an option instead of mandatory as in chrome
When trying to rerender the console the component the variant, BASE_FONT_FAMILY, BASE_FONT_SIZE are note getting affected.
<div style={{ backgroundColor: '#242424' }}>
<Console
style={{ fontFamily }}
styles={{
BASE_FONT_FAMILY: 'Cousine',
BASE_FONT_SIZE: fontSize,
OBJECT_VALUE_STRING_COLOR: '#D0273D',
LOG_RESULT_COLOR: '#000000',
BASE_COLOR: theme.toLowerCase() === 'light' ? '#000000' : '#ffffff',
LOG_COLOR: theme.toLowerCase() === 'light' ? '#000000' : '#ffffff',
BASE_BACKGROUND_COLOR: 'transparent',
LOG_BACKGROUND: 'transparent',
}}
logs={this.state.logs} variant={theme.toLowerCase()} />
</div>
theme can have values 'light'
& 'dark'
Hey, thanks for your great work done here!
l wanna ask can you enable optional properties in interface Message
?
Hi,
I am trying to implement a logging component that incrementally deletes old logs when there are too many logs.
I noticed that console-feed does not rerender properly when I delete and add new logs.
Have a look at this example: https://codesandbox.io/s/x9wpm9w1vz
Try pressing the new log button.
Thanks!
When an object is created using Object.create(null) it does not contain properties that are inherited from Object for example hasOwnProperty
or __proto__
Inside EncodingTransformer.prototype._handlePlainObject
this causes an issue where in we depend on hasOwnProperty
and also on __proto__
.
https://github.com/samdenty/console-feed/blob/master/src/Transform/replicator/index.ts#L98
This becomes an issue when someone is using query-string
npm package
https://www.npmjs.com/package/query-string
This packages parse
method creates a parsed object with Object.create(null);
I think we will have to place in a check for the existence of these properties on an object and only then handle them correctly.
@samdenty If it's alright then I would like to pick up this issue and propose a solution around the same.
Hi! π
We added support for Map
a while ago, but there are some issues with it when you set a key to be an object or a function.
When it's a function, it renders empty and we get a warning from React about children
being of type function
. When it's an object, it breaks because children
can't be an object.
https://codesandbox.io/s/staging-worker-wrhqp
I'm not sure about what the expected output should be in this case, but if you want to, we can add a method to stringify object and functions, like:
getCustomName(name: any) {
if (typeof name === 'object') {
let customName: string
try {
customName = JSON.stringify(name)
} catch (e) {
customName = String(name)
}
return customName
}
if (typeof name === 'function') {
return '' + name
}
return name
}
The output to the failing logs on the demo would be:
I am using console-feed in my custom code editor. It is working fine with all other things, but showing only one key for an event object and some other responses with larger objects.
This is the JS code I have used
This is the console-feed output I got,
This is the output in the chrome console
Is there any workaround or am I missing something?
Consider this code:
console.time("merge");
for (let i = 0; i < 100000; i++) {
merge(obj, a);
shallowEqual(a, b);
}
console.timeEnd("merge");
Expected output (from Chrome's console):
Actual output:
Reproduction sandbox: https://codesandbox.io/s/console-feed-time-timeend-n2v9n
(be warned it can be a bit taxing on the CPU)
Related CodeSandbox issue: codesandbox/codesandbox-client#5077
hey there i am building an IDE for JS and i am trying to console.log from it and the Console components does't update.
this text is showing in the browser console but not in the Console Component when trying to console from my IDE
i want only know how to make console-feed Component listen when console in the virtual machine log
i am using esbuild to build the code from the ide
Hey @samdenty this is a fantastic project!
I've noticed that this repository does not have a License attached. Do you intend to add an open-source license of some sort to the repo?
I am trying to get the logs from an iframe and have run into several major issues. I have not been able to find a example of getting logs from one anywhere, so I found a way to get them but I am not sure it is the proper way. That leads to my core issue is getting the Hook() to work correctly. It will either never run or it will run in a infinite loop. Here is the component I am making to show the iframe and the logs below. I have a operation in the setLogs hook to prevent the endless empty data arrays from being added to the state.
Here is a video I made of the error and how it happens. https://drive.google.com/file/d/1qtrsCLr8RTC1TirnpXKuGkDkwVpfTRL4/view
My React Component:
`
import React, { useState, useEffect } from "react";
import { Hook, Console, Decode, Unhook } from "console-feed";
import SplitPane from "components/SplitPane/SplitPane";
const WebViewer = ({ webTemplate }) => {
const [contentRef, setContentRef] = useState(null);
const useFrameObject = () => {
const [logs, setLogs] = useState([]);
const frameData = contentRef?.contentWindow?.console;
useEffect(() => {
function grabConsoleData() {
console.log("grab console data", frameData);
if (frameData) {
Hook(frameData, (log) =>
setLogs((curLogs) =>
log[0].data.length ? [...curLogs, Decode(log)] : [...curLogs]
)
);
console.log("hook ran now unhook");
return () => Unhook(contentRef);
}
}
// For some reason the loop will not run unless this function is called but is always a undefined value so I have it called as a unused varible
// eslint-disable-next-line
let foundLog = frameData?.feed?.pointers.log();
console.log("add"); // To keep track of when event listener is added
document
.getElementById("webPreviewFrame")
.addEventListener("load", grabConsoleData);
grabConsoleData();
return () => {
console.log("remove");// To keep track of when the event listener is removed
document
.getElementById("webPreviewFrame")
.removeEventListener("load", grabConsoleData);
};
}, [frameData]); // If I have a dependency array it never catches logs, without it logs appear in logs state but endless loop
console.log("return logs", logs);
return logs;
};
return (
<iframe
id="webPreviewFrame"
title="Web Preview"
className="editor_console_panel"
srcDoc={${webTemplate}
}
referrerPolicy="origin"
width="100%"
ref={setContentRef}
/>
<div
style={{ backgroundColor: "#242424", height: "100%", width: "100%" }}
>
);
};
export default WebViewer;
`
SrcDoc string being fed into the iframe:
<!DOCTYPE html><html><body><h1>Hey Buddy</h1><script>console.log("hey",2);console.log("Bro")<script/></body></html
I am new to npm and don't know the full ecosystem required to build these types of projects. Ideally I would like to download the javascript that has been built for the browser, then I hope to simply reference that js file in my html and be able to use the component on my site. Please let me know if this is possible.
console-feed version: 2.8
I'm investigating a CodeSandbox bug someone reported where a Proxy{}
object (Vue) gets output as null
in the CodeSandbox console, and this might be a bug in console-feed?
The linked issue has more details, and I'm happy to help dive into it more if I can (or pass it on to one of our frontend developers - who are perhaps more useful than me as a backend dev)
Thanks!
When the Console is rendered, each Message component is given a key based on its message type and position in the list:
console-feed/src/Component/index.tsx
Line 94 in a393bad
However, if you try to remove old log entries, it will not work as expected because another Message will get the same key.
I think you are already adding a GUID to the Message objects for hooked console.log()
calls, so this could be used instead. Maybe something like this:
<Message log={log} key={log.id || `${log.method}-${i}`} />
I am developing an online code editor (similar to codesandbox.io) and I am trying to incorporate console-feed after reading codesandbox use it however it does not seem to detect console.log statements in the editor even though I see the console logs in google chrome. I've followed your README to setup console-feed... Is there some extra or special configuration I need to do to get it to work in this way? Here is my code:
// code editor component.
// setConsoles updates an array in redux.
...
useEffect(() => {
Hook(window.console, log => setConsoles({ log }), false);
return () => Unhook(window.console);
}, []);
// reducer
...
[actions.setConsoles]: (state, { payload: { log } }) => {
return {
...state,
consoles: [...state.consoles, log],
};
},
// console component - consoles comes from reducer state
...
return (
<ConsoleFeed logs={consoles} variant="dark" />
);
function sum(){
console.log(this);
}
console.log(sum.prototype);
when I tried console.log(this) my app was crashed and I tried console.log(sum.prototype) printed empty like this sum{}
Hi,
I am just curious about the intended usage of Unhook
method.
Currently, I have the following inside my component:
const [logs, setLogs] = useState<Message[]>([]);
useEffect(() => {
Hook(
window.console,
(log) => setLogs(currLogs => [...currLogs, log]),
false,
);
return () => {
Unhook(window.console as any);
}
}, []);
This matches the usage example in the README and I think this would pass in a JavaScript project. However, in TypeScript, I need to cast window.console
to any
type when passing it to Unhook
otherwise the following error occurs:
Argument of type 'Console' is not assignable to parameter of type 'HookedConsole'.
Property 'feed' is missing in type 'Console' but required in type 'HookedConsole'. TS2345
21 |
22 | return () => {
> 23 | Unhook(window.console);
| ^
24 | }
25 | }, []);
26 |
Casting as any
would be an acceptable solution (but not a desirable one) to me, but I also noticed that Hook
method returns the console back as a HookedConsole
object (whose type is basically the same as Console
but with feed
property).
Is there any difference in using the return value of Hook
and passing that into Unhook
instead? Like this:
const [logs, setLogs] = useState<Message[]>([]);
useEffect(() => {
const hookedConsole = Hook(
window.console,
(log) => setLogs(currLogs => [...currLogs, log]),
false,
);
return () => {
Unhook(hookedConsole);
}
}, []);
After viewing the implementation, this should work the same as the previous, since window.console
has the feed
property injected into it and a reference to the same object is returned from the Hook
method. But this doesn't seem to be documented. Is there a caveat to this approach? Or could the documentation be updated to reflect this approach instead? This is more desirable for a TypeScript project IMO since it avoids a cast to any
.
edit: User could also cast window.console
to HookedConsole
directly, but this requires the user to have read the code and understood what it does to the window.console
object to verify that this type conversion is valid. Not sure what the best approach is here from documentation standpoint.
The eval()
in the code trips CSP which don't allow eval. Possible to remove it?
I'm investigating what was reported on #61 within CodeSandbox. I tried to upgrade to the newest version (3.1.9) and now we're getting Cannot read property 'toUpperCase' of undefined
in some cases.
I think that instead of 9acd017, we should check for !error
in the Error
component and return The error you provided does not contain a stack trace.
.
The original issue that triggered my investigation is codesandbox/codesandbox-client#4963 - we were getting a blank error message there, then we got indexOf of undefined
and now toUpperCase of undefined
.
What do you think about my suggestion? The error you provided does not contain a stack trace.
is what we get in the browser console inside CodeSandbox, so the behaviour would match in our case I think.
I tried to create a reproducible example in the demo app to verify the behaviour with more scenarios but I couldn't get to the state reported in codesandbox/codesandbox-client#4963.
Issue:
console-feed
does not seem to work with src-doc
attribute.
Reproduction: https://codesandbox.io/s/5wx6qlox1n
When the same content is provided as src
attribute (you can test by changing srcdoc
to src=iframe.html
), it shows logs.
From README.md:
logs: Log[]
An array consisting of Log objects. Required
But from the code in my node_modules (@3.0.0):
export interface Props {
logs: Message[]
// ...
}
Is it the case that the Log object was changed to Message at some point and the documentation became outdated? If so I would be happy to submit a PR updating the docs.
Hey, I just wanted to start a discussion about support for emotion v10 and Iβve been unable to get two packages one depending on v9 and the other v10 running side-by-side.
Fortunately the upgrade was straight forward. Iβve a fork of the project working with v10 let me know if youβd like me to open a PR against this repo. Though I donβt know how youβd like to handle backwards compatibility.
Cheers,
Aron
Hey!
It would be great if you could upgrade to the latest emotion version.
This project is no longer compatible with emotion v11.
When I call concole.clear() I have the following error in the console:
[console-feed] Failed to parse message! log.data was not an array!
How to clear console silently without any other messages?
Brace yourselves, issues from CodeSandbox incoming! π
Consider this code:
const testSet = new Set();
testSet.add(1);
testSet.add(2);
testSet.add({ foo: 'bar' });
testSet.add([3, 4]);
console.log(testSet);
Expected output (from Chrome's console):
Actual output:
(note that objects are handled fine)
Reproduction sandbox: https://codesandbox.io/s/console-feed-set-array-item-f3dmn
Related CodeSandbox issue: codesandbox/codesandbox-client#5493
To reproduce:
const obj = {
foo: 3n
};
console.log(obj);
I believe that this file would need to detect bigints (typeof x === 'bigint') and handle encoding/decoding them.
Hey!
We got an error report that I could test, seems like when doing console.time it always returns 0ms when inside of codesandbox and outside works
This seems to only happen in Firefox. Here is the issue: codesandbox/codesandbox-client#5077
The sandbox: https://codesandbox.io/s/infallible-tdd-ex27s?file=/src/index.js
Any idea what this could be?
I am super willing to help out if you have any ideas
There are multiple types called "Message", one in console.d.ts and one in component.d.ts. Console component takes props of type Message[] (the readme states is takes Log[] I think) and this is the type from component.d.ts, but the Hook takes the type from console.d.ts. I have something like this:
import { useState, useEffect } from "react";
import { Console, Hook, Unhook } from "console-feed";
import { Message as MessageComponent } from "console-feed/lib/definitions/Component";
import { Message as MessageConsole } from "console-feed/lib/definitions/Console";
const LogsContainer = () => {
const [logs, setLogs] = useState<MessageConsole[]>([]);
// run once!
useEffect(() => {
Hook(
window.console,
(log) => setLogs((currLogs) => [...currLogs, log]),
false
);
return () => {Unhook(window.console as any)};
}, []);
return <Console logs={logs as MessageComponent[]} variant="dark" />;
};
export { LogsContainer };
I wonder if something should be done to make the experience more seamless in TS? Error is thrown when copy pasting from the example.
Sometimes message
can be undefined
in
Steps to reproduce:
@samdenty Let me know if you need more info on this.
Reproducing sandbox: https://codesandbox.io/s/8w24l?file=/index.js
To reproduce: check / uncheck a tree item, the console.log()
from index.js:55
will output immediately in Chrome's console, will block the preview for ~30s, and then will output in CodeSandbox's console. Removing info
from the console.log()
works fine, so this is caused by logging the info
object.
Related CodeSandbox issue: codesandbox/codesandbox-client#5656 .
I'm trying to use this component in a project which uses React Hooks, and wondering if there's a pattern that makes more sense. Here's what I have now:
function MyComponent() {
const [logs, setLogs] = useState([]);
useEffect(() => {
Hook(window.console, log => {
setLogs([...logs, Decode(log)]);
});
});
return <Console logs={logs} variant="dark" />;
}
I think this is either wasteful or just wrong. The console-feed Hook will run on every render, which is why it works at all. If I make it run only once, the logs
state value would not update. Any thoughts on the right pattern for this?
How about adding virtualization to the message list? This is a big performance issue.
Consider this code:
const testPromise = new Promise((resolve) =>
setTimeout(() => resolve(42), 1000)
);
testPromise.then(() => console.log(testPromise));
Expected output (from Chrome's console):
Actual output:
Reproduction sandbox: https://codesandbox.io/s/console-feed-resolved-promise-xye1i
Related CodeSandbox issue: codesandbox/codesandbox-client#5830
The Chrome developer tools have a feature to enable timestamps on all entries. This also includes hover text with a full timestamp.
Is there anyway to accomplish this with console-feed? In my case I would prefer to supply the timestamps for my log messages and not have them auto generated when the items are added.
First of all you did great job!
I change example code just 'dark' to 'light'
it only affected after one depth object.
root level object display as 'dark' themeed.
Hey!
I can not find information in this repository about console.group
and console.groupCollapsed
After using in my Sandbox and researching examples of use, I made a preliminary conclusion that there is no support for this functionalityπ₯
Whether such functionality is needed in this module and whether support for this will be added in the future?
Hi,
I believe you forgot to include d.ts files in your latest npm package.
I looked through every folder in the console-feed node_module and it doesn't seem to have it.
Here's what I have for the latest console-feed npm package.
console-feed
βββ lib
βΒ Β βββ Component
βΒ Β βΒ Β βββ devtools-parser
βΒ Β βΒ Β βΒ Β βββ format-message.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βΒ Β βββ string-utils.js
βΒ Β βΒ Β βββ elements.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ Message.js
βΒ Β βΒ Β βββ message-parsers
βΒ Β βΒ Β βΒ Β βββ Error.js
βΒ Β βΒ Β βΒ Β βββ Formatted.js
βΒ Β βΒ Β βΒ Β βββ Object.js
βΒ Β βΒ Β βββ react-inspector
βΒ Β βΒ Β βΒ Β βββ elements.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βΒ Β βββ util.js
βΒ Β βΒ Β βββ theme
βΒ Β βΒ Β βββ default.js
βΒ Β βΒ Β βββ index.js
βΒ Β βββ definitions
βΒ Β βΒ Β βββ Methods.js
βΒ Β βββ Hook
βΒ Β βΒ Β βββ construct.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ parse
βΒ Β βΒ Β βΒ Β βββ GUID.js
βΒ Β βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βΒ Β βββ methods
βΒ Β βΒ Β βΒ Β βββ assert.js
βΒ Β βΒ Β βΒ Β βββ count.js
βΒ Β βΒ Β βΒ Β βββ timing.js
βΒ Β βΒ Β βββ store
βΒ Β βΒ Β βββ actions.js
βΒ Β βΒ Β βββ dispatch.js
βΒ Β βΒ Β βββ reducer.js
βΒ Β βΒ Β βββ state.js
βΒ Β βββ index.js
βΒ Β βββ Transform
βΒ Β βΒ Β βββ arithmetic.js
βΒ Β βΒ Β βββ Function.js
βΒ Β βΒ Β βββ HTML.js
βΒ Β βΒ Β βββ index.js
βΒ Β βΒ Β βββ Map.js
βΒ Β βΒ Β βββ replicator
βΒ Β βΒ Β βββ index.js
βΒ Β βββ Unhook
βΒ Β βββ index.js
βββ package.json
βββ README.md
Thanks,
Sam L.
I am making a console log input (very similar to the one on code sandbox) and I am using the Encode
function for the data property of the log object like this:
const result = eval(`${this.state.code}`);
const logs = [{
method: 'log',
id: shortid.generate(),
data: Encode(result),
}];
this.props.appendToConsoles({ logs });
This seems to work fine for other objects but if I type window
I get a warning and Encode kills my app.
The warning:
[Deprecation] 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
which seems to be coming from:
EncodingTransformer.prototype._handlePlainObject = function (obj) {
var result = Object.create(null);
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? "#" + key : key;
result[resultKey] = this._handleValue(obj[key], result, resultKey); // <------- this line
I understand the issue now; the window object has circular references which cannot be serialized without some help. I had a peek into your library and you seem to be handling this so I'm not sure what my next move is. I found a little snippet I can use to pass as a replacer function to JSON.serialize
but that is pointless if you are already handling this case.
We were creating a Function Component with useState and useEffect to see if the ConsoleFeed showed correctly. Seems like if the console.log calls are separated in time we will see all correctly, but, when calling many of them together, like before rendering in a component, we will only see the last call even though we can see in the console that the Functional component did re-render.
export const ConsoleFeed: FunctionComponent = () => {
const [logs, setLogs] = useState([]);
const [visible, setVisibility] = useState(false);
const handleKeyDown = (evt: KeyboardEvent) => {
switch (getKeyFromEvent(evt)) {
case Keys.YELLOW:
evt.preventDefault();
console.log('ALLO', visible);
setVisibility(!visible);
break;
}
};
useEffect(
() => {
console.log('hook', logs);
Hook(window.console, log => {
setLogs([...logs, Decode(log)]);
});
scrollConsoleToBottom();
return () => {
Unhook(window.console);
console.log('unhooking', logs);
};
},
[logs]
);
useEffect(
() => {
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('keydown', handleKeyDown);
};
},
[visible]
);
return (
<div ref={consoleRef} className={`console-feed ${visible ? 'visible' : 'hidden'}`}>
<Console logs={logs} variant="dark" />
</div>
);
};
In the hooking and unhooking logs we will see 4 calls, so it is updating logs 4 times, and that is good. But the object in the data will get overwritten with the next object until the last one is done.
Might be related to: #15
Codesanbox: https://codesandbox.io/s/elegant-maxwell-sjem1?file=/index.js
Hello, I found that sometimes the page crashes when console.log(e) when I use a public component library like ant-design.
But I donβt think this is a problem with the component library like ant-design.
Because when I use other component libraries, if console.log(e), I also have this problem.
Even when my project has a little complexity, even if I use the native tag, the problem will occur.
But when the project is very simple, if console.log(e), the page will just be stuck for a while, about a few seconds.
So I guess itβs because when the project becomes more complex, the parent-child relationship between the elements leads to the circular reference of e.target, which leads to an endless loop.
Thanks for the great library!
I seem to have ran into an eccentric recursion issue.
You can quickly notice the page slowing down. When you inspect the log you get a result like this:
cc @CompuIves CodeSandbox has this too!
When you change font size of the console, icons are not lined with text or in other words icons are not centered vertically. Changing Icon height with font size doesn't solve issue. I tried to multiply icon height with some number (like 1.5*fontsize) to align it vertically but it is not working for all sizes.
Here is demo
The "%o" substitution string doesn't seem to be supported.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.