TC39 Roundup and Bevy’s ECS

In this episode, Surma shares what he learned while getting started with the Bevy Game engine, Entity Component Systems and why they might be useful for the Web. Jake rounds up the newest JavaScript language features that landed in TC39’s Stage 3.


  1. Surma:We're on a streak, mate!
  2. Jake:Yeah, three episodes in a row!
  3. Jake:Um, and-
  4. Jake:Ow! Me! Ow!
  5. Jake:Man. Oh, this house-
  6. Jake:Oh, ow, sorry.
  7. Jake:This house has got real bad static electricity.
  8. Jake:I don't know if it's because of the weather.
  9. Jake:It seems like once the cold weather came in,
  10. Jake:like, the whole house is live,
  11. Jake:and I just got a-
  12. Jake:I just got a static shock right up my fingernail.
  13. Jake:It really hurt.
  14. Surma:Ooh, that's that's oddly specific or is is your your ground not actually grounded in all your
  15. Jake:Yeah!
  16. Surma:Electric devices are just yoloing
  17. Jake:Oh, it could be that.
  18. Jake:It was on the-
  19. Jake:the metal of the Mac keyboard.
  20. Jake:Just so you can picture it.
  21. Surma:No that so that's worth looking into I had that before where in
  22. Jake:It was actually live.
  23. Surma:Well, not not not live but in in a house where the ground wasn't actually working
  24. Surma:When the laptop was charging and I slid my hand over the aluminum body of the MacBook
  25. Jake:Oh.
  26. Jake:Vibrating.
  27. Jake:Yes.
  28. Surma:It had this this tingly
  29. Jake:Now, here's a-
  30. Surma:Yeah
  31. Jake:here's a thing that
  32. Jake:I wouldn't believe-
  33. Jake:I wouldn't believe me if I said this,
  34. Jake:but thankfully, there was someone else there.
  35. Jake:I, uh,
  36. Jake:went to a party in London,
  37. Jake:me and my other half.
  38. Surma:Yeah, I don't believe you
  39. Jake:Um, yeah, this is-
  40. Jake:this is back when I had friends.
  41. Jake:And I-
  42. Surma:You
  43. Jake:and then we stayed over at the friend's,
  44. Surma:You
  45. Jake:and we woke up both incredibly hungover,
  46. Jake:and we went to
  47. Jake:Farringdon Station
  48. Jake:to catch a train home.
  49. Jake:And we were just kind of, like,
  50. Jake:hungover.
  51. Jake:And I
  52. Jake:touched my other half's face,
  53. Jake:and it did-
  54. Jake:it did that thing.
  55. Jake:Like the-
  56. Jake:you know, you described that you run your hand along the MacBook,
  57. Jake:and it did that vibratey thing.
  58. Jake:Her face was doing it.
  59. Surma:Yeah
  60. Jake:Her face was doing it.
  61. Surma:Are you sure it wasn't a robot?
  62. Jake:And...
  63. Jake:It- well, but she did it to me,
  64. Jake:and she could feel the same thing on my face.
  65. Jake:Now, Farringdon Station is
  66. Jake:overhead, electrically powered,
  67. Jake:so I think something had just
  68. Jake:been going very wrong in the station
  69. Surma:That's very reassuring
  70. Jake:with the power.
  71. Jake:The whole air was charged. Yeah.
  72. Jake:Because it's- I've been at that station a ton,
  73. Jake:uh, before and since, and it's never happened.
  74. Jake:But that morning, and, you know,
  75. Jake:in the sort of hangover state, we were both
  76. Jake:sort of just there, like, sort of
  77. Surma:You
  78. Jake:gently touching each other's faces, going,
  79. Jake:what is- what is wrong
  80. Jake:with the world? The world is broken.
  81. Jake:This isn't normal.
  82. Surma:Dude I can totally feel the electricity on your face
  83. Jake:Yeah.
  84. Jake:It was such a lovely moment
  85. Jake:to share with my partner, so...
  86. Jake:Well, yeah, it's another
  87. Jake:episode of Off the Main Thread.
  88. Jake:It's- yeah, we're-
  89. Jake:we're still doing it
  90. Jake:to both of our amazement.
  91. Jake:We should say, this is sponsored by
  92. Jake:Shopify, in that they let us record it
  93. Surma:You
  94. Jake:and they don't ask us to say that,
  95. Jake:but I'm saying it anyway, because it's quite nice of them.
  96. Surma:Thank you Shopify
  97. Jake:Cheers!
  98. Jake:Let's throw forward, because that seems like a
  99. Jake:professional thing to do. What are you-
  100. Jake:what are you going to be talking about today?
  101. Surma:Ah in in this episode I will talk about
  102. Jake:...
  103. Surma:Architecture and entity component systems and a bit of rust with bevy because it all ties together and whether
  104. Jake:...
  105. Jake:...
  106. Jake:...
  107. Jake:...
  108. Jake:...
  109. Surma:We can just throw the DOM away
  110. Jake:Oh, wow.
  111. Jake:Okay. And I'm
  112. Jake:going to be talking about some of the
  113. Jake:TC39 stage-free
  114. Jake:proposals, which is always my
  115. Jake:go-to topic when I can't think of
  116. Jake:anything else. But I think there's some really interesting
  117. Jake:stuff in there, so we'll get
  118. Surma:Yeah, there's enough movement so I'm excited for that because I have not kept up
  119. Jake:to that in a bit.
  120. Jake:Well, I hadn't either. I was quite
  121. Surma:You
  122. Jake:surprised by some of the things that I
  123. Jake:read yesterday as I was preparing for the
  124. Jake:show.
  125. Jake:But,
  126. Jake:you mentioned on the last show
  127. Jake:that
  128. Jake:a conversation between two people
  129. Jake:on a plane, which was totally normal, but it wound you up.
  130. Jake:Like, it sounded weird to you. Because it was weird.
  131. Surma:Yeah, you're on a plane
  132. Jake:Now, I had the same thing.
  133. Jake:Uh, no.
  134. Jake:So, I was in
  135. Jake:Arundel.
  136. Jake:And I like Arundel for two reasons.
  137. Jake:There's a lovely castle there, which
  138. Surma:You
  139. Jake:I was visiting with a bunch
  140. Jake:of friends. But also,
  141. Jake:it has to be the one place
  142. Jake:in the UK that sounds
  143. Jake:most like Middle-earth.
  144. Jake:Right, just its name.
  145. Surma:I was gonna say I'm most like can you tell me where this is or are we talking about like dungeons and dragons?
  146. Jake:...
  147. Jake:...
  148. Jake:...
  149. Surma:You
  150. Jake:It sounds like it, because you're on the train, and the
  151. Jake:announcement's like, you know, this train stops at
  152. Surma:You
  153. Jake:Salem Junction, East Croydon,
  154. Jake:Gatwick Airport,
  155. Jake:Amberley, and Arundel.
  156. Surma:You
  157. Jake:It does feel like that is
  158. Jake:in another dimension.
  159. Jake:I must journey to Arundel to retrieve
  160. Surma:You
  161. Jake:the amulet from the castle
  162. Jake:gift shop, which is where
  163. Jake:I was going. Anyway,
  164. Jake:in the castle, there was these
  165. Jake:tight, spiral
  166. Jake:staircase things, because it's a castle,
  167. Surma:You
  168. Jake:right. And
  169. Surma:You
  170. Jake:there was a group in front of us,
  171. Jake:you know, a separate group.
  172. Jake:And one guy
  173. Surma:You
  174. Jake:in the group turned to his mate,
  175. Jake:and he said,
  176. Jake:I wouldn't like to fall down these stairs.
  177. Jake:...
  178. Surma:You
  179. Jake:...
  180. Jake:I was like, what?
  181. Jake:Let me get this straight. You
  182. Surma:You
  183. Jake:wouldn't like to fall down
  184. Jake:these stairs?
  185. Jake:Like, when it comes to these stairs,
  186. Jake:falling down them is just
  187. Jake:not on your want list,
  188. Surma:You
  189. Jake:you know.
  190. Jake:And it reminded me of the situation you had,
  191. Jake:because I was saying this to my friends, and they were like,
  192. Jake:Jake, this is a totally
  193. Jake:normal thing for two humans to say to each other,
  194. Jake:just let it go, this isn't a thing,
  195. Jake:this isn't a bit. But
  196. Jake:I was having...
  197. Surma:But logically extrapolating from the sentence has been said it implies that they would enjoy falling down any other set of stairs
  198. Jake:...
  199. Jake:...
  200. Jake:...
  201. Jake:Exactly! And I was not prepared to let this
  202. Jake:go. So just for the rest of the trip,
  203. Jake:for instance, we all
  204. Jake:walked into this big, grand room in the castle,
  205. Surma:You
  206. Jake:and I was like, hey,
  207. Jake:hey everyone, look, look,
  208. Jake:hey, look, look,
  209. Jake:look, hey, look. And then I
  210. Jake:pointed to a giant sword that was
  211. Surma:You
  212. Jake:hanging on the wall, and I was like,
  213. Jake:wouldn't like to get stabbed by that sword.
  214. Jake:...
  215. Surma:I
  216. Jake:Can you imagine?
  217. Jake:Ah! No!
  218. Jake:I don't like this! Ow!
  219. Jake:Like, no...
  220. Surma:Wanted the other sword
  221. Jake:I mean, even if you offered it for
  222. Jake:free, I'd say no to
  223. Jake:being stabbed by that sword. And I
  224. Surma:You
  225. Jake:carried that on for the rest of the day,
  226. Jake:and everyone got extremely
  227. Surma:I was gonna ask are you now have you gotten rid of some friends this way in a very
  228. Jake:annoyed with me.
  229. Jake:...
  230. Jake:Exactly, yeah, that's...
  231. Jake:Yeah, that's why I have to have internet friends
  232. Jake:instead, because, you know, the real-life ones
  233. Jake:desert me. For good reason, I'd say.
  234. Jake:...
  235. Surma:Full for very good reason, but I suspect that we should rather talk about the web
  236. Jake:...
  237. Jake:...
  238. Surma:You
  239. Jake:Let's do it! Well, I went
  240. Jake:first last episode, so
  241. Jake:logic dictates. It's your turn,
  242. Surma:That's my turn, isn't it
  243. Jake:I think.
  244. Surma:Well, we can take this as you may have noticed when I said, what am I going to talk about today?
  245. Jake:...
  246. Jake:...
  247. Jake:...
  248. Surma:I'm not quite sure which direction we want to take this and I'm open to
  249. Jake:...
  250. Jake:...
  251. Surma:to all of the directions, but as
  252. Jake:Okay.
  253. Jake:...
  254. Surma:For a long time. I'm on the internal hunt to figure out how we can
  255. Jake:...
  256. Jake:...
  257. Surma:make better use of
  258. Jake:...
  259. Jake:...
  260. Surma:Multi-threading on the web and I
  261. Jake:Yes!
  262. Surma:Looked
  263. Surma:Started playing around with bevy, which is the game engine for rust not for this purpose
  264. Surma:But it ended up actually playing into this eternal hand
  265. Surma:And because in general I feel like
  266. Surma:game developers or and game
  267. Surma:development, it's a lot of
  268. Surma:Interesting things happening there and things that I wonder if web development could steal or learn a thing
  269. Jake:...
  270. Surma:or two because
  271. Jake:Well, they are pushing, like, you know,
  272. Jake:on some platforms,
  273. Jake:144 frames a second,
  274. Jake:and that's just the rendering
  275. Jake:in the background, there's physics
  276. Jake:and game engine, and
  277. Jake:it has to be delivering at that rate,
  278. Jake:right? So, it sometimes feels
  279. Jake:silly when you see that kind of graphics,
  280. Jake:even on a, you know, a kind of
  281. Jake:moderate hardware thing, like a PlayStation
  282. Surma:You
  283. Jake:5, a PlayStation 4, pushing out
  284. Jake:frames at that rate, and we struggle
  285. Jake:to move boxes around
  286. Jake:the screen. I mean, I know it's different,
  287. Jake:but, yeah, I think there is so much
  288. Jake:we can learn from them.
  289. Surma:And as a topic I want to talk about on another episode which is that I looked at the original Gameboy and how
  290. Jake:...
  291. Jake:...
  292. Jake:...
  293. Surma:it worked and
  294. Jake:...
  295. Surma:how
  296. Jake:...
  297. Surma:Limited it is and yet the games
  298. Jake:...
  299. Jake:...
  300. Surma:They made on that thing, it's just it's just blowing my mind, but in general, I think that's exactly
  301. Jake:...
  302. Jake:Hmm.
  303. Jake:...
  304. Surma:one of the fests of game development that make it interesting in that
  305. Jake:...
  306. Jake:...
  307. Surma:They are
  308. Jake:...
  309. Surma:Squeezing every last bit of performance. Usually are the devices that they run on while at the same time
  310. Jake:...
  311. Jake:...
  312. Jake:...
  313. Jake:...
  314. Surma:Rarely can they use a lot of off-the-shelf stuff in at the macro level because
  315. Jake:...
  316. Jake:...
  317. Jake:...
  318. Surma:Any every game has almost its own, you know
  319. Jake:...
  320. Jake:...
  321. Jake:...
  322. Surma:UX or UI paradigm like sometimes it's buttons. Sometimes it's controller
  323. Jake:...
  324. Jake:...
  325. Surma:Sometimes it's keyboard and mouse and often it's all of these at once
  326. Jake:...
  327. Jake:...
  328. Surma:You want the same code base to run on a desktop on the switch on your Xbox or your phone?
  329. Jake:...
  330. Jake:...
  331. Surma:you want to iterate really really fast because game the game industry is really intense and you have to
  332. Jake:...
  333. Jake:...
  334. Jake:...
  335. Jake:...
  336. Surma:Be able to pivot and change things and often you have multiple people
  337. Jake:...
  338. Jake:...
  339. Jake:...
  340. Surma:Working on different aspects of the game and want to work independently without breaking each other and all these
  341. Jake:...
  342. Jake:...
  343. Jake:...
  344. Surma:goals combined pull off constraint on or
  345. Jake:...
  346. Jake:...
  347. Surma:Requirements onto the code and how you write it and how the engine is supposed to be laid out
  348. Jake:...
  349. Jake:...
  350. Jake:...
  351. Surma:So I think in general I always am fascinated when I look at how games are architected
  352. Jake:...
  353. Jake:...
  354. Surma:And so bevy is a game engine and rust
  355. Jake:...
  356. Jake:...
  357. Jake:...
  358. Surma:Which is interesting for multiple reasons for me on the one hand
  359. Jake:...
  360. Jake:...
  361. Surma:It is rust and I like rust and it compiles natively so you can you know
  362. Jake:...
  363. Jake:...
  364. Surma:As in like you just get a binary out and it runs on
  365. Jake:...
  366. Jake:...
  367. Surma:my class Windows on Linux and
  368. Jake:...
  369. Surma:but it also compiles to WebAssembly using
  370. Jake:...
  371. Jake:Duchess of Edinburgh
  372. Surma:WebGL WebGL to or WebGPU so it uses that WGPU crate that I mentioned on I think two episodes ago
  373. Jake:I like catastrophes
  374. Jake:...
  375. Jake:...
  376. Surma:which basically
  377. Jake:...
  378. Surma:implements the WebGPU API in rust and then in the background dispatches to whatever the operating system has or
  379. Jake:...
  380. Jake:...
  381. Jake:...
  382. Jake:...
  383. Surma:Straight through if you're in WebAssembly land to actual WebGPU or now also WebGL
  384. Jake:...
  385. Jake:...
  386. Jake:...
  387. Surma:so it's interesting that you know, you there is the the super low-level primitive that this engine is using is
  388. Jake:...
  389. Jake:...
  390. Jake:...
  391. Surma:an API that I happen to understand but even if you don't it is an API that is platform independent and
  392. Jake:...
  393. Jake:...
  394. Jake:...
  395. Jake:...
  396. Jake:...
  397. Surma:you could even make use of outside of baby, so it's
  398. Jake:...
  399. Jake:...
  400. Surma:Knowledge that you learn that is not tied to the specific game engine, which I always think is a big plus
  401. Jake:...
  402. Jake:...
  403. Jake:...
  404. Surma:And in terms of features it also it comes with a couple things of a box like it can do UI
  405. Jake:...
  406. Jake:...
  407. Jake:...
  408. Surma:elements like 2d UI elements and layouts and
  409. Jake:...
  410. Jake:...
  411. Surma:those are
  412. Jake:...
  413. Surma:using flexbox in grid as in
  414. Jake:...
  415. Surma:CSS they use the same property names and
  416. Jake:...
  417. Jake:...
  418. Jake:...
  419. Surma:Yes
  420. Jake:...
  421. Jake:...
  422. Jake:...
  423. Jake:...
  424. Surma:You
  425. Jake:...
  426. Jake:...
  427. Jake:...
  428. Jake:...
  429. Jake:...
  430. Jake:...
  431. Surma:Oh, really, I did not know that
  432. Jake:...
  433. Jake:...
  434. Jake:...
  435. Jake:...
  436. Jake:...
  437. Jake:...
  438. Jake:...
  439. Jake:...
  440. Surma:You
  441. Jake:...
  442. Jake:...
  443. Jake:...
  444. Jake:...
  445. Jake:...
  446. Jake:...
  447. Jake:...
  448. Surma:Well, I I find it really interesting because
  449. Jake:...
  450. Jake:...
  451. Surma:it's it's this thing where I
  452. Jake:...
  453. Jake:...
  454. Surma:don't think
  455. Surma:CSS is perfect or that
  456. Jake:...
  457. Jake:...
  458. Surma:WebGPU is perfect, but I do like
  459. Jake:...
  460. Jake:...
  461. Surma:That rather than inventing something
  462. Jake:...
  463. Surma:That you know
  464. Jake:...
  465. Surma:Does a lot of things well?
  466. Jake:...
  467. Surma:specifically the use case that you as the inventor think about or care about and
  468. Jake:...
  469. Jake:...
  470. Surma:You lean on something that has stood the test of time a little bit something that has already been
  471. Jake:...
  472. Jake:...
  473. Jake:...
  474. Jake:...
  475. Surma:Lots of you know brain hours have been invested into it and while it may be a bit quirky or not always convenient
  476. Jake:...
  477. Jake:...
  478. Jake:...
  479. Surma:It has proven that it is flexible enough to do all the things or most of the things and so in that sense
  480. Jake:...
  481. Jake:...
  482. Jake:...
  483. Surma:I think it's a really interesting move something that they for example don't have is the cascade and I actually
  484. Jake:...
  485. Jake:...
  486. Jake:...
  487. Surma:Currently I'm missing a bit because the cascade is you know a bit
  488. Jake:...
  489. Jake:...
  490. Surma:It's very deeply ingrained in the way I think about these kind of layouts
  491. Jake:...
  492. Jake:...
  493. Surma:and so it's a bit weird to not be able to overwrite the text color by adding a class or by
  494. Jake:...
  495. Jake:...
  496. Jake:...
  497. Surma:Changing the text color of a parent element and but you can you can work around it
  498. Jake:....
  499. Jake:...
  500. Jake:...
  501. Surma:But the fact that I can immediately go okay. I want a menu and I can just do
  502. Jake:...
  503. Jake:...
  504. Surma:Flex direction column and add a couple of children and the thing then works
  505. Jake:...
  506. Jake:...
  507. Surma:It's cool, and I mean obviously it's cool for me as a web developer
  508. Jake:...
  509. Jake:...
  510. Surma:But I could I like that even if you don't know this learning it is not engine specific knowledge, but it's actually
  511. Jake:...
  512. Jake:...
  513. Jake:...
  514. Jake:...
  515. Surma:You're learning parts of another open platform, so you get more bang for the buck for investing the time
  516. Jake:...
  517. Jake:...
  518. Jake:...
  519. Surma:So and that I thought was really nice, but it's not even the core part
  520. Jake:...
  521. Surma:I want to talk about but I thought it just makes it really interesting to me
  522. Jake:...
  523. Surma:And I'm not sure I should say obviously I am NOT a game developer. I am NOT even an amateur game developer
  524. Jake:...
  525. Jake:...
  526. Jake:...
  527. Surma:I'm interested in it, but whatever I talk about should not be seen as representative of
  528. Jake:...
  529. Jake:...
  530. Jake:...
  531. Surma:the game industry or anything like that, but I
  532. Jake:...
  533. Jake:...
  534. Surma:Just thought that was really interesting well and the core part of
  535. Jake:...
  536. Jake:...
  537. Surma:bevy is an
  538. Jake:...
  539. Surma:ECS an entity component system
  540. Jake:...
  541. Jake:...
  542. Surma:Which is an architecture that I think has seen more popularity recently in game engines
  543. Jake:...
  544. Jake:...
  545. Jake:...
  546. Surma:I know unity now has one. I'm pretty sure unreal also has one
  547. Jake:...
  548. Jake:...
  549. Surma:and
  550. Jake:...
  551. Surma:that is
  552. Jake:...
  553. Surma:The thing I want to talk about a bit more because as an architecture. I find it quite interesting
  554. Jake:...
  555. Jake:...
  556. Jake:...
  557. Surma:So I guess I should maybe try to do like a like it like a brief
  558. Jake:...
  559. Jake:...
  560. Surma:Summary explanation of what it is
  561. Jake:...
  562. Jake:...
  563. Jake:...
  564. Surma:All right, so ECS entity component system it consists of entities
  565. Jake:...
  566. Jake:...
  567. Jake:...
  568. Surma:Components and systems which makes it a really good name
  569. Jake:...
  570. Jake:...
  571. Surma:So I'm the terminology. I'm just going to explain how bevy does it
  572. Jake:...
  573. Jake:...
  574. Surma:I think it's fairly representative of how it works everywhere else, but I don't know much about it everywhere else
  575. Jake:...
  576. Jake:...
  577. Jake:...
  578. Surma:So you have a world which is basically a container for all your entities all your components and all your systems
  579. Jake:...
  580. Jake:...
  581. Jake:...
  582. Jake:...
  583. Surma:entities are
  584. Jake:...
  585. Surma:kind of just that they're just
  586. Jake:...
  587. Surma:Identifiers they have no data. They have no
  588. Jake:...
  589. Jake:...
  590. Surma:Behavior, they're basically just a number so that you can distinguish between entities
  591. Jake:...
  592. Jake:...
  593. Jake:...
  594. Jake:...
  595. Surma:And you can attach
  596. Jake:...
  597. Surma:Components to entities and components are just bundles of data
  598. Jake:...
  599. Jake:...
  600. Surma:No code
  601. Jake:...
  602. Surma:It's just you have different entities and you can attach little
  603. Jake:...
  604. Surma:Buckets of data to them and then systems are functions that operate on that world
  605. Jake:...
  606. Jake:...
  607. Jake:...
  608. Surma:That sounds really abstract. So I think it gets a bit more interesting when we talk about an example. So for example, let's say I
  609. Jake:...
  610. Jake:...
  611. Jake:...
  612. Jake:...
  613. Surma:Spawn I create two entities in my world. I
  614. Jake:...
  615. Jake:...
  616. Surma:give them a
  617. Jake:...
  618. Surma:Position component, which is you know a position X&Y. I give them a
  619. Jake:...
  620. Jake:...
  621. Surma:sprite
  622. Jake:...
  623. Surma:component which contains let's say a path to an image file and
  624. Jake:...
  625. Jake:...
  626. Surma:Then you have a function a system called render
  627. Surma:That runs queries against this world
  628. Surma:so every every system just basically
  629. Surma:Asked questions like give me all the entities that have a position and a sprite
  630. Surma:Component and you get back an array or an iterator that gives you the entities and only the entities
  631. Surma:With those components on them
  632. Surma:so this way the system that renders only cares about entities have a position and a sprite and
  633. Jake:Okay, so if you have, like, a nested component structure that would be handled by the render function, right?
  634. Surma:It rates over them and draws all those images to the screen at the position
  635. Surma:that way
  636. Jake:That would handle, like, the component has children, something, something, something, is that...?
  637. Surma:So that is an interesting question usually it's flat and
  638. Jake:Okay.
  639. Surma:You emulate the the hierarchy. So in baby, for example you have
  640. Surma:children components and parent components
  641. Surma:Which are just the ID of your respective children or your parent and that way you can now
  642. Jake:...
  643. Surma:Walk up and down the tree. So the actual list of entity to the entities is the population
  644. Surma:It's just a flat collection an array
  645. Surma:But by having basically the ID of your parent or the ID of your children
  646. Surma:You can walk up and down the tree and do the corresponding
  647. Surma:Actions that you want to do and that is in fact what baby does to do
  648. Jake:...
  649. Surma:A scene graph where you know, when you move the parent all the children have to move as well
  650. Surma:So they have a system that
  651. Surma:propagates the
  652. Surma:Translation like the the 3d transform matrix up and down that tree so you can move a parent and it
  653. Surma:Automatically propagates down to all the children and the children's children and so on so forth
  654. Jake:Hmm.
  655. Surma:But as you can see at the the system the function that does the painting to screen
  656. Surma:Only cares that you have a sprite in a position everything else is on the on your on the entities
  657. Surma:It doesn't know about or care about. So for example, we could also add a new component called
  658. Surma:velocity and have a system that says give me all the entities with a position in the velocity and
  659. Surma:I will move them per frame according to the velocity. So now we have two systems one is completely
  660. Jake:...
  661. Surma:independent of the act of rendering and
  662. Jake:Hmm.
  663. Surma:the other one is completely independent of how entities move about it just cares about rendering and
  664. Surma:and
  665. Surma:That is kind of the core concept of ECS if you write these pretty fairly small
  666. Surma:self-contained systems that
  667. Surma:express what kind of
  668. Surma:Components are interested in and then the ECS takes care of running all these systems and you get
  669. Jake:So, hang on, let me sort out the hierarchy of this in my head.
  670. Surma:Things that are going across screen with a specific velocity
  671. Jake:So, entities have components. Is that a one-to-one mapping, or does a single entity have many components?
  672. Surma:Yeah
  673. Jake:Right. And then the systems, they don't sit within that relationship, they're kind of external, they're just looking at all of the entities and doing stuff for them.
  674. Surma:Entity can have as many components as you like
  675. Surma:Yeah, they're part of the world
  676. Jake:Yeah.
  677. Surma:Maybe maybe as an implementation detail actually
  678. Jake:Hmm.
  679. Surma:but usually I've seen them as being part of the world and they are usually run in a user-defined or automatically defined order and
  680. Jake:...
  681. Surma:It's often called a query
  682. Surma:So they they basically query the world of give me all the entities with that have these components
  683. Jake:That makes sense.
  684. Jake:...
  685. Surma:but maybe specifically don't have it's almost like a SQL query really maybe because you're right give me all the components that
  686. Jake:Yeah.
  687. Jake:...
  688. Surma:entities with component A and component B
  689. Surma:But don't have component C and where component D has changed since the last frame all of these things you can usually
  690. Jake:...
  691. Surma:Express which obviously the job of the actual
  692. Surma:ECS implementation is to make that fast and to optimize with all these things that you're giving it ahead of time
  693. Jake:...
  694. Surma:That it can figure out
  695. Surma:You only need a small number of entities like it's a very smooth system that runs fast
  696. Surma:But for example what what bevy does it automatically figures out which systems are independent and schedules them
  697. Surma:Across your course, so it figures out which systems can run in parallel because they're independent
  698. Jake:Oh, that's neat.
  699. Surma:which I think is fascinating and
  700. Surma:This made me think if and how
  701. Surma:This could work on the web, you know, because you have these super granular systems these two examples
  702. Surma:I just gave the move my entities according the velocity system and the render my
  703. Surma:Entities on the screen system. One of them is not tied to the UI thread
  704. Surma:Right, it's only data that needs to be manipulated
  705. Surma:It's really the painting on screen that is main thread bound unless you're talking off-screen canvas, but let's not
  706. Jake:...
  707. Jake:But you would expect the positional changing stuff has to happen before the rendering, because the renderer needs to know where to render it. Is that fair?
  708. Surma:Right, I
  709. Jake:...
  710. Surma:Think so
  711. Surma:my hunch is that though that in most like at least game like scenarios you have one rendering system and
  712. Surma:Most of the other stuff is just data stuff that isn't main thread bound. So all the
  713. Jake:Hmm.
  714. Jake:...
  715. Surma:Processing could be paralyzed across multiple workers and work on the data
  716. Surma:And then only once that is done you do one main thread bound rendering
  717. Surma:so in fact the way bevy does it is that they run all the
  718. Surma:calculations for the next frame in parallel with the rendering for the current frame, so they
  719. Jake:Oh, that's neat.
  720. Surma:They accept a delay of one frame technically
  721. Jake:...
  722. Surma:But I can imagine it's it's classic pipelining
  723. Surma:So basically the main thread is busy doing its you UI work and painting well on all the other course
  724. Jake:...
  725. Surma:effectively, it's already doing all the non UI bound computations to prepare the data for the next frame and
  726. Surma:I
  727. Jake:...
  728. Surma:was like, you know what considering that these systems are small and often the
  729. Surma:The amount of data in a component that each system needs is very small I
  730. Surma:Wonder if that is something that workers would be good at because the big difference from the web to all native platforms is
  731. Surma:You can't just send the pointer
  732. Surma:You can't just work on the same data as the other threats
  733. Surma:You have to structured clone and copy and send the response back. There is actually some efforts going on
  734. Jake:Well, we've got the shared array buffer, right? That's the closest thing we have to actually being able to... yeah.
  735. Surma:Right, but then but that's bytes and now you're in writing now you have to I did write a library once called
  736. Jake:...
  737. Surma:What was it called?
  738. Surma:Buffer backed objects. I think I called it buffer backed objects. We're basically through a proxy
  739. Surma:You get normal JavaScript objects, but it's
  740. Surma:Automatically serialized down into an array buffer. So that worked on shatter that would work
  741. Surma:So that worked on shatter that would work but it's it's not quite the same like you end up
  742. Jake:Nice.
  743. Jake:...
  744. Surma:You know in uncanny valley and JavaScript just doesn't have good ergonomics yet
  745. Surma:I know there's actually some exploration going on and she's denying. Maybe you will talk about it. Who knows
  746. Jake:Hmm.
  747. Jake:...
  748. Surma:But it as of now, I wouldn't say that JavaScript is well set up
  749. Surma:But it has never stopped me before to not explore JavaScript in in this way and that's actually only one part
  750. Jake:...
  751. Surma:This is the part where I thought easy ss could be interesting for the web
  752. Surma:As a means to make use of workers because this whole thing about which of these systems need to run on the main thread
  753. Jake:Hmm.
  754. Surma:kind of becomes
  755. Surma:automatically analyzable
  756. Surma:through the means of the query if the query grabs
  757. Surma:Components that are main thread bound because they have textures or because it issues draw commands
  758. Surma:it has to be main thread if not, it can probably run on a different thread and
  759. Jake:...
  760. Surma:I found that really interesting the other part and
  761. Surma:This is more towards a contrast to our current landscape of UI framework is that easy ss are
  762. Surma:By definition escape hatch by default and I should probably explain a bit what I mean by that
  763. Surma:so I look at stuff like
  764. Jake:Yes, do.
  765. Surma:Preact or react or angle at the time. I don't know enough about swelter view, but basically
  766. Surma:Whenever you write a react components
  767. Surma:You do not by default you lose access to the underlying
  768. Surma:Backing DOM element unless you explicitly expose it with forward ref
  769. Jake:Mm-hmm.
  770. Surma:I think because if you write your own component, you can get access to the DOM element by using ref
  771. Surma:But if you have multiple layers of component boundaries ref doesn't work unless you explicitly forward it with forward ref
  772. Jake:Yes.
  773. Surma:And of course you could you could do like, you know
  774. Jake:...
  775. Surma:Like a display content span wrapper and then use JavaScript to get a child like you can drill through
  776. Surma:But it's not
  777. Surma:You know, it doesn't feel like it should be used that way and you can probably break stuff quite quite easily that way
  778. Surma:What I found really interesting is that because easy ss are so flat
  779. Surma:As in like there is there is no hierarchy in the way that data is stored
  780. Surma:You can always look at all the other components that are in on your entity
  781. Jake:...
  782. Surma:so like you don't work necessarily on a component level you often work in what is called a bundle because
  783. Surma:You need multiple components to be present and so you can add multiple components at once in a so-called bundle
  784. Jake:...
  785. Surma:so for example for
  786. Surma:The sprites component was mentioned earlier
  787. Surma:It's probably actually a bundle where you know need a position you need a size
  788. Jake:...
  789. Surma:You need the texture and you probably also need a mesh and a shader because this is rendered using web GPUs
  790. Surma:So it needs to know which triangle should be put where and how do I what is the shader code?
  791. Jake:Hmm.
  792. Surma:It runs to put the texture on there and you most of the time you don't care about that
  793. Surma:You don't know about that. You just you know, you create your sprite you pass in the image and a position and you're done
  794. Surma:it's now on screen, but
  795. Surma:You can and I found it quite interesting that I could grab in and actually grab
  796. Surma:the web GPU mesh data and muck about with it and
  797. Surma:Everything still work because it is by default all accessible
  798. Surma:And so I was kind of thinking about that what it would be like on the web where you can provide convenience abstractions by default
  799. Jake:...
  800. Surma:The escape hatch of grabbing the underlying primitive is there rather than having to explicitly
  801. Jake:...
  802. Surma:Expose an options object or you know forward ref like you have to remember
  803. Surma:To expose a level primitive by default the escape hatch is hidden in most frameworks today
  804. Jake:...
  805. Surma:With ECS, it seems to be inverted and I wonder how big of a difference that would make on a database
  806. Surma:I don't know if there's any good
  807. Surma:ECS frameworks for the web. I'm sure there are some
  808. Surma:But I found it really interesting to think about because another thing I did is
  809. Surma:That I wrote a little demo and an example with bevy just to play around where I wanted to do Boyd's
  810. Surma:like bird or it's just the things that fly around and
  811. Jake:...
  812. Surma:kind of look like they have
  813. Surma:Like a hive mind intelligence and it looks really nice and swarmy
  814. Jake:Yes.
  815. Surma:And I wanted to move the computation for that to the GPU because it's many many boys and they all run the same code
  816. Jake:...
  817. Surma:It's like it screams
  818. Surma:GPU rather than CPU and so because bevy uses
  819. Jake:Yes.
  820. Surma:ECS and it uses ECS for everything even its own internals and it uses web GPU
  821. Surma:I was able to just grab into the bag of entities that
  822. Surma:maybe spawns by default and grab the reference to the web GPU device and add my own
  823. Surma:Compute pipeline and shader code to use the same
  824. Surma:pipelines that bevy already have
  825. Jake:...
  826. Surma:To add my own bit of computation to it and it just integrated cleanly and nicely
  827. Surma:Ah good point so you you can hide
  828. Jake:Okay.
  829. Surma:Implementation details. It's just not by default and I think that's really nice
  830. Jake:...
  831. Surma:So the the GPU device is just a GPU device and web GPU is set up to run
  832. Surma:different
  833. Surma:Shaders, that's like that. That's actually, you know, that's more like props to web GPU that it's designed that way. Um
  834. Surma:But you can definitely hide
  835. Surma:Entities if you want to and bevy does do that
  836. Jake:But this is one they've chosen not to hide, or they haven't chosen to hide.
  837. Surma:Yeah, I think they really only do it if it's necessary if it's in any way delicate and like and sometimes it does not work
  838. Jake:Hmm.
  839. Surma:so for example there when you add your camera as it's called to the scene because that's usually you
  840. Surma:The camera is just an empty object. It kind of encodes how to move the world coordinate space. It feels like
  841. Surma:You are moving the camera rather than all the objects, but in the end, it's just another transform
  842. Surma:But in a 3d world you have a bit more you have like your field of view and your depth of field and all that
  843. Jake:...
  844. Surma:stuff and
  845. Surma:You have the frustum which defines your angle of view and where the clipping planes are and
  846. Jake:...
  847. Surma:When you start changing those values after the camera has been created they do nothing
  848. Surma:so there is sometimes situations where changing a component isn't really having effect because that's not how the
  849. Jake:...
  850. Surma:Underlying system is implemented. So it is obviously a bit dependent on how the individual functions are implemented whether
  851. Jake:...
  852. Surma:Changing a component or grabbing it has desired effect
  853. Surma:but most of the time especially if you are grabbing through to a
  854. Surma:standardized piece like a GPU device or let's say if it was a file handle or a web socket or any of those things and
  855. Jake:...
  856. Surma:then you have a pretty good understanding of what you're doing could mess with the rest of the system or if it is a
  857. Jake:...
  858. Surma:Fine or safe thing to do. I just really like that
  859. Surma:I was able to use the entire architecture of a game engine, which usually sounds overwhelming and like black magic to me
  860. Jake:...
  861. Surma:and in this case it feels
  862. Surma:It's just code, you know, like it's a nice demystification in my head
  863. Jake:...
  864. Surma:You
  865. Surma:Well, so that's that this is a bit maybe go
  866. Surma:too far into rust but there's
  867. Surma:read only access to components and
  868. Jake:...
  869. Surma:Read write access to components
  870. Surma:So there can only ever be one person that has a read write reference to any given data object
  871. Jake:Hmm.
  872. Jake:I see.
  873. Surma:but there can be as many as you want if it's read only and
  874. Surma:That is expressed in rust type system and as a result in the
  875. Surma:queries for your system, so if
  876. Surma:Multiple systems want read access to the current
  877. Jake:...
  878. Surma:position of
  879. Surma:I don't know all my my birds on the screen
  880. Surma:Then all these systems can still run in parallel as long as there
  881. Surma:Hasn't been scheduled a system that also wants to write to it
  882. Jake:Right.
  883. Surma:Which is usually where you then explicitly order and say like, you know
  884. Jake:...
  885. Surma:The writing stuff is at the very last stage where you do
  886. Surma:Update positions is the system that runs by itself at the very end or something, but everything else can be paralyzed
  887. Surma:with the GPU device
  888. Surma:it is actually a read-only reference because web GPU is
  889. Jake:...
  890. Surma:In internally designed to be accessed from multiple threads
  891. Surma:So while it's actually I don't think it's actually implemented on the web the design and the spec very much prescribes that you can
  892. Surma:Send around the web GPU device to multiple workers and they all do their stuff at the same time and the browser and the operating
  893. Surma:system take care of
  894. Surma:making that work without
  895. Surma:Them overwriting each other state or anything like that
  896. Jake:Nice.
  897. Surma:So that in that sense even in that example, I was not hurting the parallelism
  898. Surma:Which again, it's really interesting
  899. Jake:...
  900. Surma:Yeah, that was actually really interesting because I ran it on my computer and I built a little FPS meter
  901. Surma:It's like oh look it it runs at 60 and let's see how many birds I can add
  902. Surma:Until it gets slower and then I wanted to test it out on
  903. Surma:The web compiled it to web GPU had to fiddle a bit because web GPU isn't quite the default in baby yet
  904. Surma:But it wasn't too hard
  905. Jake:...
  906. Surma:And I opened it and it ran at 120 Hertz
  907. Surma:Yeah, but why didn't it do it on native I haven't quite figured out why it was throttle it as a native binary
  908. Jake:...
  909. Surma:I wonder if like if that's an option for the library that I used to create windows on Mac OS native or something
  910. Jake:...
  911. Surma:I just thought was really interesting. It's like Oh suddenly 120 frames per second
  912. Jake:So what we're saying is the web is better, right? That's... yeah.
  913. Surma:Yeah, that's that's really the takeaway from from from all of this and yeah, I'm curious
  914. Jake:...
  915. Surma:I could see an ECS being interesting to implement in JavaScript where you know
  916. Jake:...
  917. Surma:Entities are just empty objects and maybe uses unique symbols for components and you can just add all the components to your
  918. Jake:...
  919. Surma:Objects and that's how you model the entities
  920. Surma:I don't know
  921. Surma:I would quite interesting to me if you had a UI framework using the system where you can always access the underlying
  922. Surma:DOM element or the underlying event listener or all these things and
  923. Jake:...
  924. Surma:you often wouldn't but if you need to it's there and
  925. Surma:And I need to look around if that's ever been tried by someone. I'm assuming it must have
  926. Surma:but I've been
  927. Jake:And if it hasn't, then you're it, right? You've got to go create it.
  928. Surma:Yeah, I guess I guess I have now officially volunteered
  929. Jake:...
  930. Surma:The the other thing I want to talk about but I think I think I may just do that on the next episode
  931. Surma:Because you know
  932. Jake:...
  933. Surma:Forward teaser we haven't done that ever in a while
  934. Jake:No.
  935. Surma:I don't know
  936. Surma:So you now you have this framework or not framework you have this library bevy that you know
  937. Surma:Does really high performance rendering has its optimized system it integrates on the web with?
  938. Surma:You know tap events pointer events key events can go full-screen
  939. Surma:You can grab all the other web API's from within your rust code
  940. Surma:Like you could technically do index DB and all those shenanigans
  941. Surma:This kind of reminds me a bit of if you want to take full control
  942. Jake:...
  943. Surma:just take wasm web GPU and
  944. Surma:you know web HID and
  945. Surma:build your complete own stack from the ground up and
  946. Surma:I guess at some point we should talk about is is that worth it? What do you win? What do you lose?
  947. Jake:...
  948. Jake:...
  949. Surma:I think figma is one of them, right?
  950. Surma:Like they have they're just they're just canvas and wasm and it feels really good. It looks really good
  951. Jake:...
  952. Jake:Yeah.
  953. Surma:And the question is would that have been possible?
  954. Surma:with just
  955. Surma:Like let's say the Dom and what would've been harder or would've been easier like but yeah
  956. Jake:...
  957. Surma:I think I think considering I've already like blabbered on for way too long. I'm just gonna leave it here for this time. Yeah
  958. Jake:...
  959. Surma:Yeah, I know you do
  960. Jake:...
  961. Surma:So my
  962. Surma:my future father-in-law
  963. Jake:...
  964. Surma:told me recently that
  965. Surma:his neighbor
  966. Surma:Has
  967. Surma:Started to smartify their home
  968. Jake:...
  969. Surma:And I was like, that's interesting I've recently
  970. Surma:Fallen into the the home assistant rabbit hole, which I think it seems like many people are doing right now
  971. Jake:I am as well, yeah.
  972. Surma:I'm seeing it. I've seen it popping up more and more
  973. Surma:but specifically I was told that this neighbor has two cats and
  974. Surma:So they've been buying smart devices around the cat's life
  975. Surma:I think a well-known smart device for pets is for example the smart cat flap
  976. Jake:I've got one. Yep. Yep. Mm-hmm. I do.
  977. Surma:Yeah, do you get notifications when your cats that's is and how are you finding how you finding that?
  978. Jake:Yep.
  979. Jake:...
  980. Surma:I
  981. Jake:...
  982. Surma:Like that there's this angle of quantified cell where it was like I can tell you exactly the average times my cats go out at night
  983. Jake:Yep. Absolutely.
  984. Surma:That's but then my what he told me was
  985. Jake:...
  986. Surma:Mind-blowing to me is that that said neighbor also has bought a smart cat litter
  987. Surma:And
  988. Jake:...
  989. Surma:Yeah, I
  990. Surma:Wasn't sure if that is the kind of conversation you want to deepen but I had to know and so I asked well
  991. Surma:What what's smart about it? And the first thing sounded not too bad in that it
  992. Jake:...
  993. Surma:Automatically, I guess robotically
  994. Surma:bags up
  995. Surma:the business for you to
  996. Jake:...
  997. Jake:...
  998. Surma:For in I know
  999. Jake:...
  1000. Surma:Right, and I guess the whole point is like, you know, it doesn't smell like it doesn't distribute the smell for
  1001. Jake:...
  1002. Surma:Extended periods of times. It's easy for you to grab and take out and the other parts
  1003. Surma:Well, it all and it sends a notification. So, you know, there is something to take out which seems I don't know
  1004. Surma:Do I want that notification? It seems a bit weird, but then he told me that this smart cat litter
  1005. Surma:Also weighs your cat before and after
  1006. Jake:...
  1007. Jake:...
  1008. Jake:...
  1009. Surma:And the leaderboard right like you want
  1010. Jake:I mean I want that as a human. I want that on my toilets, right? I want to know I want those stats.
  1011. Surma:You want to like check in and you want to have the leaderboard and you want to make it you want to gamify it
  1012. Jake:...
  1013. Surma:Achievement unlocked crack that the one pound
  1014. Jake:Oh, absolutely. Yeah.
  1015. Jake:...
  1016. Jake:Oh, yeah.
  1017. Surma:Maybe there's my market niche
  1018. Jake:...
  1019. Jake:Oh, I'm going to have to look into that.
  1020. Jake:...
  1021. Jake:My cats normally don't use the litter tray, although they have in the new house for a bit, but, you know.
  1022. Jake:...
  1023. Jake:Yeah, if it carries on like that, I might need to get this self-bagging thing. Yeah, that sounds good.
  1024. Surma:Get the smart litter tray well with the the staple bathroom story out the way
  1025. Jake:...
  1026. Jake:Oh, yeah. Very good.
  1027. Jake:...
  1028. Surma:What wanna wanna what wanna web
  1029. Jake:Want a web? I do want a web.
  1030. Jake:...
  1031. Jake:So, yeah, I want to talk about the stuff in Stage 3 TC39 that hasn't really been picked up by, well, certainly all the browsers.
  1032. Surma:You
  1033. Jake:That's only been picked up by one browser so far, and what I'm excited to hear is what you think of them and which ones are best.
  1034. Jake:...
  1035. Surma:Is it chrome
  1036. Jake:No, not which browser's best. Which feature's best. Come on.
  1037. Surma:Oh, but it's the one brother picked it up chrome
  1038. Jake:...
  1039. Jake:No. No. No. And, yeah, we'll get onto that, but it is not that straightforward.
  1040. Surma:Oh
  1041. Jake:...
  1042. Jake:Except for the first one, which is a Chrome one, which is iterator helpers, right? Stage 3.
  1043. Surma:Ah, I do not know exactly what's in it, but the name already makes me happy
  1044. Jake:...
  1045. Jake:And...
  1046. Jake:...
  1047. Jake:Yeah, it just means all your iterator instances get map filter. Take, drop, flat map, reduce.
  1048. Jake:...
  1049. Jake:Two array for each every find. The kind of stuff you get on arrays, but you just get them on plain iterators.
  1050. Surma:You
  1051. Jake:...
  1052. Jake:Well, but then, you know, things like take and drop are kind of, yeah, not on arrays, but are useful for iterators.
  1053. Surma:Yeah
  1054. Jake:...
  1055. Jake:They are shipped in Chrome, but they're not in Safari or Firefox yet.
  1056. Jake:What's your rating? How are you feeling?
  1057. Surma:If they
  1058. Jake:...
  1059. Surma:Actually don't do like the intermediate array allocations, which is the problem with the other with the array methods, right? Like if you have
  1060. Jake:Hmm.
  1061. Jake:...
  1062. Surma:Big old can array and you do map filter map map filter each of these
  1063. Surma:calls will create a
  1064. Surma:New array with the same well in the case of filter with the same size
  1065. Jake:You're essentially chaining the values through. So, yeah, so...
  1066. Surma:And I'm sure engines do clever stuff but with on an iterator it is clear that you are you you want to
  1067. Jake:...
  1068. Surma:Do the stream ease?
  1069. Jake:Yes, so, on an array, when you do a .filter, then a .map, you know, all the filtering happens, then all the mapping happens.
  1070. Surma:You
  1071. Jake:Whereas with iterators, you're creating a chain where, you know, the values can get filtered, then mapped.
  1072. Jake:...
  1073. Jake:And it's more likely to happen that way around. Filter, map, filter, map, filter, map, rather than filter all the things, map all the things.
  1074. Jake:But, yeah, there's no intermediate array creation.
  1075. Surma:Is it like like all all of them is flat map flatten all the jazz
  1076. Jake:...
  1077. Jake:Flat map is there. Flat isn't.
  1078. Surma:Interesting, well, I guess flat map is the same as flat in this instant. I
  1079. Jake:...
  1080. Jake:Yeah.
  1081. Jake:...
  1082. Jake:Exactly. Exactly. Yeah.
  1083. Surma:I'm
  1084. Surma:Really? I like it a lot because I always like I like it. Sometimes I like expressing
  1085. Jake:...
  1086. Surma:Transformations that way where you make it is discrete map and filter steps
  1087. Surma:But I at some point you feel a bit bad about all the intermediate arrays like often
  1088. Surma:It's not big enough to actually make a difference, but I would just feel better if I didn't
  1089. Jake:Yeah.
  1090. Jake:...
  1091. Surma:Yeah, yeah
  1092. Jake:Oh, it saves you having to create an array from the...
  1093. Jake:You know, there's that thing where you do the angle brackets, dot, dot, dot, your iterator.
  1094. Surma:Exactly, I mean I immediately now want to like ask and what about async iterators. Is it part of it as well?
  1095. Jake:And the only reason you're doing that is because you want to use map and filter and stuff.
  1096. Jake:But now you don't have to. Yeah.
  1097. Jake:...
  1098. Jake:Nope. But I think they plan to do it, but it's not in that particular proposal.
  1099. Surma:Right, okay
  1100. Jake:...
  1101. Jake:All right. Moving on.
  1102. Jake:And now, if we were looking for the feature with the coolest name, it's this one.
  1103. Surma:You
  1104. Jake:We're not, but, you know, Shadow Realm.
  1105. Jake:...
  1106. Surma:Are you all the shadow realm that's been around for a long old time
  1107. Jake:I know, but it is now stage three.
  1108. Surma:You
  1109. Jake:So, for folks who haven't been sort of looking through TC39 for years and years, this lets you create a place to run code.
  1110. Jake:It has its own global and a restricted set of APIs compared to like a page.
  1111. Surma:Yeah, it has nothing to do with shadow roots really
  1112. Jake:...
  1113. Jake:I know. Yeah.
  1114. Jake:...
  1115. Surma:So it's like a worker but without the separate thread, isn't it
  1116. Jake:Yes. Very, very similar.
  1117. Jake:So, yeah, it has, you know, it has things like event and event target in there, but it doesn't have access to the DOM.
  1118. Surma:You
  1119. Jake:...
  1120. Surma:Mm-hm
  1121. Jake:And, yes, you would do like new Shadow Realm.
  1122. Surma:You
  1123. Jake:And then on that, you do Shadow Realm dot import value.
  1124. Jake:You give it a module ID and an export that you want.
  1125. Jake:That returns a promise and it gives you the thing from the module.
  1126. Jake:But, yeah, as you say, it feels a little bit like a worker, but it is same thread and same process.
  1127. Surma:So, is it a sandboxing primitive
  1128. Jake:...
  1129. Jake:To a degree, but not because it is the same process.
  1130. Jake:So, it is Melt-A-Spec down. Hang on. Specter Meltdown.
  1131. Jake:...
  1132. Surma:You
  1133. Jake:Vulnerable.
  1134. Jake:So, it's security to a point.
  1135. Surma:So it's not don't use it for running untrusted code
  1136. Jake:...
  1137. Jake:Well, semi-trusted code, I think, is the thing.
  1138. Jake:It's because it's synchronous. It can still lock up everything, right?
  1139. Surma:Okay
  1140. Jake:And it can still, I'm going to say Melt-A-Spec down again.
  1141. Surma:Right
  1142. Surma:You
  1143. Jake:It can still, you know, attack the memory, because it exists in the same process.
  1144. Jake:It can attack things in the same process.
  1145. Jake:...
  1146. Surma:Okay, then let me flip it around what should you be using this for
  1147. Jake:Well, that is where I start to wonder.
  1148. Jake:The explainer mentions Google AMP a lot, which dates when some of this documentation was written.
  1149. Surma:You
  1150. Jake:But it does suggest, like, yeah, running third-party code in there.
  1151. Jake:But it is with an eye of a third-party that you kind of trust.
  1152. Jake:...
  1153. Jake:But, yeah. So, the values you get back can only be primitives or functions.
  1154. Surma:Oh
  1155. Jake:And if it's functions, the arguments have to be primitives or functions, and it has to return primitives or functions, right?
  1156. Jake:Like, that's the only two values that can go around.
  1157. Jake:...
  1158. Jake:But, yeah. Like, I...
  1159. Surma:Also, you can get a function
  1160. Jake:...
  1161. Jake:Yes.
  1162. Jake:...
  1163. Surma:Back, but it is automatically invoked within that other realm
  1164. Jake:Yes.
  1165. Jake:...
  1166. Surma:But it doesn't require structured cloning
  1167. Jake:No. Because it's only primitives.
  1168. Jake:So, it's, you know...
  1169. Surma:You it's an object and primitive
  1170. Jake:...
  1171. Jake:No.
  1172. Jake:No. So, primitive as in string, number, big int.
  1173. Jake:Like, that kind of stuff. That kind of stuff.
  1174. Jake:Like, not objects.
  1175. Surma:That that feels odd
  1176. Jake:Yeah, but that's the thing.
  1177. Surma:You
  1178. Jake:It's like, I'm looking at this API where it's .importvalue, you give it a module ID and the export name that you want to get hold of.
  1179. Jake:And I'm like, give me that on workers and give me it with structured clone.
  1180. Jake:And I...
  1181. Surma:Yeah, but even for Shadowrun why wouldn't use structured clone this as a like it's there
  1182. Jake:...
  1183. Jake:Ah, yeah. I think maybe they're open to expanding it in future, but right now, no.
  1184. Surma:Maybe okay. So we are basically you're saying is we're both a bit
  1185. Jake:...
  1186. Jake:Yeah, just give me...
  1187. Surma:Left with a question mark when we would use this I
  1188. Jake:...
  1189. Jake:Yeah. And maybe it's more useful in nodeland, but I want that API on workers now.
  1190. Surma:Mean I I
  1191. Jake:...
  1192. Surma:Could see untrusted ish code like if I wrote something like
  1193. Jake:...
  1194. Surma:Like a jspin code pen kind of thing where yeah, you can block yourself that that's all good, but you cannot
  1195. Jake:...
  1196. Surma:muck with
  1197. Surma:My business logic of the thing that I've written so in that maybe that's a use case where it would work
  1198. Jake:...
  1199. Surma:But then again within that within the shadow realm
  1200. Jake:...
  1201. Surma:You do not have a dom and you cannot expose it on my because I doubt that you can just send a reference to like
  1202. Surma:An iframe or something into the shadow realm
  1203. Jake:Yeah.
  1204. Jake:Like, I would consider maybe, like, you know, in a worker, create a shadow realm so the code is running in a place that it can't mess around with index.db.
  1205. Surma:Yeah
  1206. Jake:But then you still have to remember you're running in the same process, so...
  1207. Jake:...
  1208. Surma:So it doesn't come with all the web globals, it's really like a completely
  1209. Surma:blank canvas
  1210. Jake:It's, no, it's not even that, because it has event target, it has event, it has some of the performance.
  1211. Surma:JavaScript scope almost
  1212. Surma:Right that which I would consider vanilla JavaScript, but nothing that interacts like it's hermeneutically sealed you can't really into
  1213. Jake:Oh, I see, okay.
  1214. Jake:Yeah.
  1215. Jake:...
  1216. Surma:Can you manually expose anything to the shadow realm? It sounds like you can't because of only primitives
  1217. Jake:You can evaluate code into that realm, so you can evaluate code that adds to the global.
  1218. Surma:But could I expose like a function from the owning scope I could I say
  1219. Jake:...
  1220. Surma:Import like this function from inside the shadow realm should invoke this function on my end. So I could that
  1221. Jake:Oh, that's interesting. I think maybe you could, because I think, you know, because functions are allowed, I think functions are allowed as arguments as well.
  1222. Surma:You
  1223. Surma:Oh, so you can't pass in callbacks almost and that way I could then through a lot of duct tape kind of re-expose
  1224. Jake:I would have to double check that.
  1225. Jake:Maybe.
  1226. Jake:...
  1227. Surma:Local storage if I was so inclined
  1228. Jake:I would have to double check that.
  1229. Jake:...
  1230. Surma:Seems like we'd come link for shadow realm now
  1231. Jake:Well, yeah, exactly.
  1232. Jake:Get on it.
  1233. Jake:Yeah, okay, so I think we're sort of similar opinion there.
  1234. Surma:Low excitement, honestly, which
  1235. Jake:It's interesting.
  1236. Jake:Yeah, it may be more important in certain systems that we aren't involved in.
  1237. Surma:Yeah, I wonder if it really like you say maybe it is really the groundwork for making it more capable in the future
  1238. Jake:...
  1239. Surma:Because I'm assuming this has covered a lot of new ground and they want to get this
  1240. Jake:Yeah.
  1241. Jake:...
  1242. Surma:Slotted in implemented so that then adding what we maybe find obvious
  1243. Surma:Are then easy additions that can be discussed in isolation rather than discussing the entire thing in detail
  1244. Surma:discussing the entire thing as a whole all the time
  1245. Jake:And part of that might be moving structured cloning from HTML land into JavaScript land.
  1246. Surma:You are right because I was wrong I said structure clone is right there but like in spec land it is not it does not exist
  1247. Jake:...
  1248. Surma:In TC 39 exists only in the what WG
  1249. Jake:Hmm.
  1250. Jake:Exactly, exactly.
  1251. Jake:All right, next feature.
  1252. Jake:Regular expression pattern modifiers. Here we go, here we go.
  1253. Jake:You know those little things you put at the end of regex, like I, to make it case insensitive?
  1254. Surma:You
  1255. Surma:Yeah
  1256. Jake:You can put those in a sub-expression.
  1257. Jake:...
  1258. Jake:So, you know, a part of your regex is case insensitive, rather than the whole thing.
  1259. Jake:...
  1260. Surma:Okay, I I sure
  1261. Jake:That's it.
  1262. Jake:...
  1263. Jake:Yeah, that's my opinion as well.
  1264. Jake:It's like, yeah, sure, man, cool.
  1265. Jake:I mean, whatever, you know.
  1266. Surma:I'm easy
  1267. Jake:I'm going to keep the champagne in the fridge when that ships, but, like, great.
  1268. Jake:And do you know what, I'll probably use it one day and go, yeah, yeah, yeah, I'm glad this happened.
  1269. Surma:Yeah
  1270. Surma:Yeah, I'm trying to think it could get really confusing because there's
  1271. Jake:...
  1272. Surma:I'm guessing stuff like G global doesn't work as a
  1273. Jake:No, I think it's more the, yeah.
  1274. Jake:...
  1275. Surma:But stuff like M where or usually a dot doesn't capture a new line but with M it can match a new line
  1276. Jake:Exactly, exactly.
  1277. Jake:...
  1278. Surma:Yeah, okay cool, yeah, well done
  1279. Jake:Yeah, that's it.
  1280. Jake:All right.
  1281. Jake:Set methods.
  1282. Surma:You
  1283. Jake:So, on set, you get
  1284. Jake:.intersection, .union,
  1285. Surma:Yes, yes want gimme gimme now good
  1286. Jake:difference, yeah, symmetric difference,
  1287. Jake:is subset of, is superset of, is disjoint from, yeah, yeah.
  1288. Jake:...
  1289. Jake:There you go.
  1290. Jake:Yeah, I think I, my opinion as well, yeah.
  1291. Jake:I want these.
  1292. Jake:They are shipped in Safari already, and in,
  1293. Jake:they're behind a flag in Firefox, I know.
  1294. Surma:Damn look at them go
  1295. Jake:So this is what you were saying at the first, it's like,
  1296. Surma:You
  1297. Jake:it seems like Chrome is the furthest behind
  1298. Jake:in this implementation.
  1299. Jake:So, yeah.
  1300. Surma:Hmm I wonder why it seems like such an obvious
  1301. Surma:Thing was the problem with sets. Well, I say problem the I
  1302. Surma:Just now because I was doing the the the bevy stuff where you know
  1303. Surma:I build up sets of entities sometimes to figure out which ones do I actually want to
  1304. Jake:...
  1305. Surma:Process I used a set a B tree set in rust which is
  1306. Surma:Ordered by the value of the thing that's in there
  1307. Surma:So if you can if the the value type it's in my set
  1308. Surma:has operations like is greater than you can use a B tree to store the set where they are stored in order and
  1309. Surma:when you have that it is easy to do an intersection because you just iterate through both of them in lock step and
  1310. Surma:If one is smaller than the other you iterate that one and if they're equal it's an intersection you can like it's an O of n
  1311. Jake:Hmm.
  1312. Jake:...
  1313. Surma:intersection in
  1314. Surma:JavaScript sets are ordered in the sense that the objects are given back to you in the order. They are inserted
  1315. Jake:Yes.
  1316. Surma:So if you had let's say a set of what you can't use numbers
  1317. Jake:...
  1318. Surma:But a set of objects to two sets of objects
  1319. Jake:Hmm.
  1320. Surma:There's no easy way in user lands to implement a section except an O of n squared where you iterate over both
  1321. Jake:...
  1322. Surma:Well, I'm assuming it's good that I'm assuming that has is often
  1323. Surma:it's probably faster than that, but you have to basically do loop over one set and check in the other set all the time and I
  1324. Jake:Yes.
  1325. Jake:...
  1326. Surma:Think under the hood. There's probably a better way, but it's not accessible to use lines
  1327. Jake:Exactly.
  1328. Surma:And so I'm just quite happy that because those are common operations, right?
  1329. Jake:...
  1330. Surma:You want to join two sets you want to intersect two sets. It seems like
  1331. Surma:That should just be provided. So I'm surprised that Chrome hasn't just shipped that
  1332. Jake:Well, do you know what?
  1333. Jake:Maybe I'm getting wrong information from
  1334. Jake:canIuse and the regular places,
  1335. Jake:because this was championed by someone
  1336. Jake:who works, you know,
  1337. Jake:Satya, who,
  1338. Jake:do you remember Satya? He was, we,
  1339. Surma:Yeah, we did
  1340. Jake:we interviewed him in one of the
  1341. Jake:old HTTP two or three episodes.
  1342. Jake:Yeah, and he championed this, so
  1343. Jake:I would be surprised if there wasn't
  1344. Jake:some code sitting in Chromium somewhere,
  1345. Surma:You
  1346. Jake:but yeah, I imagine this will,
  1347. Jake:we will get hold of this sometime
  1348. Surma:Yeah
  1349. Jake:this year in browsers.
  1350. Jake:All right, next up.
  1351. Jake:Temporal, or temporal,
  1352. Jake:I'm not quite sure what the
  1353. Jake:best way to pronounce it is.
  1354. Jake:So, JavaScript dates
  1355. Jake:are hard work.
  1356. Surma:Yeah, oh yeah
  1357. Jake:So the way
  1358. Jake:a date is stored in JavaScript is
  1359. Jake:milliseconds from 1970,
  1360. Jake:right, the Unix
  1361. Jake:epoch.
  1362. Surma:Yes
  1363. Jake:But in DevTools, when you look at a date,
  1364. Surma:You
  1365. Jake:you are shown, like, a
  1366. Jake:version of it which is in your local
  1367. Jake:time zone. And the methods
  1368. Surma:Mm-hmm
  1369. Jake:on it of, like, get me the day, get me the
  1370. Jake:hour, or whatever, these are your local
  1371. Jake:time zone. There are some other methods on there
  1372. Jake:which get the UTC values,
  1373. Jake:but it's an absolute
  1374. Surma:Mm-hmm
  1375. Jake:minefield, right? So,
  1376. Surma:Yeah, it's months are
  1377. Jake:it,
  1378. Surma:One indexed like if you say get month it starts at one get ISO string
  1379. Surma:Which should give you the date in your what is it called?
  1380. Surma:Is it ISO 8 6 6 1 1 of those the standard string format?
  1381. Jake:I think months are zero
  1382. Jake:indexed. I think that was one of the weird
  1383. Jake:bits, that days are
  1384. Jake:one indexed and months are zero indexed,
  1385. Jake:which is stupid. So, like, January
  1386. Surma:Check it check it right now
  1387. Jake:is zero. Oh my god,
  1388. Jake:okay, here we go.
  1389. Jake:Right, MDN,
  1390. Jake:get month.
  1391. Jake:I wrote
  1392. Jake:get moth just to,
  1393. Surma:You
  1394. Jake:yeah,
  1395. Jake:yeah, yeah, get month,
  1396. Jake:zero for January.
  1397. Jake:Anyway,
  1398. Surma:And
  1399. Jake:yay.
  1400. Surma:Yeah, and I get ISO string which the name kind of implies it gives you the date in ISO
  1401. Jake:Yeah.
  1402. Jake:UTC.
  1403. Surma:Yeah, it forces UTC even though it shouldn't the the ISO format can very well handle time zones
  1404. Jake:Yeah.
  1405. Jake:So, this is
  1406. Jake:where it's messy, because,
  1407. Jake:like, if you have an input
  1408. Jake:type date, on that you
  1409. Surma:You
  1410. Jake:have .value as date,
  1411. Jake:and that gives you the selected
  1412. Jake:date, midnight
  1413. Jake:UTC,
  1414. Jake:which means that if
  1415. Jake:you look at that date in the console,
  1416. Jake:if you're not on
  1417. Jake:GMT or UTC time,
  1418. Jake:it could be showing the wrong date, right?
  1419. Jake:Like, it's very confusing.
  1420. Jake:And it means that you need to make sure
  1421. Surma:Yeah
  1422. Jake:if you're getting the data out of that, you need
  1423. Jake:to get the value of, which gives you the
  1424. Jake:milliseconds from the epoch, or you use
  1425. Jake:the UTC methods. If you use one of the other methods,
  1426. Surma:You
  1427. Jake:it's going to be wrong.
  1428. Jake:Well, yeah, if you are in
  1429. Jake:GMT, it's going to be right, coincidentally.
  1430. Jake:And then someone else
  1431. Surma:Yeah, England well England in winter
  1432. Jake:runs your code and it's wrong, yeah.
  1433. Jake:Exactly. England in winter,
  1434. Jake:what a better place to be.
  1435. Jake:But here's the thing,
  1436. Jake:Polaris, the
  1437. Jake:design, the component library
  1438. Jake:at Shopify, their date
  1439. Jake:picker returns you a date object
  1440. Jake:and it's midnight
  1441. Jake:of the date selected
  1442. Surma:You
  1443. Jake:in the current time zone,
  1444. Jake:which means it appears
  1445. Surma:Oh
  1446. Jake:great in the console,
  1447. Jake:and if you do get month, get day,
  1448. Jake:you get the right values. But if you
  1449. Jake:did value of, that gives you the
  1450. Jake:milliseconds, and you sent that
  1451. Jake:to the server, you're going to get the wrong
  1452. Jake:stuff back at the other side, right?
  1453. Surma:That's awful, yeah
  1454. Jake:Because it's
  1455. Jake:that's such a, you know,
  1456. Jake:whoever coded that, just
  1457. Jake:they've been bitten by
  1458. Jake:date, right? It's not their fault, it's just
  1459. Surma:Yeah
  1460. Jake:hard. Anyway, temporal
  1461. Jake:to the rescue.
  1462. Surma:You
  1463. Jake:It lets you create a
  1464. Jake:date object that just has
  1465. Jake:like month and date.
  1466. Jake:It lets you create a time object, which is just
  1467. Jake:a time.
  1468. Jake:Or, you know, you can create a date and time,
  1469. Jake:which is just a date and time, like no time zone.
  1470. Jake:And this stuff is, this is
  1471. Jake:great, because it's exactly the amount of
  1472. Surma:Oh
  1473. Jake:data you're selecting, like month and
  1474. Jake:date is the amount of data you're picking in the
  1475. Jake:date picker. The fact that you end up with an object
  1476. Jake:which represents time
  1477. Jake:and displays, you know, has methods that
  1478. Jake:are associated with time zone, it's just
  1479. Surma:You
  1480. Jake:confusing because it shouldn't, right?
  1481. Jake:That data isn't there.
  1482. Surma:And if I have a
  1483. Surma:daytime object from temporal and
  1484. Surma:I say okay, and now give me the Unix timestamp of the state in this time zone. Does that exist?
  1485. Jake:If you've got, uh,
  1486. Jake:just an object that is representing time
  1487. Jake:or just an object that's representing a date,
  1488. Surma:You
  1489. Jake:you can mash these together to create one that
  1490. Jake:represents both. And then you can add a time zone,
  1491. Jake:which now represents a particular time zone
  1492. Jake:of that time and date.
  1493. Surma:And then hopefully at some point I can turn it to Unix timestamp because that's you know, usually the thing you want
  1494. Jake:Well, Unix timestamp is supposed to be UTC,
  1495. Jake:right? But you could do it
  1496. Jake:for the, you know, for the
  1497. Surma:You
  1498. Jake:UTC timestamp, right?
  1499. Jake:But you could do it for a particular
  1500. Jake:time zone if you wanted, right?
  1501. Surma:And Unix timestamp doesn't have a time zone it's a number of seconds since the point in time
  1502. Surma:So that's why I'm wondering if they're because usually often with
  1503. Jake:Well, that's fair.
  1504. Jake:Oh, I see
  1505. Jake:what you mean.
  1506. Surma:APIs or server communication that is your ground truth format where you say like if you want to communicate a point in time
  1507. Jake:Yes.
  1508. Surma:That's what you send, but I'm assuming they have thought of this
  1509. Surma:I would be surprised if there isn't a way to
  1510. Surma:then say okay, I now have a date time in a time zone and now do do the fancy math because
  1511. Jake:Hmm.
  1512. Surma:My god, you do not want to do the math yourself if you've ever looked
  1513. Jake:Oh, absolutely.
  1514. Jake:Yeah, and
  1515. Jake:being able to represent a time as well
  1516. Jake:is great for cases where
  1517. Jake:because it, you know, if we
  1518. Jake:organize a
  1519. Jake:time to have a meeting, then
  1520. Jake:that needs to include
  1521. Jake:a time zone because if we're in different
  1522. Jake:countries, we're agreeing on a point of
  1523. Jake:a shared point of time.
  1524. Surma:Exactly
  1525. Jake:But if you're setting an alarm on your
  1526. Jake:phone, like
  1527. Jake:if you set your alarm to go off at 9
  1528. Jake:in the morning,
  1529. Jake:you don't expect that to change if you
  1530. Jake:get on a plane and travel somewhere else.
  1531. Jake:You don't want to be woken up at 2
  1532. Jake:in the morning because that's where
  1533. Surma:Or would you that's actually I think it's a question
  1534. Jake:you've traveled.
  1535. Surma:I asked a couple months ago on Twitter because I was stumbling over this when the when summertime ended
  1536. Jake:Hmm.
  1537. Surma:Where it is technically possible that your alarm time never happens
  1538. Jake:Yes.
  1539. Jake:I think that is a fun one to ponder.
  1540. Jake:It's like, what happens if you skip
  1541. Jake:your alarm by, you know,
  1542. Jake:changing the time on your
  1543. Jake:phone, which might happen automatically
  1544. Jake:by crossing time zones
  1545. Surma:Yeah
  1546. Jake:or summertime, that kind of thing.
  1547. Jake:Yeah, anyway.
  1548. Surma:I think so sometimes the temporal stuff sounds like an amazing affordance similarly to the
  1549. Surma:Internationalization stuff about currencies and dates and stuff and I think that's
  1550. Jake:Yeah.
  1551. Jake:Yeah, exactly.
  1552. Surma:Great. I love that. They're doing it heavy lifting
  1553. Jake:It's one small part of the platform,
  1554. Jake:and their docs are great,
  1555. Jake:actually, in the proposal.
  1556. Jake:I urge folks to have a look.
  1557. Jake:And there are little bits of it in Safari,
  1558. Jake:TP, technical preview,
  1559. Jake:whatever, but nothing else.
  1560. Jake:It's not really being picked up, but I'm
  1561. Jake:really hoping we see some implementations
  1562. Jake:of that this year.
  1563. Jake:All right, what's next up?
  1564. Surma:You
  1565. Jake:Oh, JSON modules.
  1566. Jake:We talked about this.
  1567. Jake:I wasn't sure
  1568. Jake:where to put them in this because
  1569. Jake:they're technically in Safari only,
  1570. Jake:but the old
  1571. Jake:assert syntax is in Chrome.
  1572. Surma:Oh, this is with import blah blah blah dot JSON with type Jason
  1573. Jake:Yeah, so
  1574. Jake:this is
  1575. Jake:JSON. Yeah.
  1576. Jake:Exactly, that's it. What do you think?
  1577. Surma:Sure, I
  1578. Jake:Yeah, that's my opinion as well.
  1579. Jake:Yeah.
  1580. Surma:Think I think Jason specifically was never
  1581. Surma:Especially since top-level await is a thing I can just do a weight fetch then dot Jason
  1582. Jake:Yeah.
  1583. Surma:You know like it's kind of the same thing, but the groundwork that this syntax opens up
  1584. Surma:I think that's where the real payoff comes in
  1585. Jake:I think it's something
  1586. Jake:I'm glad that it's there. I think in most cases
  1587. Jake:I would only ever use it for
  1588. Jake:local, for the same origin data that
  1589. Jake:I really trust.
  1590. Surma:You
  1591. Jake:And I would then
  1592. Jake:probably bundle it in that case.
  1593. Surma:Yeah
  1594. Jake:Because if I'm getting data
  1595. Jake:from somewhere else, I don't want
  1596. Jake:a failure to fetch that data to
  1597. Jake:break my whole module graph, right? To break the whole
  1598. Jake:script. So, yeah.
  1599. Surma:Yeah, exactly
  1600. Jake:Fair enough. Whatever. Fine.
  1601. Jake:Here's another
  1602. Jake:feature, which I had no idea about this.
  1603. Jake:Import source.
  1604. Surma:You
  1605. Jake:So instead of
  1606. Jake:import x from
  1607. Jake:specifier,
  1608. Surma:You
  1609. Jake:import source
  1610. Jake:x from specifier.
  1611. Jake:Ooh.
  1612. Surma:Wait, can you can you spell that syntax for me? Like is that a new keyword?
  1613. Jake:So import
  1614. Jake:Yeah, it's a new keyword. Import
  1615. Jake:space source as in S-O-U-R-C-E
  1616. Jake:and then
  1617. Jake:x
  1618. Jake:from specifier.
  1619. Jake:So it's just adding that word source
  1620. Jake:after the import and it
  1621. Surma:What does that mean
  1622. Jake:gives you the source code
  1623. Jake:of the thing.
  1624. Surma:For X, oh it gives me the sort of the the entire the source of the module. Ah
  1625. Jake:For specifier,
  1626. Jake:it gives you the module source code.
  1627. Jake:Yeah.
  1628. Jake:Yeah.
  1629. Surma:Okay, that's hmm
  1630. Jake:And
  1631. Jake:when I first saw this, I was like,
  1632. Jake:why isn't this
  1633. Jake:an import
  1634. Jake:attribute?
  1635. Jake:And it just so
  1636. Jake:happens that the explainer has a section on this, which
  1637. Jake:is great. It's like, well,
  1638. Jake:when you change the import
  1639. Jake:attribute,
  1640. Surma:You
  1641. Jake:that is a different entry in the
  1642. Jake:module graph. You can import the same thing in two
  1643. Jake:different ways and get two different results.
  1644. Jake:Whereas import source, it gives you
  1645. Jake:exactly the same thing. You're just getting the
  1646. Jake:source of it rather than
  1647. Surma:So it populates the module graph it just doesn't evaluate it
  1648. Jake:the module graph.
  1649. Jake:Yes.
  1650. Jake:So you could do...
  1651. Jake:No. So you can do
  1652. Jake:import source x from specifier
  1653. Jake:with... and you can have
  1654. Jake:import attributes after it, which work
  1655. Jake:as expected. You can get the
  1656. Jake:WASM source or
  1657. Surma:You okay, can I then evaluate that source lazily?
  1658. Jake:whatever. The JSON source.
  1659. Jake:You could.
  1660. Jake:You would just use an import, right?
  1661. Jake:I think part of the idea is like, it's
  1662. Jake:aimed at tools which might want to
  1663. Jake:introspect something or modify something
  1664. Jake:before calling a val or whatever.
  1665. Surma:But then why does it matter that it's in the module graph
  1666. Jake:I think purely just because
  1667. Jake:it needs to be in the module graph, so
  1668. Surma:You
  1669. Jake:if you import it twice, it's not going to the network
  1670. Jake:twice. So you import source
  1671. Jake:and then you import not source.
  1672. Jake:It only goes to the network
  1673. Surma:Yeah, I guess that could be nice
  1674. Jake:once.
  1675. Jake:I think it's interesting.
  1676. Jake:I don't know if I'd ever use it, but I think
  1677. Jake:interesting tools could be built around this.
  1678. Surma:Yeah, I'm trying to think if there's like, you know, you could import source and
  1679. Surma:Then turn it into a blob URL to spin up a worker with that file
  1680. Jake:Oh, yeah.
  1681. Surma:But then you have all you if you have module workers
  1682. Surma:Why why would you could as you say you could you know, you could run Babel at runtime or something?
  1683. Jake:Yeah.
  1684. Surma:I do some transpilation. I yeah, I
  1685. Surma:I'm not quite sure where I would use it. It's
  1686. Jake:Hmm.
  1687. Surma:Maybe wasm is the better use case. But then again, I keep wondering like what?
  1688. Surma:it is the same as fetch except for it's in the module graph and
  1689. Surma:And
  1690. Surma:HTTP caching I would have thought would give you most of the benefits, but maybe I'm missing it
  1691. Surma:So yeah, don't don't take my word for it. I should probably read the explainer before I say I don't get it. But
  1692. Surma:Yeah from my current
  1693. Surma:Standpoint. I don't know where I would go. Yes. That's exactly what I was looking for
  1694. Jake:Yeah, I think
  1695. Jake:it's one of those things where I'm like, I don't
  1696. Surma:Yeah, yeah, that's probably nice way to look at it. Oh boy
  1697. Jake:really know what I'd use it for, but
  1698. Jake:I imagine I will very much
  1699. Jake:enjoy tools that are built using it
  1700. Jake:in future.
  1701. Jake:All right. Next one. Decorators.
  1702. Jake:And decorator metadata. Technically
  1703. Surma:How long is the decorator journey been going on
  1704. Jake:two proposals, but
  1705. Jake:I think you need them together.
  1706. Surma:I was gonna ask
  1707. Jake:Yeah.
  1708. Jake:So this is...
  1709. Jake:I know.
  1710. Jake:So this is a way
  1711. Jake:that you can put at
  1712. Jake:and then the name of a function
  1713. Surma:Watch my
  1714. Jake:and you can put that before
  1715. Jake:a class method, a class field,
  1716. Jake:a class getter, a setter,
  1717. Jake:or a class accessor, which is a new
  1718. Jake:thing, and it can transform
  1719. Surma:Mmm
  1720. Jake:that thing in some ways.
  1721. Jake:Interestingly, not functions. This is
  1722. Jake:only on classes.
  1723. Jake:Class accessor, which is a new thing,
  1724. Surma:You
  1725. Jake:is just a getter, setter combined.
  1726. Jake:Imagine you had a getter
  1727. Surma:Hmm
  1728. Jake:which just got from a private value
  1729. Jake:and a setter which just set
  1730. Jake:to the private value.
  1731. Jake:That's what an accessor is.
  1732. Jake:But it means you can
  1733. Jake:put a decorator in front of
  1734. Jake:that sort of getter-setter
  1735. Jake:combo.
  1736. Jake:So I've been using decorators
  1737. Jake:at Shopify in TypeScript
  1738. Jake:land, these new stage
  1739. Jake:three ones.
  1740. Jake:I think they're useful. They're really useful
  1741. Surma:I
  1742. Jake:to take a class property and
  1743. Jake:when getter-setters happen
  1744. Jake:on it to do extra stuff.
  1745. Jake:But it's
  1746. Jake:complicated, right?
  1747. Surma:Remember that previously that you would just like basically
  1748. Surma:return
  1749. Surma:Then you get passed in the original value. You can return the new values
  1750. Surma:You can return a wrapper function or something. And if I remember correct, the new ones are a lot more complicated than that
  1751. Jake:Yeah.
  1752. Jake:The whole system seems to have
  1753. Jake:been designed so the decorator can only
  1754. Jake:change that thing.
  1755. Jake:I think previously if you were
  1756. Surma:You
  1757. Jake:modifying the getter-setter
  1758. Jake:or the field, you would be
  1759. Jake:given a reference to the class as well.
  1760. Jake:So you could mess around with the rest of the class.
  1761. Jake:That is no longer the case.
  1762. Surma:Surely you can still go full JavaScript
  1763. Jake:Yes, you could go, but you would need to know
  1764. Jake:which class you're going and
  1765. Jake:getting.
  1766. Jake:That would be a case where the decorator is only ever applied to one
  1767. Surma:Yeah, okay
  1768. Jake:class.
  1769. Jake:But you do have this metadata
  1770. Jake:object which lets you
  1771. Jake:associate data with the class.
  1772. Jake:So you can create side effects
  1773. Surma:I see
  1774. Jake:that way, which I'm using
  1775. Surma:You
  1776. Jake:that for when
  1777. Jake:a property
  1778. Jake:like a class field or
  1779. Jake:a class accessor is assigned as
  1780. Jake:reactive,
  1781. Jake:the decorator I have means that it
  1782. Jake:knows when that value
  1783. Jake:changes it needs to re-render the component.
  1784. Jake:But it also reflects that
  1785. Jake:value to an attribute and then
  1786. Jake:puts that attribute in the observed
  1787. Jake:attributes array with the class.
  1788. Jake:The only way I can do that last bit is through this metadata
  1789. Surma:Yeah
  1790. Jake:object because I can't just
  1791. Jake:go and add to that observed
  1792. Surma:You
  1793. Jake:attributes array because I don't have
  1794. Jake:access to the class at that moment.
  1795. Jake:Yeah, it's complicated.
  1796. Surma:I mean in general decorators unlock great DX. It's so it can be so convenient
  1797. Surma:I worry sometimes that too much magic is hidden
  1798. Surma:But it is a way of almost like meta programming where you could go, you know
  1799. Surma:Just run this callback whenever a certain class property gets changed, but yeah, that would be getters as a stupid example
  1800. Surma:But you know what? I mean, it's just it can remove a lot of clutter by hiding it in a decorator and just giving it
  1801. Jake:Yeah.
  1802. Surma:a good name, so I think as far as
  1803. Surma:DX goes it's I'm glad if we are
  1804. Surma:Getting close to the end of the Odyssey that is decorators in JavaScript and stabilize something
  1805. Jake:Yeah.
  1806. Jake:It feels like the most,
  1807. Jake:of all of the proposals
  1808. Jake:that I've talked about, I think it's
  1809. Jake:the one that's hardest to understand.
  1810. Jake:There's a lot of timing stuff
  1811. Jake:that's caught me out working on it.
  1812. Surma:Yeah
  1813. Jake:But yeah, I'm glad it's there.
  1814. Jake:I'm using it in TypeScript already
  1815. Jake:but there's no actual browser support
  1816. Jake:for it and so I would like that to change
  1817. Jake:even if I think it's
  1818. Surma:Hmm
  1819. Jake:pretty complicated as a feature in terms
  1820. Jake:of using it.
  1821. Jake:Alright, next one.
  1822. Jake:A short one. Float16Array.
  1823. Surma:Yep, cool got it got it got a half that that's LLM data on in JavaScript
  1824. Jake:Yeah, same.
  1825. Jake:Exactly.
  1826. Jake:And I imagine
  1827. Jake:that's what it's aiming for.
  1828. Jake:Similar to,
  1829. Surma:You
  1830. Jake:do we already have
  1831. Jake:Float64Array? We do, don't we?
  1832. Jake:Is that what it's called? Yeah.
  1833. Surma:Yeah
  1834. Jake:So it's just the lower
  1835. Jake:accuracy version of that.
  1836. Jake:Yeah, sounds good.
  1837. Jake:Last one. Here we go.
  1838. Jake:JsonPars
  1839. Jake:SourceTextAccess.
  1840. Jake:And this is a fun one, I think.
  1841. Jake:So,
  1842. Jake:I think we've all...
  1843. Surma:Is this for like replaces
  1844. Jake:Kinda.
  1845. Jake:So, JsonPars
  1846. Surma:You
  1847. Jake:has this second argument,
  1848. Jake:the reviver.
  1849. Jake:Yeah.
  1850. Surma:Reviver
  1851. Jake:So this is where you can
  1852. Jake:map
  1853. Jake:the value that's coming in
  1854. Jake:to something else.
  1855. Jake:So,
  1856. Surma:Or is stringify the one where it's called replacer
  1857. Jake:yes.
  1858. Jake:Yes, exactly.
  1859. Jake:And this feature does involve both
  1860. Jake:to an extent.
  1861. Surma:Wait if it's called reviver in past surely it should be called killer in stringify
  1862. Jake:So...
  1863. Surma:Oh
  1864. Jake:Yeah, there is a sort of
  1865. Jake:lack in general
  1866. Jake:of symmetrical naming
  1867. Jake:in the JSON API.
  1868. Jake:Well, we've got pars.
  1869. Jake:Alright, so we've got serialize.
  1870. Jake:No.
  1871. Jake:We have stringify in this house.
  1872. Jake:You know?
  1873. Jake:I love it, I love it.
  1874. Surma:Ooh quick side note, you know how Jason
  1875. Surma:stringify
  1876. Surma:Has that replacer argument and then the third one is the indent argument
  1877. Jake:Yes.
  1878. Jake:And stringify,
  1879. Jake:yes. Yep.
  1880. Surma:right
  1881. Surma:If if you want it's pretty printed you do object comma null
  1882. Jake:And then, yeah.
  1883. Surma:Because you don't want to represent and then usually I do the string
  1884. Jake:Yes.
  1885. Surma:Two spaces or four spaces or tab. I only recently learned
  1886. Surma:That you can just put the number two for two spaces as the third argument
  1887. Jake:Oh, really?
  1888. Jake:I didn't know.
  1889. Surma:Yeah
  1890. Surma:See that's how I felt like that's fucking silly that makes it a lot better
  1891. Jake:Oh.
  1892. Jake:I used this yesterday, you know.
  1893. Surma:I do wish they flipped the had flipped the order. I think the indentation is
  1894. Jake:I didn't know that.
  1895. Jake:Oh, that's amazing.
  1896. Jake:Oh, yeah.
  1897. Jake:This is a classic case where that should have been
  1898. Jake:an option object, right?
  1899. Jake:You don't want to have to use null
  1900. Surma:Yeah
  1901. Jake:to skip over an attribute.
  1902. Jake:Use null to skip over an attribute.
  1903. Jake:Anyway. But yes, okay.
  1904. Jake:So the use case for this, you've got this reviver
  1905. Jake:which lets you take a value and map it
  1906. Jake:to a different value.
  1907. Surma:Hmm
  1908. Jake:So you could look into
  1909. Jake:a string and realize that it's
  1910. Jake:like a serialization
  1911. Jake:of a particular thing and you can...
  1912. Surma:Basically allowing you to serialize values that are originally not serializable in jason
  1913. Jake:Exactly.
  1914. Jake:But...
  1915. Jake:So, the idea here is
  1916. Jake:your reviver is given a number.
  1917. Jake:Like, if it's a number in JSON,
  1918. Jake:your reviver is given a number.
  1919. Jake:Now, converting the number in JSON
  1920. Jake:to the number in JavaScript
  1921. Jake:can be lossy.
  1922. Surma:Mm-hmm
  1923. Jake:For example, if it is a very big number.
  1924. Jake:So, the reviver's
  1925. Jake:a bit rubbish in that case.
  1926. Jake:So, this proposal is that
  1927. Jake:the reviver would also receive
  1928. Jake:the source text of that value.
  1929. Surma:Oh, yes, yes, yes
  1930. Jake:So, if it's a massive number
  1931. Jake:in JSON,
  1932. Jake:you would be given the number,
  1933. Jake:sure, which is lossy,
  1934. Jake:but then you would be given a string
  1935. Jake:with the full number
  1936. Jake:which would allow you to convert it to a
  1937. Jake:big int.
  1938. Surma:Oh, that's really in that way source, okay, that makes a lot of
  1939. Jake:Ah.
  1940. Surma:Sense. I yeah, I just I wasn't sure how much jason like the actual jason standard specifies
  1941. Surma:how big a numeric value can be because I
  1942. Jake:It doesn't...
  1943. Jake:Oh, the JSON spec
  1944. Jake:is like
  1945. Jake:just one diagram.
  1946. Surma:But yeah the railway diagrams, isn't it
  1947. Jake:Like, it's...
  1948. Surma:But
  1949. Jake:Yeah, exactly.
  1950. Jake:So, it doesn't specify
  1951. Jake:what kind of number it is.
  1952. Jake:It just specifies the kind of
  1953. Surma:Interesting
  1954. Jake:characters that can appear in it.
  1955. Surma:But the source text that you get is only for this specific
  1956. Surma:property like let's say
  1957. Surma:I
  1958. Surma:The number that what is in the jason is a number but that is in fact an offset
  1959. Surma:or an index of another array and I would love to like immediately just
  1960. Surma:Look that object up and put that in there
  1961. Jake:Oh.
  1962. Jake:Hmm.
  1963. Jake:I'm not sure.
  1964. Jake:I guess it might depend on the order
  1965. Jake:in which this stuff arrives at.
  1966. Surma:I guess you're not getting access to the to the half series deserialized object in there or something
  1967. Jake:Well, I guess it, you know,
  1968. Jake:the reviver will also run for objects
  1969. Jake:so you can, you know...
  1970. Surma:I guess you could build that yourself on top. Yeah, true. Yeah
  1971. Jake:Yeah.
  1972. Jake:So, the other side of it
  1973. Jake:is the stringifier
  1974. Jake:where you've got the replacer
  1975. Surma:So
  1976. Jake:and you can
  1977. Jake:use...
  1978. Jake:So, you know, this is where you can...
  1979. Jake:You're getting values in.
  1980. Jake:You're checking values out in the replacer.
  1981. Jake:But you can wrap a value in
  1982. Jake:raw JSON
  1983. Surma:Of course and you have to because if it is a big int in your
  1984. Jake:which...
  1985. Jake:Yeah.
  1986. Surma:object you can if you just call to a string then you're now sending
  1987. Jake:Yeah.
  1988. Surma:A quoted string in the raw j is not just a sequence of numbers
  1989. Jake:Exactly.
  1990. Surma:So with raw you can return the string and tell
  1991. Surma:Just use the actual
  1992. Jake:Just blat it into the object.
  1993. Surma:Characters, can you can so you can
  1994. Jake:Exactly.
  1995. Surma:Make it emit invalid jason
  1996. Jake:You cannot.
  1997. Surma:Oh
  1998. Jake:The thing you pass to raw JSON
  1999. Jake:must be valid JSON.
  2000. Surma:Oh, that's disappointing now, it's probably a good thing but
  2001. Jake:Yeah.
  2002. Jake:I thought the same thing as you
  2003. Jake:and looked into the spec and, like, no.
  2004. Jake:It guards against that.
  2005. Jake:It can be anything that's
  2006. Jake:JSON compatible
  2007. Jake:but it has to be
  2008. Surma:Fascinating that that's quite good. Oh, wow
  2009. Jake:valid JSON.
  2010. Jake:So, yeah. That's shipped in Chrome.
  2011. Jake:That's shipped in Chrome. I didn't know.
  2012. Jake:Yeah, I know.
  2013. Jake:Not anywhere else yet but
  2014. Surma:I think that that's a nice quality of of life thing
  2015. Jake:that's there.
  2016. Surma:I'm assuming that you know, the common workaround is just like
  2017. Surma:You do strings go deal with it
  2018. Surma:And that's it. I think that's it. I think that's it. I think that's all I have to say
  2019. Jake:Yeah. I can't think of much utility
  2020. Jake:of it
  2021. Surma:You
  2022. Jake:except for BigInt.
  2023. Jake:Like, that's...
  2024. Jake:That seems to be the big use case here.
  2025. Jake:Maybe there'll be
  2026. Surma:Yeah
  2027. Jake:other things in future.
  2028. Jake:But, yeah. That's the main one.
  2029. Jake:All right. Well, there we go.
  2030. Jake:I want you to pick your favz
  2031. Jake:one. No, let's go one.
  2032. Surma:Big pick my my favie. Oh, I should have really paid attention. Um
  2033. Jake:Yeah.
  2034. Jake:I'll do the rundown.
  2035. Surma:Um
  2036. Jake:We heard iterator helpers,
  2037. Jake:shadow realm, the regular
  2038. Jake:expression pattern modifiers, the set methods,
  2039. Surma:Yeah
  2040. Jake:temporal, JSON modules,
  2041. Jake:import source, decorators,
  2042. Jake:float16 array, and the JSON
  2043. Jake:parse source text access.
  2044. Surma:Uh
  2045. Surma:Probably for me it's gotta be
  2046. Surma:iterate to help us with
  2047. Surma:Decorators being the run-up even though I haven't used them myself
  2048. Jake:Oh.
  2049. Jake:That's... Oh, yeah. That's fair
  2050. Jake:actually.
  2051. Surma:So
  2052. Jake:What am I going to pick?
  2053. Surma:So
  2054. Jake:I am going
  2055. Jake:to pick
  2056. Jake:the same runner-up, decorators,
  2057. Jake:but for number one, I'm going to say
  2058. Jake:temporal.
  2059. Jake:The reason is, the iterator helpers...
  2060. Jake:Look, I could polyfill that.
  2061. Jake:It's fine. Whereas temporal is such a big...
  2062. Jake:I mean, you could polyfill it, sure.
  2063. Jake:But it's quite a big thing.
  2064. Jake:Also, I want
  2065. Jake:other APIs on the web
  2066. Jake:to be able to return
  2067. Surma:Yeah
  2068. Jake:these temporal values.
  2069. Jake:Instead of having value as
  2070. Surma:Um
  2071. Jake:date on a date input,
  2072. Jake:I want another getter, which just gives me
  2073. Jake:the temporal...
  2074. Jake:Yeah. Date time.
  2075. Jake:No, just date.
  2076. Surma:Yeah, that's that's fair I think actually for me it's gone so far I just I just don't do date stuff
  2077. Jake:That's fair.
  2078. Surma:Any any side project it has dates. I just like nope
  2079. Surma:Opting out doing something else
  2080. Jake:I might be slightly influenced
  2081. Surma:Yeah
  2082. Jake:by looking at that stuff recently,
  2083. Jake:so there might be a sort of recency bias.
  2084. Surma:Yeah, I can totally understand no, it's good if we if we solidify it's it's a solid pick I just
  2085. Surma:um
  2086. Surma:Yeah, I guess i've just found myself too often recently writing the whole map filters
  2087. Jake:Yeah, fair.
  2088. Surma:I find them often quite readable and nice and so just making that
  2089. Surma:more okay
  2090. Jake:Good choice.
  2091. Surma:I look forward to
  2092. Jake:All right, then.
  2093. Jake:We have gone on
  2094. Jake:less than last time,
  2095. Jake:but enough, I think.
  2096. Surma:You
  2097. Jake:Enough.
  2098. Surma:Enough yeah, i'm tired of us
  2099. Jake:Yeah, I know, man.
  2100. Jake:I need to go and do some real work,
  2101. Jake:not this.
  2102. Jake:Yeah.
  2103. Surma:Thank you
  2104. Jake:Yeah.
  2105. Jake:Yeah, I definitely
  2106. Jake:should go and do some real work.
  2107. Jake:They're sponsoring this not only in terms of
  2108. Jake:the
  2109. Jake:cost of the editing and the hosting,
  2110. Jake:but probably just in the time it takes
  2111. Jake:to record this.
  2112. Surma:Yeah forested
  2113. Jake:I should be doing other things.
  2114. Jake:Oh, absolutely.
  2115. Surma:Around well, um
  2116. Surma:Let's see. We we're gonna we're gonna try and keep the streak going
  2117. Jake:Yeah.
  2118. Surma:um, and until then I think we we we just do do the thing which is
  2119. Jake:Do the thing.
  2120. Surma:Happy next time
  2121. Jake:Happy next time!
  2122. Jake:Bye-bye!
  2123. Surma:The the doorbell did not ring watson did not bark
  2124. Jake:The thing is, I have
  2125. Jake:a delivery scheduled right now,
  2126. Surma:You
  2127. Jake:so I was kind of hoping that I would
  2128. Jake:get my revenge.
  2129. Surma:The revenge doorbell, I yeah, I I have a a dude coming over and probably in about five minutes
  2130. Surma:because I have a
  2131. Jake:Oh, no!
  2132. Surma:Leak in the wall somewhere when it was raining like really heavy last week suddenly
  2133. Surma:My carpet around the window was wet and there's wet patches on the wall and it's really fun
  2134. Jake:Owning a house.
  2135. Surma:um
  2136. Jake:When it was really windy and rainy,
  2137. Jake:I could hear a tapping
  2138. Surma:You
  2139. Jake:on the bedroom ceiling.
  2140. Surma:Oh no scary
  2141. Jake:But this is the thing.
  2142. Jake:There was no...
  2143. Jake:There's no damp patch on it.
  2144. Surma:It's just your cats clicking and annoying you
  2145. Jake:Yeah.
  2146. Jake:Well, I haven't even been in the loft yet,
  2147. Jake:so I...
  2148. Jake:I'm kind of scared to look up there.
  2149. Jake:But I don't know.
  2150. Jake:I think it could have just been creaking
  2151. Jake:because of the high wind rather than rain.
  2152. Surma:Maybe that's where the dead bodies are hidden and it's just the the maggots
  2153. Surma:Oh, this is dark, I don't know why it took it to a dark place first
  2154. Jake:Did I ever tell you that?
  2155. Jake:We used to think there was a
  2156. Jake:body buried in our garden, in our old house,
  2157. Surma:What
  2158. Jake:because there was a patch
  2159. Jake:of grass that would
  2160. Jake:just grow very
  2161. Jake:differently, and would also
  2162. Jake:a lot of daisies would grow there.
  2163. Jake:And you know the saying,
  2164. Jake:pushing up the daisies?
  2165. Surma:Yeah
  2166. Jake:That's why.
  2167. Surma:It was it human shaped was it like the outline of a human
  2168. Jake:But, like, it was...
  2169. Jake:Yes, humans...
  2170. Surma:Uh
  2171. Jake:Not exactly human-shaped, but it was
  2172. Jake:like...
  2173. Jake:There's a photo of me laid down in it, and it is...
  2174. Jake:You know, it's that size.
  2175. Jake:It's person-sized.
  2176. Jake:But we lived, we backed onto a cemetery,
  2177. Jake:you see, so I wonder if they just got lost.
  2178. Jake:I don't know.
  2179. Jake:If this makes it into the edit,
  2180. Jake:I'll sneak a picture
  2181. Surma:Sneak the picture
  2182. Jake:of the body
  2183. Surma:Yeah
  2184. Jake:grass into the show notes.
  2185. Surma:My my dad is is a gp back in germany and his he's retired now
  2186. Surma:but his practice was next to a cemetery
  2187. Surma:and I
  2188. Surma:Always thought like well, that's
  2189. Jake:If things go really badly...
  2190. Surma:You're right there
  2191. Jake:Yep, straight on the phone.
  2192. Jake:Ah, yeah.
  2193. Jake:There's another one.
  2194. Surma:Uh, dr. Sommer new customer new former customer, yep, we got you covered
  2195. Jake:You just have a little
  2196. Surma:Okay
  2197. Jake:conveyor belt out the back.
  2198. Jake:Take it straight there.
  2199. Jake:Ring a bell.
  2200. Surma:Little known fact that was how that's how factorio was invented
  2201. Jake:Amazing.
  2202. Surma:Well, that's that's a great game idea actually well, I know what i'm building next with bevy
  2203. Jake:Thank you.