Skip to content

feat(kida): add latest for the value of the source that changed last - #231

Merged
dangreen merged 1 commit into
mainfrom
feat/kida-latest
Sep 3, 2026
Merged

feat(kida): add latest for the value of the source that changed last#231
dangreen merged 1 commit into
mainfrom
feat/kida-latest

Conversation

@dangreen

@dangreen dangreen commented Sep 3, 2026

Copy link
Copy Markdown
Member

What

latest(...sources) returns a signal carrying the value of whichever source changed most recently.

const $searchQuery = signal('')
const $searchParam = searchParam($searchParams, 'q', v => v ?? '')
const $search = latest($searchQuery, $searchParam)

Typing wins over the URL, navigation wins over what was typed. It is the missing half of previous from @nano_kit/store: that one looks back through a single source, this one picks the freshest across several. It lives in kida, so @nano_kit/store re-exports it too.

Contract

  • The last source wins on the first read, whatever its value, undefined included.
  • The last source also wins whenever several sources changed since the previous read. That covers writes inside one batch, sources sharing an upstream, and reads made without a subscription.
  • A change is a change of value: a write of an equal value is invisible, and so is a → b → a inside one batch.
  • The winner is kept, not recomputed. Losing the last subscriber purges the deps and leaves the node dirty, so the next read recomputes with nothing changed; a util that re-picked a winner there would flip its answer on every remount.
  • Every source is read on every run. An early exit on the first change would drop the subscriptions of the sources after it.

Tests

Seven cases in packages/kida/src/utils.spec.ts pin every rule above. They were checked against wrong implementations rather than only against a green run:

mutation caught by
drop the first-run branch should return the last source value on the first read when it is undefined
break after the first change five of seven, subscriptions are lost
re-pick the winner instead of keeping it should keep the value when nothing changed since the last read

Size

latest costs 60 B gzip and 52 B brotli in kida's All publics: 4989 → 5049 and 4604 → 4656. Both All publics entries are re-pinned in kida and in store, which mirrors them through the re-export. Signal and Popular set are untouched, the util is not in those sets.

Verification

kida unit tests green (87), oxlint and tsc --noEmit clean, test:size run sequentially across all 13 packages with no exceedances.

`latest($searchQuery, $searchParam)` merges several sources into one signal that carries whichever of them changed most recently, which is what a local cell paired with a read-only one needs: typing wins over the URL, navigation wins over what was typed. The pairing is deliberate with `previous` from `@nano_kit/store`: one looks back through a single source, the other picks the freshest across several.

The last source wins on the first read and whenever several sources changed since the previous read, so reading without a subscription and writing inside a `batch` both resolve by argument order. A change is a change of value, so a write of an equal value is invisible. The winner is kept rather than recomputed: losing the last subscriber purges the deps and forces the next read to recompute with nothing changed, and a util that re-picked there would flip its answer on every remount.
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.75%. Comparing base (b911d4c) to head (8dafa2a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #231   +/-   ##
=======================================
  Coverage   82.75%   82.75%           
=======================================
  Files          98       98           
  Lines        2465     2465           
  Branches      521      521           
=======================================
  Hits         2040     2040           
  Misses        315      315           
  Partials      110      110           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dangreen
dangreen merged commit 84efaed into main Sep 3, 2026
10 checks passed
@dangreen
dangreen deleted the feat/kida-latest branch September 3, 2026 15:02
@github-actions github-actions Bot mentioned this pull request Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant