The BIG Update
Livewire just got a pretty major update. I made some tough decisions on this one, but ultimately, think we'll be better off.
Transcript:
Hey friends, it has been a tiny bit. Uh, I'll have, you know that I actually did record a bunch of episodes, but. I wouldn't publish them right away and then I would delete them when I went back to record another one because I don't know, that's just kind of how I am. If I don't get something out right away, I end up second guessing it or looking at it and thinking, Oh, that wasn't well done or it wasn't clear enough, and I'll delete it and then just start something else. So, um, that's a bad habit of mine. And I've, uh, done that for the past, like month, almost a month on this podcast. I swear I've deleted. Probably over six or seven. Um, but that's over. So the big update, um, there's been a lot going on with Livewire and that's partially why they been so many videos and partially why I haven't published them, because it's confusing and it's hard to explain and it's frustrating. And I don't know. I don't want to drag you down with me, but I think, uh, or I'm at a point of clarity. I'm at a point of decisiveness, so let me catch you up a little bit. Um. I've, I believe I've done an episode at some point about protected properties, but here's, here's kind of the gist of this. This is the biggest problem in Livewire, quote, unquote. That's what I titled the, this forum posts that I made. Oh, by the way, there's a form. You should check it out. There's a forum post called help me solve the biggest problem Livewire, and this is, this is, this is a problem that has sort of, I don't want to say haunted me, but it's been around since almost the beginning. So here's the problem statement. Live foyer. Livewire, Livewire Livewire PHP is a one shot deal. When you make a layer of all requests, the whole thing just runs and then spits the HTML out to the server and then the user triggers some update, like a URL change, and it does that. Again, their browser, however, has a long running process, so that's why VJs and these other Java Java script is a, there's a runtime in the browser and it's continuously running and waiting for user interaction and whatnot. So in Phoenix live view, a Phoenix or elixir on the backend is a continuous process. So they can create a parody between the backend process and the front end process. So the user's browser session with their JavaScript, and then the servers backend session. Um, and there can be a one-to-one, so there can be a process for user on the page. So they can do all sorts of nice things. Well, I chose really, really early on to not go that route because PHP just isn't there yet. And our PHP WebSockets and an asynchronous PHP, um, there's, there's stuff about it and there's stuff out there, but they're either require extensions or fancy things that just nobody wants to fanangle with finagle, finagle with. Um, so I chose early on, let's just do Ajax. Let's make Livewire. Let's make it's network transfer protocol, Ajax, and so Ajax is stateless. This is a fancy word, but what it means is so a long running incident, instances, state full, it has a state, you can change it, you can mutate it. It lives in one place. Stateless is something that gets passed around, so live where actually lives in the request and response data that goes to and fro a server. I guess Livewire on the front end is stateful, but on the backend it's stateless. So Livewire keeps, keeps track of what the current state of a component is. Then when you make an update, say a click on something that has wire colon click, it sends an Ajax request with the payload back to the server. It hydrates up the component, um, and then it does a taction and then a dehydrates it back to the new data in HTML, puts it back on the front end and rinse and repeat. So I've probably said that a thousand times. I hope you understand that by now. I think that's something that, that's one of those big key pieces of knowledge to understand. And if you didn't build Livewire, I can imagine it's frustrating to wrap your head around and seems odd. It's like hearing a Ave talk about the virtual Dom and how it just means nothing to you. But if, if you had built it, you would understand. And it's not rocket science. Um, but it's just one of those things that, that, uh, you have to kind of open, open it up a little bit to understand or inspect your dev tools, or, I dunno, hear me spew it enough. Times to understand it. So that's the nature of this problem. Um, the problem comes from, we don't have a long running back end PHP instance. So how does this problem manifest itself? So basically all of the data of live wire gets transferred back and forth, like I said. So if you set a, um, you can pass data into a Livewire component right. So you could presumably pass in an eloquent model. And the first thing people tried to do when I launched live wire was save eloquent models to properties. So they would have a property called post, and they would, you know, set post to an eloquent model out of the database. And then they would get an error that says, Hey, you can't do that. You can only set. Like a a raise or integers or strings to public properties, and the reasoning for that is you're sending it to JavaScript. So I either have to serialize the whole PHP object and DCLI isn't whatever. There's so many weird things and up and things in the back of my mind like, well, I don't want to expose somebody's entire eloquent object to the front end. Like maybe they, I don't know, forgot to hide like a password field or. You know, I dunno, I'm exposing the, some part of their internal system. I'm telling the front end could inspect and see what class it is and what name's base. And I don't know, it just doesn't feel right to me. So that's the problem. And you don't actually need to store things that way. You don't need to store eloquent models. You can fetch them from the database, every update, but it's just not natural for people. So my first, my first plan of attack was I'm going to make protected properties. Uh, what people want. You can store anything in a protected property. And my strategy was I'll store it in a cash in the backend, and then when I'm rehydrating a component, I'll fetch the protected data out of the cash from the backend. So that's what I did. And that, that was me choosing the invisible path. That was me making a feature that was invisible. Now, people, when they're learning live, where they try to set up a public property, and. Uh, to an eloquent model. And they'll say, Hey, you can't do that. Um, try sending a protected property. And they do that and it works fine. And they read the docs and it gives them a little description of the differences and when to use what and they understand and they go, well, they go on their way. It's an invisible feature. They don't understand that it's cash in the back end. Even if they do, it's, they don't really understand the implications of that. So that's what I did. And there's some other wackiness I had to do to accomplish that. So it was a lot of magic. A lot of magic went into making that invisible feature. So then there was a GitHub issue that came in that basically said, Hey, back buttons don't work and my stomach just dropped night cause I, it's one of those things that I realized immediately what it was. It's like, Oh, they have a protected property. They've gone to a new page. Now they hit the back button and the protected property is out of sync with their public properties. Um, kind of a long story why that is. But I dunno, when you hit the back button, it loads a cast result of the HTML, which has all the public data encoded in it. So live wear boots up with the initial data that the component has. But the protected data is like the down the road data. So kind of weird to describe, but. I dunno. Um, so that, that's the issue of public data protected data. There's this drift and the drift happens because there's two paradigms going on in live where now each component has stateful data in a cache that's actually like living and lives on the backend and can be mutated and state list data on the front end. The data object that gets passed back and forth. Oh, it's so many words. I'm hearing myself explain to them. I'm hearing myself explain it to myself. And if I didn't know everything about this, there would be kind of sparks like, you know, flying in my brain. And it would, it would not it, but not, it's not an easy thing to grasp. So. So the high level problem is there's two types of data in Livewire. And making those work nicely together is problematic. And because I'm dealing with a cash, you get all the problems that come with dealing with a cash, cash and validation. Um, cash bloat, a cash drift. There's all of these things and there's plenty of different hacks I could have added on top of this system and added layer and layer and layer. To make this, to keep this feature and visible and to keep the feature working and just fix bug after bug bug whack-a-mole. But I opted for a simpler route with the help of my buddy Mitch. We sat down and he walked me through this problem and he's sort of a sounding board for me and, and we kinda hashed out all the different paths and realized. We're happier if we got rid of protected properties and put the onus on the user, which is my least favorite thing to do, it makes Livewire harder to use. I chose to go against the invisible path. Um, I tried to provide some API. Like a recommended API for this computed properties we can talk about in another episode. So I have a couple of recommended ways to do it, but I still get get hub issues right now. We've made the update and I still get get hub issues of people saying, Hey, this thing's broken. Hey, that thing's broken. But really what they mean is protected properties don't work anymore. And then somebody comes in and says, Oh yeah, protected properties don't work. Here's the posts. Go read it. So it pains me inside to do that, but I thought about it a long, long, long, long, long, long time. And at the end of the day, I will be able to sleep soundly. And I think, here's how I can sum it up. I've all this time, like I reached for the invisible features. I want live to feel invisible in native to people, but there's certain cases. Where it almost is deceitful. Like me making this feature invisible, invisible makes it seem like something simple and safe is happening, but it's a really complex system loaded with magic, and it seems to see full, to me now, I feel like I need to expose the underbelly in this way so that users use the tool responsibly. It requires more knowledge on their end, but they'll understand the tool. At a deeper level, and I think that's going to be for the best. I think we're going to be better off and hate developers like complexity, right? So I'm giving them something complex. There you go. Have fun. All right. Thanks.