Commit graph

182 commits

Author SHA1 Message Date
Horizontal42
460a12e695
improve date order detection tests with real Intl calls 2026-08-09 15:57:15 +03:00
Horizontal42
dcac3ae425
add registry tests 2026-08-09 15:57:13 +03:00
Horizontal42
6716f1b6da
add coverage for storage utility functions 2026-08-09 15:57:10 +03:00
Horizontal42
c958f30662 Revert "rotate updater signing pubkey"
This reverts commit c0bea836bc.
2026-07-29 15:54:41 +03:00
Horizontal42
c0bea836bc rotate updater signing pubkey 2026-07-29 15:46:13 +03:00
Horizontal42
40cdf22461 sync Cargo.lock with 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
8bfe65a1c4 update tauri.conf version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
2798bfcafa bump cargo version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
c63ec63e2f bump version to 1.2.3 2026-07-29 15:35:03 +03:00
Horizontal42
08876adae8 bump postcss to patch path-traversal advisory (GHSA-r28c-9q8g-f849) 2026-07-29 15:34:54 +03:00
Horizontal42
b0f6e9e89b run extensions in a quickjs wasm sandbox
replaces new Function() in the main window; per-script and per-call
interrupt deadlines, memory and stack limits, graceful skip if the
wasm module fails to load. csp script-src drops 'unsafe-eval' for
'wasm-unsafe-eval'.
2026-07-29 14:38:28 +03:00
Horizontal42
5c4f2db2d2 fix clippy collapsible_match warning in safe_name 2026-07-29 14:14:49 +03:00
Horizontal42
a6fc5b90f3 harden safe_name path validation 2026-07-29 14:14:49 +03:00
Horizontal42
1a12d75ec6 add regression test for sequence error recovery 2026-07-29 14:14:49 +03:00
Horizontal42
ca6fa6d381 cache findSheetByTitle lookups 2026-07-29 14:14:49 +03:00
Horizontal42
c89242b626 debounce variable highlight scanning in editor 2026-07-29 14:14:49 +03:00
Horizontal42
5ccb46b01c cache sheet results for numeric search 2026-07-29 14:14:49 +03:00
Horizontal42
fd93b00bf5 extract drag-and-drop logic from renderDocList 2026-07-29 14:14:49 +03:00
Horizontal42
8ef2f8b445 extract UI bindings out of initUI 2026-07-29 14:14:49 +03:00
Horizontal42
42f3611dca split evalBin into percent/quantity arithmetic helpers 2026-07-29 14:14:49 +03:00
Horizontal42
d66cad2dcf avoid full split() in titleFromContent 2026-07-29 14:14:48 +03:00
Horizontal42
439eec2795 add tokenizer tests 2026-07-29 14:14:48 +03:00
Horizontal42
6292bbf103 add formatter tests for formatNumber/formatValue 2026-07-29 14:14:48 +03:00
Horizontal42
adea6870fd add parser tests for parseLine 2026-07-29 14:14:48 +03:00
Horizontal42
e70c69df52 add lexer tests for lexLine 2026-07-29 14:14:48 +03:00
Horizontal42
6a88767edf extract evalAgg into an AGG_FUNCS lookup table 2026-07-29 14:14:48 +03:00
Horizontal42
f5b1fc038b sync Cargo.lock with 1.2.2 2026-07-16 03:41:10 +03:00
Horizontal42
ca19042af0 update tauri.conf version to 1.2.2 2026-07-16 02:52:03 +03:00
Horizontal42
539fb6eff5 bump cargo version to 1.2.2 2026-07-16 02:49:05 +03:00
Horizontal42
c7c87257bd bump version to 1.2.2 2026-07-16 02:44:47 +03:00
Horizontal42
68d7492dba fix modal backdrop-click guard, re-entrancy, and monotonic clock
- Track window focus via performance.now() instead of suppressing all backdrop
  clicks for 300ms after the modal appears. This fixes over-suppression (Ctrl+W
  close-sheet now dismisses on immediate click) while keeping protection for
  genuine stray refocus-clicks (native dialog closing, tray window refocus).
- Serialize concurrent askModal calls via a promise chain so a second call
  queues instead of clobbering the first's handlers (was: hang on concurrent
  modal show).
- Use monotonic performance.now() throughout to avoid clock-jump edge cases
  with Date.now().
2026-07-16 02:42:14 +03:00
Horizontal42
087ee44f12 ignore backdrop click within 300ms of showing a modal
a click that focuses the window lands on the modal backdrop too, so
the update-available prompt after an unattended auto-check could get
dismissed by the very click that brought the window to front, before
it was ever seen
2026-07-16 01:14:52 +03:00
Horizontal42
6f6c3b439a bump version to 1.2.1 2026-07-08 15:58:14 +03:00
Horizontal42
c1a7254fdf fix arbitrary file write via write_text_file/write_image_file
Both Tauri commands took a raw path string straight from the frontend
and wrote to it with no validation — any code able to call invoke()
(a compromised or malicious extension script, which run with full page
privileges) could write to any path the OS user has access to, not just
one chosen through the save dialog. Move the save-file dialog into the
Rust command itself so the only path ever used is one the native dialog
returned; the frontend now only sends the content to save.
2026-07-08 15:50:13 +03:00
Horizontal42
f2deaa1b94 split lexLine's number/date matching into named helpers
lexLine had grown into one long function trying dates, hex/bin/oct,
grouped numbers, decimals and xrefs inline. Extracted each into a
tryLex* helper with the same fallback order, so the driving loop
reads as a priority list instead of nested ifs.
2026-07-08 15:48:40 +03:00
Horizontal42
f634b1858e fetch market data symbols concurrently instead of sequentially
fetch_market_data hit Yahoo's v8 chart endpoint once per symbol in a
sequential loop — with 9 symbols that's 9 round trips end to end.
join_all fires them together.
2026-07-08 15:47:31 +03:00
Horizontal42
a674c66d63 split boot() into initSettings/initDataAndEngine/initUI
Boot had grown into one long function covering settings load, engine
and workspace setup, and all the UI wiring. Split along those natural
phase boundaries; boot() itself is now just the three awaits in order.
2026-07-08 15:46:22 +03:00
Horizontal42
216a18821c split bindSettingsUI into one function per settings tab
The settings panel grew into tabs (General/Format/Data/Updates) but
the binding code was still one 170-line function. Split it to match:
bindFormattingSettings, bindHotkeySettings, bindBehaviorSettings,
bindDataDirSettings, bindSettingsNavigation.
2026-07-08 15:45:32 +03:00
Horizontal42
eab3dbae2f add tests for storage.ts
Covers isTauri, and loadSettings/saveSettings across both the Tauri
invoke path and the localStorage fallback, including corrupt-data
and thrown-error recovery.
2026-07-08 15:44:38 +03:00
Horizontal42
afe2693acf add tests for updater.ts
Covers the three checkForUpdate outcomes (null/error/available) and
the install() flow (downloadAndInstall then relaunch).
2026-07-08 15:43:52 +03:00
Horizontal42
34fa14ffc6 add tests for extensions.ts
Covers makeApi's delegation to the engine and runExtensions' per-script
error isolation (one bad extension shouldn't stop the rest from loading).
2026-07-08 15:43:03 +03:00
Horizontal42
984275711a gitignore AI-agent scratch files and the local cargo config dir
.jules/ and test_perf.ts kept showing up in Jules/Bolt-generated PRs
(agent notes and a throwaway benchmark script) — ignore them so they
can't land on main by accident. Also picked up the pending
src-tauri/.cargo/ ignore that was sitting uncommitted.
2026-07-08 14:19:12 +03:00
Horizontal42
47beea4652 avoid rebuilding decoration fields on every editor transaction
highlightField and varHighlightField rebuilt from scratch on every
CodeMirror transaction, including ones that touch neither the doc nor
the selection (e.g. the setResults effect firing after evaluation).
varHighlightField now only rebuilds when the doc or selection actually
changed; highlightField remaps existing decorations through doc edits
and only does a full rebuild when new results arrive.
2026-07-08 14:15:04 +03:00
Horizontal42
00bd1248e1 use a Set for the cross-sheet resolving stack
resolving was an array checked with .includes() on every xref lookup
during resolution — an O(n) membership test where only membership
ever mattered, not order. Set makes it O(1).
2026-07-08 14:12:38 +03:00
Horizontal42
80bb94674d cache referencedTitles per sheet in invalidate()'s fixed-point loop
invalidate() re-scans every non-dirty sheet's text with a regex on
every pass of its while loop, even though the text hasn't changed
between passes — cache the parsed refs per sheet id, keyed by text
identity, so repeated passes reuse the same result.
2026-07-08 14:10:36 +03:00
Horizontal42
e774546818 batch doc-list DOM inserts through a DocumentFragment
renderDocList appended each sheet's element straight to the live list,
forcing a reflow per item; build them in a fragment and append once.
2026-07-08 14:09:26 +03:00
Horizontal42
fc3153a7eb add tests for i18n
Covers setLang/t language switching and fallback behavior, and
detectLang's navigator.language parsing — previously untested.
2026-07-08 14:06:47 +03:00
Horizontal42
40b5b94102 fetch historical rates for multiple dates concurrently
fetchNeededHistoricalRates awaited each date's fetch sequentially even
though they're independent requests — a sheet referencing several
historical dates paid for that latency serially instead of in parallel.
2026-07-08 14:06:00 +03:00
Horizontal42
697f1f0e3d add aria-labels to icon-only buttons and inputs
Toolbar buttons (☰ 🔍 ⚙ ✕ ─ ⤓ +) and the untitled doc-title/search
inputs had no accessible name beyond a title tooltip, which screen
readers don't reliably announce.
2026-07-08 14:03:32 +03:00
Horizontal42
d71ad92422 add tests for datetime.ts
Covers detectDateOrder, resolveZone, addToDate and isCalendarUnit —
none of it had direct unit coverage before, only indirectly through
the engine's date-arithmetic tests.
2026-07-08 14:01:34 +03:00