oficina / sheets Public

feat: the grid, painting strings the server computed

Jspreadsheet CE 5.0.2 and jsuites 5.13.5, vendored with their licences
and a README carrying the exact commands to reproduce them. jsuites is
pinned to the newest 5.x rather than npm's latest: 6.x is out, and
jspreadsheet declares ^5.8.5, so taking latest would silently cross a
major it has never claimed to work with.

parseFormulas is off. Our engine computes and the client paints; a
client-side evaluator would disagree with the server on the first
SUM(1,2,"3") — the divergence the corpus already documents — and the
disagreement would look like a number in a cell either way.

Cell data holds display strings and the raw input lives in a side map,
so the grid shows 42 and the formula bar shows =6*7. Paints are
discarded by version, not by arrival: without that, optimistic painting
plus last-write-wins produces a visibly wrong grid under two editors,
which is the exact bug the optimism is meant to hide.

live.js closes the stream when the tab is hidden and opens a new one
when it returns, and closes explicitly on the server's "bye" — without
that, EventSource's own retry brings the browser straight back and the
server's idle timeout is decoration. Coming back refetches before
reopening, because the stream has no backlog.

The JS line cap guard arrives with them, and it found its own bug
first: it reused repo_test.go's skipDir, which skips any directory
named "vendor" — right for Go dependency trees, exactly wrong for our
vendored JavaScript. It walked past every file its exemption list named
and passed. TestEveryJSExemptionIsLive now asserts the walk reaches
each exemption, so an entry can never again be a comforting line that
exempts nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RN4HhHR4rHH3Fxh4LMds5
Paul Campbell pushed by paul@keymail.dev 26b1254f29a988a3ecfaa7cfdf9f69db9c4b492f parent 4b94b94
12 files changed, +18065 −4
  • internal/guardstest/jscap_test.go +133 −0
  • internal/sheets/handlers_sheets_test.go +54 −0
  • internal/sheets/static/grid.js +206 −0
  • internal/sheets/static/live.js +145 −0
  • internal/sheets/static/vendor/LICENSE.jspreadsheet +21 −0
  • internal/sheets/static/vendor/LICENSE.jsuites +21 −0
  • internal/sheets/static/vendor/README.md +58 −0
  • internal/sheets/static/vendor/jspreadsheet.css +716 −0
  • internal/sheets/static/vendor/jspreadsheet.js +18 −0
  • internal/sheets/static/vendor/jsuites.css +3068 −0
  • internal/sheets/static/vendor/jsuites.js +13602 −0
  • internal/sheets/templates/sheet.html +23 −4
internal/guardstest/jscap_test.go

Loading diff…

internal/sheets/handlers_sheets_test.go

Loading diff…

internal/sheets/static/grid.js

Loading diff…

internal/sheets/static/live.js

Loading diff…

internal/sheets/static/vendor/LICENSE.jspreadsheet

Loading diff…

internal/sheets/static/vendor/LICENSE.jsuites

Loading diff…

internal/sheets/static/vendor/README.md

Loading diff…

internal/sheets/static/vendor/jspreadsheet.css

Loading diff…

internal/sheets/static/vendor/jspreadsheet.js

Loading diff…

internal/sheets/static/vendor/jsuites.css

Loading diff…

internal/sheets/static/vendor/jsuites.js

Loading diff…

internal/sheets/templates/sheet.html

Loading diff…