Perfecting lifecycle hooks w/ Caleb Porzio
00:04.85
Chris Morrell
All right? Welcome back to overng engineered the podcast where we ask the very important question. What's the absolute best way to do things that don't particularly matter I am here today with Caleb Pozio hey Caleb Porzio
00:19.50
Caleb Porzio
Chris boss man Chris great to be here. Thanks for having me.
00:25.00
Chris Morrell
Thanks for coming I Ah you know I often start the episode saying I'm here with my friend. So and so I feel like we're more acquaintances but I have to thank you for ah well you know I don't want to presume here.
00:33.18
Caleb Porzio
Chris why would you say that Chris we played ding pong together for like an hour and didn't keep score there. You go.
00:42.76
Chris Morrell
That's true. okay okay I am here with my friend Caleb Posio who I I think ah I don't know which of you did it. But I think I'm going to give you credit for ah giving me the name boss man Chris which now now I get.
00:58.44
Caleb Porzio
Ah, was that right.
01:00.69
Chris Morrell
I Get boss man dad from my kids which I kind of love. Yeah, it's ah it's pretty fun. So ah.
01:03.20
Caleb Porzio
Um, come on. That's amazing. Um Chris I'm sorry to to prevent you from continuing on but I feel I'm really hung up on this acquaintance designation. You know I'm not going to give passes right away.
01:20.94
Caleb Porzio
I Think our buyer for acquaintance and friend is different. You know what I'm saying like we've hung out in person. We've hung out on like we've pair programmed like multiple times we've had.
01:25.61
Chris Morrell
Okay, okay, yeah, that's True. You know that's true. Okay, that's true. That's a fair point.
01:39.79
Caleb Porzio
Like telegram conversations. We've ah Chris come on now.
01:45.20
Chris Morrell
All right? I right? You're making me feel bad here I just I didn't want to extend here's the thing you know I feel like I knew you more through no plans to emerge for a long time and there's that whole like weird parasocial thing that happens with podcasts and ah.
01:55.31
Caleb Porzio
Um, yeah, right? yes.
02:01.93
Chris Morrell
So I think I'm always I'm always ah very hesitant with like online stuff to like presume that like hey we've been like talking on Twitter for like a while that doesn't really mean anything. You know what I mean.
02:12.72
Caleb Porzio
Right? right? right? Yeah and you were in the position of like because you were the person saying whether or not we were friends or not if you you didn't want to presume and be like oh is my friend Caleb and then I'm like dead. We're not even like that close you know so you were just erring on the side of acquaintance which I totally agree with and the parasocial thing.
02:26.53
Chris Morrell
Um, right.
02:32.52
Caleb Porzio
You're right? However, most of the time if you just listen to a podcast of mine. You would have that but on our podcast you are a character so I have that with you too. You know so it's like I have just as much of a parasocial relationship.
02:44.79
Chris Morrell
That's true.
02:49.15
Caleb Porzio
As you do with me. So I think that turns it into a social relationship I think I think we pinned it down we over thought it and we figured it out. That's the podcast.
02:52.78
Chris Morrell
I All right I think that's technically how that works I think you're right? Okay, we solved it right? I mean that's the whole premise. So okay I'm in ah I'm going to do the pitch of what I what I'm thinking about here right.
03:07.42
Caleb Porzio
Great.
03:09.64
Chris Morrell
So ah, you know, ah Daniel and I are working on verbs. This is our this is our like theory unified theory of event sourcing for Lareville right? You just launched livewire v three ah I had a couple of interesting conversations on top of that around.
03:21.23
Caleb Porzio
True.
03:29.23
Chris Morrell
Um, some features that are being worked on and on like larevell core or like ideas that people are are wanting to Pr that all like fall into this same category of ah lifecycl hooks or just hooks in general. Um, and it's it's a thing that I just.
03:42.20
Caleb Porzio
Yeah.
03:47.89
Chris Morrell
Ah, constantly bump into this question of like how do you make? How do you make package like you know this is mostly talking about like a package code right? Not application code. Um Framework code. How do you make code extensible and really. Flexible ways. Um especially around ah around things that sort of happen in a specific kind of important sequence and like we see this in the framework around like hooking into ah different.
04:16.23
Caleb Porzio
Yeah.
04:26.23
Chris Morrell
Like how how different traits hook into ah tests right? Um, refresh database like that sort of thing like I think of that as like an opportunity to maybe have like a formal hook system I know that Livewire has a huge like life cycle hook.
04:31.34
Caleb Porzio
Sure. Okay.
04:40.39
Caleb Porzio
Yep.
04:45.14
Chris Morrell
System and and verbs is going to as well and so I just like it feels to me like I had this thing like tickling my brain That's like there should just be this concept of a hook that just works across the whole ecosystem.
04:50.86
Caleb Porzio
Um, yeah yeah yeah I mean this? ah interesting I I mean I feel like I'm the guy because I've converted like the entire backend and frontend. To a hook system. So pretty much every feature I write I start with hooks both frontend and backend everything core and plugin and is all hook related and I've written like a handful of different implementations and even just today I did like a hook related addition to make the hooks even more. Flexible. Um, so I think I'm your guy but also there regarding like laravelle lacking these hooks I've found a need for times where you want to like if you want to hook in. Okay, the main hook in laravelle that we use is a service providers. Ah, register and boot method and I have found that it's actually like it's useful to hook into those points from other areas in an application and it's difficult so in livewire like if I want a scope.
05:49.38
Chris Morrell
Sure. Absolutely.
06:05.46
Caleb Porzio
A feature to a specific folder or file but I need it to do something inside. That's at that point in time in the service provider boot to like register a blade directive or something. It's kind of difficult. So and there's no like great affordance in Larryville to do it. So what I ended up doing in the core.
06:13.43
Chris Morrell
Yeah.
06:22.33
Caleb Porzio
Is I take the instance of the service provider and I'm pretty sure this is what I do I forget exactly this might not be 100% accurate I think I abandoned this but I I took the actual instance of the service provider because there's certain methods on provider that don't exist globally.
06:31.10
Chris Morrell
06:41.14
Caleb Porzio
I'm trying to think of of which one it is but there's a few that's like if you want to add like a view name space or something things like that like only exist on this arrow inside of a service Provider. So I've like taken the service provider object and like passed it around to different places so that I still have the ability. To call a method on that provider. But um in my hooks in in livewire I have a static method called provide that gives me a hook into the provider Lifecycle. So from one of my like feature hooks like if I'm developing a new livewi feature like whatever and ah.
07:00.77
Chris Morrell
Um, yeah for sure.
07:18.83
Caleb Porzio
I don't know I can't even think a 1 right now if I'm developing a new feature that involves like a blade directive or something I do that all in my provide method because it's really useful. So whatever. That's a little bit on. Yeah.
07:27.13
Chris Morrell
Oh that's that's pretty cool. Yeah, it's like the it's It's almost like the inverse. It's like a hook that then can reach back out into other places.
07:36.87
Caleb Porzio
Yeah, it it gets called from the service provider those provide methods and I think they get past the instance of the search provider so that I can easily call those those like public or protected methods that normally you can't call from other places. So whatever. That's just a little trick I do yeah.
07:50.79
Chris Morrell
Right? Yeah,, That's cool. Yeah I mean I think it it Also I think probably a reason why a lot of people don't bump into this is really the place where hooks feel the most important. And powerful and also like the hardest to to pin down is when you have a library whether it's lairvell or something like livewire and then you have another library that works with it and so like like lairvell I mean one of my favorite things about lairrevell is. Every time you need to do something you go source diving and usually there's some empty function just waiting for you to put your code into and it just gets called for you. You know.
08:31.79
Caleb Porzio
Um, yeah, yeah, there's always a hack path like yeah I've never.. There's very few times where I've been totally stumped because even if you get stumped with like.. There's not an empty method or something most things are registered in the container and you can you can like wrap them in your own extended class that gets injected in the container and basically do whatever you want? Um, yeah, there's like very very few times that I've been really.
08:56.86
Chris Morrell
Um, yep, yep.
09:06.21
Caleb Porzio
Stumped. So yeah, kudos to lairville for being so hackable.
09:06.38
Chris Morrell
Yes, and those are like application level hooks I would call them right? They're they're like things that are meant to be called from application code right? yeah.
09:17.37
Caleb Porzio
True like a con base controller that it has like a method. Yeah.
09:23.40
Chris Morrell
And and the thing that I bump into is you know say I have a package that I want to I want to register a little like extra something somewhere I can't like I can't I don't want to ask the end user to be like well instead of extending service provider extend my service provider so that.
09:31.37
Caleb Porzio
Yeah.
09:38.80
Caleb Porzio
Um, yeah.
09:42.18
Chris Morrell
I can like also hook into those places.
09:42.61
Caleb Porzio
Right? Like if you want to add some method on to the base Controller class from a package. You're kind of screwed like if you want somebody in their project to be able to use your thing in their controller right from their controller. There's no good story for that.
09:49.63
Chris Morrell
Right.
09:58.52
Chris Morrell
Right? Yeah and like a great example is you know another package that I maintain is modular which I know Daniel has talked about a ah bunch with you like we basically have to extend every single like make.
10:08.60
Caleb Porzio
Um, yeah.
10:16.13
Chris Morrell
Command in the framework just to add an additional argument to them and they're not. We're barely doing anything more than that you know we're just adding another argument and then potentially changing like where the file gets written to um.
10:17.62
Caleb Porzio
Um, yep, yep.
10:28.64
Caleb Porzio
Yeah.
10:32.10
Chris Morrell
But we you know it ends up being this sort of awful hacky thing that I have to maintain and every time like a new change happens to those make commands because I'm kind of like messing with things that aren't really part of the public Api I mean I know you've dealt with that. Yeah, and um.
10:43.91
Caleb Porzio
Yeah, yeah, right? You're on the hook for it. Yeah, tons of times. Yeah.
10:51.73
Chris Morrell
It's like it's moments like that where I feel like if there was a more sort of formal system of like here are all the places where you might want to hook in and they they need to be composable. They need to be like I can stack one. Implementation from this package and another package can push itself into it and then my application can push like its own logic in there. Yeah.
11:14.77
Caleb Porzio
Yeah, right are not replaced like you're not like replacing the other side effects of that hook. You're just hooking in jumping in the pile of people hooking in. Yeah um, should we I don't know your listener like.
11:24.60
Chris Morrell
Um, right is that how.
11:30.93
Caleb Porzio
The level of the listener listening to this. Do they know what we mean by hooks and stuff like like do we need to intro this concept of what a hook is and anything like that.
11:35.83
Chris Morrell
Ah I I think it's okay I mean I would say I would be amazed other than my daughter my my eleven year old does listen to this which is so funny to me? Um, no, ah.
11:45.47
Caleb Porzio
Nice, What's are we do do does the listener know her name is this private information. Okay have you assigned a fake name yet. So that we can at least say Hello Genevive hi genevive.
11:53.30
Chris Morrell
I I don't think so I haven't I should I should think I should ah sure. Um, ah I don't I actually don't think she listens anymore but she did listen the first couple episodes which really made me crack me up. But ah.
12:08.25
Caleb Porzio
Um, how bad that's great. That's all.
12:12.86
Chris Morrell
Other than that I feel like the listener to this. This podcast is very highly technical larevell Pach P Developer I would imagine because we're talking about pretty pretty wild wild things. Um, but yeah I mean what? what would be your definition hook.
12:16.66
Caleb Porzio
Okay.
12:26.19
Caleb Porzio
Um, yep.
12:29.89
Chris Morrell
Because I think it's a useful question. Anyway.
12:31.66
Caleb Porzio
Yeah, um I purposely said hook like you did earlier you dropped lifecycle because lifecycle hook. Well one it's like 1 of the worst names. It's just it screams boring. You don't want to know about me, you know it's kind of like service provider like.
12:43.44
Chris Morrell
Um, right? This is like the bottom of the react docs.
12:48.60
Caleb Porzio
Yeah, right, It's at the bottom of the docks and I unfortunately use it high up in the docks and livewear and alpine. But um I really hate the word and it's like the way the thing we're talking about is more than like like a lifecycle hook to me is like a view component. It's like Mount and destroy or something. Where like a hook can be anything anywhere. You know? Um, yeah so I guess my my definition of a hook is basically how I use them which is from some place in your code anywhere. You trigger a hook you just I call this little trigger method and I pass a name to it and then I pass any parameters that anybody would want.
13:09.42
Chris Morrell
Right? right.
13:27.85
Caleb Porzio
And it's just its sole purpose is just for other people or other places in the code to hook into that without me having to call those things directly and then so to hook into it I have a little on method. So let's say that the trigger is called um I'm trying to think of something not live wire specific. Ah.
13:46.12
Chris Morrell
Um, you can use livewire. It's fine.
13:47.83
Caleb Porzio
Yeah, okay, so like a really common one for me on the frontend is the request of a component when a component makes a request to the server. So I just have like in the codebase when I actually do the ajax request I call like trigger and then I pass the string request and then I pass in. Payload I'm sending to the server. Um, and then anywhere else in the codebase I can just use on and then pass in request and then a callback that receives those parameters and I can have 100 on request you know hooks so to me a hook is that it's just a little trigger with a name. And some parameters and then that's the trigger and then the hook part is the listener that I've I've used the word bull hook and on for that method. Um, but yeah, you hook into that place. You get the parameters and you do whatever you want and that's its most like simple form which it it can expand.
14:40.75
Chris Morrell
Yeah I have been I've been thinking about like because there's the the difference or the the distinction between a hook and an event listener is like a little bit fuzzy.
14:45.13
Caleb Porzio
Beyond like with affordances you know.
14:55.74
Caleb Porzio
Yeah, yeah, true.
15:00.60
Chris Morrell
And it's almost like a hook is a specialized ah event dispatching system where the the intention it this is this is a question that I've been kind of like pondering is is this just a.
15:12.10
Caleb Porzio
Are.
15:17.55
Chris Morrell
Thing where you you just use the event dispatcher but there's a different intention or is there something fundamentally different because the the main differences I see it is like a hook implies that like either what you're passing to the hook might be manipulated.
15:20.20
Caleb Porzio
Right.
15:34.57
Chris Morrell
Or the results of those calls might be used by the code that's calling the hook right.
15:36.46
Caleb Porzio
Yeah, yeah I think that is the distinction when I think of an event like it's It's like purest form is in the browser. You know like a click event or something and there is some some ability of mutation with like a browser click event. But in general I think a browser event is meant the person dispatching the event is just like anybody else is listening to this do whatever side effects you want and that's that I'm doing my own thing where a hook to me is like I'm doing a thing and I'm giving you the opportunity to change stuff right here.
16:02.20
Chris Morrell
Right.
16:13.56
Caleb Porzio
And then the code that follows that trigger might be impacted by what you put inside that hook I might be passing mutable data like an object by reference that you might be mutating even though I depend on 1 of those pieces of data right? after the hook. Yep.
16:18.94
Chris Morrell
Um, yeah.
16:27.51
Chris Morrell
Right? right? or maybe what you return in the callback is then used. Yeah.
16:34.80
Caleb Porzio
Yeah, it might be like a middleware type thing like yeah, changing that. Um, yeah, there's a lot of interesting, very specific things because I went down that road of like returning things and using like middleware type hooks and such. Pretty much backed out of it in favor of just mutating references. You know, um because it it's yeah well a there's just a lot of times where you don't want to mutate anything but you still have to like return the thing you know.
16:53.87
Chris Morrell
Um, oh interesting. Okay, why ah why did you make that like.
17:06.66
Caleb Porzio
Like if you have that cult. So let's take for example just to have like a specific example. Let's use this request thing As an example, you trigger request and then all these listeners that have on request except in the payload that's going to go to the server as a parameter you could make it.
17:14.00
Chris Morrell
Are.
17:20.94
Chris Morrell
Are.
17:25.52
Caleb Porzio
So that you have to return a payload object from that little hook and then every every hook is basically a middleware the problem with that is it's it's a there's a lot of times you don't need to mutate payload. So you still have to return it. But you can even get around that like I had a system at 1 point where if you returned something.
17:29.10
Chris Morrell
Um, sure right? each one has to to return it? yeah.
17:39.52
Chris Morrell
Um, yay sure.
17:44.97
Chris Morrell
Um, yeah, yeah.
17:45.33
Caleb Porzio
You meant to override it if you return nothing then I leave it alone but then you get into like you know it's just as like a little bit vague for the user and then also there's it's inflexible because you might want to add something else to be mutated and now what are you returning to things to return a tuple.
18:00.95
Chris Morrell
Right? right? right.
18:04.56
Caleb Porzio
Or an object of things and it just gets like restricting where if you just pass in payload if payload is an object in Javascript or php it is by reference and you can just mutate it and then you're set.
18:14.83
Chris Morrell
Right? Yeah yeah I mean that's true and I mean even if you have a scaler like the consuming code as long as you're planning for it. The consuming code can accept it by reference and manipulate that too.
18:28.32
Caleb Porzio
True that that does get like really gnarly if you start like passing scalers and trying to like in like take them in by reference and such um, my solution to this is pretty much like I I switched in javascript most of my hooks I stopped passing individual parameters. Instead an object of parameters so that the whole thing by reference and then you're covered with scalrs and with Javascript. You can easily detructure those object params it even looks nicer and the user has they don't to worry about parameter order. They can just destructure the value they want the parameter they want.
18:46.61
Chris Morrell
Um, sure. Yeah.
18:53.78
Chris Morrell
Um, yeah, sure.
19:00.32
Chris Morrell
Yeah, and you don't have to worry about like if you had have to add new stuff to that object is it's much better for sure.
19:02.60
Caleb Porzio
And they don't have to worry if you yeah exactly yes, you don't just keep yeah so a lot of the ph p codebase is still that parameter order thing where then it restricts you now it's like it's a breaking change if you need to like add 1 before something and. Whatever in in Javascript. It's mostly the object syntax which was actually a breaking change between v 2 and v 3 live warrior javascript but it's I did at the last minute and it's so much better. Yeah, yeah, so much better. Yep.
19:26.41
Chris Morrell
Yeah, yeah I I get I think that I have I've been tempted to do kind of what you were talking about before where it's like okay well if you return something and it's of the type. Like we're expecting then use it otherwise just continue to use the original thing and I can see how that would get Brittle. It's like it's a little tricky. Yeah.
19:52.74
Caleb Porzio
1 thing I do so this is the another reason why that's not great. Um, because if in your hook you were. You're returning a value I like to instead most of my hooks you can return a callback from and it's like a follow up so in. Ph p side and in the Javascript side of livewire when I trigger a hook I'm often I'll say like let finish or follow up equal trigger and that variable so I trigger I trigger the hook. Okay, this are in the trigger side I assign the result of trigger.
20:12.65
Chris Morrell
Um.
20:25.78
Chris Morrell
Um, yep, yeah yeah, yeah.
20:30.87
Caleb Porzio
To a callback to this you know, finish or whatever variable and then so in the request scenario with a request you often need to hook into the response. So if I'm just using hooks one off events then it's like I trigger request then you can do something and then I trigger response.
20:38.52
Chris Morrell
Right.
20:49.70
Caleb Porzio
But often you need the request payload and the response It's like you need both and then you have all this cobbly code to like share scope between them or it's so much nicer if now I'm talking the consuming side if you just say on request you accept in the payload and then you can return a callback that is the response.
20:55.23
Chris Morrell
Yeah.
21:06.51
Chris Morrell
Um, yeah.
21:07.54
Caleb Porzio
And now you can you know you have that you have the scope of the request and you can optionally follow up that return callback is like a follow up.
21:16.47
Chris Morrell
Um, that's that's like a common pattern in Javascript. Do you do that in the ph p side as well because I feel like it's cool.
21:20.68
Caleb Porzio
Yeah I do it in the I use it heavily in the php side. And yeah I pretty much like that got lodged my brain from use effect like that to me was was like react's use effect was like okay this is now a pattern and I can.
21:29.11
Chris Morrell
Um, yeah, yeah, yeah.
21:33.50
Chris Morrell
Then.
21:36.28
Caleb Porzio
Use that pattern without feeling like I'm just introducing some random api. It's like no, there's like a ah precedence for this but I will add 1 more thing that I like in the scenario of the request you are hooking into the response but often it's like helpful what if the response fails you know.
21:41.00
Chris Morrell
Right.
21:56.00
Caleb Porzio
It's like oh now is the response. Follow up callback Now What are you dealing with like maybe you give status and print you know and then you deal with So what I've opted for instead is so when you're consuming request like on request. Okay, you get past the payload.
22:09.70
Chris Morrell
Are.
22:14.11
Caleb Porzio
And the first scenario I was describing you were returning a callback to deal with the response. Well now instead when you're consuming you say on request and you can get the payload but you can also get a few other object parameters and they are respond and succeed and fail.
22:19.87
Chris Morrell
Um, ah.
22:30.83
Chris Morrell
Okay, sure right? You're just like getting callbacks that you can then use. Yeah.
22:32.73
Caleb Porzio
And I'm not like sold on the names or anything. But now you can follow up on different things. Yes, Yes, so I found that is actually that that's the ultimate inflexibility is like pass mutable object parameters into the hook. And also pass in their Follow-ups as parameters and then you have to do a little bit of glue work. You know on the trigger end to to deal with like when you call respond and when you call you know you have to kind of aggregate a bunch of individual trick or hook callbacks. But.
22:55.84
Chris Morrell
Um, sure.
23:06.88
Caleb Porzio
Um, but anyway this is what I've sort of found as the most flexible and powerful way to deal with hooks. Um, yeah.
23:12.72
Chris Morrell
So what do you? do you think like what's the what's the advantage there I can't I can't see it immediately. What's the advantage there of using that pattern versus just having additional hooks for those other moments in the request lifecycle.
23:28.73
Caleb Porzio
Right? So here's let me give you a liveware example where I I started down just the return callback Follow up path and then I had I got kind of bit by it. So when a live warrior let me just get this right? It's like when you're maybe it was render.
23:38.55
Chris Morrell
Okay.
23:48.53
Caleb Porzio
There's some callback where it's like I want to hook in or maybe it's maybe it's mount It's like a component's mounted and then I want the return callback to be like the html I don't know I needed some 3 chain not just to. Trigger and follow up I needed 3 things I needed like the trigger is like mount the follow up is like the html that's returned or something and then the follow follow-up is like the of the final html or the whatever maybe the second one is the. The blade view that's going to be rendered and then the third one is the html that gets rendered. It was like I needed a 3 chain if I didn't use that 3 chain and I just had individual methods like mount and you know html or whatever you end up with all these conditionals like if the thing.
24:27.78
Chris Morrell
Um, great.
24:39.71
Caleb Porzio
Like if you don't do that 3 chain if you just have like listen for mount then listen for render that you have all these conditionals like I only want to respond to the render if something happened in mount so I have to set like an outside variable and there might be scope that mount passed that I have to set by reference outside of it so that I can use it in the listener.
24:47.75
Chris Morrell
Right? right.
24:55.51
Chris Morrell
Um, right? Yeah I can see. Yeah yeah.
24:59.15
Caleb Porzio
And there's all just all sorts of things that it that it gets like totally oh and also like if it's ah if it's an event sent from a component. You might be hooking into it for like that component. But then the render hook it's going to trigger for every component. And you have to like scope that reaction just to that specific component. Um, yeah I don't know it just gets really gnarly. So I've again found that like a solution to that was Return. A follow up callback and then enable you to return Infinite Nested follow up callbacks to like.
25:20.19
Chris Morrell
Right.
25:33.74
Chris Morrell
Um, right? yeah.
25:34.59
Caleb Porzio
Hook in all these stages and it's like this is stupid just just pass a parameter that somebody can call and pass in their follow of callback. It's named um and they can do anything they want. So if anybody's still following that like those are kind of the hurdles I've found with all the stages of the lifecycle hooks stuff.
25:51.69
Chris Morrell
Um, yeah.
25:53.63
Caleb Porzio
And where I've kind of come to is like this works for me, you know.
25:58.42
Chris Morrell
I Like that as a pattern I mean I can imagine maybe having like a more formal concept of like ah like you know hook context or something like that where you could generalize that but I.
26:14.10
Caleb Porzio
Yeah I I do have like component context that because they're yeah I have you're right that especially in Php where you can't just create like a quick you know, um, object literal. You know like you kind of can.
26:16.10
Chris Morrell
I get.
26:31.47
Caleb Porzio
But in php it's it's in Javascript you can just make an object literal now. It's mutable. You pass any paras you want in php it doesn't feel like that you could use like standard class but then or like Json and code decode to an object to get them mutability. But then yeah, just it doesn't.
26:31.48
Chris Morrell
Ah, yeah, it's not yeah.
26:48.78
Caleb Porzio
Php you end up making a class and whatever. So yeah, maybe there's a context class that's like built into the system that's meant for this kind of thing that has all the juice on it. That's not a bad idea.
26:52.70
Chris Morrell
Um, yeah.
26:58.16
Chris Morrell
Yeah, or like ah like a sequence like a hook sequence where it's like you pass in a bunch of hooks and they only fire if they like if like they only fire if they fire in sequence or something like that. But in the end I mean honestly, just passing a couple. Callbacks that you can use feels a lot better I think.
27:19.77
Caleb Porzio
It's so nice. Um, yeah that that part kind of feels like again I'm not using that heavily in the ph p side I am in the javascript side because it's so much more flexible and simple and PhHP I would have to like build it out as a cunts you know what I could just do it in ph p it'd be no problem.
27:33.85
Chris Morrell
Right? There's there's no difference. Really yeah that I can see that there's There's probably some like there's more complexity hiding in like how do you orchestrate calling all those callbacks in like the right sequence.
27:37.63
Caleb Porzio
There's no difference now.
27:51.91
Chris Morrell
Ah, in the at the right times I would imagine.
27:53.29
Caleb Porzio
Yeah, well the thing is is that you control it. You can you know the person triggering the hook you control when those callbacks are run so because it has to be that way. It has to be bespoke. You know.
28:03.86
Chris Morrell
Right? right? right.
28:09.56
Caleb Porzio
And that's the beauty of it coming up with like clean Apis for it that aren't like the most gnarly implementations ever is not the simplest thing like you need some ah helpers because if you think about it like already you have a we talked about a hook is not just like a trigger happens and then only one hook happens. Like everybody who hooked in has a callback that needs to get run and passed these things in an order these follow ups have to be aggregated as well. They have to be collected. That's another problem I fortunately, there's inherent priority.
28:31.10
Chris Morrell
Um, right right? Yeah yet, do you deal with any like priority handling in any of that.
28:47.33
Caleb Porzio
In when on is called the first person to call on on that hook is going to get run first so because a lot of this stuff is core I can just change the order that the listeners are registered in you know, like if.
28:51.89
Chris Morrell
Yep yep.
28:58.42
Chris Morrell
Um, yeah.
29:00.94
Caleb Porzio
Feature needs to take priority over another feature I can put that higher up literally in like the file that includes that feature but there are times where it's like oh I am in some random file and I need to hook into the response before Morphdom does anything in liveware like I need to.
29:05.16
Chris Morrell
Um, yeah.
29:17.64
Chris Morrell
Um, right? Yeah yeah.
29:19.16
Caleb Porzio
You take that html before more thumb happens. So I just want to be able to there's you could go so deep with like priority and such but I think the simplest thing that I've used is before and after so it's like I have methods. There's on that just is a listener then there's before.
29:31.39
Chris Morrell
Are.
29:38.25
Caleb Porzio
Which is just on with top priority and then there's after which is bottom priority and if that's not enough for you. You're really in the weeds and you're you're playing with fire. Um, because you're creating order dependencies. Anyway, it yeah.
29:38.89
Chris Morrell
Um, yeah, yeah, yeah, sure yeah for sure. Yeah.
29:55.97
Caleb Porzio
So on or before and after have worked for me of just like bump to the top bump to the bottom you know? Yeah yep.
29:58.61
Chris Morrell
Yeah, that I mean that feels like enough for almost all cases. So okay so I can I can imagine a world where there is basically a generic thing called a hook right.
30:15.33
Caleb Porzio
Um, yeah.
30:17.30
Chris Morrell
And you can fire a hook I would argue that like you should be able to chain on as many for lack of better term right now like life cycle moments for that hook right? So I'm imagining a world where I do like Hook Colon Colon make ah, request right? And then I can do like ah you know arrow incoming and that are you know arrow.
30:37.37
Caleb Porzio
Um, yeah.
30:48.10
Caleb Porzio
I see.
30:53.90
Chris Morrell
Life cycle I don't know and give it a name like incoming aero life cycle outgoing or whatever right? So these are like the 2 moments of the request hook. Um, and then I would call like fire and pass in the arguments right? and all of my like consuming.
30:54.61
Caleb Porzio
Um, yeah, whatever. Yeah yeah, yep.
31:08.75
Caleb Porzio
Gotcha. Yep.
31:12.62
Chris Morrell
Anywhere that I had registered to like you know interact with that hook I would get basically all of the arguments that had been passed into fire as well as a callback for every lifecycle moment that I had registered on the hook when I called it.
31:23.10
Caleb Porzio
Yeah.
31:30.80
Caleb Porzio
Yes, yep.
31:31.60
Chris Morrell
Right? to just sort of like generalize that concept So you're not just like passing random functions in then having to keep track of them and then the hook system like when I get I would just like get back The result of that call as like a you know.
31:37.23
Caleb Porzio
Sure.
31:47.20
Caleb Porzio
Hook object or something. Yeah.
31:49.89
Chris Morrell
Ah, hook object that then I can I can then just call like hook call incoming and pass more arguments into that and then hook call outgoing and pass arguments into that and just like have the system handle with all the orchestration.
31:55.96
Caleb Porzio
Um, yeah, yep.
32:06.70
Chris Morrell
You could have a ah little bit of like an Api around like before and after and like maybe some sort of thing where like if you need to you can like manually push your your like callback into the collection in like the exact place that you care about.
32:26.17
Caleb Porzio
Yeah, yeah I think that's yeah, that's good. Um, right. The only part of so that's good and that would solve the problems. The only part of that that's like fuzzy on an api level or K two like random hangups with it one.
32:26.34
Chris Morrell
Um.
32:42.86
Caleb Porzio
It's very PhHP which is you know fine for ph p but like Hook Colon Colon make I'm already like ah like can't this just be a function called hook and it can be sure. Um, so I can solve that by just making a function done that internally calls hook make fine if you say hook on Colon make you specify name.
32:55.77
Chris Morrell
Sure.
33:02.41
Caleb Porzio
And now you're specifying lifecycle chains like arrowincoming you know and then a callback that Er oh right? Okay so I guess this is the part where it's like those are names bespoke hooky names incoming outgoing. They're whatever the user wants to call them. Um.
33:18.90
Chris Morrell
Um, yep, whatever you need.
33:21.15
Caleb Porzio
How do we take those names and use them throughout. You know so is it a magic function when you're saying hook Colon and call and make request. You're saying arrow incoming is that a magic function that.
33:32.25
Chris Morrell
Well I would probably do like arrow life cycle or arrow the break point or you know like that and you just give it another name and that would just turn into a.
33:40.58
Caleb Porzio
Yeah, yep.
33:50.56
Caleb Porzio
Yeah.
33:51.80
Chris Morrell
Closure That's passed to the hook and then on the object that you'd get back. So that's on the the like consuming side you are like code that's hooking into things would get get a function with that name for each like breakpoint that you add then on the end.
34:06.13
Caleb Porzio
Right.
34:10.81
Chris Morrell
I call that hook and I get back an object that now has you know magic methods on it essentially or or you could just like call have a method called call breakpoint or whatever or call lifecycle that you passed in that name again and now that would orchestrate calling all of the callbacks for each hook.
34:23.35
Caleb Porzio
Right.
34:30.63
Chris Morrell
That had been registered.
34:32.43
Caleb Porzio
Yep yep Yep Yep yep yeah and the and the rest is just how you want to do the api like I could see so let's say you just call those magic methods on Hook make or maybe they're not maybe they're break point or whatever and then you or hook. Um.
34:45.10
Chris Morrell
I Kind of like breakpoint.
34:48.50
Caleb Porzio
Yeah, breakpoint's not bad. So maybe it's breakpoint and then you pass in a name and then now you have that hook object and you call like hook Arrow Call break point or something you pass or maybe it's called break and then you pass in the name of the breakpoint and then any parameters you want to pass to it and now on the consuming end you say.
35:05.90
Chris Morrell
Um, yep.
35:06.96
Caleb Porzio
Hook hold on or whatever pass in the name and then a callback that receives the initial hook parameters. But maybe there's also a like a context object like a hook object on the consuming end that you would say arrow and then maybe it's a magic method called in coming or maybe it's just breakpoint and then it's like a breakpoint listener.
35:25.14
Chris Morrell
Yeah, or it could just be that it spreads closures into the arguments. So like I just get each breakpoint in the order that they're defined I mean I guess.
35:26.12
Caleb Porzio
You know.
35:31.62
Caleb Porzio
Yeah, yeah, guess the only random problem with that for me is just it feels like you're defining a magic string at the trigger end and then on the breakpoint end. So even just for something as simple as.
35:44.48
Chris Morrell
Yeah, yeah, yeah, no I get it.
35:49.89
Caleb Porzio
Is because the primary drawback of using hooks and triggers is that you can't follow the code anymore because it goes into a bus. So the way to follow code for me often is global find in my project and then that string you know that hook string. So.
35:58.24
Chris Morrell
Um, right.
36:07.49
Chris Morrell
Um, yeah.
36:09.12
Caleb Porzio
It's like to use a breakpoint as a magic string at the trigger level but then a magic method at the listener level kind of like neuters. The find replace story.
36:14.23
Chris Morrell
Um, all right? How about this, you just pass in a breakpoint breakpoints object as the last argument to the the listener.
36:27.19
Caleb Porzio
Um, yeah.
36:27.22
Chris Morrell
And that object has some like function has some methods on it that you can call if you prefer that syntax but it's also invocable so you could just do breakpoints ah open parents and then just give it the name and then pass a closure as a second argument and you get basically.
36:31.64
Caleb Porzio
Yeah.
36:45.49
Caleb Porzio
Yeah, that right just pass a like breakpoint closure. Um that you can just call it I mean it can just straight up you we could just offer it as an invocable thing that like breakpoint always accepts.
36:46.34
Chris Morrell
The same api as what you're you're describing just with one object. Yeah.
36:59.88
Chris Morrell
Um, yeah, exactly.
37:01.60
Caleb Porzio
The string of the breakpoint and then a callback to receive the parameters of the breakpoint. Yep.
37:04.29
Chris Morrell
And like in a lot of cases if they're simple, you can just do it in arrow function. So you don't even have to worry about scope. You just have access to the scope inside of your main hook call like that would be pretty cool. Yes.
37:15.23
Caleb Porzio
Yeah, right? Yep yeah, That's the other drawback of Ph P is all the uses. But um, but even that yeah, whatever it's just part of the part of the thing and yeah, you can use short closures. So Yeah I mean I like that a lot I think the break kind of hardening that Breakpoint. Concept is useful. Um, yeah, that honestly if I had started with that like I my journey through hooks and triggers and everything is codified in the code base at every point you know unfortunately and it would be great if I could start fresh and just have like like.
37:43.00
Chris Morrell
Right.
37:51.28
Caleb Porzio
I mean why we're here a codified um cant ah like Canon Hooks canon it's like these are the words this is the api you can see it and use it in Javascript. You can see it and use it in php. It's simple like it could be a github gist to save you the hour. It'll take you to build it. You know.
37:55.97
Chris Morrell
Um, yeah.
38:08.89
Chris Morrell
Um, right? Yeah yeah I mean I feel like we can. You can handle priority pretty easily there right? because that you know that that um, the breakpoint object could handle its own.
38:10.44
Caleb Porzio
Yep.
38:26.62
Chris Morrell
Priority and the hook call the initial hook call could handle some priority. So if I need like you know I'm kind of thinking probably you just use an integer and you just like say before is starting at 0 and after is starting like 10000 and everything's registered at like 5000 or whatever and then like you can push things.
38:36.96
Caleb Porzio
Um, yeah.
38:43.38
Caleb Porzio
Yeah, a Z Index for priority. Ah true.
38:45.92
Chris Morrell
Into other spots if you need to with like a special method and like that can just exist on both the breakpoints and the initial hook call.
38:54.77
Caleb Porzio
Yep Yep! okay.
38:56.35
Chris Morrell
Yeah I mean the only other piece that I can think of is like sometimes you need to like halt right? like there's like yeah, it's basically stop propagation right.
39:09.45
Caleb Porzio
Yep, ah prevent your stop propagation I've done that like in my hooks I'll pass a callback called stop propagation that does that I'm trying to think of the point where I've needed that. But I think it's it's um.
39:15.43
Chris Morrell
Um.
39:19.39
Chris Morrell
Yeah.
39:25.70
Caleb Porzio
I Think even error handling in livewire like validation errors and stuff like there's times I need to hook into exceptions that are thrown in livewere. So I actually have like a try catch and that catch fires a trigger and when you're listening for that. There's times where you need to bail out. Um.
39:42.86
Chris Morrell
Um, yeah.
39:43.73
Caleb Porzio
So it's only 1 or 2 plays in the codebase but I have used the stop propagation pattern to basically allow a hook to prevent going on. So yeah, build it. You're right building it in in the system. So we got like aggregate hooks breakpoints and aggregate breakpoint calls bespoke breakpoints and then. Ordering numerically and then a stop propagation mechanism to prevent everything else from reacting problem solved done that I mean honestly, those are all of the points. Good point on the stop propagation because I have needed that and I totally forgot about that. But those are.
40:10.91
Chris Morrell
Bam! We did it.
40:20.52
Caleb Porzio
Those are that's it. That's a robust hook system that any more robustness you you wouldn't even need I can't even think of something you would need but I would be really like you know it's I don't know I think this is a solved problem I think we just solved it I think we cracked the code.
40:27.40
Chris Morrell
Right.
40:36.41
Chris Morrell
Okay, so so here's here's the test right? because I have a few pet places in the framework that I would love to see this happen in Laval right? So I have noticed ah somebody somebody maybe isn't thinking about the problem.
40:44.35
Caleb Porzio
Um, yeah.
40:52.90
Chris Morrell
In this way, but someone is aware ah and thinking about it a little bit in like Apis that have been added because like I have you know there there are a bunch of places in Laraville and I'm blanking out on that on one. So maybe you'll have one where there's like a static like. Create x using or like do something using and you just can pass it a callback and if you don't do it. There's like a default implementation that laraville calls but you can just like pass different different classes like so ah, a callback and they just use them if they're there.
41:28.17
Caleb Porzio
Okay.
41:30.31
Chris Morrell
That's that's like a pattern throughout the framework. Um, and I feel like all the old ones accepted a single closure and replaced a ah you know it replaced a single property on the the class itself and.
41:44.60
Caleb Porzio
Yeah.
41:47.10
Chris Morrell
All the ones that have been created anytime recently basically push that closure into an array and then loop through the array I mean to the degree that it makes sense. There are some places where you wouldn't want to have it be and that's actually an interesting question.
41:52.37
Caleb Porzio
O.
42:01.28
Caleb Porzio
I got I got a ah laravele example of this for you if you want to hook into larave's pagination. You say like whatever pagination and then Colon Colon resolve and now like your.
42:05.52
Chris Morrell
Okay.
42:21.21
Caleb Porzio
The person resolving the paginator instance and you can um you can basically use it. However, you like instead of this is how livewire overrides the paginator to do its own pagination. Um.
42:28.96
Chris Morrell
Right.
42:37.75
Caleb Porzio
There's yeah those the there's those anytime in layer ofll I think what you're talking about is anytime you see resolve or resolve using which has been. There's been more and more resolve and resolve using type things in Laravell and I think is that what we're talking about.
42:43.19
Chris Morrell
E.
42:51.89
Chris Morrell
Well, that's one of them I mean the one that I can think of is like the queue has a create payloads using static method that basically you can register a callback and it's going to cycle through that all those callbacks and essentially like let.
42:58.81
Caleb Porzio
Okay.
43:04.45
Caleb Porzio
Yeah. Um, yeah, sure. Okay.
43:10.79
Chris Morrell
Multiple callbacks kind of push additional stuff onto the queue Payload right? And that's useful. You know the the like bugsnag ah package will like put some other stuff on there or like um and so that's an example where that is a hook.
43:18.80
Caleb Porzio
Yeah, just hooking to yeah yeah.
43:28.90
Caleb Porzio
Honestly hooking in the handle would be great and maybe there is a way in Larall but just like or even like hooking into database queries to like log time and stuff any sort of like logging of like time performance and database stuff and exception handling like basically anything.
43:38.18
Chris Morrell
Um, yep, yep.
43:45.37
Caleb Porzio
When you install like the bugsnag package. They probably want all this stuff so you don't have to like you know, add something to your own handler in your file or or override the handler. Yeah.
43:47.80
Chris Morrell
Right.
43:54.46
Chris Morrell
Um, and there's a way I mean there's a way to do it right in almost all these cases to some degree some of them are not as flexible as I would like especially older Apis like don't account for potentially wanting to have like multiple hooks registered.
44:09.32
Caleb Porzio
Yeah.
44:11.62
Chris Morrell
Um, but you know in most cases there is a way to do timing or logging or whatever. Ah some other way but it would be really cool if there was just sort of like a unified way to approach all this stuff. You know.
44:24.71
Caleb Porzio
So Here's here's the so this is great because what we've we've already we've we've started with the premise that hooks are useful and good for extending and building like modular systems. And now we're identifying where Lairve falls short with that and how nice it would be if Laravelle used what we're describing this sort of Universal hook thing. So a bugsnag package could easily hook into something logging right? I'm assuming you have some kind of wordpress background.
44:56.13
Chris Morrell
Um, yeah, Wordpress definitely has a million concepts of hooks.
44:58.43
Caleb Porzio
Yes, so like I remember when I was digging in a wordpress development like building plugins and stuff. It's like you can do anything you want to do because you can hook into anything and that experience sucked and I have such a bad taste in my mouth for that I bet.
45:10.93
Chris Morrell
Um, yeah.
45:17.21
Caleb Porzio
Like if there's a a sufficiently talented wordpress developer on here. They're like oh my gosh. It's actually amazing because whatever. But I just remember that system feeling so using it doesn't feel ergonomic. It's overwhelming and it's indirect where like when you're. Interacting with your laville application. It's well-documented. There's like distinct Apis that feel ergonomic and you can source dive where it's setting the thing and calling the thing. Maybe that's what it is is like I've eaten the cost of lack of source diveability in my project.
45:53.87
Chris Morrell
Um, yeah for sure.
45:55.23
Caleb Porzio
But in Laraval if I lost that ability. Ah that would suck because it's not my project. You know, great. Okay.
45:59.10
Chris Morrell
Yeah I mean okay I have I'm going to push back a little bit I have 2 thoughts there my first. My first thing is I do think that wordpress hooks could be a nightmare to deal with.
46:14.96
Caleb Porzio
Yeah.
46:17.90
Chris Morrell
I Also think that wordpress's success is almost entirely because of the extensibility that that comes through the hook system. The reason that so many packages can do the things that they can do is because almost.
46:19.98
Caleb Porzio
Yeah, true.
46:33.64
Chris Morrell
Every function in like wordpress core has multiple hook calls in it to like hook into the beginning and the middle and the end and like after the end you know like there's a million hooks everywhere.
46:38.53
Caleb Porzio
Um, yeah.
46:44.80
Caleb Porzio
Yes I got a lot of like knowledge and hook inspiration just from New Wordpress like their new hook system or whatever. It's kind of been the same thing for a while. But um, but yeah, like everything we're talking about Wordpress uses fundamentally.
46:56.98
Chris Morrell
I Think you're right though that that shouldn't be the like the the the thing that makes it bad in wordpress is that is the primary interface for everything right whereas I think.
47:09.38
Caleb Porzio
Yes.
47:14.10
Chris Morrell
That hooks lend themselves to specific moments in time and shouldn't be. It shouldn't be the every single feature that you're building requires like you know you're basically talking about like a fully like evented.
47:18.55
Caleb Porzio
Yep.
47:26.13
Caleb Porzio
Yeah.
47:33.58
Chris Morrell
System not like but not like event source system like just a system that is fully like listening for events and firing events right? which is so hard to reason about in general and that yeah I don't think that anybody.
47:40.98
Caleb Porzio
Yes, yeah, yep.
47:53.31
Chris Morrell
Should have to do that That is not the solution to like or that's not the new paradigm for laravell by any means like that's not good.
48:02.40
Caleb Porzio
Yeah, it's it's so tricky because I'm the offender in this case where I've totally wholeheartedly gone in on you know what? though? Actually this is this is good here's here's a counterpoint. Um. But's say laral goes to this universal hook system. The way wordpress has again I told you my like just gut reaction is like oh no, you like following the premise. Everything's good then I'm like oh wait we did this in wordpress didn't feel good and let's say that that exists in Laraville I mean the problem is that. When you introduce hooks like this like here's the problem in wordpress you install a plugin and yet it's crazy powerful and can frickin overhaul everything but it adds all sorts of ah like maybe there's slowness. Maybe there's weird side effects to other parts of the system that you don't you wouldn't expect it to so you're like wait like. Why is this thing so slow. Oh because this plugin is hooking into that process and it's slowing the page render or slowing saving a new post or or parsing ah the tags. Whatever those like short tags or something so that feels horrible as a user.
49:09.23
Chris Morrell
Um, yep.
49:12.15
Caleb Porzio
You know it just feels horrible and similarly with larall if let's say all it's exception handling it. It might even be this way but let's just say it's all like what we've described with our hooks if you install bugsnag and everything works magically. But then there's some slowness or something you can't pin down. You're not like going into vendor. Bugsnag bug snag find all that a certain you don't even know what string to look for it just doesn't feel great where in the the alternate universe the one we have right now which isn't hooky. It's like oh I know where to look I'm going to look in my handler because I have control over my handler and I let bugsnag into my handler. I gave them that and I know I did that and it's in their docs because I had to add it to my app. So it's friction this same argument could be made about auto registering service providers that before you had to you had to handwrite in the service provider and the facades you wanted included in your app from a package and now they're package Json. Can just auto register their own service providers which is awesome, especially for stuff like liveware where I want it I want zero config. It's like now you actually don't know where to look for stuff and you don't have control over it. It's that's that's that push and pull that tradeoff of this that indirectness that it introduces and it really.
50:24.53
Chris Morrell
Yeah.
50:30.33
Caleb Porzio
Not only does it introduce that indirection of like um, just following code. It also removes control from the user from their Application. You're like taking things away from them. Um, which is good for their onboarding and experience. But. Bad for their discovery and all that you know.
50:48.10
Chris Morrell
Yeah I mean I think that my my my main feeling there is like I'm not proposing that like I don't think that I don't think that the framework should add basically any new hooks like the only thing that I could imagine is introducing a new hook.
51:02.21
Caleb Porzio
Yeah.
51:07.58
Chris Morrell
System and like in lairville 12 replacing all the like just just unifying all the different ways that the framework allows for this like reaching into different components and adding callbacks and just make it all work the same way and like.
51:22.22
Caleb Porzio
Yep.
51:24.95
Chris Morrell
That would even make things more discoverable because potentially you could just have a like Pgp Artisan Hooks list method now that just are a command that just lists all the registered hooks right? It'll give you all the locations and all the the files that are calling it right? like you would basically be able to go.
51:36.34
Caleb Porzio
Yeah, yeah.
51:44.74
Chris Morrell
To like more discoverable not less and you're not like making anything because right now I can go you know Queue Colon Colon create payloads using and give it a callback and.
51:47.16
Caleb Porzio
Yeah, yeah.
52:03.10
Chris Morrell
That will hook into the queue system and like and the difference is I happen to know that but like the way that ah using like refreshes database on my test like the mechanism that makes refreshes database.
52:03.67
Caleb Porzio
Yeah.
52:22.57
Chris Morrell
Call the right things at the right time is totally different from this mechanism and that's totally different.
52:24.79
Caleb Porzio
Yeah, yeah, so the only way to find this stuff is to go in the docks for all the different points that there's these extension points where if there was a reference of global hooks like you could just read through the list of 50 or 15 and see them all and.
52:37.27
Chris Morrell
Um, yeah.
52:43.00
Caleb Porzio
And know what's available to you? Um, yeah I agree in the areas that it's already kind of doing its own hooking in different points. You could unify it and then it would be like a single it would be more discoverable in a sense? Yeah, um, yeah.
52:56.65
Chris Morrell
And then like verbs could just use the larevell hook system Livewi 4 could just use the Larelle hook system like and it wouldn't be a new concept for people to learn when they come to your package or like and a slightly different api for the same problem.
53:12.69
Caleb Porzio
Um, yeah, true right? Like I've wore ads on to this list. Yeah.
53:16.42
Chris Morrell
Just be like oh like live war. Yeah, this is just another hook. This is a livewire hook. They'd just be namespaced like everything else it be livewi Colon Colon mounted or whatever you know what? I mean and like if you wanted to add an internal function that abstracts away some of the the you know.
53:27.70
Caleb Porzio
Yep.
53:35.60
Chris Morrell
Um, stuff you can.
53:35.67
Caleb Porzio
Yes, so I think I think you're right Chris and I think because what what you're saying is like they're already doing hooks. It's just not universal and so there really isn't anything to be lost by choosing a more universal approach. So I agree. Um. So the thing I'm about to say it's not saying but because you're right? Yes, full stop Um this but is just another layer on the hooks versus non-hooks tradeoffs like first is just like indirection in general. That's just a problem that it just exists a tradeoff.
53:54.19
Chris Morrell
Okay.
54:05.78
Chris Morrell
Um, okay yeah, yep for sure.
54:11.28
Caleb Porzio
And then so this I guess I'm fleshshing out the second con that I'm trying to describe that is ah user control. It's like a zillion hooks gives gives a ah user or an extender complete control. Um.
54:15.86
Chris Morrell
Um, yeah.
54:25.73
Caleb Porzio
But yeah, it's actually there's there's the extender and the consumer you know there's the library maintainer like you and me and we have complete control but we are potentially robbing the the owner from some of that control in this sense like let's say let's just stick with the exception handler scenario even though I don't think it's. Right one if if instead of having your own app handler It just fires some handler thing that all these packages can hook into and do stuff with the handler. For example, detect if it's a certain status code and return a payload of a certain shape or return us a different screen or something when it's a specific. Error status code or something. Um, so that's good in all the ways we described but in the the control way The it's the same thing as using private or yeah private classes you know or what are they final Classes. You know right? which everybody hates.
55:16.40
Chris Morrell
A.
55:21.26
Caleb Porzio
Um, so I'm I'm giving a pro to final classes even though I've never used one but when I so for example I was writing a feature. Um yesterday that is a but it might not be in live way or not but it hooks into the html that gets returned from the server and mutates it.
55:39.82
Chris Morrell
Sure.
55:40.91
Caleb Porzio
So The work I was doing in there though if I hook if I wasn't careful I'm very aware that like oh this thing is going to get called every single time any liveware component returns Html. So I Want to be careful to not penalize all requests. So I Add a little bit of juice to conditionally process what I need to process only when I need to process it so that I'm not introducing any extra overhead but hooks make it so that you don't have to be good like that where when you're not using hooks. You You are inherently good like that because you just have normal imperative code like if this thing then do this thing where with hooks it's like tempting and I I find this actually this is really relevant because almost any time I'm using a hook I have it in my head that this hook if I add a hook. Even if it's just got a single conditional to not do itself. It's still an extra callback in the stack with a conditional if that conditional depends on querying something in the Dom. It's like that ad slowness and then if inside that hook I do something that I'm very acutely aware of when it runs and to be careful to minimize that impact. And I think that requires a lot of developer knowledge about the whole system and so it's almost like I don't trust you guys to use my hooks So I'm not going to document them. There's a handful that I don't document um because they're not public I'm using them but don't use them.
57:09.44
Caleb Porzio
Don't I'm not telling I'm not advertising it because you're probably going to abuse them and you're going to hurt the whole application. So that's along those lines of the owner control the owner of the app is like if there's no hooks you have full control people extending. It have a harder time wordpress is so successful because. Everybody gets to extend it and you have all sorts of powerful plugins. Um, but it also is at the cost of the integrity of the system. So for Taylor to maintain an experience where the community where you're in in the ecosystem and you're installing packages into your app and whatever it. Increases the likelihood that everything is going to be stable and sound and and harmonious when there's not extension points flying all over the place you know or when they are so I think it's just a It's just a tradeoff I'm not saying it's a blocker but it is a tradeoff.
57:57.74
Chris Morrell
Yeah I mean and and I think that that's like that's like part of the reason why Laravelle is good and not bad is that like the right tradeoffs have been made right.
58:11.36
Caleb Porzio
Yeah, yeah.
58:14.23
Chris Morrell
And I mean that's like that's the thing that Taylor has done so well is just like be willing to bring things in when there's really going to be value even if like you could really shoot yourself in the foot with it right? and not be willing to bring things in that like.
58:29.26
Caleb Porzio
Yep yep.
58:33.32
Caleb Porzio
Yeah, yes.
58:33.63
Chris Morrell
Have undeniable value but like are just not worth it right? and I feel like this is the same thing like there are undeniably valuable um places where having these types of extension points just makes sense. Um.
58:51.45
Caleb Porzio
Um, yeah.
58:53.70
Chris Morrell
And like it's up to like the like the the lairvell maintainers to kind of like decide because they're I mean they're already making these decisions right? They're they already decided that like you know, ah I just saw another one and like well yeah, ah create. Payload using on the queue. That's one that was what I have like they already decided that that's worth it to be able to hook into that moment for various reasons right? and I think they're right like I think it's 100 % a good thing to be able to hook into and so yeah, like all things like you can abuse.
59:18.79
Caleb Porzio
Yeah, for sure. Yeah.
59:31.72
Caleb Porzio
Yeah yep I think strings in in our hooks I'm just thinking about what you were saying about Taylor and taste and knowing the right tradeoffs when like ah, let's say that you make a giant Pr that introduces these hooks and let's say that Taylor's not necessarily intimidated by like.
59:31.98
Chris Morrell
You can abuse any tool right? Um, or.
59:49.90
Caleb Porzio
Breaking stuff or whatever. Um I think his taste and similarly my taste although clearly I've already accepted that tradeoff is strings are gross and not aesthetic and he cares so much about how that code looks and the.
59:51.27
Chris Morrell
Um.
01:00:05.18
Chris Morrell
Um.
01:00:08.81
Caleb Porzio
Prettiness of it where like q Colon Colon something using and then passing a callback looks like it fits right in. It's beautiful passing in a bespoke string feels gross. You know, like any time there's a bespoke string. It is now not aesthetic.
01:00:20.48
Chris Morrell
Oh I would still have a helper function for it. Yeah.
01:00:26.34
Caleb Porzio
Um, I see what you're saying it would just you under the hood. You would have the bespoke even so. But yes, you're right? because there's there's bespoke strings with the container. You know you're just yeah, you don't You're not typing in a a string. Yep, you're not seeing that green.
01:00:32.38
Chris Morrell
Yeah, there are strings all over the framework but you just don't have to think about them. Yeah I mean like when you call the request helper All that's doing is app string request right? like yeah, all that stuff. Yeah.
01:00:45.27
Caleb Porzio
Yeah Blade dot compiler. Everything is just yeah, yep.
01:00:51.61
Chris Morrell
So I don't think I but I do think yeah I I think that that is um as I get older I find myself less and less willing to put up with just like magic strings. You know like I can accept.
01:01:06.58
Caleb Porzio
Yeah.
01:01:10.36
Chris Morrell
That they are useful in in different places. But like if I can avoid having it be a string I Do you know and I you know? yeah and yeah, been been really loving enoms lately I've been.
01:01:16.16
Caleb Porzio
Yeah, of course yep so I got E Numbs constants. Yep, nice.
01:01:30.13
Chris Morrell
And like as a I feel like I have I had mostly been thinking of enoms as like kind of a list of strings or integers. But I've been I've been doing a few things where like the enums aren't actually even backed by anything right? It's like a more pure enumeration and it's it's cool to just be like.
01:01:36.27
Caleb Porzio
Yeah.
01:01:42.45
Caleb Porzio
Yeah.
01:01:49.93
Chris Morrell
There's just one This is just a thing. It's his own space. It's not strings. It's not ins. It's not anything. It's it's in it's you know directions or whatever you know.
01:01:51.40
Caleb Porzio
Yeah. It is nice like I was pleasantly surprised at Ph P making Enums not just like backed by default and being like their own powerful entity that you know if you can add methods to something I'm already just like oh sick all right I'm in you know it's like oh I can hack this and do crazy cool stuff and.
01:02:12.86
Chris Morrell
Um, yep, yep.
01:02:15.77
Caleb Porzio
This makes me more able to make cool Apis um, yeah, word.
01:02:19.50
Chris Morrell
Okay, the last. The last thing that like was kind of on my on my mind that we didn't talk about is in Verbs we and and I know if you if you to go. We can. We can stop. I'll throw this out and we can decide if we want to talk about it. But I know we've been going for a while um in verbs we do a lot of stuff with Pachp Attributes right? Like um, you can annotate a function and that ah.
01:02:37.93
Caleb Porzio
Okay.
01:02:45.60
Caleb Porzio
Yeah, yeah.
01:02:55.17
Chris Morrell
That basically quees that function up to be registered as a as a lifecycl hook right? Um, which I think is how livewire 3 works in a lot of places right.
01:02:59.57
Caleb Porzio
And good. Yep.
01:03:05.88
Caleb Porzio
Yeah, not necessarily the lifecycle part. But yeah, you know? Yeah yes, it is totally.
01:03:13.97
Chris Morrell
Um, and I'm wondering if that like is that is that its own thing or is that part of the hook system like is is Discovery. Discovery through it through Ph P Attributes does that solve some of the problems that we talked about or does that just add another layer of complication.
01:03:40.61
Caleb Porzio
I think it I think it does like the live lawyer case is an example of it I think solving some of the problem. Um, yeah I was going to bring this up before where like there's kind of what we were talking about like you but you want larael to have a hook system. You're not saying you want Larell's api to expose magic strings to a consumer you know, keep the helper function keep the nice api and then internally use a hook so in livewi I started out really hook strong.
01:04:07.51
Chris Morrell
Um, yeah, exactly.
01:04:14.44
Caleb Porzio
Um I was using it all over the place I expected people to extend it extend live where using those hooks all over the place but I ended up sort of cannibalizing hooks in that there's actually very few places. It is available. You know for me if I do need to actually truly hook in with a magic string with that on thing I described. But instead I turned hooks into like a class like so there's component hooks and but let's forget about that for a second. Let's just pick on attributes. So a php attribute used in livewi that you would decorate a property or a method with if you source dive it that attribute.
01:04:40.50
Chris Morrell
Are.
01:04:53.99
Caleb Porzio
Has lifecycle methods that it can use. It has all the methods that you would normally use inside your um inside your component right inside the attributes. So there's mount. There's hydrate dehydrate boot render to ah destroy all of those things are just methods in the attributes. So. It's very source divable. You're not exposed to hooks at all everything under the hook is under the hood is hooks all those pre attributes go through a hook system for every all of that. But from a consumer s perspective if you are in user land and you use 1 of these attributes you can command click to view the definition.
01:05:17.50
Chris Morrell
Um.
01:05:29.66
Caleb Porzio
And you'll see just php methods called mountund and and and you know what those do and there's code inside of them and it's like very discoverable. There's no place where it's like on magic string mount and then gets past a component instance and all this stuff. It's yeah so I think it's um, it's gift wrappped and.
01:05:44.59
Chris Morrell
Um, sure.
01:05:49.10
Caleb Porzio
Enables some of that ah Discovery makes it feel better. So yeah, Ph P attributes in this scenario the way I'm describing them and the way I think you're describing them help that that user experience feel more ergonomic and discoverable. Yeah.
01:06:02.34
Chris Morrell
Yeah I mean the way we do the way we do it in verbs is a little different but I feel like it's I'm trying to think I mean basically so in in verbs there are like 5 lifecycle moments. You've got authorize validate. Those happen before events are fired. You can authorize whether an event can be fired. You can validate that the event state is valid. Um, then you have apply ah I doesn't really matter but apply and handle. Let's oh sweet.
01:06:28.67
Caleb Porzio
Yeah I have the docs here Daniel just sent it to me actually yesterday. So I'm I'm seeing validate and apply yeah and I see the state id attribute or whatever. But yeah.
01:06:39.10
Chris Morrell
Um, yeah, yeah, so um, there is a convention right now right? Where on an event if you're if you write a method that starts with the word apply or starts with the word validate or whatever.
01:06:54.93
Caleb Porzio
Yep.
01:06:57.19
Chris Morrell
Ah, that is automatically registered as a ah hook on that moment in the lifecycle. But like if you want to name your function something else like you should be able to annotate it with just like an apply attribute. And yeah.
01:06:59.68
Caleb Porzio
Need yeah.
01:07:09.84
Caleb Porzio
Yeah, that's nicer than a magic prefix for sure.
01:07:15.48
Chris Morrell
And in that case, the attribute itself like is named for the hook that you're hooking into so I would imagine like in that case like there would still be like ah, an attribute for each hook that you're like hooking into and that attribute would then just like have a reference.
01:07:19.52
Caleb Porzio
Yeah.
01:07:28.86
Caleb Porzio
And.
01:07:34.54
Chris Morrell
To the like string name for the hook. So it would still be like I don't think passing around like you know verbs col and Colon apply into some generic. Ah Discovery attribute would be good.
01:07:36.43
Caleb Porzio
Yeah.
01:07:48.66
Caleb Porzio
Um, yeah.
01:07:51.50
Chris Morrell
I I Definitely think like having bespoke attributes for each of these hooks makes a lot of sense.
01:07:56.14
Caleb Porzio
Yeah I don't know ah verbs enough or event sourcing enough or anything to actually speak to to to to to have any credibility with my taste when it comes to that so it could be good or bad. Um. But I'll say in like in livewire instead of a mount method if I had a randomly named method and then a mount attribute above it. Um I think I think the ergonomics wouldn't line up there for me I think it would feel I don't know I don't like the way it feels where if I'm I'm looking at the you know the um verbs. Docs and I just see a plain standalone method called validate that feels right to me single word clean predictable. Um, where if I saw a validate you know? Yeah I don't know it's tough to know if I saw a validate or apply or something. Attribute above a randomly named method then we're back to I feel like when when a non Java user encounters like dot net and and and it's like what what are these attributes running and how do they run you know then I'm back to like I don't know about that. but um but I actually can't say because I don't know.
01:08:58.26
Chris Morrell
Um, yeah, yeah, a little the distinction. Yeah, the the distinction here is that like you may have multiple right? So if you have 1 validate method then that's fine. But if you want to validate a couple different things.
01:09:13.84
Caleb Porzio
Yeah, it's a problem.
01:09:16.52
Chris Morrell
Um, you need different methods and and in this case like you know I'm I'm like 1 of the examples that I've been working on in verbs is just like trying to rebuild monopoly ah, ah and you know.
01:09:25.95
Caleb Porzio
Okay, this is what JD's been tweeting about John Drexler but he was saying you were showing him your yeah.
01:09:33.34
Chris Morrell
Ah, yeah, no, he's working on his own game. Ah oh maybe? yeah yeah yeah that that probably is um and like you know when you fire an event oftentimes you need to like validate the game like and validate the player.
01:09:51.87
Caleb Porzio
Sure.
01:09:51.96
Chris Morrell
That's doing the thing right? like I need to make sure that like the player is in a state that I would expect to do that thing and I also need to validate that like the game is in a state that like allows the player to do that thing. Um, and so it makes sense to have multiple.
01:09:58.52
Caleb Porzio
Yeah.
01:10:05.80
Caleb Porzio
Yeah, ah.
01:10:11.84
Chris Morrell
Hooks into the validate moment in verbs and ah for me like from a taste perspective I'm always going to name those functions validate something right? and so going with the like naming convention is not a problem but I think that having the attributes as a.
01:10:22.00
Caleb Porzio
Yeah.
01:10:31.10
Chris Morrell
And option feels kind of nice as like a yeah if you want.
01:10:32.55
Caleb Porzio
Yeah, if I was a verbs user and I wanted multiple methods I could see myself being onboard with the validate attribute as a Nonverbs user just because it's not out and I haven't worked with an app with it. I would prefer to just see a validate method that calls two sub methods that do their own thing. You know personally it be so simple people would see it to be so Discoverable. It would just be like I know exactly what's happening here. You know personally but there you go you know.
01:10:56.11
Chris Morrell
Um, yeah, yeah, sure.
01:11:03.58
Chris Morrell
Um, yeah I I hear what you say sweet Well I feel like we solved it. You know I think ah we're great.
01:11:10.63
Caleb Porzio
Sweet I think we did I think we yeah we defined it. We defined the problems we solved the problems and we defined the solution.
01:11:18.83
Chris Morrell
And the great thing is like I got all of the like payoff of feeling like I solved it and now I can just move on and not actually like implement. This is like the best you get that dopamine hit.
01:11:28.40
Caleb Porzio
And actually do it I know same? Yeah yep, if I were to be in the middle of the live or rewrite I'm almost positive I would go and implement what we've described. But unfortunately I'm probably going to do nothing about it.
01:11:46.90
Chris Morrell
Yeah I mean unfortunately for unfortunately for Taylor I probably will pr a hook thing at some point now that we talked about this I ah I I can't tell I don't know what youre what I feel like you've got a bunch of La L Prs
01:11:47.40
Caleb Porzio
Until next time.
01:11:53.65
Caleb Porzio
Ah, right.
01:12:02.64
Chris Morrell
Not recently, but back in the day. Um, what's your did did you ever like look at your like ratio because I feel like my Pr ratio is especially in the beginning heavily skewed towards not merged. Ah.
01:12:04.82
Caleb Porzio
Beer.
01:12:15.66
Caleb Porzio
Yeah I mean I definitely have a podcast called no plans to merge because of this but my Pr merge ratio I think started out kind of low but it it's almost I I could be wrong here. But I think it's.
01:12:20.92
Chris Morrell
Yeah, that's true.
01:12:34.18
Caleb Porzio
Pretty fricking high because I would just never pr anything. It's like um you watch suits you know, um now come on. You're the third person in the world who doesn't watch suits but the main one of the main characters Harvey Spector he's he never goes to trial. You know like he.
01:12:40.39
Chris Morrell
I don't.
01:12:52.30
Caleb Porzio
He doesn't have any like losses on his record because he always settles before trial. So it's kind of like I'm settling before trial by I'm only going to Pr the thing if there's a tweet that's really popular and people are amped about it and if I just have like an almost hundred percent gut that tailors into it. He's expressed. He's into it. He's.
01:12:53.32
Chris Morrell
Um, right.
01:13:11.23
Caleb Porzio
Then I Pr and when I pr'd make sure the footprint's really small and I'm like you know what I'm saying so there I don't yeah.
01:13:13.37
Chris Morrell
Yeah, no, no, that's that's where I am now but I I definitely feel like every once in a while I like will swing for something just to see what happens right.
01:13:23.53
Caleb Porzio
And it's good. It is good to swing and you should swing but ah, but yeah, it definitely tanks your ratio. It's going to take your ratio and pring this. He's not going to merge it straight up. He wouldn't merge it.
01:13:29.68
Chris Morrell
It does it does? Yeah yeah.
01:13:38.36
Chris Morrell
Um, yeah, it feels like a really hard one to get through. Yeah.
01:13:42.60
Caleb Porzio
You would have to he would have to be in love with the idea in some way or have enough community pressure to be I have a hard time seeing him merging it did Unfortunately yeah.
01:13:52.51
Chris Morrell
Dude I have okay here's my pet peeve. This is my pet peeve I keep on bringing up the the test the test case like ah, refresh database thing I don't know why it bugs me so much but like it has always bugged me that.
01:14:01.60
Caleb Porzio
Yeah.
01:14:10.30
Chris Morrell
In the laravell test case set up it like Maintains a like bespoke list of traits that it's looking for and initializes those traits that it's not like some generalized system that just like like everywhere else like on your model if you have a trait.
01:14:20.58
Caleb Porzio
M.
01:14:26.95
Caleb Porzio
Yeah, initialized or whatever. Yeah, yeah, right, right? right? yeah.
01:14:28.67
Chris Morrell
Right? You can call boot and you can all call initialized like there's there's multiple moments that like your tray can hook into the model lifecycle and like that's ah that's a thing that exists in a lot of the framework but because of like a few weird issues. Ah mostly having to do with like ah. Ph P unit doesn't call annotated like setup functions in a predictable order ah laravell needs to like maintain this list and I've like I've taken I've probably taken like 4 stabs at trying to like trying to fix that because it just like annoys me.
01:14:52.84
Caleb Porzio
M who. Really trying to break into this? yeah.
01:15:08.46
Chris Morrell
And this is this is just another one of them. That's what that's really all I care about is like getting getting those those to be a generalized system.
01:15:12.29
Caleb Porzio
Interesting. Um, yeah, that's funny I haven't dealt with that because I haven't tried ah trait. But if I did and was blocked I would feel the same way. Yeah, well.
01:15:24.94
Chris Morrell
Yeah, well all right? This was fun. Yeah.
01:15:29.34
Caleb Porzio
You're going to get it someday. Chris Chris this was this was great. This was ah this was a great discussion. Um I have yeah I'm coming away with this with more clarity on hooks. It's great. Hooks are good and bad. Good and bad.
01:15:41.14
Chris Morrell
Um, hooks are good. They're there. They could be bad. They're mostly good I'm going to say sweet all right? Well thanks for hanging out.
01:15:48.31
Caleb Porzio
Yep, dude, thanks for having me Chris.