swrly 0.2.0-dev.4
swrly: ^0.2.0-dev.4 copied to clipboard
Server-state cache for Flutter — dedupe, cache by query key, stale-while-revalidate. A TanStack Query for Flutter.
0.2.0-dev.4 #
- Example: rebuilt as a verification harness for all 0.2.0 features —
pagination with
keepPreviousData(dimmed previous page while loading), a "Fail next" retry demo, and a "make next create fail" toggle that shows the optimistic insert being rolled back automatically. - Tests: 100% line coverage on
lib/src(addedrefetch(),refetchOnResume, custom-keytoStringfallback, idle getters, singleton). - Docs: added
doc/VERIFICATION.md(status, remaining TODOs, how to verify the prerelease). README updated for the 0.2.0-dev feature set.
0.2.0-dev.3 #
- New:
keepPreviousData/placeholderData.QueryBuilder.keepPreviousDatakeeps rendering the previous key's data (flaggedstate.isPlaceholderData) while a new key loads, instead of flashing to a spinner — ideal for search / pagination.QueryBuilder.placeholderDatashows a static stand-in until the first real value arrives. Neither is cached or affects freshness. NewQueryState.isPlaceholderDataflag. See SPEC §9.
0.2.0-dev.2 #
- New: optimistic updates with automatic rollback.
MutationBuilder.onMutateruns beforemutationFn, applies your optimistic write, and returns a rollback closure; swrly runs it automatically on error (beforeonError) and keeps the optimistic value on success. Backward compatible — existingonSuccess/onError/onSettledsignatures are unchanged. See SPEC §9.
0.2.0-dev.1 #
First 0.2.0 feature, on the dev prerelease track for real-world verification.
- New: retry + backoff. A
queryFnthat throws is retried up toretrytimes with aretryDelay(attempt)backoff. Configure per query (QueryBuilder.retry/retryDelay,fetchQuery(retry:, retryDelay:)) or globally (QueryClient(defaultRetry:, defaultRetryDelay:)). Default is0retries (unchanged 0.1.x behaviour);defaultRetryDelayFnprovides an exponential 1s→30s backoff. While retrying the query staysisFetchingand only surfaces anerrorafter retries are exhausted; retries respect the generation guard (a supersede/dispose stops them). See SPEC §8.1.
0.1.1-dev.1 #
Prerelease of the 0.1.1 correctness patch, published for verification before the
stable 0.1.1 release. Everything below plus the review fix noted here.
- Fix (review):
QueryBuilderonly re-captures the refetcher (primeRefetcher) on a same-key rebuild whenenabledis true. Previously a disabled query that rebuilt could get a refetcher installed, so a laterinvalidateQuerieswould fetch a query the caller setenabled: false— violating SPEC §9. Added a regression test plus tests foronError/onSettledon unmount,hasDataretention across errors, andcopyWithfield clearing (31 tests total).
0.1.1 #
Correctness patch — behaviour fixes found in review, all backward compatible.
- Fix:
QueryState.hasDatais now based on a stored "has a successful value" flag instead ofdata != null. A query that legitimately resolves tonullnow reportsisSuccess && hasDataat the widget layer, matching the cache's own freshness contract (SPEC §2/§5.1). - Fix:
QueryState.copyWithcan now cleardata/error/stackTrace(via a sentinel). Entering a fetch and a successful refetch clear a stale error/stackTrace, so an old failure no longer leaks into a later loading/success state. - Fix:
MutationBuildernow runsonSuccess/onError/onSettledregardless ofmounted— a widget that disposes mid-flight no longer silently skips a cache invalidation done inonSuccess. OnlysetStateis guarded. - Fix:
QueryBuilderre-captures the currentqueryFn/staleTimeon a same-key rebuild (newQueryClient.primeRefetcher), so a laterinvalidateQueriesrefetch uses the current closure rather than a stale one. It still does not refetch on a plainqueryFnidentity change. - New:
QueryClient.invalidateQueriesWhere((key) => bool)— predicate form ofinvalidateQueriesfor sets a prefix can't express. - Docs: documented the last-writer-wins semantics for an entry's captured
queryFnwhen subscribers share a key (SPEC §6). Added 6 tests.
0.1.0 #
- Example: rebuilt around a real dio client hitting a public API, with a
live request counter + event log so the cache is observable — cache hits
show as "0 requests", keyed detail queries (
['post', id]) demonstrate per-key caching, and mutations show optimisticsetQueryData. Runs on web. - Docs: README overhauled — "why server state", how-it-works flow, and
comparison tables (vs
FutureBuilder, vs Riverpod/Bloc, vs a dio cache interceptor).docs/renamed todoc/(pub convention); added pubspec topics. - Bundles all the
0.0.2cache-correctness fixes below.
0.0.2 #
- Fix:
invalidateQueries(refetch: true)now actually refetches active subscribers (the lastqueryFnis captured per entry) instead of only marking data stale. - Fix: stale responses can no longer overwrite fresher data — each fetch carries a generation token and only the newest may write back.
- Fix: a successful
nullvalue is treated as fresh; nullable-data queries no longer refetch on every call. - Fix: freshness uses a monotonic clock, immune to wall-clock jumps.
- Fix: garbage collection can no longer dispose an entry that is being reused imperatively; idle imperatively-created entries are now collected too.
- Fix:
QueryBuilderkicks off the fetch whenenabledflips false → true. - Docs: added
docs/SPEC.md; expanded test coverage (dedup, race, GC, nullable, invalidate-refetch, widget lifecycle).
0.0.1 #
- Initial scaffold:
QueryClient,QueryBuilder,MutationBuilder, prefix invalidation, refetch-on-resume.