data_management 2.4.9
data_management: ^2.4.9 copied to clipboard
Collection of service with advanced style and controlling system.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
2.4.9 — 2026-05-12 #
Initial stable release.
Added #
Core Architecture
DataOperation— low-level CRUD + listen engine built from composable mixinsDataSource<T>— abstract typed source withLocalDataSourceandRemoteDataSourcesubclassesDataRepository<T>— high-level repository withLocalDataRepositoryandRemoteDataRepositoryconvenience subclassesDataDelegate— abstract backend adapter interface (implement once, swap freely)MulticastDataDelegate— shared upstream stream subscriptions to prevent duplicate listeners per pathErrorDelegate— pluggable error reporting (silent,printing, or custom)DataWriteBatch— abstract atomic batch with committed-state guard
Write API
create(entity)— write entity usingEntity.id+Entity.filteredcreateById(id, data)— write document with explicit id and raw data mapcreates(entities)— parallel batch-create multiple entitiescreateByWriters(writers)— batch-create from explicitDataWriterlistupdateById(id, data)— partial update preserving untouched fieldsupdateByWriters(writers)— partial update multiple documents in paralleldeleteById(id)— single document delete with optional cascadedeleteByIds(ids)— multi-document delete queued as one operationclear()— delete all documents in the collection (optionally cascade)write(writers)— low-level heterogeneous atomic batch (DataSetWriter/DataUpdateWriter/DataDeleteWriter)
Read API
checkById(id)— existence check with optional backup auto-synccount()— aggregate document countget()— full collection fetchgetById(id)— single document fetchgetByIds(ids)— multi-document fetch with automaticwhereInsplittinggetByQuery(...)— filter / sort / paginatesearch(checker)—Checker.containsandChecker.equaltext search
Listen (Real-time) API
listen()— real-time stream of all documentslistenById(id)— real-time stream of a single documentlistenByIds(ids)— merged real-time stream of multiple documentslistenByQuery(...)— filtered and sorted real-time streamlistenCount()— real-time aggregate count stream
@ Reference Fields
DataFieldValueWriter.set— atomic set of a related document in the same batchDataFieldValueWriter.update— atomic update of a related document in the same batchDataFieldValueWriter.delete— atomic delete of a related document in the same batch@field asStringpath — resolved to full document on read (resolveRefs: true)@field asListof paths / writers — resolved toList<Map>on read@field asMapof paths / writers — resolved toMap<String, Map>on read- Up to 8 levels of recursive reference resolution
- Configurable concurrency via
DataOperationSemaphore(refConcurrencydefault 16)
# Countable Fields
#field as collection path — resolved to liveintcount on read (countable: true)#field asListof paths — resolved toList<int>on read#field asMapof paths — resolved toMap<String, int>on read
DataFieldValueReader — Deferred Read-Time Resolution
DataFieldValueReader.get(path)— fetch and inline a document on every readDataFieldValueReader.count(path)— count and inline a collection on every readDataFieldValueReader.filter(path, options)— query and inline results on every read
DataFieldValue — Write Sentinels
DataFieldValue.serverTimestamp()DataFieldValue.increment(num)DataFieldValue.arrayUnion(List)DataFieldValue.arrayRemove(List)DataFieldValue.delete()
DataQuery — Filter Operators
isEqualTo,isNotEqualToisLessThan,isLessThanOrEqualToisGreaterThan,isGreaterThanOrEqualToarrayContains,arrayContainsAny,arrayNotContains,arrayNotContainsAnywhereIn,whereNotInisNullDataQuery.filter(DataFilter)— compositeDataFilter.and/DataFilter.or
DataSelection — Cursor Pagination
startAt,startAfter,endAt,endBefore(value-based)startAtDocument,startAfterDocument,endAtDocument,endBeforeDocument(snapshot-based)
DataFieldPath
DataFieldPath.documentId— backend-agnostic document-ID field reference
DataFieldParams — Dynamic Path Replacement
KeyParams(Map<String, String>)— named placeholder replacement{key}IterableParams(List<String>)— positional placeholder replacement{0},{1}
Dual-Write & Backup
- Primary-first execution with connectivity awareness
- Optional eager (
lazyMode: false) or lazy (lazyMode: true) backup mirroring - Per-call override of
backupMode,lazyMode,queueMode
Offline Queue
- Automatic persistence of failed remote writes to
DataCacheDelegate - Auto-drain on reconnect via
DM.connectivityChanges - Manual drain via
DM.i.drainAll() - Up to 5 retry attempts per queued operation before discard
- Supersession logic: pending creates/updates are removed when a delete for the same ID is enqueued
DataQueuedOpKind:create,creates,updateById,updateByWriters,deleteById,deleteByIds,clear
Fallback Streams
_FallbackStream— automatically switches between remote and local source based on connectivity- 300 ms debounce on connectivity transitions to prevent rapid swapping
- Generation counter prevents stale events from cancelled subscriptions
Local ↔ Remote Sync
restore()— hydrate local source from remote backup on first launch- Idempotent restore flag stored in
DataCacheDelegate clearRestoredFlag()— force re-restore on next callflushBackupNow()— immediate local→remote flush
Cache
CacheManager— TTL-aware LRU in-memory cacheCacheConfig—maxSize,defaultTtl,deduplicateInFlight,evictionInterval- In-flight deduplication — identical concurrent requests share one
Future - Optional persistent
CacheStorageAdapter(no-op on native,localStorageon Web) CacheStats—hits,misses,writes,evictions,expirations,inFlightDedupes,hitRateCacheManager.put,pick,pickByKey,remove,removeByKey,clear,evictExpired
Encryption
DataEncryptor— AES-256-CBC with per-document fresh IV- Platform-adaptive backend:
encryptpackage on IO, Web Crypto API on Web DataEncryptor.generateKey()— secure 32-byte hex key generator- Custom
EncryptorRequestBuilder/EncryptorResponseBuilderfor envelope format control
Global Manager (DM)
DM.i.configure(connectivity, cache)— wire connectivity + cache once at startupDM.i.isConnected— current connectivity stateDM.i.connectivityChanges— broadcast stream of connectivity changesDM.i.register/unregister— per-repository drain callback registryDM.i.drainAll()— re-entrant-safe sequential drain of all queued operations
Utilities
DataLimitations—whereInsplit threshold,batchLimit,maximumDeleteLimitDataOperationSemaphore— bounded concurrency for parallel async operationsDataIdGenerator— cryptographically secure random ID / hex key generationDataByteType—x2throughx128byte-size enum for key generationDataFieldReplacer— regex-based path placeholder replacementChecker—contains/equalsearch descriptor
0.9.0 — 2025-04-01 (pre-release) #
Added #
- Initial internal beta with basic CRUD, Firestore delegate, and offline queue prototype
Changed #
CacheDelegaterenamed toDataCacheDelegateConnectivityDelegaterenamed toDataConnectivityDelegate
Fixed #
DataOperationSemaphore._releasedouble-decrement when waiter queue is empty_FallbackStreamstale event delivery after rapid connectivity toggle_MulticastStreamteardown race condition when last subscriber cancels during upstream event
0.8.0 — 2025-03-01 (internal) #
Added #
MulticastDataDelegatewith per-path stream caching and subscriber reference countingCacheManagerwith in-flight deduplication and WeblocalStorageadapterDataEncryptorwith IO / Web platform-adaptive AES-256-CBC backendDataFieldValueReaderdeferred resolution (get,count,filter)
Changed #
_ReadResolveMixinrefactored to resolveDataFieldValueReaderfields before@prefix fieldsDataOperation.refSemaphorenow configurable via constructor (refConcurrency)
0.7.0 — 2025-02-01 (internal) #
Added #
- Cascade delete via
_CascadeDeleteCollectorwith@and#field traversal batchMaxLimitparameter to cap cascade collection sizeDataQueuedOp.copyWithfor attempt increment without full reconstruction
Fixed #
_RepoQueueMixin._mergeOnPushincorrectly superseding multi-writer ops when only a subset of IDs matched
0.6.0 — 2025-01-01 (internal) #
Added #
_RepoDualWriteMixin— extracted dual-write logic from repository base_RepoReadWithFallbackMixin— extracted fallback read + backup sync logicDataFilter.and/DataFilter.orcomposite filter supportDataSelectioncursor pagination helpersDataFetchOptions.single()/DataFetchOptions.limit(n, fromLast)
Changed #
_RepoQueueMixindrain logic split into_drainPrimaryQueueand_drainBackupQueueDataRepository.queueIdnow defaults totype:sourceType:pathwhenidis not provided
0.5.0 — 2024-12-01 (internal) #
Added #
@reference field write transform viaDataFieldValueWriter#countable field resolution via_ReadResolveMixinDataFieldValueWriter.set,.update,.deleteDataFieldPath.documentIdfor backend-agnostic ID queriesDataFieldValuesentinels:serverTimestamp,increment,arrayUnion,arrayRemove,delete
0.4.0 — 2024-11-01 (internal) #
Added #
LocalDataRepositoryandRemoteDataRepositoryconvenience subclassesrestore()with idempotent restore-flag viaDataCacheDelegateDataRepository.backupFlushIntervalandbackupFlushSizetimer-based flush
0.3.0 — 2024-10-01 (internal) #
Added #
- Offline queue with
DataCacheDelegatepersistence and auto-drain on reconnect DataQueuedOpserialization / deserialization- Supersession logic for
deleteByIdover pending creates and updates