appcraft_list_loading_flutter
Dispatcher for paginated list loading with offset/cursor support, debounced search and pluggable cancellation strategies.
1.1.0
153 downloads/mo
#1591 most downloaded on pub.dev
AppCraftTeam/appcraft-list-loading-flutter
What this package is like to depend on
Last release 4 days ago
19 Aug 2026
Ships on a steady schedule
a new release about every 2 months
Nearly every release is documented
notes for 6 of 6 stable releases
Nothing withdrawn
no release was ever pulled
4 months old
6 releases · first in 2026
6 releases in the last 12 months
see the full history below
Release timeline
6 releases · Apr 2026 to Aug 2026Releases
latest 6-
1.1.019 Aug 2026Release notes
Open source →Migration from 1.0.0 → 1.1.0: see MIGRATION.md.
Added
ACAnchoredDispatcher.reloadOlder/reloadNewer— seed each side of a window around an anchor with a plainACPage. Each replaces its side's items, takeshasMorefrom its own page, cancels that side's in-flight load and discards a late answer as stale. A window is composed by the caller out of the two seeds: the request count, their concurrency and the handling of a one-sided failure stay outside the package.ACAnchoredDispatcher.isReloadingAny/reloadingAnyListenable— true while either side is being seeded, and deliberately blind toloadOlder/loadNewer, so an initial-load spinner does not flicker on scroll.ACAnchoredDispatcher.lastErrorAny/errorAnyListenable— the last error held by either side; stays non-null while at least one side has one, so a success on one side cannot hide a failure on the other.ACLoadingDispatcher.reloadingListenable— a reactive channel mirroringisReloadingalone. UnlikeloadingListenable, which carries the derivedisReloading || isLoadingMore, it still fires when areloadstarts on top of an in-flightloadMore. Available inACListDispatcherandACPageDispatchertoo.
Fixed
- A window around an anchor is now expressible at all.
loadAroundunconditionally cleared the older side, so after an around-load that side was guaranteed empty whatever the loader returned; when the anchor was the last item of a feed the window collapsed to a single element and the history sat beyond the edge. lastResultOlder/lastResultNewerare populated right after the window is seeded, because the seeds are real loads. The initial cursors are read from the same members as every subsequent one —lastAroundis no longer needed for that.retryOlder/retryNewernow repeat a seed as well as an edge load.- The per-side search strategy is neutralised inside
ACAnchoredDispatcher: a non-empty query shorter than the defaultminLengthcarried inparamswould otherwise have turned a seed into a silent clear of the side.
Deprecated
Scheduled for removal in
2.0.0; behaviour is unchanged and existing code keeps compiling.ACAnchoredDispatcher.loadAround— usereloadOlder+reloadNewer.ACAnchoredPage<T>— useACPage<T>on each side. It carries a single list and therefore cannot express a window around an anchor; its documentation claimed otherwise and has been corrected.lastAround— uselastResultOlder/lastResultNewer.isLoadingAround— useisReloadingAny.loadingAroundListenable— usereloadingAnyListenable.lastErrorAround— uselastErrorAny.errorAroundListenable— useerrorAnyListenable.
-
1.0.010 Jul 2026Release notes
Open source →What's Changed
- Релиз 1.0.0 — удаление deprecated API by @dmitriyap11 in #15
Full Changelog: 0.3.0...1.0.0
Release notes
Open source →Migration from 0.2.0 → 1.0.0: see MIGRATION.md.
BREAKING CHANGE
- Removed deprecated parser-based API:
ACDispatcher,ACDefaultDispatcher,ACCustomDispatcher,ACParser,ACDefaultParser,ACResultParser,ACResult,ACDebouncedSearchStrategy. Migrate to the self-contained dispatchers — see MIGRATION.md.
-
0.3.006 Jul 2026Release notes
Open source →What's Changed
- feat(dispatcher): ACListDispatcher + депрекация ACDefault* by @dmitriyap11 in #4
- feat(dispatcher): mutate + сеттер hasMore в ACListDispatcher by @dmitriyap11 in #5
- feat(dispatcher): ACPageDispatcher + ACPage, депрекация parser-архитектуры by @dmitriyap11 in #6
- feat: публичный движок ACLoadingDispatcher, общий для диспетчеров by @dmitriyap11 in #7
- feat: loadingListenable и раздельные isReloading/isLoadingMore by @dmitriyap11 in #8
- feat: параметр force в loadMore для обхода guard hasMore by @dmitriyap11 in #9
- feat: lastError, errorListenable, retry и модель операций by @dmitriyap11 in #10
- fix: дефолт hasMore false до первой загрузки by @dmitriyap11 in #11
- feat: ACDebouncer и ACSearchDebouncer на композиции by @dmitriyap11 in #12
- feat: двунаправленный ACAnchoredDispatcher (anchor-based) by @dmitriyap11 in #13
- docs: релиз 0.3.0 + гид миграции 0.2.0->0.3.0 by @dmitriyap11 in #14
Full Changelog: 0.2.0...0.3.0
Release notes
Open source →Migration from 0.2.0 → 0.3.0: see MIGRATION.md.
- Added: new self-contained
ACAnchoredDispatcher<P extends ACParamsMixin, R extends ACPage<T>, T>— a bidirectional, anchor-centred dispatcher for chat/feed pagination, built as a composition of twoACPageDispatchers (one per side), so each side reuses the full loading engine (cancellation, staleness guards,isLoading,lastResult, error channels,retry,mutate).loadAroundseeds the window around an anchor (cancelling any previous around-load and both sides);loadOlder/loadNewergrow each side independently vialoadMore. Exposes the separateitemsOlder/itemsNewer(for aCustomScrollView(center:)without scroll jumps) and a merged read-onlyitems(reverse(itemsOlder) ++ itemsNewer), fully per-side state (isLoadingOlder/isLoadingNewer/isLoadingAround,hasMoreOlder/hasMoreNewer,lastErrorOlder/Newer/Aroundwith matchingerror*Listenableandloading*Listenable,lastResultOlder/Newer,lastAround,retryOlder/retryNewer), realtimemutateOlder/mutateNewer, pluscanceland an idempotentdispose. Cursors are managed manually by the consumer (initial ones fromlastAround, subsequent ones fromlastResult*). - Added: new around-page contract
ACAnchoredPage<T>(mixin withitems,hasMoreOlder,hasMoreNewer) — returned byACAnchoredDispatcher.loadAround, it carries both directional flags at once (unlike the per-sideACPage, whosehasMoremeans "more on this side"). The per-sideloadOlder/loadNewerkeep using the existingACPagemodel. - Additive only — a new composition on top of two existing
ACPageDispatchers; no existing class is changed and no migration is required. - Added: new standalone
ACDebouncer— an action-neutral debounce utility that collapses a burst of calls into a single trailing-edge invocation (run(void Function()),isActive,cancel(),dispose()), with a non-negativeduration(default300ms;Duration.zerofires on the next tick). It knows nothing about loading or search, so it is reusable for any debounced behaviour (read-tracking, autosave, analytics throttling, ...).dispose()is mandatory — it cancels the pending timer so a deferred action never fires after teardown. - Added: new
ACSearchDebouncer implements ACSearchStrategy— the new default search strategy on both dispatchers (debounce: 300ms,minLength: 3), built by composing anACDebouncerfor timing. Search behaviour (empty /< minLength/ equal / zero / debounce gating) is unchanged from the previous default. TheACSearchStrategycontract is kept for custom strategies. - Deprecated:
ACDebouncedSearchStrategy— will be removed in 1.0.0; useACSearchDebouncerinstead (samedebounce/minLengthparameters and identical behaviour — a straight rename). It keeps working and is still exported; it was moved tolib/src/deprecated/. Additive change — the search behaviour of the dispatchers is unchanged and no migration is required beyond the optional rename. - Changed: BEHAVIOR CHANGE — a fresh
ACListDispatcher/ACPageDispatchernow reportshasMore == falsebefore the first load (wastrue), sohasMorealone already gates a bottom loader without the extralastResult != null && hasMorecheck. As a result,loadMore()before the firstreloadis a no-op (thehasMore == falseguard) — usereloadfor the first load, orloadMore(force: true)to force it (forcestill bypasses thehasMore == falseguard, now including this initial state). ThehasMorecomputation after a load is unchanged (offset rule /page.hasMore), and thehasMoresetter andminLengthare unaffected. Migration: if you relied on a fresh dispatcher reportinghasMore == true(e.g. callingloadMorefirst), switch toreloadorloadMore(force: true). Deprecated dispatchers are not affected. - Added: built-in error state on
ACLoadingDispatcher—Object? lastError(the last thrown object, read synchronously) andValueListenable<Object?> errorListenable(its reactive channel, deduplicated by value and released indispose). A failingloadstill propagates the exception exactly as before — the error state is additive, so existingtry/catcharoundreload/loadMorekeeps working. The error clears on the next successful load, and changinglastErrordoes not firenotifyListeners(). - Added:
Future<void> retry()onACLoadingDispatcher— repeats the last operation (reloadorloadMore) through the public methods with the originalparams/loadand, forloadMore, the originalforce. A no-op when there is no prior operation or afterdispose. - Added: read-only
ACDispatcherOperation<Params, T>? lastOperationonACLoadingDispatcherfor introspecting the captured operation, plus the new public sealed modelACDispatcherOperationwith the variantsACReloadOperationandACLoadMoreOperation(the latter carryingforce); both expose the commonparamsandload. An exhaustiveswitchneeds no default clause. - All of the above live in the base
ACLoadingDispatcher, soACListDispatcher,ACPageDispatcherand third-party subclasses inherit them. Additive only — the exception propagation is unchanged (no breaking changes, no migration). - Added: optional
bool forceparameter (defaultfalse) onACLoadingDispatcher.loadMore— force a load past the end of the list by bypassing only thehasMore == falseguard, without a fullreloadand without losing the accumulated list. It is one-shot (hasMoreis recomputed after a successful load) and keeps every other guard:forcehas no effect during an active load or afterdispose. Additive only — the defaultfalsepreserves the previous behaviour, no breaking changes and no migration. Lives in the baseACLoadingDispatcher, soACListDispatcher,ACPageDispatcherand third-party subclasses inherit it. - Added: public
ValueListenable<bool> loadingListenableonACLoadingDispatcher— a reactive channel that mirrors the overallisLoadingflag, notifying on everyfalse ↔ truetransition (deduplicated by value). Drive a spinner reactively viaValueListenableBuilderor anaddListenerin a Cubit/Bloc, without manualsetStateand without subscribing to list changes. Released indispose. - Added: public synchronous flags
bool isReloadingandbool isLoadingMoreonACLoadingDispatcher— tell areload(full-screen spinner) apart from aloadMore(bottom spinner). Exactly one istrueduring an active load; both arefalseotherwise.isLoadingis now the derivedisReloading || isLoadingMore, so its semantics are unchanged. - All of the above live in the base
ACLoadingDispatcher, soACListDispatcher,ACPageDispatcherand third-party subclasses inherit them. Additive only —isLoadingis unchanged and no existing behaviour changes (no breaking changes, no migration; there is no separate listenable for the granular flags). - Added: new public abstract
ACLoadingDispatcher<Params extends ACParamsMixin, T>— the shared loading engine that owns the whole lifecycle (search scheduling, cancellation of a previous load, staleness guards, theisLoadingflag and the typedlastResult) behindreload/loadMore/cancel/dispose. It is also a public extension point: subclass it to implement non-standard pagination by providing only the collection state and thehasMore/onLoadSuccess/onLoadRejectedhooks. - Changed:
ACListDispatcherandACPageDispatcherare now thin subclasses ofACLoadingDispatcher— the duplicated loading state machine lives in one place. Internal refactor only: their public API and behaviour are unchanged, no breaking changes and no migration required. - Added: new self-contained
ACPageDispatcher<P extends ACParamsMixin, R extends ACPage<T>, T>for DTO/cursor pagination where the loader returns a page model. It works directly with the model —itemsandhasMoreare read from it — without extendingACDispatcherand without a parser. Full behavioural parity with the deprecatedACCustomDispatcher, plus themutatemethod and thehasMoresetter (same semantics as onACListDispatcher). - Added: new page-model contract
ACPage<T>(mixin withitemsandhasMore) — the renamedACResult<T>. DTOs mix inACPageinstead. - Deprecated: the parser architecture and the old model —
ACDispatcher,ACCustomDispatcher,ACParser,ACResultParserandACResult— will be removed in 1.0.0. Use the self-containedACListDispatcher(plainList) orACPageDispatcher(ACPagemodel) instead; migrate DTOs fromACResulttoACPage. All keep working and are still exported; they were moved tolib/src/deprecated/. - Added:
ACListDispatcher.mutate(void Function(List<T> items) update)— the sanctioned way to mutate the accumulated list from outside (realtime append, optimistic update, seed). The callback receives the mutable list; a singlenotifyListeners()fires on successful completion (batched — many operations, one notification). No-op afterdispose; a callback exception propagates without notifying;lastResultis untouched. Theitemsgetter stays unmodifiable — directitems.add(...)still throws. - Added: public setter
ACListDispatcher.hasMore— manually control whetherloadMoremay fetch (seed / end-of-list). Does not notify listeners (parity with the existing "notify only on items change" rule). - Added: new self-contained
ACListDispatcher<P extends ACOffsetParamsMixin, T>for the most common scenario — offset pagination over a plainList<T>. It does the job directly, without extendingACDispatcherand without a parser: item extraction andhasMore(result.length >= limit, ortruewhenlimit == null) are built in. Public API is a drop-in match forACDefaultDispatcher(per-callload, search viaACSearchStrategy, per-callcancelStrategy,List<T>? lastResult, identical notify/cancel/error/stale-result/guard semantics). - Deprecated:
ACDefaultDispatcherandACDefaultParser— will be removed in 1.0.0; useACListDispatcherinstead. Both keep working and are still exported; they were moved tolib/src/deprecated/. - No breaking changes — all 0.2.0 public names remain available.
-
0.2.026 Apr 2026Release notes
Open source →What's Changed
- feat!: чистка публичного API (v0.2.0) by @dmitriyap11 in #3
Full Changelog: 0.1.0...0.2.0
Release notes
Open source →-
Added: public
R? lastResultgetter onACDispatcher— stores the last successfully loadedRreturned by the loader (the same reference, no defensive copy). Updated after every successfulreload/loadMore; not reset onminLengthrejection, loader/parser exception, orcancel(). Reset tonullbydispose(). Useful for cursor pagination and DTO scenarios where the response carries metadata beyonditems/hasMore— for example, a server-sidenextCursortoken that the consumer feeds into the nextloadMorecall. -
BREAKING CHANGE: all 9 public types renamed — the
ListLoadingprefix was dropped to keep names short. Search/Cancel strategies kept their names (noListLoadingprefix to begin with). No deprecatedtypedefaliases — migrate via find-replace.Old name New name ACListLoadingDispatcherACDispatcherACDefaultListLoadingDispatcherACDefaultDispatcherACCustomListLoadingDispatcherACCustomDispatcherACListLoadingParamsMixinACParamsMixinACOffsetListLoadingParamsMixinACOffsetParamsMixinACListLoadingParserACParserACDefaultListLoadingParserACDefaultParserACResultListLoadingParserACResultParserACListLoadingResultACResult -
BREAKING CHANGE: flat
lib/src/layout. The intermediatelib/src/list_loading_dispatcher/list_loading_dispatcher.dartbarrel was removed; the six implementation files now live directly inlib/src/. The public entry pointlib/appcraft_list_loading_flutter.dartexports them directly. Consumers that import via the public entry are unaffected; deep imports throughlib/src/list_loading_dispatcher/...must be updated tolib/src/.... -
Removed:
ACCursorListLoadingParamsMixin— empty marker mixin not read by the dispatcher. Cursor-style params now declare a plaincursorfield on the params class withACParamsMixin. Carry the next-page cursor between calls throughdispatcher.lastResult?.<your_field>. -
Migration guide:
- Find-replace the 9 type names per the table above.
- Drop
ACCursorListLoadingParamsMixinfrom your params classes; declare a plainString? cursor(or any type) field instead. - (Optional) Use
dispatcher.lastResultto access the raw last loader response — for cursor pagination or DTO metadata. - If you used deep imports (
package:appcraft_list_loading_flutter/src/list_loading_dispatcher/...), either switch to the public entrypackage:appcraft_list_loading_flutter/appcraft_list_loading_flutter.dartor update paths to the flatpackage:appcraft_list_loading_flutter/src/....
-
0.1.026 Apr 2026Release notes
Open source →What's Changed
- feat: открыть публичные классы для extends/implements (v0.1.0) by @dmitriyap11 in #2
Full Changelog: 0.0.1...0.1.0
Release notes
Open source →- BREAKING CHANGE: removed
finalmodifier from public concrete classes, allowing bothextendsandimplementsfor downstream consumers. Affected classes:ACDefaultListLoadingDispatcher,ACCustomListLoadingDispatcher,ACDefaultListLoadingParser,ACResultListLoadingParser,ACDebouncedSearchStrategy,ACOperationCancelStrategy. For consumers that did not rely onfinalguarantees, this is a non-breaking relaxation; no migration is required. - Added "Extending the API" section to README with subclassing example.
- Added inheritance/implementation note to dartdoc of all open classes.
-
0.0.126 Apr 2026Release notes
Open source →What's Changed
- feat: подготовка к публикации appcraft_list_loading_flutter v0.0.1 by @dmitriyap11 in #1
New Contributors
- @dmitriyap11 made their first contribution in #1
Full Changelog: https://github.com/AppCraftTeam/appcraft-list-loading-flutter/commits/0.0.1
Release notes
Open source →- Initial package release.
- Added
ACListLoadingDispatcher<P, R, T>— a dispatcher for paginated list loading with support for offset/cursor pagination, search and cancellation. - Added facade dispatchers
ACDefaultListLoadingDispatcher<P, T>andACCustomListLoadingDispatcher<P, R, T>with pre-configured parsers. - Added parsers
ACListLoadingParser,ACDefaultListLoadingParser,ACResultListLoadingParser. - Added
ACListLoadingResult<T>mixin for response DTOs. - Added parameter mixins
ACListLoadingParamsMixin,ACOffsetListLoadingParamsMixin,ACCursorListLoadingParamsMixin. - Added search strategy
ACSearchStrategywith implementationACDebouncedSearchStrategy(debounce + minLength). - Added cancellation strategy
ACCancelStrategy(contract + implementation based onCancelableOperation).