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.