Navigated to Remote Functions with Simon Holthausen - Transcript

Remote Functions with Simon Holthausen

Episode Transcript

1 00:00:21,640 --> 00:00:27,060 Speaker 1: Hello, everyone. Welcome to another episode of Svelte Radio. I'm here today with Simon 2 00:00:27,140 --> 00:00:28,020 Speaker 1: from the Svelte team. 3 00:00:28,180 --> 00:00:28,280 Speaker 1: Hello. 4 00:00:29,420 --> 00:00:30,720 Speaker 1: Hey, welcome for having me. 5 00:00:31,460 --> 00:00:31,660 Speaker 1: Thank you 6 00:00:31,660 --> 00:00:32,160 Speaker 2: for having me. 7 00:00:32,220 --> 00:00:32,619 Speaker 2: Not welcome. 8 00:00:35,660 --> 00:00:36,340 Speaker 3: Great intro. 9 00:00:37,000 --> 00:00:37,680 Speaker 2: Stumbling upon 10 00:00:37,680 --> 00:00:38,400 Speaker 3: my words right 11 00:00:38,400 --> 00:00:38,580 Speaker 2: away. 12 00:00:39,820 --> 00:00:40,680 Speaker 1: When it's digital, 13 00:00:41,240 --> 00:00:42,200 Speaker 1: am I visiting you 14 00:00:42,380 --> 00:00:43,100 Speaker 1: or are you visiting me? 15 00:00:44,480 --> 00:00:44,800 Speaker 1: You know? 16 00:00:45,420 --> 00:00:46,100 Speaker 3: I'd say I 17 00:00:46,100 --> 00:00:46,740 Speaker 1: visit you. 18 00:00:47,540 --> 00:00:48,160 Speaker 1: Oh, okay. 19 00:00:48,719 --> 00:00:50,020 Speaker 1: I was trying to save you here 20 00:00:50,140 --> 00:00:50,560 Speaker 1: with the welcome. 21 00:00:51,240 --> 00:00:51,520 Speaker 3: Yeah. 22 00:00:52,280 --> 00:00:53,540 Speaker 1: Yeah, it's beyond repair. 23 00:00:54,560 --> 00:00:54,700 Speaker 1: Yeah. 24 00:00:55,080 --> 00:00:55,580 Speaker 1: All right, all right. 25 00:00:55,760 --> 00:01:03,380 Speaker 1: So before we start, Anthony and Brittany were supposed to be here, but we ran into a couple of scheduling issues. 26 00:01:03,570 --> 00:01:07,420 Speaker 1: And I decided I'm just going to do this on my own because it's easier. 27 00:01:07,680 --> 00:01:11,140 Speaker 1: And we want to get this out there because it's really interesting and fun. 28 00:01:12,980 --> 00:01:14,880 Speaker 1: The stuff that we're going to talk about today. 29 00:01:16,920 --> 00:01:21,920 Speaker 1: Remote functions, async, svelte, I guess that's what you would call it? 30 00:01:22,360 --> 00:01:22,620 Speaker 1: Yes. 31 00:01:23,240 --> 00:01:24,060 Speaker 1: Kind of two parts, yeah. 32 00:01:24,420 --> 00:01:29,540 Speaker 1: So maybe start off with what are remote functions in SvelteKit? 33 00:01:30,240 --> 00:01:31,140 Speaker 1: So remote functions 34 00:01:31,140 --> 00:01:37,060 Speaker 2: are a new way to interacting with data in your SvelteKit applications. 35 00:01:38,020 --> 00:01:42,100 Speaker 2: Today, you have load functions and form actions to do that. 36 00:01:42,800 --> 00:01:48,040 Speaker 2: So load functions you have in your plus page TS or plus page.server TS file, 37 00:01:48,660 --> 00:01:51,780 Speaker 2: export a load function and you do things in there. 38 00:01:51,940 --> 00:01:53,920 Speaker 2: You can also have layout load functions. 39 00:01:55,600 --> 00:01:57,560 Speaker 2: And that's how you can get your data. 40 00:01:57,740 --> 00:02:05,100 Speaker 2: And if you want to interact with that data, not just read it, but also manipulate it, 41 00:02:05,420 --> 00:02:12,340 Speaker 2: the first class way to do that is forum actions, which live in plus page.server.ts files. 42 00:02:13,240 --> 00:02:20,180 Speaker 2: And basically, it's a nice way of writing regular forum posts, 43 00:02:20,740 --> 00:02:23,940 Speaker 2: just like basic web form posts. 44 00:02:24,740 --> 00:02:28,220 Speaker 2: And this has served us very well so far. 45 00:02:28,740 --> 00:02:32,520 Speaker 2: But over the years, a few things have become apparent 46 00:02:33,160 --> 00:02:37,880 Speaker 2: that it just doesn't like scale as much as 47 00:02:37,880 --> 00:02:38,760 Speaker 1: you'd like, 48 00:02:38,800 --> 00:02:40,980 Speaker 2: like both scale up, but also scale down. 49 00:02:41,960 --> 00:02:42,460 Speaker 2: I know. 50 00:02:42,740 --> 00:02:43,420 Speaker 2: I know one-- 51 00:02:44,280 --> 00:02:46,320 Speaker 1: sorry, I didn't mean to cut you off. 52 00:02:46,320 --> 00:02:50,700 Speaker 1: But I know one thing I've always gotten a bit irritated 53 00:02:50,720 --> 00:02:51,260 Speaker 1: is that 54 00:02:51,260 --> 00:02:52,740 Speaker 3: when you have 55 00:02:52,740 --> 00:02:53,240 Speaker 1: one page 56 00:02:53,260 --> 00:02:55,440 Speaker 1: and you have a bunch of different kinds of data 57 00:02:55,600 --> 00:02:57,220 Speaker 1: that you want to bring into the page 58 00:02:57,220 --> 00:02:57,820 on first load, 59 00:02:58,000 --> 00:03:00,580 but then you might want to refresh just part of the data. 60 00:03:01,580 --> 00:03:02,780 At the moment, with load functions, 61 00:03:02,880 --> 00:03:04,300 you have to rerun the whole thing, right? 62 00:03:04,480 --> 00:03:06,500 And then you would fetch everything from... 63 00:03:07,240 --> 00:03:07,420 Correct. 64 00:03:07,740 --> 00:03:11,380 That's one of the drawbacks 65 00:03:11,820 --> 00:03:14,940 Speaker 2: that you can only get as granular with loading 66 00:03:15,260 --> 00:03:17,300 Speaker 2: or reloading as a load function. 67 00:03:17,600 --> 00:03:22,920 Speaker 2: So I don't know if you want to only reload a certain thing, 68 00:03:22,970 --> 00:03:26,640 Speaker 2: then maybe you, I don't know, need to introduce a layout 69 00:03:27,180 --> 00:03:28,460 Speaker 2: that is UI 70 00:03:28,460 --> 00:03:29,400 Speaker 3: -wise empty 71 00:03:29,400 --> 00:03:31,440 Speaker 2: just to split it apart. 72 00:03:31,790 --> 00:03:33,020 Speaker 2: And that's like really clunky. 73 00:03:34,780 --> 00:03:35,320 Speaker 2: So yeah, you're 74 00:03:35,320 --> 00:03:36,140 Speaker 3: forced to... 75 00:03:36,140 --> 00:03:36,800 Speaker 3: You can use groups, 76 00:03:37,100 --> 00:03:37,200 Speaker 2: right? 77 00:03:37,920 --> 00:03:38,580 Speaker 2: You could use 78 00:03:38,580 --> 00:03:38,800 Speaker 1: groups. 79 00:03:38,840 --> 00:03:39,480 Speaker 3: Nested groups. 80 00:03:40,080 --> 00:03:40,360 Speaker 2: Yes. 81 00:03:40,420 --> 00:03:50,460 Speaker 2: And yeah, so there are ways around it with enough like painkillers besides you. 82 00:03:51,900 --> 00:03:54,140 Speaker 2: But yeah, it's not good. 83 00:03:54,530 --> 00:04:03,020 Speaker 2: It also, another problem with loading data like that is that the co-location is not great. 84 00:04:03,310 --> 00:04:07,120 Speaker 2: So you're loading your data in all these load functions. 85 00:04:08,560 --> 00:04:16,359 Speaker 2: And then maybe you're using part of that data only very deep inside your page, like, I don't know, five components deep. 86 00:04:16,870 --> 00:04:17,579 Speaker 2: And then you 87 00:04:17,579 --> 00:04:18,060 Speaker 3: have either 88 00:04:18,060 --> 00:04:26,720 Speaker 2: the choice to do prop drilling or go with the page store, which basically is a collection of all the data on that page. 89 00:04:26,850 --> 00:04:29,280 Speaker 2: But that is no longer really type safe. 90 00:04:30,000 --> 00:04:33,960 Speaker 2: So, yeah, that's another problem here. 91 00:04:34,400 --> 00:04:37,960 Speaker 2: And also keeping those things in sync isn't as nice 92 00:04:38,540 --> 00:04:41,420 Speaker 2: because maybe you want to refactor something 93 00:04:41,700 --> 00:04:42,960 Speaker 2: or delete that data, 94 00:04:43,200 --> 00:04:46,380 Speaker 2: but then you have to always think about the other end 95 00:04:46,560 --> 00:04:49,660 Speaker 2: where you also need to change or delete your code. 96 00:04:50,760 --> 00:04:52,480 Speaker 2: And speaking of TypeScript, 97 00:04:52,500 --> 00:04:54,240 Speaker 2: the same is true for forum actions. 98 00:04:54,600 --> 00:04:58,820 Speaker 2: So they work really nicely the way you author them, 99 00:05:00,160 --> 00:05:01,540 Speaker 2: but it's not exactly type safe 100 00:05:01,560 --> 00:05:07,660 Speaker 2: because the way you do it is you write basically the action path for the form. 101 00:05:08,150 --> 00:05:12,880 Speaker 2: You write yourself and then you have to be sure that it's in sync 102 00:05:13,260 --> 00:05:16,320 Speaker 2: with whatever you have in your plus page.server.ts file. 103 00:05:17,100 --> 00:05:19,100 Speaker 2: And we have also heard people saying like, 104 00:05:19,580 --> 00:05:23,540 Speaker 2: hey, I have this in my plus page.server.ts file, 105 00:05:23,660 --> 00:05:27,060 Speaker 2: but maybe I want to use this on several pages. 106 00:05:27,410 --> 00:05:28,820 Speaker 2: And so how can I do this? 107 00:05:30,500 --> 00:05:36,300 Speaker 2: And so there are multiple, basically, problems to that too. 108 00:05:37,160 --> 00:05:44,020 Speaker 2: And so also, what if you don't want to use form actions? 109 00:05:44,540 --> 00:05:48,920 Speaker 2: So, I mean, we, of course, advocate for progressive enhancement, 110 00:05:48,980 --> 00:05:53,860 Speaker 2: which means everything ideally should also work without JavaScript. 111 00:05:55,400 --> 00:05:58,280 Speaker 2: But maybe you're doing some internal business app 112 00:05:58,300 --> 00:06:02,500 Speaker 2: or the thing you're interacting with requires JavaScript? 113 00:06:04,080 --> 00:06:07,740 Speaker 2: And then why would you want to use forms in that case? 114 00:06:07,900 --> 00:06:11,500 Speaker 2: And SvelteKit basically offers you nothing in that regard. 115 00:06:11,710 --> 00:06:14,700 Speaker 2: So you're completely on your own, just using 116 00:06:14,700 --> 00:06:15,400 Speaker 1: regular fetch. 117 00:06:15,490 --> 00:06:19,380 Speaker 1: And so I've had to use, I mean, I would use, 118 00:06:19,720 --> 00:06:23,120 Speaker 1: so I always use SuperForms to do forms in SvelteKit before. 119 00:06:24,000 --> 00:06:24,360 Speaker 3: And that 120 00:06:24,360 --> 00:06:26,180 Speaker 1: kind of works in the SPA way as well. 121 00:06:26,740 --> 00:06:29,180 Speaker 1: But it's still, like, it's a bit weird. 122 00:06:29,960 --> 00:06:32,360 Speaker 1: You're kind of, what's it called? 123 00:06:34,100 --> 00:06:35,380 Speaker 1: Faking forms in a way. 124 00:06:36,500 --> 00:06:40,760 Speaker 1: Because you're using super forms and it kind of looks like you're using form actions, but you're not really. 125 00:06:41,480 --> 00:06:43,600 Speaker 1: Because it's all SPA networks. 126 00:06:43,760 --> 00:06:48,040 Speaker 1: But it would be better if it was easier, better DX. 127 00:06:48,980 --> 00:07:09,200 Speaker 2: Right. And so we were thinking, okay, how can we basically keep the niceness about data loading and make it more granular, more type safe, give a better first class integration with when you don't want to use forms and so on. 128 00:07:09,300 --> 00:07:12,780 Speaker 2: And this is how remote functions came to be. 129 00:07:13,620 --> 00:07:20,940 Speaker 2: And it all started back in May when we had our offsite, basically. 130 00:07:21,060 --> 00:07:28,420 Speaker 2: So prior to the Svelte Summit, many of the maintainers came together and we did a brainstorming. 131 00:07:28,700 --> 00:07:31,940 Speaker 2: And previously, we already had written up some discussions. 132 00:07:32,380 --> 00:07:38,860 Speaker 2: But yeah, the bulk of the design happened in those two to three days prior to the conference. 133 00:07:39,460 --> 00:07:45,540 Speaker 2: like it's it's amazing what you can do when when you get people in a room yeah and and talk to each 134 00:07:45,550 --> 00:07:48,560 Speaker 2: other live so i mean i'm a proponent of remote 135 00:07:48,560 --> 00:07:50,900 Speaker 1: uh first i was gonna say the exact same thing 136 00:07:52,700 --> 00:07:53,860 Speaker 2: yeah right like remote first 137 00:07:53,860 --> 00:07:57,560 Speaker 1: is nice but it's hard things like this it's 138 00:07:57,560 --> 00:07:58,720 Speaker 2: hard to beat in person 139 00:07:58,990 --> 00:08:07,280 Speaker 2: right especially when you consider that many of us are not working on this full-time and to have 140 00:08:07,280 --> 00:08:13,900 Speaker 2: these voices in the same room still and not having to wait on them like I don't know four days until 141 00:08:14,060 --> 00:08:22,680 Speaker 2: they give a response that that is so valuable and so yeah we we got out with remote functions and 142 00:08:22,720 --> 00:08:31,739 Speaker 2: that is basically I would say our take on RPC so it looks like you write regular functions and call 143 00:08:31,760 --> 00:08:39,460 Speaker 2: regular functions and on the server that is what you are doing but on the client you're actually 144 00:08:39,620 --> 00:08:47,260 Speaker 2: doing a fetch call to the server and the server knows how to basically deal with this special call 145 00:08:47,820 --> 00:08:57,799 Speaker 2: call the actual function and then come back to the client where it can unpack the serialized 146 00:08:57,860 --> 00:09:07,200 Speaker 2: response. And more specifically, you write your remote functions in.remote.ts or.remote.js 147 00:09:07,580 --> 00:09:13,280 Speaker 2: files. So for example, I don't know, if you have a blog post and then maybe you do like a 148 00:09:13,900 --> 00:09:21,700 Speaker 2: blog.remote.ts file. And in there you can then have a so-called query function, 149 00:09:21,920 --> 00:09:27,000 Speaker 2: query remote function. So you import all these functions from $app.server. 150 00:09:28,280 --> 00:09:35,580 Speaker 2: and for get posts you would do a query and in there you would query your database and return 151 00:09:35,690 --> 00:09:47,140 Speaker 2: the list of posts when you are creating a new blog posts you would use the form function which 152 00:09:48,820 --> 00:09:55,980 Speaker 2: yeah you give a schema standard schema like zod or valley bot and then that parses the form 153 00:09:56,960 --> 00:10:04,020 Speaker 2: gives you back an object from that and then you can interact with that and i don't know do a few 154 00:10:04,240 --> 00:10:12,360 Speaker 2: checks like are you authenticated are you authorized to do a blog post to create a new entry and so on 155 00:10:13,080 --> 00:10:14,260 Speaker 2: and then call the database. 156 00:10:15,740 --> 00:10:18,240 Speaker 2: And you can even right then and there 157 00:10:18,380 --> 00:10:20,400 Speaker 2: do something like a single flight mutation 158 00:10:20,680 --> 00:10:21,440 Speaker 2: where you're saying, 159 00:10:21,720 --> 00:10:25,040 Speaker 2: okay, I want to refresh get posts. 160 00:10:25,900 --> 00:10:27,640 Speaker 2: So as part of the response, 161 00:10:27,960 --> 00:10:30,720 Speaker 2: you're also already getting the new data. 162 00:10:32,140 --> 00:10:35,800 Speaker 2: And you could maybe also have a toggle like in there. 163 00:10:36,340 --> 00:10:39,740 Speaker 2: So as a reader, you could press the like button 164 00:10:39,900 --> 00:10:41,699 Speaker 2: and maybe that is for some reason 165 00:10:41,720 --> 00:10:45,020 Speaker 2: not a form under the hood, but it's a so-called command. 166 00:10:45,080 --> 00:10:47,080 Speaker 2: So that's the third one you have. 167 00:10:48,400 --> 00:10:50,520 Speaker 2: And the command works very similar to the form. 168 00:10:50,520 --> 00:10:54,100 Speaker 2: You also have a schema if you have arguments. 169 00:10:54,560 --> 00:10:58,200 Speaker 2: In case of toggle like, you probably don't have arguments and so on. 170 00:10:58,200 --> 00:11:01,320 Speaker 2: And so basically you have all these different functions, 171 00:11:02,460 --> 00:11:04,900 Speaker 2: which all are called remote functions, 172 00:11:05,140 --> 00:11:07,800 Speaker 2: and you have them inside this.remote.ts file. 173 00:11:08,640 --> 00:11:15,120 Speaker 2: And then in your plus page, Svelte or any other Svelte file or regular file, 174 00:11:15,120 --> 00:11:21,520 Speaker 2: you can just, you just can interact with them like regular functions, which return promises. 175 00:11:22,300 --> 00:11:23,120 Speaker 1: So things 176 00:11:23,120 --> 00:11:24,220 Speaker 2: that 177 00:11:24,220 --> 00:11:27,460 Speaker 1: come out of this is like, we get full type safety, right? 178 00:11:28,440 --> 00:11:28,640 Speaker 1: Yes. 179 00:11:28,790 --> 00:11:34,379 Speaker 1: Without any magical kind of things that, because before we had, you had to do some 180 00:11:35,139 --> 00:11:37,280 Speaker 1: magic under the hood, right, for the load functions, 181 00:11:37,760 --> 00:11:39,680 Speaker 1: or am I misremembering? 182 00:11:39,820 --> 00:11:41,100 Speaker 2: Yes, so, right. 183 00:11:41,290 --> 00:11:42,080 Speaker 2: So one of the, 184 00:11:44,180 --> 00:11:46,740 Speaker 2: that's another thing that gets better here. 185 00:11:47,060 --> 00:11:49,000 Speaker 2: So for load functions, 186 00:11:49,710 --> 00:11:50,740 Speaker 2: to make them type safe, 187 00:11:50,870 --> 00:11:53,340 Speaker 2: we had to do a bit of TypeScript voodoo. 188 00:11:54,220 --> 00:12:01,520 Speaker 2: Like if you do let brackets data equals dollar props, 189 00:12:04,120 --> 00:12:09,540 Speaker 2: Like there's zero types, type safety. 190 00:12:09,660 --> 00:12:09,740 Speaker 2: Yeah. 191 00:12:09,940 --> 00:12:11,440 Speaker 2: So you don't write the types yourself. 192 00:12:11,760 --> 00:12:15,340 Speaker 2: It's done in the background for you by the language service. 193 00:12:15,400 --> 00:12:26,840 Speaker 2: You could also write it explicitly by importing page props from a relative file called dollar types, which doesn't 194 00:12:26,840 --> 00:12:27,100 Speaker 3: exist. 195 00:12:27,240 --> 00:12:27,640 Speaker 3: And 196 00:12:27,640 --> 00:12:36,200 Speaker 2: at this position, it actually exists somewhere in the generated files, which is another TypeScript trick which you can employ to make that 197 00:12:36,200 --> 00:12:36,480 Speaker 3: work. 198 00:12:37,600 --> 00:12:47,200 Speaker 2: And it works and it's nice, it's clever, but wouldn't it be better if we didn't have to do this? 199 00:12:47,480 --> 00:12:47,680 Speaker 2: Because 200 00:12:47,680 --> 00:12:49,640 Speaker 3: it's 201 00:12:49,640 --> 00:12:51,480 Speaker 2: something we have to maintain. 202 00:12:51,610 --> 00:12:56,640 Speaker 2: It may break down in some places and so on. 203 00:12:57,220 --> 00:13:02,880 Speaker 2: And if we can just rely on regular TypeScript, so to speak, that would be even better. 204 00:13:02,940 --> 00:13:07,780 Speaker 2: And yeah, with remote functions, from a TypeScript perspective, it's just that. 205 00:13:07,920 --> 00:13:09,660 Speaker 2: It's just TypeScript functions. 206 00:13:10,400 --> 00:13:18,880 Speaker 2: And so that's why TypeScript will have a much easier time with this and why type safety will 207 00:13:19,040 --> 00:13:22,020 Speaker 2: be increased with this with less effort. 208 00:13:22,460 --> 00:13:26,460 Speaker 2: Because it's not just that your load functions will have type safety. 209 00:13:26,640 --> 00:13:29,320 Speaker 2: Also, your forms now will have type safety. 210 00:13:30,640 --> 00:13:33,120 Speaker 2: And your commands will also have type safety. 211 00:13:35,280 --> 00:13:44,860 Speaker 2: It's not actually functions, though, and that's because, like, on the client, you're actually doing a fetch call to the back end. 212 00:13:45,840 --> 00:13:52,340 Speaker 2: And that's why we encourage people to use a schema 213 00:13:52,820 --> 00:13:58,680 Speaker 2: whenever they require arguments for the commands or queries or forms. 214 00:14:00,000 --> 00:14:04,720 Speaker 2: Because in theory, everyone could call this endpoint with rubbish 215 00:14:05,220 --> 00:14:07,120 Speaker 2: and could try to break it. 216 00:14:08,000 --> 00:14:08,260 Speaker 2: And 217 00:14:08,260 --> 00:14:09,660 Speaker 1: so that's why schema is required. 218 00:14:09,660 --> 00:14:10,260 Speaker 1: Yeah, they're not hidden or anything. 219 00:14:10,960 --> 00:14:11,080 Speaker 2: Right. 220 00:14:11,380 --> 00:14:14,660 Speaker 2: It's auto-generated and it has funky names. 221 00:14:15,320 --> 00:14:20,940 Speaker 2: So it's not exactly predictable or anything, but it's still public after all. 222 00:14:22,280 --> 00:14:24,600 Speaker 2: And so you have to be careful there. 223 00:14:25,400 --> 00:14:26,920 Speaker 2: And that's why we encourage you 224 00:14:26,920 --> 00:14:27,580 Speaker 1: to do this. 225 00:14:27,760 --> 00:14:46,480 Speaker 1: So speaking of schemas, then, it's a bit interesting that we ended up, because I have some vague memory of the Svelte core maintainers not wanting to deal with validation in any sense, because it's like an extra thing to have to do. 226 00:14:46,990 --> 00:14:53,680 Speaker 1: But I think since then, there's this, what's it called, standard schema that's come out from all of these validation libraries. 227 00:14:54,620 --> 00:14:55,660 Speaker 3: So these remote 228 00:14:55,660 --> 00:15:03,880 Speaker 1: functions, they have support for passing in, well, support for, you have to pass in something if you're taking a parameter, right? You have to pass in a schema. 229 00:15:03,940 --> 00:15:04,560 Speaker 1: You 230 00:15:04,560 --> 00:15:09,460 Speaker 2: could also do a quote as a string unchecked. 231 00:15:10,420 --> 00:15:12,320 Speaker 2: That way you can bypass it. 232 00:15:12,820 --> 00:15:20,740 Speaker 2: Like if you know what you're doing or you're using some very custom built validation library 233 00:15:21,080 --> 00:15:26,320 Speaker 2: that is not standard schema compliant, then you can bypass it. 234 00:15:27,340 --> 00:15:32,800 Speaker 2: But the name unchecked should already clue you in that this goes unchecked. 235 00:15:32,860 --> 00:15:37,080 Speaker 2: Like the types say this is a string, but it's not necessarily a string. 236 00:15:38,540 --> 00:15:43,560 Speaker 2: And so that's where the encouragement to use it comes in, 237 00:15:43,660 --> 00:15:43,860 Speaker 2: but 238 00:15:43,860 --> 00:15:45,720 Speaker 1: we don't force you to do it. 239 00:15:46,680 --> 00:15:48,180 Speaker 1: So what does it look like? 240 00:15:48,560 --> 00:15:54,740 Speaker 1: Let's say I have a blog and I want to fetch one blog post. 241 00:15:55,180 --> 00:16:00,960 Speaker 1: So I do const get post equals query. 242 00:16:01,640 --> 00:16:03,820 Speaker 1: And then what do I do to get the 243 00:16:03,820 --> 00:16:04,360 Speaker 3: post? 244 00:16:04,400 --> 00:16:04,860 Speaker 3: Yeah, if you're 245 00:16:04,860 --> 00:16:06,100 Speaker 2: using ValleyBot, for example, 246 00:16:06,300 --> 00:16:10,420 Speaker 2: then you would do v.string as the first argument, 247 00:16:10,700 --> 00:16:12,220 Speaker 2: which is the first argument is the schema 248 00:16:12,480 --> 00:16:13,560 Speaker 2: or the string unchecked. 249 00:16:14,720 --> 00:16:15,760 Speaker 2: And you do v.string. 250 00:16:16,070 --> 00:16:19,340 Speaker 2: And then the second argument is the function 251 00:16:19,660 --> 00:16:20,480 Speaker 2: that is then called. 252 00:16:22,120 --> 00:16:22,540 Speaker 3: And 253 00:16:22,540 --> 00:16:25,960 Speaker 2: in that case, it's, I don't know, probably the ID. 254 00:16:26,740 --> 00:16:26,880 Speaker 2: And 255 00:16:26,880 --> 00:16:27,680 Speaker 3: ID would 256 00:16:27,680 --> 00:16:32,940 Speaker 2: already be type checked in that sense. 257 00:16:32,980 --> 00:16:35,820 Speaker 2: So you don't have to do like colon string yourself anymore. 258 00:16:36,100 --> 00:16:36,660 Speaker 2: That's inferred 259 00:16:36,660 --> 00:16:37,280 Speaker 3: from the schema. 260 00:16:38,080 --> 00:16:38,900 Speaker 3: So in a sense, 261 00:16:39,400 --> 00:16:42,960 Speaker 2: most of the time you're actually not typing anything more 262 00:16:43,460 --> 00:16:47,280 Speaker 2: compared to not using a schema, which is kind of nice. 263 00:16:48,180 --> 00:16:51,120 Speaker 2: Yeah, and then in there you would, I don't know, query 264 00:16:51,120 --> 00:16:51,640 Speaker 3: your database, 265 00:16:52,820 --> 00:17:00,120 Speaker 2: fetch fetch the blog post from wherever and return it in a way that svelte kit can 266 00:17:01,640 --> 00:17:07,020 Speaker 2: then serialize it you serialize it and so on so as long as you use something that is 267 00:17:07,880 --> 00:17:15,000 Speaker 2: devalue compliant then it works so like everything about json is okay dates are okay map is okay 268 00:17:16,079 --> 00:17:16,939 Speaker 2: and you can even 269 00:17:17,480 --> 00:17:19,280 Speaker 2: so SvelteKit has this transport 270 00:17:20,079 --> 00:17:20,760 Speaker 2: transport hook 271 00:17:21,319 --> 00:17:22,980 Speaker 2: where you can basically define 272 00:17:23,449 --> 00:17:24,459 Speaker 2: custom classes 273 00:17:25,480 --> 00:17:26,420 Speaker 2: and how they should be 274 00:17:27,000 --> 00:17:29,260 Speaker 2: serialized, deserialized. You could even use that 275 00:17:29,450 --> 00:17:29,920 Speaker 2: in there. 276 00:17:31,600 --> 00:17:32,180 Speaker 2: I was going 277 00:17:32,180 --> 00:17:32,860 Speaker 1: to ask about 278 00:17:33,220 --> 00:17:34,960 Speaker 1: the types of data that you can 279 00:17:35,700 --> 00:17:37,440 Speaker 1: send back and forth. I assume you can't 280 00:17:38,210 --> 00:17:39,000 Speaker 1: do functions. 281 00:17:40,460 --> 00:17:41,460 Speaker 1: Correct. You could do 282 00:17:41,600 --> 00:17:43,400 Speaker 1: functions. You can do 283 00:17:43,540 --> 00:17:44,820 Speaker 1: functions? No, you couldn't. 284 00:17:45,380 --> 00:17:46,760 Speaker 1: okay I 285 00:17:46,760 --> 00:17:53,600 Speaker 2: mean you could maybe you could have a special class that represents a function or 286 00:17:54,100 --> 00:17:54,480 Speaker 2: in some 287 00:17:54,480 --> 00:17:55,180 Speaker 3: way and then you 288 00:17:55,180 --> 00:17:59,920 Speaker 2: have knowledge domain knowledge about how this should be deserialized 289 00:18:00,040 --> 00:18:01,840 Speaker 2: and serialized and then 290 00:18:01,840 --> 00:18:03,860 Speaker 1: but not like a generic function yeah but 291 00:18:03,860 --> 00:18:05,440 Speaker 2: no generic functions so 292 00:18:05,440 --> 00:18:05,860 Speaker 1: that 293 00:18:06,639 --> 00:18:08,160 Speaker 1: I've tried the 294 00:18:09,200 --> 00:18:10,400 Speaker 1: query functions a bit 295 00:18:10,560 --> 00:18:11,800 Speaker 1: and I find that 296 00:18:13,140 --> 00:18:14,020 Speaker 1: having to 297 00:18:14,680 --> 00:18:16,140 Speaker 1: use a schema for 298 00:18:16,520 --> 00:18:17,780 Speaker 1: my queries also makes 299 00:18:18,340 --> 00:18:20,220 Speaker 1: it kind of encourages using 300 00:18:20,900 --> 00:18:22,140 Speaker 1: schemas in the rest of the application 301 00:18:22,480 --> 00:18:23,860 Speaker 1: as well, which is kind of nice. 302 00:18:24,840 --> 00:18:26,440 Speaker 1: So that's another side effect, I guess, 303 00:18:26,520 --> 00:18:28,340 Speaker 1: of remote functions, 304 00:18:28,800 --> 00:18:30,180 Speaker 1: if you will, for me at least. 305 00:18:31,980 --> 00:18:32,140 Speaker 2: Yeah, 306 00:18:32,440 --> 00:18:34,439 Speaker 2: I think so too, that in general 307 00:18:34,460 --> 00:18:38,060 Speaker 2: will encourage better practices 308 00:18:38,320 --> 00:18:41,420 Speaker 2: and ultimately make your app more resilient. 309 00:18:42,480 --> 00:18:42,600 Speaker 1: Yeah. 310 00:18:43,700 --> 00:18:47,780 Speaker 1: Okay, so remote functions do rely on this other feature 311 00:18:49,020 --> 00:18:51,040 Speaker 1: that was built for Svelte called, 312 00:18:51,679 --> 00:18:54,600 Speaker 1: I don't know if you call it async Svelte or async? 313 00:18:55,140 --> 00:18:55,680 Speaker 1: Yeah, async. 314 00:18:55,740 --> 00:18:56,700 Speaker 3: Top level await. 315 00:18:57,720 --> 00:18:58,600 Speaker 1: Async Svelte, okay, yeah. 316 00:18:59,460 --> 00:19:00,820 Speaker 1: But maybe we can talk a bit about that. 317 00:19:01,920 --> 00:19:06,240 Speaker 1: It was introduced, was it introduced at Svelte Summit or a bit before? 318 00:19:06,490 --> 00:19:10,140 Speaker 1: And then Rich did a talk about, I don't remember. 319 00:19:10,420 --> 00:19:14,160 Speaker 2: Yeah, it was introduced at Svelte Summit. 320 00:19:15,120 --> 00:19:15,540 Speaker 2: That's correct. 321 00:19:16,160 --> 00:19:18,900 Speaker 2: And remote functions also got like an outlook there. 322 00:19:19,660 --> 00:19:24,720 Speaker 2: And yeah, so async Svelte, for those who don't know yet, 323 00:19:25,580 --> 00:19:28,420 Speaker 2: basically for the longest time, people have asked, 324 00:19:28,640 --> 00:19:32,640 Speaker 2: I want to use the await keyword in my components, 325 00:19:33,420 --> 00:19:35,700 Speaker 2: preferably at the top level, but maybe also somewhere else. 326 00:19:37,060 --> 00:19:38,140 Speaker 2: And so far that didn't work. 327 00:19:38,140 --> 00:19:44,560 Speaker 2: The only way you could do that is either by using the await block, 328 00:19:45,030 --> 00:19:47,480 Speaker 2: the curly braces hash await. 329 00:19:48,560 --> 00:19:52,260 Speaker 2: And that's a bit like clumsy because it only works 330 00:19:52,260 --> 00:19:52,620 Speaker 3: for 331 00:19:52,620 --> 00:19:57,220 Speaker 2: one promise at a time. 332 00:19:57,920 --> 00:20:03,680 Speaker 2: so you have multiple then you got to repeat this again and again and again and each of them are 333 00:20:04,280 --> 00:20:09,860 Speaker 2: basically in their own life cycle of showing a loading screen and then showing the data and if 334 00:20:09,860 --> 00:20:16,240 Speaker 2: you have i don't know 10 of this uh these on your page and it's like 10 loading spinners and it's 335 00:20:16,360 --> 00:20:18,360 Speaker 2: like it makes for a horrible experience 336 00:20:18,360 --> 00:20:19,880 Speaker 3: so so 337 00:20:19,880 --> 00:20:23,800 Speaker 2: you want to coordinate that somehow ideally the other 338 00:20:23,800 --> 00:20:30,380 Speaker 2: way you could work around it is by flattening the async into something synchronous by having like a 339 00:20:31,020 --> 00:20:39,100 Speaker 2: resource like object where you have loading and current and error properties on an object and 340 00:20:39,100 --> 00:20:47,680 Speaker 2: then you could use that but that also like it could be clumsy sometimes and could make it so that 341 00:20:47,960 --> 00:20:55,760 Speaker 2: the coordination problem is still there like ideally you want to somehow have maybe define 342 00:20:55,980 --> 00:21:05,660 Speaker 2: okay this is my boundary basically and that's where I want the one loading screen to appear 343 00:21:06,660 --> 00:21:16,679 Speaker 2: and then once that's done I like I want to show that loading screen until all async functions 344 00:21:17,460 --> 00:21:25,380 Speaker 2: are resolved and then go from showing that to showing the the end result and not have 10 345 00:21:25,620 --> 00:21:34,740 Speaker 2: spinners i only have one spin spinner so to speak and that's what async spelled basically gives you 346 00:21:34,740 --> 00:21:40,400 Speaker 2: it gives you the ability to use a weight inside the template and at the top level you can also 347 00:21:40,440 --> 00:21:47,200 Speaker 2: use it inside derived so basically like asynchronous derivations that then also works 348 00:21:48,410 --> 00:21:58,540 Speaker 2: um and you can wrap these in a boundary and give that boundary a pending snippet which then shows 349 00:21:58,720 --> 00:22:09,420 Speaker 2: up on first render for as long as anything inside the boundary is still loading and that that doesn't 350 00:22:09,420 --> 00:22:15,000 Speaker 2: have to be in the same component it could be 10 components deep so it's a runtime concept like the 351 00:22:15,140 --> 00:22:24,300 Speaker 2: runtime knows where the nearest boundary is and what async work is still out pending and yeah and 352 00:22:24,400 --> 00:22:27,740 Speaker 2: that that way you you can coordinate it so 353 00:22:27,740 --> 00:22:30,760 Speaker 1: you mentioned uh you mentioned the word resources 354 00:22:31,300 --> 00:22:35,980 Speaker 1: I've heard this word kind of in some places. 355 00:22:37,400 --> 00:22:39,160 Speaker 1: Is that something special? 356 00:22:42,419 --> 00:22:45,200 Speaker 3: No, I think it's just like a term 357 00:22:45,200 --> 00:22:47,320 Speaker 1: that is 358 00:22:47,320 --> 00:22:53,320 Speaker 2: more or less common in the async. 359 00:22:53,900 --> 00:22:57,300 Speaker 2: When talking about async, you're talking about resources, 360 00:22:57,300 --> 00:22:59,840 Speaker 2: or at least we in the team are calling it resources. 361 00:23:00,380 --> 00:23:00,600 Speaker 2: Okay. 362 00:23:00,660 --> 00:23:21,940 Speaker 2: In fact, we, so with remote functions, especially with queries and so on, like they give you nice ergonomics and people have rightfully asked us, hey, this requires a server because like the remote function lives on the server. 363 00:23:21,940 --> 00:23:23,160 Speaker 2: So you have to have a server runtime. 364 00:23:24,000 --> 00:23:25,440 Speaker 2: What about the SPA case? 365 00:23:26,620 --> 00:23:29,280 Speaker 2: What if I want to use something like a query there too? 366 00:23:30,080 --> 00:23:44,680 Speaker 2: And we are actually in the process of designing and implementing a resource-like API right now, which will bring the query-like capabilities to Svelte itself. 367 00:23:45,700 --> 00:23:52,500 Speaker 2: And the client implementation of remote function queries will then likely use that under the hood. 368 00:23:53,920 --> 00:23:58,380 Speaker 1: So you would kind of migrate the current remote functions 369 00:23:58,720 --> 00:24:00,300 Speaker 1: to use that when 370 00:24:00,300 --> 00:24:01,680 Speaker 2: the resource API is 371 00:24:01,680 --> 00:24:01,860 Speaker 1: done. 372 00:24:02,040 --> 00:24:02,120 Speaker 1: Right. 373 00:24:03,380 --> 00:24:04,640 Speaker 1: Yeah, it's all connected. 374 00:24:05,640 --> 00:24:05,820 Speaker 1: Yeah. 375 00:24:06,800 --> 00:24:06,920 Speaker 1: Yeah. 376 00:24:07,600 --> 00:24:10,880 Speaker 1: That's kind of nice to hear that the SPA use case 377 00:24:10,900 --> 00:24:12,180 Speaker 1: is getting some love 378 00:24:12,640 --> 00:24:14,880 Speaker 1: because it's been a bit neglected, I feel like, 379 00:24:15,060 --> 00:24:16,780 Speaker 1: in SvelteKit, at least. 380 00:24:17,060 --> 00:24:17,200 Speaker 2: Yeah. 381 00:24:17,440 --> 00:24:19,100 Speaker 2: Like you've always been able to use Svelte, 382 00:24:19,120 --> 00:24:19,240 Speaker 1: right? 383 00:24:20,480 --> 00:24:21,320 Speaker 2: That is true. 384 00:24:21,560 --> 00:24:23,159 Speaker 2: Like, I... 385 00:24:24,080 --> 00:24:26,380 Speaker 2: it felt a bit neglected 386 00:24:26,700 --> 00:24:28,660 Speaker 2: and I appreciate that feedback 387 00:24:29,040 --> 00:24:31,320 Speaker 2: and I get where it comes from. 388 00:24:34,440 --> 00:24:36,680 Speaker 2: And I think with Async Svelte itself already, 389 00:24:37,980 --> 00:24:40,940 Speaker 2: the SPA case already is easier, 390 00:24:41,100 --> 00:24:42,060 Speaker 2: much easier to do 391 00:24:42,300 --> 00:24:45,880 Speaker 2: because if you wanted to have proper data loading, 392 00:24:46,160 --> 00:24:47,260 Speaker 2: a proper data loading story, 393 00:24:48,160 --> 00:24:50,280 Speaker 2: you basically had to use SvelteKit. 394 00:24:51,140 --> 00:24:51,580 Speaker 2: But now 395 00:24:51,580 --> 00:24:52,660 Speaker 3: with async 396 00:24:52,660 --> 00:25:09,420 Speaker 2: Svelte, where you can just slap in a weight in front of a fetch, for example, coordinating asynchronous work in SPA only applications, even applications that don't use SvelteKit, they just use Svelte. 397 00:25:10,420 --> 00:25:14,920 Speaker 2: That's now much easier and much more doable compared to before. 398 00:25:16,540 --> 00:25:16,640 Speaker 1: Yeah. 399 00:25:18,560 --> 00:25:18,840 Speaker 2: We 400 00:25:18,840 --> 00:25:20,600 Speaker 1: haven't had enough 401 00:25:20,600 --> 00:25:23,320 Speaker 2: documentation on this topic though yet. 402 00:25:23,320 --> 00:25:24,880 Speaker 2: So that's another part. 403 00:25:25,860 --> 00:25:32,720 Speaker 2: The feeling comes from that many of our documentation is SSR and progressive enhancement centric. 404 00:25:33,700 --> 00:25:47,480 Speaker 2: And I think we can do better here with having more for SPA use cases without like abandoning the progressive enhancement. 405 00:25:48,460 --> 00:25:50,220 Speaker 1: yeah because that's an important part 406 00:25:50,270 --> 00:25:52,140 Speaker 1: like the progressive enhancement and the 407 00:25:52,880 --> 00:25:54,320 Speaker 1: kind of building for 408 00:25:54,460 --> 00:25:56,180 Speaker 1: people that aren't necessarily 409 00:25:56,860 --> 00:25:58,320 Speaker 1: using JavaScript in their 410 00:25:58,420 --> 00:25:58,580 Speaker 1: browser 411 00:26:00,100 --> 00:26:01,600 Speaker 2: or don't get it fast enough 412 00:26:02,500 --> 00:26:02,620 Speaker 2: yeah 413 00:26:03,520 --> 00:26:05,340 Speaker 1: for any reason that 414 00:26:05,340 --> 00:26:05,820 Speaker 2: they don't have 415 00:26:05,820 --> 00:26:06,140 Speaker 1: JavaScript 416 00:26:06,400 --> 00:26:08,280 Speaker 1: working on the website on the page at the moment 417 00:26:09,700 --> 00:26:10,220 Speaker 1: okay 418 00:26:10,370 --> 00:26:11,480 Speaker 1: cool so 419 00:26:12,340 --> 00:26:13,780 Speaker 1: that was ASIC Svelte 420 00:26:16,320 --> 00:26:17,520 Speaker 1: there's talk 421 00:26:17,540 --> 00:26:24,860 Speaker 1: and link. We talked a bit about queries. Anything else about queries that we should talk about? I 422 00:26:24,920 --> 00:26:33,100 Speaker 1: know there's a query.batch where you can kind of fetch many things and then... Yeah, so now that we 423 00:26:33,240 --> 00:26:34,080 Speaker 1: have this remote 424 00:26:34,080 --> 00:26:40,440 Speaker 2: functions primitive, it's very fun to think about all the additional things we 425 00:26:40,520 --> 00:26:41,700 Speaker 2: can bring to it on top. 426 00:26:43,800 --> 00:26:44,060 Speaker 2: So 427 00:26:45,260 --> 00:26:46,120 Speaker 2: query batch is 428 00:26:46,440 --> 00:26:47,080 Speaker 2: one example. 429 00:26:49,240 --> 00:26:50,200 Speaker 2: Just to quickly 430 00:26:50,520 --> 00:26:52,020 Speaker 2: explain what query batch does, it's 431 00:26:52,360 --> 00:26:54,080 Speaker 2: solving the so-called n 432 00:26:54,260 --> 00:26:56,180 Speaker 2: plus one problem. So 433 00:26:56,420 --> 00:26:58,160 Speaker 2: imagine you have a list of 434 00:26:58,260 --> 00:27:00,100 Speaker 2: cities and for each city you want 435 00:27:00,100 --> 00:27:00,940 Speaker 2: to get the 436 00:27:02,340 --> 00:27:03,900 Speaker 2: weather data for that city. 437 00:27:05,120 --> 00:27:05,460 Speaker 2: And 438 00:27:06,720 --> 00:27:08,220 Speaker 2: I mean, you could have 439 00:27:09,359 --> 00:27:10,200 Speaker 2: like a 440 00:27:10,600 --> 00:27:16,980 Speaker 2: an endpoint which says okay let's get me the weather for all these cities and you could write 441 00:27:17,080 --> 00:27:23,600 Speaker 2: it yourself but i don't know maybe the list changes and then you basically you you re-request 442 00:27:24,700 --> 00:27:30,760 Speaker 2: the data for all the ones you already have and not just the i don't know five that are new or 443 00:27:30,800 --> 00:27:39,560 Speaker 2: something so instead ideally what you want is to call on the client just get weather as a query 444 00:27:40,660 --> 00:27:49,620 Speaker 2: for each of the cities but that means that you would in the worst case do um i don't know let's 445 00:27:49,700 --> 00:27:57,180 Speaker 2: say it's a list of 20 and then you do 20 uh query requests and do therefore do query 10 446 00:27:58,560 --> 00:28:05,420 Speaker 2: at 20 back-end requests and maybe each with i don't know in the case of whether it's probably 447 00:28:06,380 --> 00:28:11,680 Speaker 2: easy but i don't know maybe this is behind some authentication and then for each thing you're 448 00:28:12,280 --> 00:28:17,880 Speaker 2: doing the authentication dance doing some database request the database request maybe itself is 449 00:28:18,060 --> 00:28:23,580 Speaker 2: already pretty complex and therefore taxing on the database and so on and you're doing that 20 times 450 00:28:24,180 --> 00:28:35,640 Speaker 2: And instead, what you could do is basically do what the alternative is to do it, to do manually to bulk request 20 at one. 451 00:28:36,860 --> 00:28:45,500 Speaker 2: But from the client, it looks like you're doing like 20 requests and query batch then batches them into one request. 452 00:28:46,580 --> 00:28:51,520 Speaker 2: So on the client, you're calling this with one city each. 453 00:28:51,590 --> 00:28:55,160 Speaker 2: And on the backend, you receive an array of cities. 454 00:28:56,080 --> 00:28:59,200 Speaker 2: So you only do one request, only do one response. 455 00:29:00,080 --> 00:29:07,180 Speaker 2: And on the client, it can then spread it out again to the right requests. 456 00:29:07,900 --> 00:29:10,100 Speaker 2: And that's what query batch does. 457 00:29:10,400 --> 00:29:18,480 Speaker 1: So in my example of getting a blog post, this would be get the list of blog posts for the front page. 458 00:29:18,980 --> 00:29:21,200 Speaker 1: Basically, you would use query batch there, I assume. 459 00:29:21,940 --> 00:29:27,080 Speaker 2: If you want to have the details of all the blog posts, then yes, you could do that. 460 00:29:27,280 --> 00:29:35,920 Speaker 2: I guess for the front page, I would probably still do one get posts, which has a different structure. 461 00:29:36,000 --> 00:29:37,640 Speaker 2: like it's only containing 462 00:29:38,100 --> 00:29:39,620 Speaker 3: some short 463 00:29:39,620 --> 00:29:39,860 Speaker 2: summary 464 00:29:39,970 --> 00:29:40,980 Speaker 2: and the title or something 465 00:29:43,139 --> 00:29:43,960 Speaker 2: but yeah 466 00:29:43,960 --> 00:29:45,780 Speaker 2: like it's not common 467 00:29:46,080 --> 00:29:47,600 Speaker 2: but when you run into this 468 00:29:47,900 --> 00:29:48,560 Speaker 2: it's kind of 469 00:29:49,940 --> 00:29:51,300 Speaker 2: annoying and 470 00:29:52,080 --> 00:29:53,840 Speaker 2: now with remote functions 471 00:29:54,900 --> 00:29:55,860 Speaker 2: with this nice 472 00:29:56,040 --> 00:29:57,160 Speaker 2: primitive we have 473 00:29:57,930 --> 00:29:59,940 Speaker 2: the ability to also 474 00:30:00,340 --> 00:30:01,920 Speaker 2: provide more quality 475 00:30:01,920 --> 00:30:03,860 Speaker 2: of life functions 476 00:30:04,300 --> 00:30:07,440 Speaker 2: that way. And if you don't use it, it's basically 477 00:30:07,740 --> 00:30:12,000 Speaker 2: it's tree shakable. So if you don't use that, then you're also not paying for this. 478 00:30:12,500 --> 00:30:13,500 Speaker 2: That's the best scenario. 479 00:30:15,310 --> 00:30:16,460 Speaker 1: Getting a lot of functionality. 480 00:30:19,770 --> 00:30:21,540 Speaker 2: Right. There's going to be others. 481 00:30:22,020 --> 00:30:25,560 Speaker 2: Like we have to think about what we want 482 00:30:25,560 --> 00:30:29,300 Speaker 2: to do with caching. This is an ongoing design 483 00:30:29,620 --> 00:30:33,840 Speaker 2: question. Ideally, it's 484 00:30:34,340 --> 00:30:35,920 Speaker 2: more than just set headers 485 00:30:37,540 --> 00:30:37,680 Speaker 2: because 486 00:30:38,260 --> 00:30:39,860 Speaker 2: setting headers and getting that right 487 00:30:40,000 --> 00:30:40,820 Speaker 2: that's like really 488 00:30:42,559 --> 00:30:44,040 Speaker 2: it's almost rocket science 489 00:30:44,720 --> 00:30:45,760 Speaker 2: like setting 490 00:30:45,940 --> 00:30:48,000 Speaker 2: the correct cache headers in the correct ways 491 00:30:48,180 --> 00:30:49,480 Speaker 2: that's not easy 492 00:30:49,940 --> 00:30:51,720 Speaker 2: and like many 493 00:30:52,800 --> 00:30:53,660 Speaker 3: cloud providers 494 00:30:55,020 --> 00:30:55,760 Speaker 2: have now 495 00:30:56,820 --> 00:30:57,800 Speaker 2: more elaborate 496 00:30:57,940 --> 00:30:59,600 Speaker 2: ways of doing caching and 497 00:30:59,940 --> 00:31:01,720 Speaker 2: ideally we can on a provider basis 498 00:31:02,040 --> 00:31:02,960 Speaker 2: integrate with that 499 00:31:03,960 --> 00:31:04,660 Speaker 2: but having an 500 00:31:04,660 --> 00:31:06,140 Speaker 3: API that basically 501 00:31:07,360 --> 00:31:09,640 Speaker 2: makes this write ISR for example. 502 00:31:10,840 --> 00:31:12,980 Speaker 2: So that's one thing we're talking about. 503 00:31:13,280 --> 00:31:15,720 Speaker 2: We're talking about query.stream 504 00:31:16,180 --> 00:31:19,380 Speaker 2: which basically allows you to stream data 505 00:31:20,580 --> 00:31:23,360 Speaker 2: live data from the backend to the frontend. 506 00:31:24,300 --> 00:31:27,360 Speaker 2: There's people who want this both ways 507 00:31:27,940 --> 00:31:28,900 Speaker 2: in both directions. 508 00:31:29,540 --> 00:31:32,299 Speaker 2: So something around WebSockets 509 00:31:32,320 --> 00:31:35,860 Speaker 2: We have to think about that, see how that goes. 510 00:31:36,470 --> 00:31:38,620 Speaker 2: So yeah, there's lots of possibilities 511 00:31:39,470 --> 00:31:45,020 Speaker 2: and it's all going to revolve around the same primitives 512 00:31:45,480 --> 00:31:48,400 Speaker 2: and the same ideas and APIs. 513 00:31:48,550 --> 00:31:53,020 Speaker 2: And so I feel like it's going to become a really nice set of APIs, 514 00:31:53,540 --> 00:32:00,340 Speaker 2: which will give you a good way for many of your use cases 515 00:32:02,359 --> 00:32:04,320 Speaker 2: without restricting you or something 516 00:32:04,680 --> 00:32:08,320 Speaker 2: and also without forcing you to use it all at once. 517 00:32:08,620 --> 00:32:11,580 Speaker 2: You can explore over time and grow with it. 518 00:32:12,380 --> 00:32:12,600 Speaker 1: Yes, 519 00:32:13,020 --> 00:32:13,460 Speaker 2: I've 520 00:32:13,460 --> 00:32:14,620 Speaker 1: tried it out for a bit 521 00:32:16,120 --> 00:32:18,000 Speaker 1: in preparation of this interview 522 00:32:18,280 --> 00:32:22,220 Speaker 1: and I experimented with moving. 523 00:32:23,220 --> 00:32:24,120 Speaker 3: I've only had 524 00:32:24,120 --> 00:32:26,000 Speaker 1: time to try out the query one, 525 00:32:26,860 --> 00:32:30,320 Speaker 1: but just converting a load function into a query 526 00:32:30,840 --> 00:32:33,800 Speaker 1: remote function super easy. I 527 00:32:33,800 --> 00:32:34,060 Speaker 3: really 528 00:32:34,060 --> 00:32:38,200 Speaker 1: enjoyed it. Like it's very nice. And you also get that like 529 00:32:38,480 --> 00:32:46,220 Speaker 1: one thing I ran into, because I stupidly didn't read the documentation that well, was the like, 530 00:32:46,480 --> 00:32:52,340 Speaker 1: how do I get access to locals? And then I discovered, what do you call it? Like get request 531 00:32:52,580 --> 00:32:59,460 Speaker 1: event for this, which is pretty nice. And it's what I discovered as well. I didn't realize this 532 00:32:59,480 --> 00:33:03,380 Speaker 1: at first, but you can use getRequestEvent 533 00:33:03,540 --> 00:33:07,320 Speaker 1: in a function that you're using inside of a remote 534 00:33:07,440 --> 00:33:11,100 Speaker 1: function. So at first I thought 535 00:33:11,660 --> 00:33:13,140 Speaker 1: I would chain 536 00:33:15,480 --> 00:33:18,780 Speaker 1: I would call a remote function inside of another remote function 537 00:33:19,620 --> 00:33:23,240 Speaker 1: but then I realized why would I do that when I can just call 538 00:33:23,240 --> 00:33:27,460 Speaker 1: a regular function? For some reason I didn't realize 539 00:33:28,680 --> 00:33:29,300 Speaker 1: that I could do that. 540 00:33:30,900 --> 00:33:33,080 Speaker 2: Yeah, that's definitely another beauty of this. 541 00:33:33,480 --> 00:33:37,100 Speaker 2: It's all functions and it looks like functions, 542 00:33:37,340 --> 00:33:43,300 Speaker 2: but it actually is just functions without any gotchas. 543 00:33:44,420 --> 00:33:47,160 Speaker 2: So you could use other queries from within queries. 544 00:33:47,900 --> 00:33:50,760 Speaker 2: You could use regular functions from within queries. 545 00:33:52,960 --> 00:33:55,920 Speaker 2: So yeah, you can compose and nest this as you like, 546 00:33:56,500 --> 00:33:58,220 Speaker 2: Which is really nice. 547 00:33:58,770 --> 00:33:59,080 Speaker 2: And at 548 00:33:59,080 --> 00:33:59,760 Speaker 3: the same time, 549 00:34:00,040 --> 00:34:01,460 Speaker 2: because it's so like, 550 00:34:03,000 --> 00:34:05,320 Speaker 2: because the boundary is the file, 551 00:34:06,500 --> 00:34:07,380 Speaker 2: you don't 552 00:34:07,380 --> 00:34:07,980 Speaker 3: run into 553 00:34:07,980 --> 00:34:12,399 Speaker 2: any weird hiccups where, I don't know, 554 00:34:13,040 --> 00:34:15,360 Speaker 2: you accidentally close over a variable 555 00:34:17,099 --> 00:34:21,540 Speaker 2: and then somehow end up having a security leak. 556 00:34:22,100 --> 00:34:22,540 Speaker 2: That's one of 557 00:34:22,540 --> 00:34:23,260 Speaker 3: the reasons why 558 00:34:23,260 --> 00:34:24,500 Speaker 2: we went with file boundaries 559 00:34:24,520 --> 00:34:29,040 Speaker 2: compared to use server, for example. 560 00:34:29,610 --> 00:34:32,480 Speaker 1: Ah, right, like in React, I guess. 561 00:34:33,399 --> 00:34:36,800 Speaker 1: I have no idea how use server and stuff works in React. 562 00:34:40,190 --> 00:34:40,560 Speaker 1: So, all right. 563 00:34:40,610 --> 00:34:42,000 Speaker 1: So the experience is nice. 564 00:34:42,280 --> 00:34:43,480 Speaker 1: I really enjoyed it. 565 00:34:43,770 --> 00:34:45,480 Speaker 1: I haven't tried the form stuff yet, 566 00:34:45,960 --> 00:34:49,280 Speaker 1: but I am sure I'll have a great time. 567 00:34:49,610 --> 00:34:50,500 Speaker 1: But there's also like, 568 00:34:50,840 --> 00:34:53,679 Speaker 1: I've heard that you're not quite done 569 00:34:53,720 --> 00:34:56,820 Speaker 1: with how the form stuff works yet? 570 00:34:57,920 --> 00:35:00,080 Speaker 1: Like you're evaluating, maybe changing it a bit. 571 00:35:00,180 --> 00:35:01,140 Speaker 1: Is that right? 572 00:35:01,440 --> 00:35:04,980 Speaker 1: Or am I misremembering maybe? 573 00:35:05,780 --> 00:35:10,740 Speaker 2: Yeah, so there's a couple of ongoing tweaks right now. 574 00:35:12,220 --> 00:35:12,920 Speaker 3: So we 575 00:35:12,920 --> 00:35:16,080 Speaker 2: started out with form functions 576 00:35:17,400 --> 00:35:19,300 Speaker 2: retrieving the regular form data, 577 00:35:19,440 --> 00:35:25,640 Speaker 2: and then you have to like pull out the data yourself from there. 578 00:35:26,960 --> 00:35:32,180 Speaker 2: We since then have switched it to requiring a schema 579 00:35:32,520 --> 00:35:37,960 Speaker 2: as the first argument and then doing conversion logic there 580 00:35:38,820 --> 00:35:42,700 Speaker 2: so that you get a regular pojo from form data, 581 00:35:42,710 --> 00:35:44,020 Speaker 2: which is already much nicer. 582 00:35:44,140 --> 00:35:49,780 Speaker 2: and the way you interact with the form on the client 583 00:35:50,740 --> 00:35:54,340 Speaker 2: when, for example, you have, I don't know, 584 00:35:55,100 --> 00:35:59,920 Speaker 2: you return a list of issues via the schema 585 00:36:00,220 --> 00:36:02,720 Speaker 2: and then you can show that in the client. 586 00:36:02,890 --> 00:36:05,000 Speaker 2: You can show the current value on the client. 587 00:36:05,770 --> 00:36:08,420 Speaker 2: And the way this works is still a bit rough 588 00:36:08,550 --> 00:36:11,779 Speaker 2: and we're in the works of tweaking this 589 00:36:11,800 --> 00:36:14,720 Speaker 2: to give a much nicer API. 590 00:36:15,680 --> 00:36:19,340 Speaker 2: So it's probably going to be something like this 591 00:36:19,520 --> 00:36:22,740 Speaker 2: that you have a fields property on your form. 592 00:36:24,060 --> 00:36:27,080 Speaker 2: And from there on, you just use regular.notation 593 00:36:27,300 --> 00:36:30,580 Speaker 2: to go wherever you want to go in your model. 594 00:36:32,060 --> 00:36:35,940 Speaker 2: And it's type safe because through the schema, 595 00:36:36,080 --> 00:36:40,560 Speaker 2: it knows which things are available at which level. 596 00:36:42,920 --> 00:36:49,440 Speaker 2: so in other words you don't have to have flat forms like it your your object can be nested 597 00:36:49,920 --> 00:36:57,140 Speaker 2: you don't have to have it only one level deep yeah and through the stop mutation and then you can get 598 00:36:57,520 --> 00:37:06,240 Speaker 2: a much easier time connecting that to your input so that things are in sync with the value and so 599 00:37:06,240 --> 00:37:09,680 Speaker 2: on and yeah it's it's it's a bit hard to explain just 600 00:37:09,680 --> 00:37:10,000 Speaker 1: over 601 00:37:10,000 --> 00:37:12,060 Speaker 3: voice but yeah for sure yeah 602 00:37:12,060 --> 00:37:13,080 Speaker 2: just just 603 00:37:13,200 --> 00:37:15,640 Speaker 2: stay tuned it's it's gonna be out soon 604 00:37:15,640 --> 00:37:16,840 Speaker 3: and um yeah 605 00:37:16,840 --> 00:37:20,600 Speaker 2: it will make forms uh even easier to work with 606 00:37:21,120 --> 00:37:22,960 Speaker 2: um yeah yeah so 607 00:37:22,960 --> 00:37:33,880 Speaker 1: uh some questions there um with with regards to forms like form handling forms 608 00:37:33,880 --> 00:37:37,080 Speaker 1: from end to end is like a huge undertaking, right? 609 00:37:37,910 --> 00:37:38,020 Speaker 1: If 610 00:37:38,020 --> 00:37:38,360 Speaker 3: you 611 00:37:38,360 --> 00:37:41,160 Speaker 1: look at super forms, it's super complicated 612 00:37:41,400 --> 00:37:42,620 Speaker 1: because there are so many edge cases 613 00:37:42,920 --> 00:37:44,780 Speaker 1: and so much functionality that people want. 614 00:37:47,280 --> 00:37:52,640 Speaker 1: How far do you think you guys will go with implement? 615 00:37:52,960 --> 00:37:54,440 Speaker 1: Because validation is the first step, right? 616 00:37:55,060 --> 00:37:57,340 Speaker 1: Because then you have to handle error messages. 617 00:37:58,040 --> 00:37:59,160 Speaker 1: How do you display the error? 618 00:37:59,380 --> 00:38:00,780 Speaker 1: Like where do you get the error messages from? 619 00:38:01,720 --> 00:38:08,320 Speaker 1: Where do you, how do you handle like if the form has been touched, et cetera, et cetera? 620 00:38:08,600 --> 00:38:10,960 Speaker 1: Like there's just like a, like 621 00:38:10,960 --> 00:38:12,640 Speaker 2: a rabbit hole of stuff that you 622 00:38:12,640 --> 00:38:14,100 Speaker 3: can end up implementing. 623 00:38:16,000 --> 00:38:24,640 Speaker 2: Yeah, I mean, we started out without having a way to get issues because we didn't have schema yet. 624 00:38:25,060 --> 00:38:32,220 Speaker 2: Now that we have a schema, through the schema, you can tell when a field fails, 625 00:38:32,250 --> 00:38:37,340 Speaker 2: you can basically return a message along with it that is then sent back to the client. 626 00:38:38,980 --> 00:38:45,260 Speaker 2: You can also now have so-called pre-flight, which is basically validation on the client as you type. 627 00:38:46,360 --> 00:38:51,220 Speaker 2: So yeah, we have added more stuff because the community said like, 628 00:38:51,300 --> 00:38:54,180 Speaker 2: oh yeah this is nice but do you know what would be even nicer if you 629 00:38:54,180 --> 00:38:54,960 Speaker 1: also had 630 00:38:54,960 --> 00:38:55,260 Speaker 2: this 631 00:38:56,200 --> 00:38:59,140 Speaker 1: yeah just i mean just just opening the super forms documentation 632 00:38:59,140 --> 00:39:00,520 Speaker 2: is basically like that 633 00:39:00,520 --> 00:39:01,020 Speaker 1: that's how you 634 00:39:01,020 --> 00:39:05,100 Speaker 1: end up with super forms or like all the fresh now because you kind of need that the 635 00:39:05,100 --> 00:39:06,080 Speaker 2: goal so the 636 00:39:06,820 --> 00:39:10,940 Speaker 2: the goal will explicitly not be to rebuild super forms into 637 00:39:10,940 --> 00:39:11,760 Speaker 3: svelte 638 00:39:11,760 --> 00:39:14,460 Speaker 2: kit so there will still be room 639 00:39:14,480 --> 00:39:22,780 Speaker 2: for super form to to exist but the the goal basically is to solve the 80 percent use case 640 00:39:24,020 --> 00:39:31,980 Speaker 2: and leave the rest of the 20 percent which are the ones where like you get increasingly 641 00:39:32,980 --> 00:39:34,080 Speaker 2: diminishing returns 642 00:39:34,080 --> 00:39:35,500 Speaker 3: yeah with 643 00:39:35,500 --> 00:39:37,960 Speaker 2: even more edge cases and so on and to leave those 644 00:39:38,460 --> 00:39:48,180 Speaker 2: out in favor of a consistent, concise API that is easy to use, to understand, but at the same time 645 00:39:48,460 --> 00:39:57,360 Speaker 2: leave enough room for people to build something on top of it. So you could imagine a world in which 646 00:39:57,980 --> 00:40:04,060 Speaker 2: maybe at some point SuperForms is built as an extension on top of remote form functions. 647 00:40:04,360 --> 00:40:22,720 Speaker 1: That makes sense. I mean, the complexity would just like skyrocket if you would add all of the functionality and features that you would need from, if you wanted to build a one-to-one kind of thing, proper full featured form library, if that makes sense. 648 00:40:23,060 --> 00:40:23,400 Speaker 2: That's correct. 649 00:40:24,220 --> 00:40:31,400 Speaker 1: But that sounds like a good, like, building for 80% of the use cases sounds good. 650 00:40:32,840 --> 00:40:35,240 Speaker 1: Anything else about forms that we should talk about? 651 00:40:35,800 --> 00:40:37,900 Speaker 1: That nothing springs to mind right now. 652 00:40:38,140 --> 00:40:42,940 Speaker 2: Just that, like, you can still redirect from there. 653 00:40:42,940 --> 00:40:45,060 Speaker 2: You can still throw an arrow in there. 654 00:40:45,460 --> 00:40:52,700 Speaker 2: So basically all the existing ways in which you used forms so far, they still continue to exist. 655 00:40:53,780 --> 00:40:54,260 Speaker 1: - Okay, cool. 656 00:40:54,900 --> 00:40:58,680 Speaker 1: So let's say not having used the form remote function yet. 657 00:40:59,060 --> 00:41:02,320 Speaker 1: What if I, after posting some data to, 658 00:41:03,080 --> 00:41:04,640 Speaker 1: let's say it's a to-do list and I'm, 659 00:41:04,920 --> 00:41:05,920 Speaker 1: I want to post a new to-do, 660 00:41:06,860 --> 00:41:09,200 Speaker 1: and then I want to refresh the data that I have on, 661 00:41:09,800 --> 00:41:11,640 Speaker 1: on the, from my query that, 662 00:41:11,840 --> 00:41:13,640 Speaker 1: that I use to fetch the to-dos, right? 663 00:41:13,880 --> 00:41:15,220 Speaker 1: So let's say I have a query, 664 00:41:16,100 --> 00:41:18,320 Speaker 1: a query remote function that's called get to-dos. 665 00:41:19,080 --> 00:41:22,460 Speaker 1: And then I have a create to-do form remote function. 666 00:41:23,480 --> 00:41:27,640 Speaker 1: what would be like an easy way to refresh the data? 667 00:41:27,760 --> 00:41:29,780 Speaker 1: Because in the old SvelteKit way, 668 00:41:29,880 --> 00:41:32,460 Speaker 1: you would just form, you would submit the form 669 00:41:32,500 --> 00:41:35,200 Speaker 1: and then the load function would rerun. 670 00:41:35,540 --> 00:41:37,580 Speaker 1: So how does it work now? 671 00:41:37,920 --> 00:41:41,980 Speaker 2: So by default, it will refresh everything on the 672 00:41:41,980 --> 00:41:42,380 Speaker 1: page 673 00:41:42,840 --> 00:41:43,140 Speaker 1: to mirror the... 674 00:41:43,140 --> 00:41:43,900 Speaker 1: So just like before. 675 00:41:44,600 --> 00:41:47,300 Speaker 2: Just like before to mirror the non-progressive 676 00:41:47,400 --> 00:41:48,960 Speaker 2: and the Hampton page case, 677 00:41:49,020 --> 00:41:52,120 Speaker 2: in which case you would basically get a full page reload, 678 00:41:52,480 --> 00:41:54,940 Speaker 2: which basically means you reload everything. 679 00:41:55,990 --> 00:41:57,820 Speaker 1: So does it, how does, yeah. 680 00:41:58,200 --> 00:41:59,180 Speaker 1: Sorry, no, I was going to say, 681 00:41:59,250 --> 00:42:01,320 Speaker 1: like, how does it, does it just know, 682 00:42:01,730 --> 00:42:06,300 Speaker 1: like, exactly what remote or query remote functions 683 00:42:06,520 --> 00:42:07,380 Speaker 1: that are on the page? 684 00:42:08,020 --> 00:42:08,580 Speaker 1: That's correct. 685 00:42:08,860 --> 00:42:09,820 Speaker 1: So there's 686 00:42:09,820 --> 00:42:13,180 Speaker 2: a, basically there's a hidden client cache 687 00:42:13,300 --> 00:42:16,340 Speaker 2: that knows about all queries that are on the page. 688 00:42:17,120 --> 00:42:19,640 Speaker 2: That also means that if you are using, 689 00:42:20,190 --> 00:42:21,320 Speaker 2: I don't know, get user, 690 00:42:22,200 --> 00:42:25,040 Speaker 2: as a query in three different places. 691 00:42:25,320 --> 00:42:27,800 Speaker 2: You're not actually doing three different fetches. 692 00:42:28,180 --> 00:42:29,040 Speaker 2: You're sharing 693 00:42:29,040 --> 00:42:29,800 Speaker 3: the 694 00:42:29,800 --> 00:42:33,120 Speaker 2: same instance under the hood. 695 00:42:33,520 --> 00:42:37,160 Speaker 2: So it's all shared, cached, client under the hood, 696 00:42:37,500 --> 00:42:38,720 Speaker 2: which is another nice thing 697 00:42:38,980 --> 00:42:41,880 Speaker 2: because you don't have to worry about like, 698 00:42:42,850 --> 00:42:45,160 Speaker 2: I don't know, hoisting your data loading up, for example. 699 00:42:45,170 --> 00:42:47,440 Speaker 2: Oh, I need get user, the user data. 700 00:42:47,470 --> 00:42:49,880 Speaker 2: I need that in my layout as well now. 701 00:42:50,140 --> 00:42:52,000 Speaker 2: So today you wouldn't hoist your 702 00:42:52,000 --> 00:42:54,560 Speaker 3: getUserFetcher 703 00:42:55,080 --> 00:42:56,320 Speaker 2: up into the layout function. 704 00:42:57,560 --> 00:42:59,500 Speaker 2: And with remote functions, 705 00:42:59,580 --> 00:43:02,380 Speaker 2: you just do like await getUser right then and there, 706 00:43:02,400 --> 00:43:02,900 Speaker 2: and that's it. 707 00:43:04,380 --> 00:43:06,180 Speaker 2: And you don't, yeah, as I said, 708 00:43:06,780 --> 00:43:09,100 Speaker 2: you're not doing an extra request that way. 709 00:43:09,200 --> 00:43:11,020 Speaker 2: It's just, it's deduplicated. 710 00:43:11,640 --> 00:43:11,740 Speaker 2: It 711 00:43:11,740 --> 00:43:12,400 Speaker 1: knows about that. 712 00:43:12,900 --> 00:43:16,560 Speaker 1: So if I have a query function that's called getPost, 713 00:43:16,760 --> 00:43:18,460 Speaker 1: and then I want to show two posts, 714 00:43:18,940 --> 00:43:27,560 Speaker 1: As long as I assume, like, if I supply two different query parameters, it would run the 715 00:43:27,700 --> 00:43:28,360 Speaker 1: query twice? 716 00:43:28,600 --> 00:43:30,340 Speaker 1: Yes, so the cache 717 00:43:30,340 --> 00:43:36,840 Speaker 2: key is basically the ID of the remote function plus the stringified 718 00:43:37,040 --> 00:43:37,220 Speaker 2: payload. 719 00:43:38,220 --> 00:43:38,800 Speaker 2: Okay, cool. 720 00:43:39,360 --> 00:43:44,100 Speaker 2: And that way, we know about all the existing query functions on the page. 721 00:43:44,480 --> 00:43:51,460 Speaker 2: And that means when a remote form function runs, it knows which things to refresh. 722 00:43:52,110 --> 00:43:54,020 Speaker 2: And by default, it will refresh everything. 723 00:43:54,970 --> 00:44:02,000 Speaker 2: But you can also opt into more granular refreshes by doing a so-called single flight mutation, 724 00:44:02,780 --> 00:44:09,840 Speaker 2: which means you are not only returning data or doing the form post, 725 00:44:10,600 --> 00:44:13,860 Speaker 2: you're also telling the client, 726 00:44:14,600 --> 00:44:19,300 Speaker 2: hey, and these are the things that I wanted to have refreshed 727 00:44:19,760 --> 00:44:24,100 Speaker 2: and this is the new data from those queries. 728 00:44:25,500 --> 00:44:28,880 Speaker 2: So basically, in your form function, 729 00:44:28,980 --> 00:44:31,540 Speaker 2: if you do like, I don't know, create post, 730 00:44:32,940 --> 00:44:38,540 Speaker 2: you would then at the end of your inside your form function, 731 00:44:38,760 --> 00:44:42,140 Speaker 2: would do something like get posts dot refresh 732 00:44:42,140 --> 00:44:45,860 Speaker 1: and then get posts is the query remote function 733 00:44:45,960 --> 00:44:48,080 Speaker 1: that exists so right right 734 00:44:48,080 --> 00:44:52,580 Speaker 2: so you invoke the query function call dot refresh on it 735 00:44:53,480 --> 00:45:00,260 Speaker 2: and that way the remote function knows okay the user is interested in getting the new data now 736 00:45:01,300 --> 00:45:11,560 Speaker 2: of this thing so i'm going to request the get posts now and i'm going going to wait on its 737 00:45:11,880 --> 00:45:19,480 Speaker 2: result and once it's there i'm going to put it into basically a hidden field on the return 738 00:45:20,460 --> 00:45:28,180 Speaker 2: um on the response and then the client knows ah okay there's this hidden field and these are the 739 00:45:29,040 --> 00:45:35,820 Speaker 2: hash keys i need to update and it's going to do that and that way you get both a more granular 740 00:45:36,040 --> 00:45:41,620 Speaker 2: refresh because you're no longer refreshing anything everything but only this one and at 741 00:45:41,620 --> 00:45:46,940 Speaker 2: the same time you get a single flight mutation which means you're faster because you're doing 742 00:45:46,940 --> 00:45:54,180 Speaker 2: the mutation plus the refresh at the same time instead of having to do one round trip to the 743 00:45:54,040 --> 00:46:00,580 Speaker 2: server to get the response uh like okay the form has succeeded to post there and then do another 744 00:46:00,980 --> 00:46:07,000 Speaker 2: round trip to the server to say okay and now give me the refreshed data you're doing it in one 745 00:46:07,320 --> 00:46:07,680 Speaker 2: single flight 746 00:46:07,680 --> 00:46:13,080 Speaker 1: invitation yeah well that i mean that's because then you reduce like uh what's it 747 00:46:14,330 --> 00:46:18,720 Speaker 1: called uh i forget what it's called like when you have to go multiple times 748 00:46:18,720 --> 00:46:19,960 Speaker 2: multiple round trips yeah 749 00:46:19,800 --> 00:46:21,560 Speaker 2: Yeah, the round trips, right? 750 00:46:22,160 --> 00:46:22,260 Speaker 1: Yeah. 751 00:46:23,180 --> 00:46:27,960 Speaker 1: So this brings up another interesting question that I have. 752 00:46:28,140 --> 00:46:31,420 Speaker 1: Like, are you batching all of the queries into one request 753 00:46:32,080 --> 00:46:35,160 Speaker 1: or are they done one at a time? 754 00:46:35,580 --> 00:46:38,100 Speaker 1: This is actually an 755 00:46:38,100 --> 00:46:39,260 Speaker 2: open question still, 756 00:46:40,220 --> 00:46:41,340 Speaker 2: if we do that or not. 757 00:46:42,300 --> 00:46:43,980 Speaker 2: It really depends. 758 00:46:44,180 --> 00:46:46,700 Speaker 2: And that's also, I guess this is a, 759 00:46:48,380 --> 00:46:53,740 Speaker 2: Please give us feedback which way you'd like us to go or rather. 760 00:46:55,840 --> 00:47:01,800 Speaker 2: Give us feedback on how many requests you're having on your page. 761 00:47:02,600 --> 00:47:06,540 Speaker 2: Like, do you have a few requests at once or do you have like, 762 00:47:06,750 --> 00:47:07,060 Speaker 3: I don't 763 00:47:07,060 --> 00:47:07,200 Speaker 2: know, 764 00:47:07,740 --> 00:47:12,440 Speaker 2: 30 requests going on in your network tab at the same time you're starting to get a bit worried. 765 00:47:13,150 --> 00:47:17,440 Speaker 2: We have it still open as a design question because 766 00:47:17,460 --> 00:47:34,300 So what we're going to do is either have a way to specifically batch things across queries or have a way to say explicitly, I don't want to have 767 00:47:34,300 --> 00:47:35,240 Speaker 3: this be 768 00:47:35,240 --> 00:47:43,360 Speaker 2: automatically batched because for some reason this query needs to be isolated because maybe I want to set headers on this or something. 769 00:47:44,060 --> 00:47:44,600 Speaker 1: And 770 00:47:44,600 --> 00:47:54,260 Speaker 2: for the same reason why we haven't done this automatic batching yet, for the same reason, you cannot use set headers yet on queries. 771 00:47:55,720 --> 00:48:05,520 Speaker 2: For the same reason, because we don't know, okay, do we disallow it only on like the dedicated batching query? 772 00:48:06,680 --> 00:48:08,780 Speaker 2: Or do we disallow it by default? 773 00:48:08,970 --> 00:48:11,700 Speaker 2: And then you're using something like query.isolated. 774 00:48:12,200 --> 00:48:17,240 Speaker 2: And then you can do set headers on there because you know this is only ever going to be this one. 775 00:48:18,280 --> 00:48:20,620 Speaker 2: And yeah, so it's still an open question. 776 00:48:21,280 --> 00:48:23,040 Speaker 2: There's a few considerations here. 777 00:48:23,340 --> 00:48:25,580 Speaker 2: So obviously less requests is better. 778 00:48:26,240 --> 00:48:40,480 Speaker 2: At the same time, if we batch requests, then we have to do post requests because like we, or rather we cannot cache things between. 779 00:48:40,700 --> 00:48:41,080 Speaker 3: Right, 780 00:48:41,760 --> 00:48:41,940 Speaker 2: right. 781 00:48:43,660 --> 00:48:44,000 Speaker 2: so yeah 782 00:48:44,000 --> 00:48:45,560 Speaker 1: it's still an open question 783 00:48:46,070 --> 00:48:47,700 Speaker 2: but we will solve it one way 784 00:48:48,120 --> 00:48:49,360 Speaker 2: or the other at some point 785 00:48:50,260 --> 00:48:50,740 Speaker 1: okay 786 00:48:51,800 --> 00:48:52,320 Speaker 1: cool 787 00:48:53,460 --> 00:48:55,880 Speaker 1: so then there's also like two more 788 00:48:56,540 --> 00:48:57,920 Speaker 1: I think you briefly mentioned 789 00:48:58,260 --> 00:48:59,840 Speaker 1: command which is kind of like the 790 00:49:00,580 --> 00:49:01,420 Speaker 1: I don't want to use 791 00:49:01,830 --> 00:49:02,940 Speaker 1: the web platform 792 00:49:03,430 --> 00:49:03,840 Speaker 3: I want to 793 00:49:03,840 --> 00:49:04,080 Speaker 1: use 794 00:49:04,080 --> 00:49:05,460 Speaker 2: just fetch 795 00:49:06,240 --> 00:49:07,080 Speaker 2: right I want to 796 00:49:08,320 --> 00:49:09,720 Speaker 2: I require my people 797 00:49:09,940 --> 00:49:11,360 Speaker 2: my users to have 798 00:49:11,380 --> 00:49:17,960 Speaker 2: JavaScript enabled, right. And then you can use commands. And yeah, commands are basically 799 00:49:20,740 --> 00:49:24,960 Speaker 2: where previously you were on your own and had to do regular fetches. Now you can use commands, 800 00:49:25,060 --> 00:49:33,800 Speaker 2: which is integrated into the rest, similar to forms. So by default, commands will request 801 00:49:34,260 --> 00:49:35,320 Speaker 2: nothing. So it's like inverse 802 00:49:35,320 --> 00:49:36,280 Speaker 3: compared 803 00:49:36,280 --> 00:49:39,800 Speaker 2: to forms because commands don't exist in the 804 00:49:39,700 --> 00:49:46,980 Speaker 2: a non-progressive enhanced case and commands by its nature are probably much more granular. 805 00:49:48,380 --> 00:49:50,400 Speaker 2: And so by default, they refresh nothing. 806 00:49:50,540 --> 00:49:56,140 Speaker 2: And so basically you opt into what do you want to have refreshed by employing 807 00:49:56,140 --> 00:49:56,480 Speaker 1: the same 808 00:49:56,760 --> 00:49:57,020 Speaker 3: mechanism 809 00:49:57,020 --> 00:49:58,380 Speaker 2: with the refresh. 810 00:49:59,460 --> 00:49:59,960 Speaker 3: Oh, and what I 811 00:49:59,960 --> 00:50:04,820 Speaker 2: didn't mention yet, you can also initiate this kind of single flight mutation 812 00:50:05,300 --> 00:50:05,860 Speaker 2: from the client. 813 00:50:06,860 --> 00:50:11,960 Speaker 2: So you can tell the command or the form, 814 00:50:12,840 --> 00:50:16,940 Speaker 2: hey, please also refresh the following. 815 00:50:18,280 --> 00:50:18,380 Speaker 2: And 816 00:50:18,380 --> 00:50:18,860 Speaker 3: then basically 817 00:50:18,860 --> 00:50:21,840 Speaker 2: we're passing in the remote function key 818 00:50:22,100 --> 00:50:23,320 Speaker 2: from the client to the backend, 819 00:50:23,390 --> 00:50:26,780 Speaker 2: and it then knows which thing to call and how to 820 00:50:26,780 --> 00:50:27,420 Speaker 3: return it. 821 00:50:28,060 --> 00:50:29,420 Speaker 3: And when you do it from the client, 822 00:50:29,470 --> 00:50:32,440 Speaker 2: you can even do optimistic updates. 823 00:50:32,820 --> 00:50:34,820 Speaker 2: So you can on the client say, 824 00:50:35,859 --> 00:50:38,980 Speaker 2: okay, while this request is pending, 825 00:50:40,070 --> 00:50:41,260 Speaker 2: I want to, I don't know, 826 00:50:41,450 --> 00:50:43,500 Speaker 2: maybe you click the toggle button 827 00:50:43,820 --> 00:50:44,860 Speaker 2: and then you're saying like, 828 00:50:45,240 --> 00:50:49,860 Speaker 2: I'm sure this will work in 99.9% of the time. 829 00:50:49,930 --> 00:50:52,660 Speaker 2: So I can just already do an optimistic update 830 00:50:53,020 --> 00:50:53,920 Speaker 2: and I don't know, 831 00:50:54,840 --> 00:50:58,480 Speaker 2: show that it's in thumbs up state already. 832 00:50:59,540 --> 00:50:59,680 Speaker 3: Yeah. 833 00:51:01,100 --> 00:51:03,060 Speaker 2: And that you can use, yeah. 834 00:51:04,180 --> 00:51:06,560 Speaker 2: The specific APIs don't matter really, 835 00:51:06,860 --> 00:51:09,900 Speaker 2: but you have the capability to do an optimistic update there, 836 00:51:10,130 --> 00:51:12,580 Speaker 2: which exists as long as the 837 00:51:12,580 --> 00:51:13,800 Speaker 1: mutation 838 00:51:13,800 --> 00:51:14,260 Speaker 2: is pending. 839 00:51:15,340 --> 00:51:16,700 Speaker 1: Yeah, no, that makes sense. 840 00:51:17,140 --> 00:51:20,500 Speaker 1: So it's basically, it's like form, basically, command. 841 00:51:21,260 --> 00:51:24,400 Speaker 1: It's form, but without using forms, in a sense. 842 00:51:24,960 --> 00:51:26,820 Speaker 1: It's probably simplified a lot. 843 00:51:28,350 --> 00:51:31,300 Speaker 1: But then there's also the last one, the pre-render one, 844 00:51:32,340 --> 00:51:33,540 Speaker 3: which this 845 00:51:33,540 --> 00:51:35,200 Speaker 1: one is pretty cool. 846 00:51:35,460 --> 00:51:38,960 Speaker 1: I feel like you can pre-render parts of your site. 847 00:51:39,800 --> 00:51:41,940 Speaker 1: Well, parts of your page, I guess, 848 00:51:41,950 --> 00:51:42,440 Speaker 1: which you couldn't 849 00:51:42,440 --> 00:51:42,900 Speaker 2: really... 850 00:51:42,900 --> 00:51:44,120 Speaker 2: Parts of your data, yes. 851 00:51:44,520 --> 00:51:44,720 Speaker 2: Yeah. 852 00:51:44,860 --> 00:51:47,180 Speaker 2: So, yeah, that's definitely something 853 00:51:47,790 --> 00:51:49,000 Speaker 2: which is really, really cool 854 00:51:50,260 --> 00:51:53,760 Speaker 2: that before you basically had to do all or nothing, 855 00:51:53,990 --> 00:51:55,720 Speaker 2: you could pre-render your whole page. 856 00:51:57,350 --> 00:51:57,520 Speaker 3: Yeah. 857 00:51:58,160 --> 00:52:02,300 Speaker 2: But what if your page is like 50-50 dynamic 858 00:52:02,320 --> 00:52:10,700 Speaker 2: 50 and the other 50 percent is static um what do you do then you you could do it today by having 859 00:52:11,340 --> 00:52:15,040 Speaker 2: like pre-rendered plus server ts endpoints and 860 00:52:15,040 --> 00:52:15,540 Speaker 3: using this 861 00:52:15,540 --> 00:52:16,980 Speaker 2: in your load function so 862 00:52:17,530 --> 00:52:24,860 Speaker 2: there is a way today but it's not obvious it's it's clumsy so yeah with pre-render you're basically 863 00:52:24,920 --> 00:52:35,180 Speaker 2: saying invoke this function at build time and then it's just like a blob that's lying around 864 00:52:35,290 --> 00:52:37,160 Speaker 2: on your file system deployed 865 00:52:37,160 --> 00:52:41,320 somewhere and then whenever a request is done you just serve that 866 00:52:41,430 --> 00:52:41,640 Speaker 2: file 867 00:52:41,640 --> 00:52:48,280 Speaker 1: yeah so an example and i think that the same example is that is done in the documentation is 868 00:52:48,360 --> 00:52:54,000 Speaker 1: like if you have a blog site you could pre-render the the actual posts but then you could have 869 00:52:54,560 --> 00:52:56,960 Speaker 1: the comments being fetched dynamically, for example. 870 00:52:57,160 --> 00:52:57,320 Speaker 1: Correct. 871 00:52:57,900 --> 00:52:59,540 Speaker 1: That'd be one example, I guess. 872 00:52:59,830 --> 00:52:59,980 Speaker 2: Yeah. 873 00:53:00,690 --> 00:53:02,760 Speaker 2: And the insight here generally is that 874 00:53:03,680 --> 00:53:05,300 Speaker 2: the thing that makes your site slow 875 00:53:05,820 --> 00:53:10,200 Speaker 2: is probably not going to be Svelte's server-side rendering. 876 00:53:11,020 --> 00:53:11,180 Speaker 2: Right. 877 00:53:11,540 --> 00:53:15,220 Speaker 2: It's going to be the data that's taking so long to load. 878 00:53:16,000 --> 00:53:18,460 Speaker 2: And if you can pre-render as much as possible 879 00:53:19,140 --> 00:53:21,300 Speaker 2: in as granular as possible beforehand, 880 00:53:21,640 --> 00:53:23,120 Speaker 2: then this will speed up your sites. 881 00:53:24,440 --> 00:53:24,520 Speaker 1: yeah 882 00:53:25,360 --> 00:53:26,960 Speaker 1: very very very nice addition 883 00:53:28,760 --> 00:53:30,980 Speaker 1: alright I think have I missed 884 00:53:31,060 --> 00:53:32,920 Speaker 1: any of the remote functions are there 885 00:53:33,180 --> 00:53:34,880 Speaker 1: secret remote functions there might be coming 886 00:53:35,240 --> 00:53:36,300 Speaker 1: secret remote functions 887 00:53:38,180 --> 00:53:39,180 Speaker 1: like if you do 888 00:53:39,180 --> 00:53:41,040 Speaker 1: a cheat code do we get another 889 00:53:41,260 --> 00:53:41,360 Speaker 1: one 890 00:53:43,100 --> 00:53:44,380 Speaker 2: no hidden 891 00:53:45,380 --> 00:53:46,720 Speaker 2: no hidden remote functions 892 00:53:47,160 --> 00:53:47,400 Speaker 2: no 893 00:53:47,400 --> 00:53:48,300 Speaker 3: April Fool's 894 00:53:48,300 --> 00:53:48,980 Speaker 2: remote functions 895 00:53:49,360 --> 00:53:49,540 Speaker 2: planned 896 00:53:49,540 --> 00:53:49,940 Speaker 3: either 897 00:53:52,740 --> 00:54:00,500 Speaker 2: yeah I mean I talked about batch caching so this is we are not sure if this will be like a another 898 00:54:00,840 --> 00:54:08,040 Speaker 2: variant like query.cache or something where it's going to be part of the regular query we'll see so 899 00:54:08,220 --> 00:54:15,420 Speaker 2: this may be another one but yeah no no immediate plans there for for 900 00:54:15,420 --> 00:54:15,740 Speaker 3: more 901 00:54:15,740 --> 00:54:18,839 so how how would we how 902 00:54:18,860 --> 00:54:20,340 Speaker 1: How would we use remote functions today? 903 00:54:21,620 --> 00:54:24,160 Speaker 1: We just enable it in the Svelte config, right, 904 00:54:24,280 --> 00:54:25,380 Speaker 1: with experimental something? 905 00:54:25,840 --> 00:54:27,320 Speaker 1: Right, so first 906 00:54:27,320 --> 00:54:27,960 Speaker 2: you would-- 907 00:54:29,060 --> 00:54:33,660 Speaker 2: for remote functions, you would go in your Svelte.config.js 908 00:54:33,900 --> 00:54:36,780 Speaker 2: and then inside the kit namespace, 909 00:54:36,900 --> 00:54:40,120 Speaker 2: you would do experimental and then objects 910 00:54:40,500 --> 00:54:43,100 Speaker 2: and then remote functions:true. 911 00:54:43,920 --> 00:54:46,400 Speaker 2: And to actually make proper use of them, 912 00:54:47,460 --> 00:54:50,700 Speaker 2: you would want to use that together with async svelte. 913 00:54:50,730 --> 00:54:52,340 Speaker 2: So that means you also have to, 914 00:54:53,080 --> 00:54:55,540 Speaker 2: at the top level, do another experimental colon 915 00:54:55,630 --> 00:54:56,840 Speaker 2: and then object async 916 00:54:56,840 --> 00:54:58,000 Speaker 1: colon true. 917 00:54:58,800 --> 00:55:00,660 Speaker 1: We'll put that into notes as well. 918 00:55:02,160 --> 00:55:05,660 Speaker 1: It wouldn't really make sense to use remote functions 919 00:55:05,890 --> 00:55:08,580 Speaker 1: without the async function. 920 00:55:09,030 --> 00:55:10,320 Speaker 1: Can you actually do that? 921 00:55:10,900 --> 00:55:11,680 Speaker 2: I mean, you could. 922 00:55:12,070 --> 00:55:14,300 Speaker 2: You could call them inside your load function. 923 00:55:14,900 --> 00:55:16,200 Speaker 2: you could call them inside a 924 00:55:16,200 --> 00:55:18,520 Speaker 3: weight block. 925 00:55:19,000 --> 00:55:20,260 Speaker 2: You could also... 926 00:55:21,300 --> 00:55:23,420 Speaker 2: So the nice thing about queries is 927 00:55:23,940 --> 00:55:25,560 Speaker 2: they don't just return a promise. 928 00:55:26,000 --> 00:55:29,780 Speaker 2: They also return an object with current and loading and error on them. 929 00:55:30,100 --> 00:55:34,280 Speaker 2: So if you want to, you can use the flattened version of this, 930 00:55:34,780 --> 00:55:36,340 Speaker 2: the non-blocking version, so to speak. 931 00:55:37,420 --> 00:55:38,600 Speaker 2: And you could use that. 932 00:55:38,860 --> 00:55:42,299 Speaker 2: So yes, theoretically, it's possible to use 933 00:55:43,380 --> 00:55:45,840 Speaker 2: remote functions without async Svelte. 934 00:55:46,000 --> 00:55:48,660 Speaker 2: But we will probably at some point 935 00:55:48,970 --> 00:55:51,920 Speaker 2: basically require you to opt into that flag anyway 936 00:55:53,220 --> 00:55:56,680 Speaker 2: because of how we will connect this 937 00:55:57,120 --> 00:55:58,440 Speaker 2: with Svelte's resource 938 00:55:58,440 --> 00:56:00,060 Speaker 3: API 939 00:56:00,060 --> 00:56:01,020 Speaker 2: and so on. 940 00:56:01,180 --> 00:56:01,700 Speaker 2: That makes sense. 941 00:56:03,000 --> 00:56:04,500 Speaker 2: Yeah, and I mean, again, realistically, 942 00:56:04,900 --> 00:56:06,540 Speaker 2: you're going to use this with await. 943 00:56:06,920 --> 00:56:07,080 Speaker 1: Yeah. 944 00:56:07,610 --> 00:56:09,300 Speaker 1: I mean, if you're going experimental, 945 00:56:09,390 --> 00:56:09,700 Speaker 1: you might 946 00:56:09,700 --> 00:56:09,820 Speaker 2: as well. 947 00:56:09,880 --> 00:56:09,980 Speaker 2: Right, 948 00:56:10,020 --> 00:56:10,940 Speaker 1: if you're going experimental, 949 00:56:11,140 --> 00:56:11,900 Speaker 1: why not go all in? 950 00:56:13,280 --> 00:56:13,840 Speaker 1: exactly 951 00:56:16,160 --> 00:56:16,540 Speaker 1: all right 952 00:56:16,640 --> 00:56:18,080 Speaker 1: I think that's 953 00:56:18,740 --> 00:56:19,520 Speaker 1: unless you have something 954 00:56:20,740 --> 00:56:21,960 Speaker 1: something else that you 955 00:56:23,500 --> 00:56:25,020 Speaker 1: that you want to highlight 956 00:56:25,560 --> 00:56:27,240 Speaker 1: I think that was a pretty good 957 00:56:27,540 --> 00:56:27,680 Speaker 1: overview 958 00:56:29,500 --> 00:56:31,420 Speaker 1: we should definitely mention that 959 00:56:31,680 --> 00:56:31,980 Speaker 1: you've made 960 00:56:32,400 --> 00:56:33,800 Speaker 1: I think you did mention it a bit 961 00:56:34,839 --> 00:56:36,940 Speaker 1: the remote functions videos 962 00:56:37,120 --> 00:56:37,640 Speaker 1: that you've done 963 00:56:39,060 --> 00:56:39,960 Speaker 3: for the South 964 00:56:39,960 --> 00:56:40,760 Speaker 1: Society website 965 00:56:40,900 --> 00:56:42,160 Speaker 1: are really good 966 00:56:42,180 --> 00:56:45,860 Speaker 1: So if you want to just have like a nice overview 967 00:56:46,240 --> 00:56:50,740 Speaker 1: and you also do one where you talk about auth, 968 00:56:51,340 --> 00:56:52,960 Speaker 1: like how to protect queries, 969 00:56:53,200 --> 00:56:56,180 Speaker 1: because this might be something that we should talk about 970 00:56:56,960 --> 00:57:01,340 Speaker 1: where in previously, like the load function, 971 00:57:01,900 --> 00:57:04,780 Speaker 1: we kind of use the hooks to protect routes 972 00:57:04,860 --> 00:57:08,600 Speaker 1: and protect stuff when it comes to auth. 973 00:57:09,020 --> 00:57:09,220 Speaker 1: I mean, 974 00:57:09,220 --> 00:57:09,800 Speaker 3: you could do it 975 00:57:09,800 --> 00:57:11,060 Speaker 1: in the load function as well, I guess, 976 00:57:11,240 --> 00:57:16,780 Speaker 1: But my experience was that you would just add an auth hook 977 00:57:17,030 --> 00:57:19,380 Speaker 1: and then you would do protection in there. 978 00:57:19,880 --> 00:57:21,860 Speaker 1: But now since the functions themselves are, 979 00:57:21,950 --> 00:57:23,240 Speaker 1: you mentioned they were public, right? 980 00:57:23,900 --> 00:57:24,940 Speaker 1: Anyone can call them. 981 00:57:24,970 --> 00:57:26,800 Speaker 1: So you have to protect them somehow. 982 00:57:28,960 --> 00:57:29,360 Speaker 1: Yes. 983 00:57:29,710 --> 00:57:30,200 Speaker 1: So you could 984 00:57:30,200 --> 00:57:30,840 Speaker 2: through it. 985 00:57:30,930 --> 00:57:33,960 Speaker 2: I mean, the handle hook still runs before remote functions. 986 00:57:34,540 --> 00:57:34,680 Speaker 3: Right. 987 00:57:34,770 --> 00:57:35,380 Speaker 3: That will not 988 00:57:35,380 --> 00:57:35,840 Speaker 2: go away. 989 00:57:36,150 --> 00:57:38,760 Speaker 2: So you could still do it in the handle hook. 990 00:57:38,920 --> 00:57:46,480 Speaker 2: But the difference is that remote functions are not tied to a page or a route. 991 00:57:46,810 --> 00:57:49,680 Speaker 2: So that's the big difference to layout and page loaders 992 00:57:49,730 --> 00:57:51,620 Speaker 2: because they are always tied to routes. 993 00:57:51,690 --> 00:57:54,540 Speaker 2: And so you could in your handle hook be like, 994 00:57:54,630 --> 00:58:00,560 Speaker 2: okay, everything under the path slash authenticated or something 995 00:58:02,700 --> 00:58:03,600 Speaker 2: should be guarded. 996 00:58:04,720 --> 00:58:05,180 Speaker 3: And that 997 00:58:05,180 --> 00:58:07,020 Speaker 2: you can't really do with remote functions. 998 00:58:08,160 --> 00:58:24,760 Speaker 2: And the way I would solve it is to have a, basically, I would say it's like a private query function, a shared query function, basically, which does all the authentication checks for you. 999 00:58:25,860 --> 00:58:32,060 Speaker 2: And then you just call that inside your query function before proceeding to do 1000 00:58:32,060 --> 00:58:32,780 Speaker 3: the 1001 00:58:32,780 --> 00:58:33,140 Speaker 2: rest. 1002 00:58:34,040 --> 00:58:39,380 Speaker 2: And that's, again, that's the niceness of having this be just functions 1003 00:58:39,620 --> 00:58:43,500 Speaker 2: because you can just use regular function composition to get this. 1004 00:58:43,720 --> 00:58:48,620 Speaker 2: You could even create higher order functions from queries to, I don't know, 1005 00:58:48,940 --> 00:58:53,780 Speaker 2: call not query, but authenticated query or something, which does this for you. 1006 00:58:53,900 --> 00:58:55,600 Speaker 2: There's a few options you have. 1007 00:58:56,800 --> 00:58:56,940 Speaker 2: Is 1008 00:58:56,940 --> 00:58:59,720 Speaker 1: this the beginning of Svelte turning into React? 1009 00:59:01,380 --> 00:59:01,580 Speaker 1: No. 1010 00:59:02,140 --> 00:59:03,140 Speaker 1: Are you kidding? 1011 00:59:04,560 --> 00:59:05,360 Speaker 1: I mean 1012 00:59:05,360 --> 00:59:06,700 Speaker 3: the thing 1013 00:59:06,700 --> 00:59:08,020 Speaker 1: in React is all about functions 1014 00:59:08,220 --> 00:59:10,020 Speaker 2: right so and function composition 1015 00:59:10,540 --> 00:59:10,820 Speaker 2: I 1016 00:59:10,820 --> 00:59:11,780 Speaker 3: mean function composition 1017 00:59:11,780 --> 00:59:12,540 Speaker 2: is nice 1018 00:59:13,359 --> 00:59:15,180 Speaker 2: React hooks not so much 1019 00:59:17,220 --> 00:59:18,600 Speaker 2: throwing some shade there 1020 00:59:21,840 --> 00:59:22,140 Speaker 1: alright 1021 00:59:23,240 --> 00:59:24,660 Speaker 1: yeah thank you for coming on Simon 1022 00:59:25,680 --> 00:59:26,480 Speaker 1: thank you for having me 1023 00:59:27,220 --> 00:59:28,940 Speaker 1: do you have any picks? 1024 00:59:30,140 --> 00:59:31,640 Speaker 2: I don't think I prepared you for this 1025 00:59:32,700 --> 00:59:33,180 Speaker 2: sorry 1026 00:59:34,580 --> 00:59:43,480 Speaker 2: My pick is probably my new microphone. So after the first YouTube video I did, 1027 00:59:44,520 --> 00:59:50,160 Speaker 2: like before then, like every now and then I thought, oh, maybe I need a proper microphone. And I just 1028 00:59:50,600 --> 00:59:56,160 Speaker 2: not just like the built in crappy one in my headset. And then there was one YouTube comment, 1029 00:59:56,960 --> 01:00:03,060 Speaker 2: like, please get a better audio for next time or something. And I was like, yeah, you're right. 1030 01:00:03,080 --> 01:00:06,280 Speaker 2: I should finally do this. 1031 01:00:06,460 --> 01:00:10,840 Speaker 2: If I do more videos, then I probably should gear up a bit. 1032 01:00:11,500 --> 01:00:13,100 Speaker 2: And so, yeah, I got a... 1033 01:00:13,900 --> 01:00:14,620 Speaker 2: What is it called? 1034 01:00:15,060 --> 01:00:17,600 Speaker 2: Elgato Wave 3, I think it is. 1035 01:00:18,720 --> 01:00:19,280 Speaker 1: Sounds very nice. 1036 01:00:20,500 --> 01:00:22,240 Speaker 2: Yeah, I really like it so far. 1037 01:00:23,880 --> 01:00:24,340 Speaker 2: So, yeah. 1038 01:00:24,720 --> 01:00:31,320 Speaker 1: And I'm sure all your colleagues as well are super hyped about the audio being even better in meetings and stuff. 1039 01:00:34,140 --> 01:00:43,020 Speaker 1: yeah all right they can finally understand me yeah yeah okay so my pick is what i haven't prepared 1040 01:00:43,200 --> 01:00:49,500 Speaker 1: myself for this so i i think my pick is my new thunderbolt dock it has all sorts of fun 1041 01:00:49,780 --> 01:00:55,420 Speaker 1: functionalities i think it's like 20 ports or something just one cable connected to my computer 1042 01:00:55,520 --> 01:01:01,660 Speaker 1: and then I have two monitors and all sorts of stuff, Ethernet. 1043 01:01:03,360 --> 01:01:09,780 Speaker 1: It's a very nice experience just having one cable to connect your laptop. 1044 01:01:11,270 --> 01:01:12,320 Speaker 1: Yeah, the 1045 01:01:12,320 --> 01:01:13,780 Speaker 2: docking stations are really nice. 1046 01:01:14,820 --> 01:01:17,940 Speaker 2: Yeah, my Surface docking station is... 1047 01:01:18,580 --> 01:01:21,860 Speaker 2: Yeah, I would need a few more USB ports 1048 01:01:21,860 --> 01:01:22,520 Speaker 1: to be 1049 01:01:22,520 --> 01:01:23,220 Speaker 2: fully happy. 1050 01:01:24,140 --> 01:01:30,200 Speaker 1: This one I got had extra USB-C ports, which was very nice. 1051 01:01:30,400 --> 01:01:32,820 Speaker 1: So I think it has like eight USB-Cs. 1052 01:01:33,080 --> 01:01:34,440 Speaker 1: And then, yeah, it's a lot. 1053 01:01:34,480 --> 01:01:38,240 Speaker 1: And then two monitors and crazy, crazy dock. 1054 01:01:41,520 --> 01:01:43,360 Speaker 3: But yeah, I think that's it. 1055 01:01:44,180 --> 01:01:45,580 Speaker 3: Thanks, everyone, for listening. 1056 01:01:46,280 --> 01:01:48,180 Speaker 3: Again, thank you, Simon, for joining me. 1057 01:01:48,940 --> 01:01:50,840 Speaker 3: And we will talk to you next week. 1058 01:01:51,160 --> 01:01:51,560 Speaker 3: Bye-bye. 1059 01:01:52,420 --> 01:01:52,600 Speaker 3: Bye.

Never lose your place, on any device

Create a free account to sync, back up, and get personal recommendations.