Answer the review (Claude Fable 5.1); estilo 846b397
- estilo's busy.js now holds only a submit with a spinner showing (rastrillo discussion 51), so script submits no longer stall. - Scripts that submit on the visitor's behalf pass the form's button, so it shows the spinner (Calendar quick-add, Sheets file drop). - Slides' presenter Next/Previous/Blackout opt out (data-busy="false"): a live talk wants those instant. Memoria's old vendoring tool no longer writes rastrillo.js, which would bring the old busy rule back.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 files changed,
+16
−6
go.mod+1 −1go.sum+2 −0internal/memoria/static/busy.js+7 −2tools/vendorassets/main.go+6 −3
CI passed — run details
CI log
=== vet === go vet ./... go: downloading amadan.net/oficina/estilo.git v0.0.0-20260929165053-846b39772f3c === fmt === === test === go test ./... ? amadan.net/oficina/memoria/cmd/memoria [no test files] ok amadan.net/oficina/memoria/internal/memoria 3.393s ok amadan.net/oficina/memoria/internal/memoria/chunk (cached) ok amadan.net/oficina/memoria/internal/memoria/fact (cached) ? amadan.net/oficina/memoria/internal/memoria/icons [no test files] ok amadan.net/oficina/memoria/internal/memoria/index (cached) ok amadan.net/oficina/memoria/internal/memoria/notion (cached) ok amadan.net/oficina/memoria/internal/memoria/provider (cached) ok amadan.net/oficina/memoria/internal/memoria/query (cached) ok amadan.net/oficina/memoria/internal/memoria/seal (cached) ok amadan.net/oficina/memoria/internal/memoria/sibling (cached) ok amadan.net/oficina/memoria/internal/memoriatest 1.656s ? amadan.net/oficina/memoria/scripts/writeestilo [no test files] ? amadan.net/oficina/memoria/tools/bench [no test files] ? amadan.net/oficina/memoria/tools/drive [no test files] ? amadan.net/oficina/memoria/tools/seed [no test files] ? amadan.net/oficina/memoria/tools/vendorassets [no test files] === migration-check === go run github.com/carlosframework/rastrillo/cmd/rastrillo migration check rastrillo migration check: models and migrations agree
diff --git a/go.mod b/go.mod| index 965f625..6998b6e 100644 |
| --- a/go.mod |
| +++ b/go.mod |
| @@ -5,7 +5,7 @@ go 1.26 |
| toolchain go1.26.5 |
| require ( |
| - amadan.net/oficina/estilo.git v0.0.0-20260929095838-0994675f496e |
| + amadan.net/oficina/estilo.git v0.0.0-20260929165053-846b39772f3c |
| amadan.net/oficina/home/connect v0.0.0-20260910000424-5b8d8410775f |
| amadan.net/oficina/home/handoff v0.0.0-20260908102137-481d2d57f489 |
| amadan.net/oficina/suite v0.0.0-20260905215529-60b01a8a0d6d |
diff --git a/go.sum b/go.sum| index 0d46593..df349a7 100644 |
| --- a/go.sum |
| +++ b/go.sum |
| @@ -6,6 +6,8 @@ amadan.net/oficina/estilo.git v0.0.0-20260929095046-d0664ee49914 h1:V0AyxXYCxqGZ |
| amadan.net/oficina/estilo.git v0.0.0-20260929095046-d0664ee49914/go.mod h1:4u0jNBtIdMLOsJyrScfqoEuYDJF7BBM3qM9YWbzt6aw= |
| amadan.net/oficina/estilo.git v0.0.0-20260929095838-0994675f496e h1:LTSmIWUS8RjPb6m94Ynf7moyFYeBXr08rdOr3nmNqvg= |
| amadan.net/oficina/estilo.git v0.0.0-20260929095838-0994675f496e/go.mod h1:4u0jNBtIdMLOsJyrScfqoEuYDJF7BBM3qM9YWbzt6aw= |
| +amadan.net/oficina/estilo.git v0.0.0-20260929165053-846b39772f3c h1:YYocIz3r3b4oIA0K/58JkSsmyTOCzMT/2GaW/MFbbPo= |
| +amadan.net/oficina/estilo.git v0.0.0-20260929165053-846b39772f3c/go.mod h1:4u0jNBtIdMLOsJyrScfqoEuYDJF7BBM3qM9YWbzt6aw= |
| amadan.net/oficina/home/connect v0.0.0-20260910000424-5b8d8410775f h1:lkw3tjzHfZxe74pNfo+tGDz4mkZLg+D6R+FTkmsym6M= |
| amadan.net/oficina/home/connect v0.0.0-20260910000424-5b8d8410775f/go.mod h1:YroavXe43Wietec+po8mtSk4a9Bir2h31Q3iAf4MWxI= |
| amadan.net/oficina/home/handoff v0.0.0-20260908102137-481d2d57f489 h1:RPKtyry/71i06o8L+gjAaUyexbmG56kO1YPs601URAM= |
diff --git a/internal/memoria/static/busy.js b/internal/memoria/static/busy.js| index 5d0a9f8..550a843 100644 |
| --- a/internal/memoria/static/busy.js |
| +++ b/internal/memoria/static/busy.js |
| @@ -166,7 +166,7 @@ |
| // back); so does the guard's own refusal of a second submit. Only a |
| // submit nobody else stopped is held, and only if the busy rule armed |
| // it (aria-busy on the form: not opted out, not a dialog, not a new |
| - // window). |
| + // window) and a button is showing the spinner. |
| var held = new WeakSet(); // submit events this listener cancelled |
| var pending = new Map(); // form -> timer, for a hold still running |
| var releasing = null; // the form whose held submit is going now |
| @@ -175,9 +175,14 @@ |
| if (!form || form.tagName !== "FORM") return; |
| if (form === releasing) { releasing = null; return; } |
| if (e.defaultPrevented || form.getAttribute("aria-busy") !== "true") return; |
| + // Only a submit with a spinner to show is held: the hold is for the |
| + // spinner. A script's requestSubmit() with no submitter, or a button |
| + // that opted out, has nothing on screen to keep up, and holding it |
| + // would only be a silent 650ms stall. The form is still guarded. |
| + var btn = e.submitter || null; |
| + if (!btn || btn.getAttribute("aria-busy") !== "true") return; |
| e.preventDefault(); |
| held.add(e); |
| - var btn = e.submitter || null; |
| pending.set(form, setTimeout(function () { release(form, btn); }, HOLD_MS)); |
| }); |
diff --git a/tools/vendorassets/main.go b/tools/vendorassets/main.go| index 053590e..ca17873 100644 |
| --- a/tools/vendorassets/main.go |
| +++ b/tools/vendorassets/main.go |
| @@ -2,6 +2,10 @@ |
| // This is what `rastrillo doctor --fix` does; the CLI installed on this |
| // machine predates v0.22.0 and has no doctor, so we do it from the |
| // linked library instead — which is the same source the pin test reads. |
| +// |
| +// Not rastrillo.js: that file comes from estilo's busy package, via |
| +// scripts/writeestilo, without the old busy rule. The one in this library |
| +// still has it, and the two rules together cancel every submit. |
| package main |
| import ( |
| @@ -15,9 +19,8 @@ import ( |
| func main() { |
| dir := filepath.Join("internal", "memoria", "static") |
| for name, body := range map[string][]byte{ |
| - "tokens.css": ui.TokensCSS(), |
| - "rastrillo.js": ui.ShimJS(), |
| - "select.js": ui.SelectJS(), |
| + "tokens.css": ui.TokensCSS(), |
| + "select.js": ui.SelectJS(), |
| } { |
| if err := os.WriteFile(filepath.Join(dir, name), body, 0o644); err != nil { |
| log.Fatalf("write %s: %v", name, err) |