Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 proposal #2982

Open
wants to merge 91 commits into
base: main
Choose a base branch
from
Open

v3 proposal #2982

wants to merge 91 commits into from

Commits on Sep 26, 2024

  1. Configuration menu
    Copy the full SHA
    c636c2f View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    3e97cc9 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    f07feb9 View commit details
    Browse the repository at this point in the history
  4. Add duplicate key check, deduplicate code, use ES6

    Perf is somewhat improved in spots, but generally the same otherwise.
    dead-claudia committed Sep 26, 2024
    Configuration menu
    Copy the full SHA
    f291d28 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    0106367 View commit details
    Browse the repository at this point in the history
  6. Drop m.trust support

    Cuts only about 2% of the bundle, but removes a pretty bad pain point in the code. Plus, inserting arbitrary HTML outside a container is usually a recipe for disaster in terms of styling.
    dead-claudia committed Sep 26, 2024
    Configuration menu
    Copy the full SHA
    c3e90f5 View commit details
    Browse the repository at this point in the history

Commits on Sep 27, 2024

  1. Configuration menu
    Copy the full SHA
    ca65f7a View commit details
    Browse the repository at this point in the history

Commits on Oct 2, 2024

  1. Configuration menu
    Copy the full SHA
    e9fad45 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    2707de3 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    ae28e2a View commit details
    Browse the repository at this point in the history
  4. Move state object creation to hyperscript

    It's simpler that way and I don't have to condition it.
    dead-claudia committed Oct 2, 2024
    Configuration menu
    Copy the full SHA
    7aca843 View commit details
    Browse the repository at this point in the history
  5. Move m.render out of initialization closure

    It's redundant and has been for ages. A v3 increment gives me the ability to minimize surprise.
    dead-claudia committed Oct 2, 2024
    Configuration menu
    Copy the full SHA
    b724902 View commit details
    Browse the repository at this point in the history

Commits on Oct 3, 2024

  1. Drop m.request

    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    3ade35c View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    a452105 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    8c619c3 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    1b0818e View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    6caacf2 View commit details
    Browse the repository at this point in the history
  6. Add lazy loader

    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    57edf21 View commit details
    Browse the repository at this point in the history
  7. Toss the "route" part of the router

    People can just use equality and regexps as needed.
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    6b3c7b3 View commit details
    Browse the repository at this point in the history
  8. Merge Vnode with the hyperscript module

    Also, rename it `m` to make dev stack traces a little more readable, and remove a useless layer of indirection.
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    ccea9a1 View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    dae2208 View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    3668dc7 View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    03fd640 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    eb0031c View commit details
    Browse the repository at this point in the history
  13. Make the event dictionary a proper class

    This makes that class fully monomorphic and also a bit safer.
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    b04519d View commit details
    Browse the repository at this point in the history
  14. Configuration menu
    Copy the full SHA
    8fbc46a View commit details
    Browse the repository at this point in the history
  15. Drop stale recycling tests

    That's not been there for years
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    1418bd3 View commit details
    Browse the repository at this point in the history
  16. Add m.tracked utility for tracking delayed removals

    The long comment at the top of it explains the motivation.
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    13c2e63 View commit details
    Browse the repository at this point in the history
  17. Configuration menu
    Copy the full SHA
    cd20a00 View commit details
    Browse the repository at this point in the history
  18. Drop onbeforeremove

    It's now been made redundant with `m.tracked`.
    dead-claudia committed Oct 3, 2024
    Configuration menu
    Copy the full SHA
    454f8e7 View commit details
    Browse the repository at this point in the history

Commits on Oct 4, 2024

  1. Configuration menu
    Copy the full SHA
    60de2e1 View commit details
    Browse the repository at this point in the history
  2. Re-duplicate children

    Dropping a premature abstraction, and I have perf concerns.
    
    This new version should hopefully avoid needing arguments allocation
    dead-claudia committed Oct 4, 2024
    Configuration menu
    Copy the full SHA
    1efdb78 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    537f828 View commit details
    Browse the repository at this point in the history
  4. Revise a comment

    dead-claudia committed Oct 4, 2024
    Configuration menu
    Copy the full SHA
    9070429 View commit details
    Browse the repository at this point in the history
  5. Drop oninit, replace all remaining lifecycle methods with m.layout

    If you remember v0.2, you'll recognize the API here. Thing is, this tries to be a little more rigorous with it by making it a proper vnode instead of just a magic attribute.
    
    Also, as these are the last remaining magic attributes (and `m.route.link` just returns the needed attributes itself), `m.censor` is gone.
    dead-claudia committed Oct 4, 2024
    Configuration menu
    Copy the full SHA
    5c2bf31 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    2942ea5 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    168b403 View commit details
    Browse the repository at this point in the history
  8. Migrate components to simple functions and closures

    Part of this meant moving children to an attribute property. I've also added a translation layer of sorts so one can pass them through to DOM vnodes and them "just work", even though the internal structure separates attributes and children.
    
    All in all, this should hopefully result in a lot less memory usage and some faster app load times.
    dead-claudia committed Oct 4, 2024
    Configuration menu
    Copy the full SHA
    b168f74 View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    d652f98 View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    bd09d8a View commit details
    Browse the repository at this point in the history

Commits on Oct 5, 2024

  1. Improve perf tests

    They weren't actually testing the update flow, only reliably the create flow.
    
    Also, they weren't testing `m.mount`, or `m.redraw` in their totality, which is honestly a very important thing to test.
    dead-claudia committed Oct 5, 2024
    Configuration menu
    Copy the full SHA
    933d4b5 View commit details
    Browse the repository at this point in the history
  2. Simplify the keyed diff fuzzer

    It shouldn't be testing particular implementation details, just that it works. Also, this one's more likely to exhaustively hit every possibility.
    dead-claudia committed Oct 5, 2024
    Configuration menu
    Copy the full SHA
    d7d8bef View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    67a30f4 View commit details
    Browse the repository at this point in the history
  4. Split code + tests, move source into dedicated directory

    Aims to ease discoverability. Plus, it's a bit easier to navigate.
    dead-claudia committed Oct 5, 2024
    Configuration menu
    Copy the full SHA
    84b0950 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    49ec364 View commit details
    Browse the repository at this point in the history

Commits on Oct 6, 2024

  1. Knock out all the intermediate closures, do a better job cleaning up,…

    … revise a few more things
    dead-claudia committed Oct 6, 2024
    Configuration menu
    Copy the full SHA
    55a8071 View commit details
    Browse the repository at this point in the history
  2. Try to get a better profile view

    Didn't fully think through that experiment of file loading - it doesn't also load Mithril, among other things.
    
    Also, remove some redundant conditionals in `src/core.js`.
    dead-claudia committed Oct 6, 2024
    Configuration menu
    Copy the full SHA
    c0821cb View commit details
    Browse the repository at this point in the history

Commits on Oct 11, 2024

  1. Improve bundle size, move to type masks to boost performance

    - `function foo(...) {...}` to `var foo = (...) => {...}` saved a fair bit of space. I also replaced other ES5 `function` functions with arrow functions where possible.
    - I inlined several functions. Turns out Terser wasn't inlining them properly (they were getting nonsensically inlined as IIFEs), and it was causing performance to suffer.
    - I dropped the `contenteditable` code, since that was only needed to handle the since-dropped `m.trust`.
    - I switched from tag names to type masks. This enabled several optimizations.
        - Size: I switched from a `switch` to function tables for create and update. Now, it just hinges on how well the CPU predicts it, and modern desktop CPUs very much can chase such multi-level indirect branches.
        - Size: I could blend single-key diffs with element and component tag name diffs, for better performance.
        - Performance: By using an expando bit, I've avoided needing to read the current namespace in some pretty hot loops, including in `setAttr`.
        - Performance: In `setAttr` and other places, I've merged as many as 4 tag comparisons to a single bit comparison.
    - I truncated the vnode properties to single letters. This resulted in a moderate savings.
    - I moved `redraw` to a return value of `m.mount` and also passed it via a context value to components so they can deal with non-global redraws.
    - I re-split `m.layout`.
    
    I also swapped out the benchmark library for something I rolled myself, and used that to set up the benchmarks. Benchmark.js isn't maintained anymore, its built-in output wasn't all that great, and it was forcing me to use globals where I otherwise didn't really need to, so I decided to roll some statistics stuff myself and make something simple. And while I was at it, I simplified the benchmark code by a lot.
    
    I also ripped out the select/option Chrome bug workaround - it doesn't seem to replicate anymore. Removing that brought a slight boost to attribute setting performance and enabled me to factor that code out to something a lot simpler.
    
    Try this page for example:
    
    ```html
    <!doctype html>
    <select>
      <option value="foo">Foo</option>
      <option value="bar">Bar</option>
      <option value="baz">Baz</option>
    </select>
    <script>
    var select = document.querySelector("select")
    
    console.log("s", select.selectedIndex, select.value)
    select.onchange = select.onclick = select.onblur = () => {
      console.log("c", select.selectedIndex, select.value)
    }
    
    var second = select.children[1]
    setInterval(() => {
      console.log("i", select.selectedIndex, select.value)
      second.value = "bar"
      console.log("i", select.selectedIndex, select.value)
    }, 5000)
    </script>
    ```
    dead-claudia committed Oct 11, 2024
    Configuration menu
    Copy the full SHA
    210d997 View commit details
    Browse the repository at this point in the history
  2. Switch from m.layout signal out m.remove, merge create/update cal…

    …lbacks
    
    Also re-added the `vnode === old` optimization, out of necessity for other utilities (there's a long code comment explaining why).
    
    Before this `m.layout` change, code would've looked like this:
    
    ```js
    // For libraries that bind state to the element itself
    function ThirdParty(attrs, old) {
      return m("div", m.layout((elem, signal) => {
        // Do DOM initialization
        Library.initialize(elem)
        // Schedule DOM cleanup
        signal.onabort = () => Library.dispose(elem)
      }))
    }
    
    // For libraries that return an instance
    function ThirdParty() {
      return m("div", m.layout((elem, signal) => {
        // Do DOM initialization
        let instance = new Library(elem)
        // Schedule DOM cleanup
        signal.onabort = () => instance.dispose()
      }))
    }
    ```
    
    The problem with this is it makes logic that only needs to care about removal a lot more complicated than it otherwise needs to be. (See `src/std/init.js` for a concrete example of this, and how this change simplifies those use cases a lot.) It also requires not only an extra closure that necessarily has to lay around until removal, but an entire `AbortController`, so this change ultimately saves a little over 200 bytes per layout/remove pair. (If you have a lot of such elements, this could be noticeable.)
    
    After this change, third-party integration code (the other main motivator for `m.layout` in the first place) would look something like this:
    
    ```js
    // For libraries that bind state to the element itself
    function ThirdParty(attrs, old) {
      return m("div", [
        // Do DOM initialization
        !old && m.layout((elem) => Library.initialize(elem)),
        // Schedule DOM cleanup
        m.remove((elem) => Library.dispose(elem)),
      ])
    }
    
    // For libraries that return an instance
    function ThirdParty() {
      let instance
      return (attrs, old) => m("div", [
        // Do DOM initialization
        !old && m.layout((elem) => instance = new Library(elem)),
        // Schedule DOM cleanup
        m.remove(() => instance.dispose()),
      ])
    }
    ```
    
    It was already possible to initialize an element outside of its scope by saving a reference to it:
    
    ```js
    function ThirdParty(attrs, old) {
      let label, root
      return [
        label = m("label", "Some text"),
        root = m("div.library"),
        m.layout((elem, signal) => {
          let instance = new Library(root.d, label.d)
          signal.onabort = () => instance.dispose()
        }),
      ]
    }
    ```
    
    This change makes that a little cleaner to wire up:
    
    ```js
    function ThirdParty() {
      let instance
      return (attrs, old) => {
        let label, root
        return [
          label = m("label", "Some text"),
          root = m("div.library"),
          !old && m.layout(() => instance = new Library(root.d, label.d)),
          m.remove(() => instance.dispose()),
        ]
      }
    }
    ```
    
    It also fits in a JSX world a little more nicely, but this wasn't something I was specifically seeking out:
    
    ```jsx
    // Old unified
    function ThirdParty() {
      return <div>
        {m.layout((elem, signal) => {
          let instance = new Library(elem)
          signal.onabort = () => instance.dispose()
        })}
      </div>
    }
    
    // Old split
    function ThirdParty(attrs, old) {
      let label, root
      return <>
        {label = <label>Some text</label>}
        {root = <div class="library" />}
        {m.layout((elem, signal) => {
          let instance = new Library(root.d, label.d)
          signal.onabort = () => instance.dispose()
        })}
      </>
    }
    
    // New unified
    function ThirdParty() {
      let instance
      return (attrs, old) => <div>
        {!old && m.layout((elem) => instance = new Library(elem))}
        {m.remove(() => instance.dispose())}
      </div>
    }
    
    // New split
    function ThirdParty() {
      let instance
      return (attrs, old) => {
        let label, root
        return <>
          {label = <label>Some text</label>}
          {root = <div class="library" />}
          {!old && m.layout(() => instance = new Library(root.d, label.d))}
          {m.remove(() => instance.dispose())}
        </>
      }
    }
    ```
    dead-claudia committed Oct 11, 2024
    Configuration menu
    Copy the full SHA
    044d1b8 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    8ddc288 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    21085ce View commit details
    Browse the repository at this point in the history
  5. Optimize stream, remove deprecated bit, simplify combine

    - Did some baseline optimization to it to reduce overhead and memory requirements. Won't be too much of a deal with smaller apps, but users using a lot of streams will appreciate the reduced overhead.
    - Removed the runtime-deprecated `Stream.HALT`.
    - Dropped the source list from `Stream.combine` callbacks' operands. It's almost always available in context anyways.
    dead-claudia committed Oct 11, 2024
    Configuration menu
    Copy the full SHA
    beaad3b View commit details
    Browse the repository at this point in the history
  6. Move redraw to an options bag

    This prepares for future possible render flags, like a "remove on error" flag that might get exposed in the future to enable userland error boundaries.
    dead-claudia committed Oct 11, 2024
    Configuration menu
    Copy the full SHA
    84472c4 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    70cc05b View commit details
    Browse the repository at this point in the history

Commits on Oct 12, 2024

  1. Configuration menu
    Copy the full SHA
    1cf9de3 View commit details
    Browse the repository at this point in the history
  2. Add bi-edge debouncing + throttling rate limiters

    Proper debouncing and throttling is easy to screw up, and the usual implementations that invoke a provided callback don't compose well. Instead, this provides functions that return promises you can filter on. This is far more composable and far easier to use.
    
    Also, the thing people usually do in a pinch, leading edge throttling, is usually the wrong thing to do. For example, if you're implementing an interactive search, you want the first to go immediately, but still incrementally update while the user is typing.
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    455765a View commit details
    Browse the repository at this point in the history
  3. Stub out error handling

    Also made some small (but needed) changes to the entry points and minified scripts.
    
    No specific tests for the error handling yet aside from the existing error-related tests that needed to change. But here's the going idea: error boundaries can be done in userland. Users would do something like this:
    
    ```js
    function slurpContext(context) {
        const chain = []
        while (context !== null && context !== Object.prototype) {
            chain.push(context)
            context = Object.getPrototypeOf(context)
        }
        return chain.reduceRight((a, b) => Object.defineProperties(a, Object.getOwnPropertyDescriptors(b)), {})
    }
    
    function ErrorBoundary(attrs, _, context) {
        return m("div.boundary", [
            m.layout((dom) => {
                try {
                    m.render(dom, m.set(slurpContext(context), attrs.view()), {
                        render: context.render,
                        removeOnThrow: true,
                    })
                } catch (e) {
                    attrs.onerror(e)
                }
            }),
            m.remove((dom) => m.render(dom, null)),
        ])
    }
    ```
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    118d748 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    4137f97 View commit details
    Browse the repository at this point in the history
  5. Add ops per sec counter

    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    313d004 View commit details
    Browse the repository at this point in the history
  6. Optimize error handling

    `finally` is apparently really slow. This improved benchmarks by about 3-4x, bringing them back to roughly what they were when I first cut the branch.
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    726e79f View commit details
    Browse the repository at this point in the history
  7. Ensure is is always set in custom elements

    This matches HTML more closely, and makes for a much better experience with custom elements.
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    2a60973 View commit details
    Browse the repository at this point in the history
  8. Normalize the render vnode input to a single unitary vnode, not an array

    It's more predictable that way, and I expect this to break approximately nobody. (If anything, it's likely to *unbreak* some users, as they may have been assuming this to have been the case from the beginning.)
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    f48beca View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    b889448 View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    3b7788b View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    95897a3 View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    966d1c0 View commit details
    Browse the repository at this point in the history
  13. Restore current size

    Some point along the way, this got erroneously changed and saved.
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    30e5ed1 View commit details
    Browse the repository at this point in the history
  14. Configuration menu
    Copy the full SHA
    86b3c31 View commit details
    Browse the repository at this point in the history
  15. Stop displaying size in the README

    It's going to unnecessarily complicate the release process, especially now that artifacts aren't saved to the repo anymore.
    dead-claudia committed Oct 12, 2024
    Configuration menu
    Copy the full SHA
    2872ca2 View commit details
    Browse the repository at this point in the history
  16. Configuration menu
    Copy the full SHA
    9099bcc View commit details
    Browse the repository at this point in the history

Commits on Oct 20, 2024

  1. Unrestrict a bunch of actually valid syntax

    I clearly didn't check this bit properly
    dead-claudia committed Oct 20, 2024
    Configuration menu
    Copy the full SHA
    1fb5104 View commit details
    Browse the repository at this point in the history
  2. Add m.match, optimize m.p a ton

    Did some math and some benchmarking and...it's actually a potential perf bottleneck for apps and so I had to optimize it a ton. Also rolled some new benchmarks for it.
    dead-claudia committed Oct 20, 2024
    Configuration menu
    Copy the full SHA
    c5c4b2f View commit details
    Browse the repository at this point in the history
  3. Remove some useless Object.assigns

    Within the hyperscript side, it's a significant (roughly 10%) perf boost.
    dead-claudia committed Oct 20, 2024
    Configuration menu
    Copy the full SHA
    fa39b98 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    310a32b View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    b33349a View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    3da7a1d View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    01fc41e View commit details
    Browse the repository at this point in the history

Commits on Oct 21, 2024

  1. Improve benchmark more

    dead-claudia committed Oct 21, 2024
    Configuration menu
    Copy the full SHA
    9dd8d17 View commit details
    Browse the repository at this point in the history
  2. Boost m.p performance by a lot

    Turns out this was way more perf-sensitive than I initially thought. Also included a long comment to explain everything, as it's not immediately obvious just looking at it that it'd be perf-sensitive.
    dead-claudia committed Oct 21, 2024
    Configuration menu
    Copy the full SHA
    fee0cca View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    451aa18 View commit details
    Browse the repository at this point in the history

Commits on Oct 29, 2024

  1. Configuration menu
    Copy the full SHA
    36d4cb3 View commit details
    Browse the repository at this point in the history

Commits on Oct 30, 2024

  1. Address some feedback around naming and (indirectly) m.key, optimiz…

    …e `m.use`
    
    `m.use` is specially designed to be used a fair amount, and simulating it is relatively slow, so it's worth making a built-in.
    
    `m.key` -> `m.keyed` provides for a simpler interface, one that you don't have to type `key` out explicitly for anymore. (Most frameworks require you to explicitly add a "key" attribute, while this approaches it more like a glorified `Map`.)
    dead-claudia committed Oct 30, 2024
    Configuration menu
    Copy the full SHA
    2e75897 View commit details
    Browse the repository at this point in the history
  2. Move context to this argument

    It's very common to want context and not care about attributes. What's *not* common is wanting the old attributes and not the new. So that's what this optimizes for.
    dead-claudia committed Oct 30, 2024
    Configuration menu
    Copy the full SHA
    5018ad0 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    5d79b07 View commit details
    Browse the repository at this point in the history
  4. Further simplify routing

    dead-claudia committed Oct 30, 2024
    Configuration menu
    Copy the full SHA
    f99850e View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    0c99734 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    814261f View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    cd26097 View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    8cafcfe View commit details
    Browse the repository at this point in the history

Commits on Oct 31, 2024

  1. Configuration menu
    Copy the full SHA
    953665e View commit details
    Browse the repository at this point in the history
  2. Bring back m.request - it's too useful.

    It mostly delegates to `fetch`.
    
    Also, kill `m.withProgress` as that only existed because there was no `m.request`.
    dead-claudia committed Oct 31, 2024
    Configuration menu
    Copy the full SHA
    3220a25 View commit details
    Browse the repository at this point in the history