kint-php / kint

Kint - Advanced PHP dumper
https://kint-php.github.io/kint/
MIT License
2.78k stars 292 forks source link

RFC: Kint 6 #422

Open jnvsor opened 2 months ago

jnvsor commented 2 months ago

If you've been paying attention to the repo you may have noticed a lot of commits showing up. Since the PHP 8.4 feature freeze on the 13th I've been working on a new major version with 7.4 as the minimum requirement.

It's essentially ready to go (Though I will only be publishing beta tags for now) but I'd like some feedback since among other things the JS has been completely rewritten and modernized.

I've got much less experience in JS than in PHP so if any JS devs have any suggestions in that area I'd welcome those too.

Semi-complete list of changes:

For now, barring any feedback, I'm going to see if I can eke out more perf with cachegrind

jnvsor commented 2 months ago

6.0-beta2 out

HLeithner commented 2 months ago

Nice work, didn't had the time to look at everything yet but would like to give feedback about

"Open in new window" button has been removed. I for one never used it, and the code involved obfuscation and the likes to get around browser security measures. Basically it was ugly and could break at any time so I figured I'd remove it. If it actually got a lot of use and I get complaints here I can port it back in but I doubt it.

It's something I use sometimes as specially if the view area of kint is really limited, so maybe an button to open a "full screen" model which is on the highest dom level would be an alternative?

jnvsor commented 2 months ago

@HLeithner

so maybe an button to open a "full screen" model which is on the highest dom level would be an alternative?

Sounds like you want Kint\Renderer\RichRenderer::$folder = true - this will put your dumps in a folder docked to the bottom of the viewport. I suppose the downside is you have to set this up before dumping. Do you think there'd be interest in a button to do it in JS?

HLeithner commented 2 months ago

yeah I know the docked function, but for normally use it's a bit not optimal tbh, so with a button it would be a good solution, but I wouldn't but it the bottom, instead on top would be better but that's another story.

HLeithner commented 2 months ago

Another interesting thing would be to customize the last line (with the stacktrace), I know that doesn't fit into this issue. But adding metadata to the rendered output would be nice, I can of course do this with my own additional line but having this as an programmable interface would be nice.

Example I would like replace the simple stacktrace with an more complex variant (ex. counting the how often a function has been called in this trace (recursion)). Or having a second column with other meta information like how often this this specific kint in this line in this file has been called. Useful for loops. And I'm pretty sure I there is more useful information that could be displayed, like user information, memory usage, cpu spikes, you name it.

I use kint warped in my own joomla plugin which prepare the usage, so filling the kint::statics would be easily possible before outputting kint.

hmm I think that should be move to it's own issue...

jnvsor commented 2 months ago

how often this this specific kint in this line in this file has been called. Useful for loops. And I'm pretty sure I there is more useful information that could be displayed, like user information, memory usage, cpu spikes, you name it

Number of calls/memory usage/timing info is there if you dump microtime() repeatedly (Like in a loop) I don't want to duplicate that in the minitrace because it would just be a downgraded version (Though the minitrace does support date() formats which you can set with RichRenderer::$timestamp)

That said, you can (And I have in the past) extend the renderer itself and change whatever you want. All the RichRenderer props/methods are protected so you just subclass it and change the Kint::$renderers entry to your subclass. Then it's just a matter of changing the postRender.

jnvsor commented 2 months ago

@HLeithner I've taken a crack at the dynamic-moving-of-the-dumps-to-folder work. Can you try out 055bc6f5ea97ca9a505683379f9937e7ac639426 and see if that does what you want? (It's f in keyboard control mode)

HLeithner commented 2 months ago

@jnvsor works as expected, on top would be good ;-) and moved back to the position before, but both is not really needed.

I converted my own plugin to this version, a migration guide would be helpful but it wasn't too hard to find out the changes (it's a simple plugin).

Thanks

HLeithner commented 2 months ago

about the renderer topic

That said, you can (And I have in the past) extend the renderer itself

kint is a moving target which makes it hard to override things like you said, having to adapt own code often is not so fun as it sounds ;-)

we at joomla have a strict semver policy (and sometimes fails) with a stable release cycle of 4 years and people are annoyed that we change anything... of course this tool has a different target group.

never the less I will have a look at this.

jnvsor commented 2 months ago

on top would be good

I think you can manage that with just CSS

kint is a moving target which makes it hard to override things

I make no guarantees about JS but kint doesn't break semver on the PHP side (Or else it's a bug and should be reported) Obviously no guarantees about 6.0 before release either

jnvsor commented 1 month ago

Beta 3 is now out:

HLeithner commented 1 month ago

On the sublevel the complexity is collected in the "Perfomance Profile" tab

image

on the first level the "Performance Profile" shows the complexity for it self and for all subentries

image

"Class Complexity" shows the subentries as a variable dump

image

Is it expected?

jnvsor commented 1 month ago

@HLeithner The performance profile is a lot easier to grok if you use it in something massive and complex like a framework's container:

image

This lets you know which specific instances are being used all over the place and making the dump slower, but it doesn't tell you if you have many different instances of a specific class or interface, so class complexity shows the total complexity found under each class/interface:

image

This is much harder to read and full of false postives (Like you probably don't want to blacklist all stringables even if there are a lot of them) but helps if what you're dumping has many heavy instances of the same type.

HLeithner commented 1 month ago

Ah ok, that makes more sense, that's thanks

jnvsor commented 1 month ago

6.0-beta4:

jnvsor commented 1 month ago

6.0-beta5:

DRSDavidSoft commented 1 month ago

Just noticed this, interesting changes for Kint 6!

  • "Open in new window" button has been removed. I for one never used it, and the code involved obfuscation and the likes to get around browser security measures. Basically it was ugly and could break at any time so I figured I'd remove it. If it actually got a lot of use and I get complaints here I can port it back in but I doubt it.

Sad to see this feature go away, I used it seldom on good old days when the front-end and back-end of an application lived in harmony together. I wasn't aware that the code relies on obfuscation to bypass browser pop-up window blocks, I mean this really shouldn't be required, as the developer certainly has the option to allow-list the domain they are working on. It was a cool handy feature.

I guess other methods are available. Also a cool feature would be to get a exported var_export() or json_encode() version of the dumped variable so that it could later be imported in another kint window. Or, you could provide a kint://var-data/... type of url, where clicking on it would open a registered Kint application written in JavaScript in another window. Just some ideas.

Full JS rewrite. Now we stop trying to be clever and just put it in 1 file and dump the whole thing on the first dump of both rich and plain renderers. It's a bit of extra bandwidth but 12kb isn't much when dumping a container from a typical framework is measured in mb.

Seems like a good re-write, I agree in the modern age of web development, 12KB isn't really much when the other aspects of the application goes into MB. Still, miss the quite handy and compact tool, but reality is we don't write apps like we used to do ten years ago.

kint-ide-link behavior removed. [....] It had custom behavior of sending an AJAX request if the link is in http or https protocol that seems to have been used for VERY old phpstorm versions. Nowadays you can just set a protocol link

Never used the http/https scheme for this, also I use VS Code as an IDE more than IntelliJ-based IDEs such as PhpStrom, which supported application link schemes from the get go.

BTW, On the CLI, Kint dumps the file path, which both the terminal (e.g. Windows Terminal) and VS Code will happily take me to the specified file an line number using some sort of keyboard combination (e.g. Alt-Click or Ctrl-Click)

In both cases (CLI and Web) this is pretty useful! πŸ‘πŸ»

"undefined" is now "uninitialized" for php naming consistency Nice change, "undefined" reminds me of JS while "uninitialized" is most definitely for PHP.

ToString, Binary, Mysqli, and DOMDocument plugins are now on by default Oh, that's a great change as many devs like me tend to dump properties and vars that are relevant to these.

DRSDavidSoft commented 1 month ago

Some more thoughts regarding the theming:

jnvsor commented 1 month ago

Sad to see this feature go away

As discussed with HLeithner I ended up replacing it with a dynamic "Move to folder" button that gives you a larger viewing space without opening a new window context, which is the best of both worlds

miss the quite handy and compact tool

The old JS was 4 files totalling 13kb but it would try to cleverly only dump the ones needed so while the new JS is now 15k in practice that 15k is 30k if you dump with both plain and rich.

But dumping a symfony request is +170k, a container from a fresh symfony install is +4mb, and container from a fresh sylius/drupal install is ~80mb. A warm system with loads of services can easily reach into multiple GB of output (And then your browser is the performance bottleneck not the server)

So I'm really not worried about a few kb more JS

I would appreciate an auto dark mode feature

This would require dumping at least 2 themes on start - one for light mode and one for dark mode. Currently the themes aren't designed to be dynamically switchable, if you load two at once it'd be some weird blend of the two.

So you'd have to output two stylesheets and throw one away with JS. Is this a good idea?

A new refreshed color scheme for a better look would be nice, the original theme is looking a bit dated

Agreed. Unfortunately I have the artistic sense of a mole. (Blind and leaves a mess) I can implement a design or color scheme if you come up with one but don't ask me to come up with one myself :)

If this is well designed and using more modern css variables that can be changed browser side, we could figure out a way to roll auto dark mode into it, but I've never looked into that.

Could you start an issue and start thinking about new design stuff?

Fix RTL issue

Oh good point. I'll have to look into this. Let me open a new issue

IE support needs to be dropped

Way ahead of you. I'm just doing an out of the box esbuild now (It doesn't try to transpile to an older subset at all)

Open in New Window can remain in the code base [...] window.open() is a standard browser feature that is still used

It's not window.open that's the problem, it's inserting script and style tags into the newly opened window. And it's not just browsers either.

For instance the 5.1.1 code had to have a mktag function that just wrapped whatever you sent it in <> for no other reason than to dodge "Security" systems that freak out when they see html in JS

It appears that the docs has been reduced through the years

No, it's been expanded, it's just that kint 1.0 wasn't extensible at all and there have been a lot of changes made to improve that over the years that never got documentation.

DRSDavidSoft commented 1 month ago

This would require dumping at least 2 themes on start - one for light mode and one for dark mode. Currently the themes aren't designed to be dynamically switchable, if you load two at once it'd be some weird blend of the two.

So you'd have to output two stylesheets and throw one away with JS. Is this a good idea?

I was actually thinking of loading one by default (which is also useful on non-JS enabled environments, like the developer console preview) then use JS to detect enabled dark mode and load that one.

But this isn't even needed. Instead of relying on two themes with different color schemes (e.g. aante-light and aante-dark, we can have an aante-auto (or even just aante) and handle the dark mode based on device preferences, entirely from CSS which is awesome because you don't need to use any kind of JS.

Using this:

@media (prefers-color-scheme: dark) {...}

Which means that in the SCSS, the default light mode is used. But upon the existence of prefers-color-scheme and its value being dark, then the color schemes can be overridden to a cool looking dark mode! A very neat trick that I tend to use in my projects.

So we have:

If you are going to drop IE support, this can be paired with css variables which means a truely awesome experience for applying customizations to the color schemes with minimal lines of stylesheets being added at all.

I also suggest creating a cool looking original-dark color scheme as well and applying this proposal on that too. I'd like to contribute to the color scheme for the dark mode too if possible.

Agreed. Unfortunately I have the artistic sense of a mole. (Blind and leaves a mess) I can implement a design or color scheme if you come up with one but don't ask me to come up with one myself :)

If this is well designed and using more modern css variables that can be changed browser side, we could figure out a way to roll auto dark mode into it, but I've never looked into that.

For sure, I would love to contribute some values for the new color scheme. Functionality and eye strain prevention are top priorities, and I would prefer a very modern and cool looking design. The original theme could either use more contrast and vibrant colors, or stay to pale colors (also known as pastel, which is easy on the eyes).

I just need some basic information about the layout and structure of the scss files, I can refactor to use CSS variables and then add dark mode into it without any worries.

Could you start an issue and start thinking about new design stuff? https://github.com/kint-php/kint/issues/428

That's awesome. Let's discuss more about theming in there.

IE support needs to be dropped Great to see IE go. It served us well in the early 2000s. Now we can refactor the code to remove all mention of it and remove all ugly code that was kept because of it. Which means the S/CSS development will once again be a joy, the same way that lack of transpilation is joyful. πŸ˜„ Exciting times.

For instance the 5.1.1 code had to have a mktag function that just wrapped whatever you sent it in <> for no other reason than to dodge "Security" systems that freak out when they see html in JS

Oh, I see, this is because Kint is rendering the content in the PHP side. You know, I was thinking of implementing a pure JS Kint app that is able to render the same thing as PHP, but from a serialized string. Wouldn't that be cool? πŸ˜‰ Maybe in Kint 7 or the future. Imagine the possibilities: We can store a serialized string in the database during bug report/crash report (Laravel uses Symfony and provides such feature). Then later we would be able to see the dumps made and render it using Kint.

Currently I resort to ob_* buffer feature of PHP to capture the entire HTML output that is generated by Kint. As said, just an idea! πŸ˜„

there have been a lot of changes made to improve that over the years that never got documentation

It's never late to document the features that Kint provides. Also happy to contribute in that area, but I have no idea where to start. Fortunately, GitHub Copilot is superb at generating good documentation based on the code, so maybe we can start at that.

My colleagues hadn't even heard of Kint, one mentioned to me he had seen it but opted to use Symfony's dumper utility since it had more docs on especial use cases. He was blown away by the feature set that Kint provides. In my opinion we need to make sure people know what they're going to miss if they don't use Kint! πŸ˜„

jnvsor commented 1 month ago

You know, I was thinking of implementing a pure JS Kint app that is able to render the same thing as PHP, but from a serialized string

kint-js renderer used to be a thing but it was a simplified dump compared to rich.

I tried rewriting rich in vue for performance once. Turns out it's way less performant to add 10k dom elements from a virtual dom than to just set 10k preexisting elements display:block and let the browser reflow.

So I'm not sure if this'll be worth the effort but you're welcome to give it a try

We can store a serialized string in the database during bug report/crash report

Yeah you could already do that if you made your own renderer. It's even documented:

What the renderer does is somewhat irrelevant. It could print out text or it could print out HTML. It could store the dumped data in a database or email it to the ISS.

Currently I resort to ob_* buffer feature of PHP to capture the entire HTML output that is generated by Kint

$output = @d($var) or Kint::$return = true will do this

Fortunately, GitHub Copilot is superb at generating good documentation based on the code

Well clearly my documentation is lacking given the last few points but I question how good the quality of AI docs will be: Kint has a lot of weird stuff and recursion that it may not be great at handling.

I think the "Using kint as a tool" part of the docs is fine, it's "Using kint as a library" that gets people confused. I'm thinking I should take the "Improving Kint" and "Writing plugins" part of the documentation and put them into a subsection (named "API" perhaps?) where I can expand on internal docs.

jnvsor commented 1 month ago

6.0-beta6:

Because of the sheer engorged mass of this refactor I'm not going to bother updating the docs just yet - it'll change more before it's done. Next steps:

  1. Remove value representations and have canonical values returned by method. This means we can just store the literal value of scalars and strings on the Value and use the representations exclusively for tabs (And not store anything for resources by default)
  2. Base representation will be split into StringRepresentation and ContainerRepresentation - the others for int/float/etc. will no longer be needed since the Value can store that directly. ContainerRepresentation will always store Value[] to simplify renderer logic
DRSDavidSoft commented 4 weeks ago

Also the CSS rewrite which I'll be submitting as a PR soon to support auto dark more and some tweaks - sorry been a bit busy at work, but super excited to include this as well!

jnvsor commented 2 weeks ago

6.0-beta7:

Besides a few minor things that can be done after 6.0 releases I have 3 main issues:

I won't have time to put much more work into kint so I'll try and restrain myself from coming up with new improvements before php 8.4 release

@DRSDavidSoft With less than a month before 6.0 has to be done, there's not much time left to review your changes. Will you have them soon or should we delay to a minor version? (I'm not particularly worried about breaking CSS BC)

jnvsor commented 2 weeks ago

6.0-beta8:

Since the rest of my todo list is stuff that can be implemented without a breaking change I'm first going to make sure kint-php/kint-twig and kint-php/kint-helpers work and then prepare to release and put the other changes as issues for a 6.1 milestone

DRSDavidSoft commented 2 weeks ago

@jnvsor Sure, give me a couple of hours so I can open a PR of changes so far, let's track this at #428. It would be nice to see it in 6.0.