Skip to content

chore: update solid-db/solid-query to latest (@fehmer) - #8521

Merged
Miodec merged 7 commits into
masterfrom
feature/update-tsdb
Oct 27, 2026
Merged

Miodec merged 7 commits into
masterfrom
feature/update-tsdb

Conversation

@fehmer

@fehmer fehmer commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Summary

Updates the TanStack data + devtools packages in frontend to their latest versions:

Package From To Kind
@tanstack/solid-db 0.2.22 0.3.12 dep
@tanstack/query-db-collection 1.0.40 1.4.8 dep
@tanstack/solid-query 5.101.0 5.104.5 dep
@tanstack/solid-devtools 0.8.5 0.8.13 devDep
@tanstack/solid-query-devtools 5.101.0 5.104.5 devDep
frontend/src/ts/
├── collections/              # 8 query-backed collections: writes → await/void, isPersisted → when("settled"), id workaround removed
│   ├── results.ts            # + last-10 average live-query: empty single-result state ([] → undefined)
│   ├── tags.ts  presets.ts  connections.ts  inbox.ts
│   ├── ape-keys.ts  custom-themes.ts  result-filter-presets.ts
│   └── utils/misc.ts         # applyIdWorkaround deleted (TanStack/db#1524 fixed upstream)
├── ape/server-configuration.ts    # fetchQuery → queryClient.query()
├── router/routes.ts               # 9× prefetchQuery → query().catch(noop), ensureQueryData → query() + staleTime "static"
└── components/pages/
    ├── leaderboard/LeaderboardPage.tsx  # next-page prefetchQuery → query().catch(noop)
    └── profile/ProfileSearchPage.tsx    # fetchQuery → queryClient.query()

Breaking changes found and how they were handled

1. @tanstack/db 0.15.0 — setWindow on findOne queries (no code change, verified unused)

Breaking: a findOne keeps its compiled limit (1). An ordered findOne's setWindow can move the offset but now throws SetWindowFindOneLimitError for any other limit (before it silently made the findOne return N rows); an unordered findOne with a nonzero offset throws SetWindowRequiresOrderByError.

Our three findOne() usages (results.ts averages/daily-best) are aggregate projections and never call setWindow/getWindow — verified unused, no fix needed.

2. @tanstack/db 0.12.0 — removal of begin({ immediate }) (no code change, verified unused)

Breaking: the immediate option of the sync begin() API was removed; writes made while a mutation persists now queue behind it instead of applying at once.

The app never calls begin({ immediate }) — verified unused, no fix needed.

3. @tanstack/query-db-collection 1.4.0 — collection writes now reject promises instead of throwing synchronously (code change)

Breaking: validation errors from writeInsert, writeUpdate, writeDelete, writeUpsert and writeBatch now reject the returned promise; before they threw synchronously. The changelog's migration guidance: "Await the promise and catch the error."

Until 1.3.2 these writes returned a sync receipt, so all 31 call sites in the 8 collections were bare expressions. Since writes now return Promise<void>, they had to be handled or the repo's no-floating-promises lint rule (error severity) fails:

  • 24 calls inside async mutationFns → await (e.g. collections/tags.ts, results.ts, presets.ts, connections.ts, ape-keys.ts, custom-themes.ts, result-filter-presets.ts). This preserves the old semantics exactly: a write validation failure rejects the mutation (previously the sync throw already did, inside the async function) instead of becoming an unhandled rejection.
  • 7 calls inside sync onMutate / writeBatch callbacks → void (tags toggleTagActive/setTagActive/clearActiveTags, inbox.ts batch delete/read) — sync callbacks can't await; these are fire-and-forget, as before.
4. @tanstack/db 0.15.x / query-db-collection 1.3.5 — transaction settlement rework, isPersisted deprecated (code change)

The sync transaction API gained two moments (accepted vs. visible): commit() receipts and subset loads resolve at visibility, while handler-facing writes resolve at acceptance. As part of this, Transaction.isPersisted is deprecated — "Use when('settled') instead. This alias will be removed in the 1.0 RC." (when('settled') has the same resolve/reject semantics: resolves with the transaction on success, rejects with the original error on failure.)

All 26 await transaction.isPersisted.promise occurrences (public action wrappers in the 8 collections, e.g. addCustomTheme, insertApeKey, acceptConnection, updateResultTags) → await transaction.when("settled").

5. @tanstack/solid-db 0.2.46 — live-query result types include the empty single-result representation (code change)

Type-level breaking: conditional live-query result types were aligned with the disabled/empty reactive bindings, so a findOne() inside useLiveQuery now types its empty state as [] (empty array) in the union: { ...; wpm: number; acc: number } | []. Property access on the union (last10()?.wpm in AverageNotice.tsx) no longer type-checks (TS2339).

useUserAverage10LiveQuery (results.ts) now normalizes through a createMemo: [] (and undefined) → undefined, keeping the existing "no average" rendering path. This is the only consumer of a single-result live query.

6. @tanstack/query-core 5.102.0 — imperative QueryClient methods deprecated (code change)

Minor in 5.x (non-breaking: methods still work, removal is "next major version"), but the repo lints deprecations as errors, so these had to be migrated to the new API:

  • prefetchQuery → queryClient.query(options) — new query()/infiniteQuery() methods added in #10658. Unlike prefetchQuery (which never rejected), query() rejects on error, so fire-and-forget prefetches in router/routes.ts (9) and LeaderboardPage.tsx (1) now end in .catch(noop) to keep the old swallow-errors behavior.
  • fetchQuery → queryClient.query(options) (1:1, both reject on error): ape/server-configuration.ts sync, ProfileSearchPage.tsx username validation.
  • ensureQueryData → queryClient.query({ ...options, staleTime: "static" }) — the mapping recommended in the deprecation tag; staleTime: "static" ("never stale") is new in 5.102. Used in the friends route loader.
  • Docs: TanStack Query — QueryClient
7. @tanstack/solid-devtools 0.8.5 → 0.8.13 / core @tanstack/devtools 0.12.2 → 0.15.0 (no code change)

The adapter is patch-only (0.8.x); the movement is in the core @tanstack/devtools package it wraps. Relevant entries, checked against our usage in components/dev/TanstackDevtools.tsx (<TsDevTools plugins={[inline query plugin, hotkeysDevtoolsPlugin(), SignalsDevtoolsPlugin()]} config={{ defaultOpen: false }} />):

  • Plugin pane workspace (#492): panes can now be split/stacked/resized, up to 18 open (was 3). User-visible change; also, state.activePlugins in the devtools localStorage state is superseded by state.layout — existing state is migrated automatically on first read (unusable entries repaired, unknown ids dropped), so no app-side action needed.
  • Plugin lifecycle guarantees (same PR): a pane's mount node is never removed while the plugin is open (iframes/canvas keep living) and destroy fires exactly once on close — a fix for plugin authors, no API change.
  • use* → create* rename (#477): the only breaking tag in the range is @tanstack/devtools-ui's exported useTheme → createTheme (prevents React Compiler from transforming the Solid panel code). We don't import @tanstack/devtools-ui directly — no impact.
  • Docs: TanStack Devtools

Our plugin objects ({ id, name, render, defaultOpen }) satisfy the unchanged plugin interface — typecheck clean. @tanstack/solid-hotkeys-devtools@0.7.0 (unchanged) peers only on solid-js, so no coupling with the new core.

8. @tanstack/solid-query-devtools 5.101.0 → 5.104.5 (no code change)

Patch-only range — every release is a version alignment with @tanstack/query-devtools/@tanstack/solid-query (5.x stable, no API changes). SolidQueryDevtoolsPanel's client prop is unchanged. Docs: TanStack Query devtools

9. applyIdWorkaround workaround removed (code change)

collections/utils/misc.ts carried applyIdWorkaround — a temp workaround for TanStack/db#1524 (Solid rendering showed one item for all rows in a getKey: (it) => it._id collection with ordered live queries, fixed by copying _id onto an id property of every fetched row). That issue is closed and its fixes — solid-db#1598 (reconcile key), solid-db#1604 (row cloning in syncDataFromCollection), solid-db#1825 (preserve live result identity for custom-key rows, shipped in @tanstack/solid-db 0.2.46, see Solid live-query docs) — are all part of the updated 0.3.12.

Removed the helper and all 7 usages (the queryFn row-mapping in the custom-themes, connections, ape-keys, presets, results, result-filter-presets and tags collections). All consumers type rows via the zod schemas, which never declared id, so no code could depend on the injected property — typecheck confirms.

Entries checked and deliberately not actioned

  • query-db-collection 1.2.0: QueryClient-default placeholderData no longer materializes as collection rows, QueryClient-default initialData no longer seeds on-demand subset observers. Our QueryClient (queries/index.ts) sets neither globally — no impact.
  • query-db-collection 1.3.0: mutation-handler auto-refetch deprecated (warnOnce when a handler doesn't return { refetch: false }). Our collections register no onInsert/onUpdate/onDelete handlers (mutations run through createOptimisticAction + explicit write*), so the warning never fires. When handlers are ever added, the library wants an explicit { refetch: false } or manual await collection.utils.refetch().
  • @tanstack/solid-db 0.3.0 (minor): opt-in network-first initial rendering for persisted (SQLite) collections (initialRender: { strategy: "network-first" }, new persistedStatus/isPersistedReady flags). We use pure Query-backed collections with no persistence adapter — no impact.
  • @tanstack/solid-query 5.104.4: type-only re-exports switched to export type * — our named imports (incl. UseQueryResult) unaffected, typecheck clean. (Same export type * change landed in solid-query-devtools's query-devtools dep — devtools-only, no app code touched.)

Evidence

  • Before: draft — signed-in browser smoke test still owed, no runtime evidence for the write/settlement rework.
    After: smoke run on the dev server (3000/5005) as a signed-in test account:

    • Average notice (useUserAverage10LiveQuery): with ≥10 results it shows the real average (84 wpm 87% acc); switching the test language so the settings filter matches zero results, the empty single-result state ([]) renders "no average" via the new createMemo normalization, and switches back when the language returns — the only consumer of a single-result live query.
    • Tags, presets, custom themes, ape keys: create → rename → delete through the real UI for each. Every mutation settled with no error notification and no optimistic rollback; every _id-keyed list rendered each row with its own data. Renaming a custom theme re-sorted it to the top with both rows keeping their own name/colors — the one-item-for-all-rows regression behind the removed applyIdWorkaround (solid-db rendering issues when not using key named id TanStack/db#1524) is not present.
    • Inbox/connections: friends page renders with the (empty) connections list; the account has no pending requests, so the writeBatch read/delete path went unexercised.
    • queryClient.query(): profile search rejects an unknown username ("Unknown user", submit disabled) and accepts an existing one (submit enabled); the about page rendered all four prefetched sections; the leaderboard rendered its table.
    • Devtools panel: skipped — core package is patch-only alignment, no app code touched.

    Observed while smoke-testing (filed as bugs, not blockers): rename modals (custom theme, ape key) apply the change but the modal takes several seconds to close — when("settled") settles later than isPersisted did for query-backed collections; and a SimpleModal whose boolean input is never touched reports invalid until the checkbox is toggled once (form layer, untouched by this PR).

  • Automated:

    • pnpm oxlint --type-aware --type-check — exit 0, 0 errors
    • pnpm vitest run — 84 files, 1622/1622 tests pass
    • pnpm vite build — success (catches bundler-level issues from the export type * change and the new db-ivm dep)

The original draft note — a signed-in browser smoke test is still owed: tag/preset/custom-theme create-edit-delete, inbox read/delete, the average notice on the test page (the transaction-acceptance and write-validation rework in 1.3.x/1.4.x is runtime behavior the test suite doesn't exercise), reordering a _id-keyed list — e.g. rename a custom theme so it sorts to the top and check every row shows its own data (the regression behind the removed #1524 workaround) — and a look at the redesigned devtools plugins panel (pane workspace layout, plus the localStorage state migration for anyone who has customized open panes) — is now resolved by the smoke run above; the observed issues remain as filed bugs, not blockers.

Merge Danger

Door: two-way

Dependency bump plus mechanical API migration; reverting the PR restores the prior versions and behavior. No schema, storage, or API contract changes — a rollback costs one revert.

Blast Radius: app-wide

Every signed-in data flow runs through the changed code: the 8 query-backed collections (tags, results, presets, connections, inbox, ape keys, custom themes, result-filter-presets) with their new write/settlement semantics, and every route's background data fetch on the new queryClient.query() API. A divergence in write timing or live-query reconciliation would surface as slow-closing modals, rolled-back mutations, or duplicated list rows across the whole signed-in experience.

@monkeytypegeorge monkeytypegeorge added frontend User interface or web stuff api A change to the Application Programming Interface (API) labels Oct 26, 2026
@socket-security

socket-security Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​tanstack/​solid-query-devtools@​5.101.0 ⏵ 5.104.598 +1610067 -398100
Updated@​tanstack/​query-db-collection@​1.0.40 ⏵ 1.4.810010075 +298 +1100
Updated@​tanstack/​solid-db@​0.2.22 ⏵ 0.3.1284 +710077 +798100
Updated@​tanstack/​solid-devtools@​0.8.5 ⏵ 0.8.1397 +2010090 +597100
Updated@​tanstack/​solid-query@​5.101.0 ⏵ 5.104.5100 +210090 +398100

View full report

@fehmer fehmer changed the title chore: update @tanstack/solid-db, query-db-collection, solid-query and devtools to latest chore: update solid-db/solid-query to latest (@fehmer) Oct 26, 2026
@fehmer
fehmer marked this pull request as ready for review October 26, 2026 22:46
@github-actions github-actions Bot added the waiting for review Pull requests that require a review before continuing label Oct 26, 2026
@Miodec
Miodec merged commit d059494 into master Oct 27, 2026
15 checks passed
@Miodec
Miodec deleted the feature/update-tsdb branch October 27, 2026 09:19
@github-actions github-actions Bot removed the waiting for review Pull requests that require a review before continuing label Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api A change to the Application Programming Interface (API) frontend User interface or web stuff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants