Threads for caolan

  1. 16

    To be clear, I don’t think there’s anything wrong with this feature - I just want to remark that only the JavaScript community - speaking with affection here - can call a pre-warmed cache “Static Regeneration”.

    1. 1

      I’m not sure it’s exactly the same a “pre-warmed cache”. Surely that would just be static generation like we’re all used to?

      The magic is in the static-first approach, and simple implementation of on-demand server-side rendering.

      (Obviously, we JS folks love hyping new releases!)

      1. 2

        I think the distinction for “pre-warmed cache” is “generate a page when it changes and serve it on all requests”, vs “generate a page on-demand and save the generated version for future requests”. Time/space tradeoff: you cache pages that may never be requested, vs. the first person to request it having to wait for it.

        1. 2

          isn’t the latter “dynamic programming”?

          1. 2

            I think you are thinking of memoization.

            1. 1

              I was, yeah. Thanks for that.

            2. 1

              No. A lot of server-side stuff never bothers saving generated web pages, on the assumption that they will always be different each time they are fetched. For many types of sites it’s a pretty safe assumption, for example, if you assume that each time someone goes to lobste.rs the state of the front page has changed and needs to be regenerated regardless of who that person is.

      1. 4

        Really well illustrated article! As someone who uses collaborative code editing daily, I really got an appreciation for all this complexity I’ve taken for granted.

        1. 3

          Thanks. It was originally a talk for some local meetup groups that - thanks to a certain pandemic - got turned into a blog post. At least I had some slides to take images from.

        1. 2

          Have you considered using an object with “as const” handlers instead of abusing class for this?

          const Handlers = {
            foo(state: State, { to }: { to: number }) { ... },
            bar(state: State, { to }: { to: number }) { ... },
          } as const
          
          • pro: more understandable to others that they can’t do class stuff like add properties or retain encapsulated state
          • con: required commas after functions
          1. 1

            Yeah, I would prefer not to use a class for clarity reasons too. Unfortunately, when I tried that it wouldn’t let me map over Handlers. Perhaps I’m missing something?

            error TS2749: 'Handlers' refers to a value, but is being used as a type here.
            
            1. 2

              In Typescript, classes are both a type representing an instance of the class, and a runtime value (the class itself in JS), as a kind of special case. Handlers here is just a runtime value (no magic) but its exact type is well-known at compile time. You can refer to its type (and the type of any runtime value) with typeof Handlers in type expressions.

              1. 1

                Thanks, I’ll give that a try and add an update to the blog post :)

                1. 2

                  I think this is what you want?

                  I’ve recently been trying to write my own version of this. I like your usage of an object as a declarative way of matching action names to handlers.

          1. 1

            Very cool. I’ve been exploring similar solutions lately but this one takes matters much further.

            One aspect I would change would be checking that every action is handled. Most Redux apps I see use multiple reducers via combineReducers, but every action is still run through every reducer in that case. So some actions definitely shouldn’t be handled. For that reason, I also want to use a single app-wide action type (to detect conflicting actions names).

            1. 1

              Thanks. The solution I end up with discards the handler for every action check since the Action types are derived from the handlers themselves. If you wanted multiple reducers I suppose you could create multiple Handler classes and derive an Action type for each, then union these for the overall Action type.

              Of course, if you have a separate handler function for each action anyway you won’t need any reducers.

            1. 3

              I think the title is misleading: This is not about simply using Redux and TypeScript but about improving on the recommended patterns by using advanced TypeScript features.

              1. 2

                That’s a good point. I can see in hindsight that it might sound like an introductory tutorial.

                Would it be good lobste.rs etiquette to edit the title after posting it?

                1. 3

                  Since I updated the title on my website I updated the lobste.rs title to match. Since it’s only the sub-heading part I hope its obvious to people it’s the same story.

              1. 3

                Nifty! I had tried to do the web-socket part of this before in rust for a collaborative 2d game map editor. This inspires me to go back and do the web side in Wasm. Good luck with it! I’d love to see how it’s put together when you’re ready

                1. 4

                  Thanks! I found the wasm tooling for rust to be pretty good now. It meant I could implement the CRDT once and use the same code for the server and client. I’d like to make it callable from C too and see if I integrate it with other text editors. Would be cool to edit a page from Emacs or vim as well as the web browser.

                  1. 3

                    I’m not sure, but atom may be able to run wasm. You could totally make an Atom plugin with this without too much change as it is

                    1. 2

                      That’s a great idea :)

                1. 4

                  “…there’s just a tremendous mess in software that’s going to take generations to clean up, assuming humanity even survives that long.”

                  Oh no, I can feel that existential dread returning. Time for a cuppa.

                  1. 1

                    This seems to confuse “borrow checking” with type checking. The file example is not the same as the HTTP example. The actual type-based pattern should be possible in any language with parametric types and static type checking.

                    The use of borrow for state checking is more unusual and requires that to be baked into the compiler.

                    1. 3

                      True, the file example is using borrow checking rather than types. I think later they’re making the case that the borrow checker can enforce the typestate pattern in the case of typestate transitions causing side-effects. This would be difficult to do in a language without proper move semantics to invalidate the previous state.

                    1. 16

                      One benefit of using a CMS or site generator is an automatic RSS feed. Hint: this blog currently has no RSS feed ;)

                      1. 5

                        I was really considering writing a blog that actually uses an RSS feed as the source of truth, then uses XSLT to generate the HTML…

                        1. 6

                          Pro tip: use an Atom feed. RSS 2.0 is pretty loose, spec wise.

                          1. 1

                            This brings back old memories. Back in 2006, I think, I used a CMS called Symphony that would generate XML and then you’d style your blog using XSLT. Since I was a junior developer back then, it was quite handy to learn XML and XSLT, which were still the rage back then :-)

                          2. 2

                            That is very true, but I’m working on a shell script to generate a feed from HTML.

                            Edit: Here’s a preliminary version of the script (results).

                            1. 3

                              Be careful your shell script doesn’t turn into a static site generator!

                              1. 1

                                Indeed! I saw it coming too, so now I’ve switched to a PHP script (feed.php) that generates it on the server from my index.html, so that I don’t have to worry about generating it :-)