at_persistence_secondary_server 5.3.0
at_persistence_secondary_server: ^5.3.0 copied to clipboard
A Dart library with the implementation classes for the persistence layer of the secondary server.
5.3.0 #
-
fix: the fold that decides which record a key names has ONE definition,
canonicalAtKey, exported from the keystore spec and called byHiveKeyStoreHelper.prepareKeyand by the SQLite backend's own normalisation. It was written out by hand in several places, which is a divergence nothing can go red about: a non-canonical key still resolves, so two spellings of the fold show up only as a caller quietly asking about a string the store does not hold. No behaviour change — the expression is the one every copy already used. -
fix: a store now honours the
storagePathit is given. Hive keeps its box registry and home path on aHiveImplinstance, and this package ran everything through the one global instancepackage:hiveexposes — so a box's identity was(the single global registry, box name). Box names here derive from the atSign, so two stores for one atSign in one process always resolved to one box however different the paths they were handed: the second silently attached to the first's, and its ownstoragePathreached nothing but the encryption-secret file beside it. Box lifecycle and type-adapter registration now run on aHiveInstances.forPath(...)instance, shared per canonical path. Callers passing one path keep exactly one store, with no box renamed and no data moved; a caller passing a different path now gets the separate store it asked for. Found from the client side, where two enrollments of one atSign shared a notification replay watermark and one consumed the other's offline backlog with nothing logged.HiveInstancesis exported frompackage:at_persistence_secondary_server/hive.dart, alongsidecloseAll()/closeFor(path)for tearing storage down: a globalHive.close()does not reach boxes opened on a per-path instance. Paths are matched by their resolved location on the filesystem, so a symlink and its target are one instance rather than two over one directory;forPathcreates the directory in order to resolve it, and refuses with aStateErrorwhile that path's instance is being closed. -
fix:
AtPersistenceFactory.initializeno longer ignores the storage locations it is handed. A factory caches one bundle per atSign —bundleForandcloseForkey on the atSign alone, so there is nowhere for a second to live — and on a cache hit it returned that bundle without ever reading the config, so a caller asking for a second location was answered with the first one's store. On SQLite the secondstoragePathreached nothing at all: its directory was never created. Asking for an atSign that already has an open bundle rooted somewhere else now throws aStateErrornaming both locations; the same locations still return the same bundle, and two spellings of one directory (foo/./bar, a symlink and its target) are not a conflict. Applies to the Hive, SQLite and dual-write factories; the dual one compares its two arms separately, sinceDualWritePersistenceConfigdelegates every path getter to its primary and would otherwise agree while the secondary had moved. -
fix: an empty storage path is refused instead of resolving to the process working directory. Resolving a path on the filesystem meant creating it first, and
Directory('').createSync()throws aFileSystemException, so the fallback caught it andp.canonicalize('')returned the CWD — a server handedsecondaryStoragePath=(an unset variable interpolated into a manifest arrives as an empty string, not as absent) would have started normally, rooted in its own image layer rather than the mounted volume, and with an unencrypted keystore, since the secret file could not be written there either and that failure is swallowed.HiveInstances.closeForno longer creates the directory it was asked to close. -
fix: the storage-location comparison no longer treats two absent paths as the same location. The filesystem arm was
_resolved(a) == _resolved(b), and an unresolvable path resolved to null, so two unrelated missing roots compared equal and the conflict guard was skipped.backendMarkerPathis no longer among the compared locations — both config classes derive it fromstoragePath, and as a file that does not exist until a backend is chosen it could only produce false conflicts. A refusal now names the location that actually differs rather thanstoragePath, which for the dual-write config always read "rooted at X, and was asked for one at X". -
fix: the dual-write mirror purges the secondary's commit entry when the primary holds none for a just-written key. A skipCommit put/create/putMeta purges the primary's entry while the key lives on, so "no entry to replay" no longer implies "never committed" — without the purge the secondary kept a stale entry that would resurface in sync after a backend switch (caught by runDualCompare.sh: 79 vs 80 commit entries).
-
fix: the Hive commit-log
iterateskips an entry whosecommitIdis still null —addstores the entry and stamps itscommitIdin two awaited steps, so a concurrent iterator (sync running while another write commits) could observe the half-written entry and crash dereferencing the id. Skipping is safe: the entry is fully visible on the next iteration, and commit-id sequences are gap-tolerant by design. SQLite is unaffected (the row and its id are written in one transaction). -
feat: keystore write paths accept caller-asserted timestamps (
AtAssertedTimestamps):put/create/putMetastore an assertedcreatedAt/updatedAt/expiresAt/availableAtfaithfully instead of rederiving, and an assertedexpiresAt/availableAtsuppresses the ttl/ttb derivation for that write only.removeacceptsdeletedAt.AtMetadataBuilderalso derives the inverse on request (AtAssertedTimestamps.deriveTtl/deriveTtb, set by callers whose own request supplied the absolute without its relative): an assertedexpiresAtstores the ttl it implies (measured from the stored updatedAt — from the asserted availableAt when that lies ahead of it), and an assertedavailableAtstores the implied ttb, in each case replacing whatever retained or coerced relative the write's metadata carries; a non-positive implied value clears the relative instead. A ttl-only write on a record whose birth is pinned by an asserted availableAt expires at exactly now + ttl — the metadata's ttb is folded into the expiry derivation only when the same write re-derives the birth window too. Assertions travel as an explicit argument rather than through nullableAtMetaDatafields, so internal callers that recycle stored metadata keep today's server-derived stamping. NOTE for the next release: these are new named parameters on theAtKeyValueStoreinterface methods — breaking for external implementers of the interface (none known besides test mocks, which tolerate it), fine for callers. -
feat:
AtCommitLog.commitaccepts anopTime(caller-asserted operation time — a delete'sdeletedAt, an update's assertedupdatedAt), recorded on the commit entry; andAtCommitLog.removeEntryForremoves a key's commit entry on both backends (previously reachable only through backend-specific escape hatches). -
feat:
put/create/putMetawithskipCommit: truenow purge the key's existing commit entry as well as writing none, matchingremove's established skipCommit behaviour;putMetagainsskipCommit. -
fix: the Hive expiry cache tracks keys by their stored
expiresAt/availableAtrather than by ttl/ttb presence, so a record whose only expiry signal is an assertedexpiresAtis swept and stops being served at its expiry instead of living forever. -
fix: Hive
remove/removeManypassed the raw key to the commit log, which utf7-decodes its argument — a second decode that mangled keys containing utf7 escape sequences. Commit-log calls now take the prepared key on every path.
5.2.1 #
-
feat:
AtCommitLog.iterateacceptsskipDeletesUntil/latestCommitId, pushing sync's delete-skip into the query. Previously sync fetched every commit entry fromfromCommitIdand discarded below-watermark DELETE entries in a Dart filter; now the backend excludes them at the source — SQLite in the SQLWHERE, so those rows are never read or deserialised — while always yielding the single latest entry so the client can still advance its watermark. Legacy callers (noskipDeletesUntil) are unaffected. -
perf: the SQLite skip-deletes query is now an index-driven range scan over a new partial index of live entries (
commit_log_live), not aNOT (operation = '-' ...)filter over the fullcommit_idindex. The filter form is correct but its plan walks every row fromfromCommitIdto the tail in SQLite's C layer, so a client near the head of a delete-dominated log still pays a full-log scan; the partial index seeks straight to the live rows. Measured on a 1M-entry log holding one live entry, the skip-deletes scan drops from ~253ms to ~0.2ms. The index is created byCREATE INDEX IF NOT EXISTSon open, with no contract-version bump — an existing database acquires it on next start. -
perf:
SqliteAtCommitLog.iteratestreams rows through a prepared cursor rather than an eagerselect()that materialised the whole result set before the caller saw a row. Callers stop early (sync breaks after one page), so an ordinarysyncreturning 25 entries against a 1M-entry log drops from ~500ms to sub-millisecond. -
fix:
getSize()on the SQLite commit-log, access-log and notification stores returned raw bytes; the spec and the Hive stores return KB. All three now return KB (they had over-reported by 1024x). -
fix:
PersistenceMigratornow drops ORPHANED commit entries rather than copying them into the target — a non-delete commit entry whose key is absent from the keystore. Hive accumulates these (its commit log's box and in-memory cache can disagree, and the TTL-expiry purge is cache-driven, so it can miss the box row); SQLite purges by atKey directly against storage and cannot produce one. Migrating them forward would make them permanent residents of a backend that can never generate one, andPersistenceSnapshotfilters them from both sides so the post-migration verify cannot see them. Migration is where both stores are already walked, so reconciling costs nothing. DELETE tombstones always survive — they legitimately have no keystore row, and dropping them would break delete propagation to clients. Keys that are expired but still present are NOT orphans and migrate verbatim. The dropped count is reported asMigrationReport.orphanedCommitEntries(a new required field on that class) and logged per entry. -
fix: corrected the 5.2.0 entry below, which described a commit-log orphan as "sync-benign". It was not — an orphan failed the whole sync request with
AT0015until the fix in at_secondary_server 3.15.0. -
fix: resolve sqlite migration deadlocks and OOMs by enforcing TRUNCATE mode and disabling true MVCC snapshots
5.2.0 #
- feat: dual-write persistence layer (
lib/dual.dart) — serves reads from a primary backend while mirroring every write byte-exactly into a secondary (viarestore/replay, not operation-replay, so server-stamped timestamps and commit ids stay identical). Run a real workload once, compare after. - feat:
bin/compare_persistence.dart— compares two DB sets (backend + storage root) for one atSign across all four stores and reports every inconsistency; exit 0 identical / 1 differences / 2 error. Backed byPersistenceSnapshot.differencesFrom(all differences, not just the first). - feat: SQLite persistence backend (
lib/sqlite.dart) implementing the same spec interfaces as Hive —SqliteAtKeyValueStore(with full- fidelitysupportsSnapshots/supportsPathQueries/ true transactions),SqliteAtCommitLog(dense/gaplesscounters-based commit ids),SqliteAtNotificationKeystore,SqliteAtAccessLog,SqliteAtPersistenceFactory. Oneatsign.dbper atSign; the schema is a stable per-atSign interchange contract. - feat: migrator-only verbatim primitives —
AtKeyValueStore.restoreandAtAccessLog.replay(symmetric toAtCommitLog.replay) — plusPersistenceMigrator(backend-agnostic Hive↔SQLite copy) andPersistenceSnapshot(canonical bundle comparator).AtPersistenceBackendIdgainssqlite. Covered by a conversion-integrity gate: hive→sqlite→hive→sqlite→hive→sqlite round-trips byte-identically. - fix:
PersistenceSnapshottolerates Hive's non-deterministic commit-log orphans — a non-delete commit entry whose key is absent or expired is skipped. After a TTL-expiryskipCommitsweep, Hive can leave a stale commit entry in its box (its cache-basedgetLatestCommitEntrypurge misses the box entry — a cache/box inconsistency); a faithful SQLite mirror carries no such entry. Such an entry is excluded from both snapshots. (Corrected in 5.2.1: this entry originally described the orphan as "sync-benign". It was not — until the fix in at_secondary_server 3.15.0 an orphan failed the entire sync request withAT0015. It is benign to the SNAPSHOT COMPARISON, which is what this change is about.) DELETE entries and live unexpired-key entries are always compared, so real mirror data loss still fails. Makes the dual-write Hive-vs-SQLite DB-set comparison deterministic under a real functional workload, so it can gate CI.
5.1.0 #
- feat: new persistence field
AtMetaData.appMetadatacarrying the provider-ownedAppMetadatafrom at_commons (opaque to the server). Stored byAtMetaDataAdapteras a JSON-encoded string (hive field 26); records written before the field existed read back withappMetadata == null. Mapped infromCommonsMetadata/toCommonsMetadataandtoJson/fromJson(the latter accepts both the Map and base64 wire forms).
5.0.0 #
Major release: persistence-overhaul. Themes:
- Bootstrap is now factory + bundle, not singletons.
AtPersistenceFactory/AtPersistenceBundlereplace every legacygetInstance()shim. Backend-pluggable by design. - Hive concretes renamed; abstract interfaces freed.
HiveAtCommitLog/HiveAtAccessLog/HiveAtNotificationKeystore/HiveAtKeyValueStoreimplement abstractAtCommitLog/AtAccessLog/AtNotificationKeystore/AtKeyValueStore. Bundles type at the abstracts. - Slim bundle + capability toggles. The bundle exposes
keyValueStore(core) plusaccessLog?andnotificationKeystore?(optional capabilities gated byAtPersistenceConfigtoggles).serverDefaultsopts into every capability;clientDefaultsopts into the keystore only. - First-class min/max/floor query surface.
KeyValueStoregainsnextExpiresAt/peekExpired(expiry wake-up + bounded ascending-order drain, on both the main and notification keystores);AtKeyValueStoregainsnextAvailableAt/peekNewlyAvailable(TTB wake-up + a caller-side-watermark sweep window);AtCommitLoggainsfirstCommittedSequenceNumber(the log's floor, pairing withlastCommittedSequenceNumberso sync clients can detect "server no longer retains my delta"). The Hive notification keystore now maintains an in-memory effective-expiry index (foldingexpiresAt, thenotificationDateTime + maxTtlguard, and already-expired-by-shape entries into one comparable instant), which also backsgetExpiredKeyswithout a full-box deserialise. Fixed: bulk commit-log removal left stale entries in the commit-log cache; cache eviction is now guarded so deleting an older duplicate never evicts the newer live entry. AtKeyValueStorewidened with ten new primitives for at_client adoption:exists,scanKeys(withKeyPattern+ ordering + pagination),getMany,removeMany,changesstream,transaction,queryByPath(+supportsPathQueries),snapshot(+supportsSnapshots), andstats. Capability flags let a future SQL backend light up native indexed query / MVCC paths while Hive falls back gracefully.- Keystore type hierarchy collapsed.
SecondaryKeyStorerenamed toAtKeyValueStore;HiveSecondaryKeyStorerenamed toHiveAtKeyValueStore. Bundle fieldkeyStorerenamed tokeyValueStore.Keystore(read-only),WritableKeystore, andSynchronizableKeyStorecollapsed into a singleKeyValueStore<K, V>interface that holds the merged CRUD + rich surface (scan, bulk, expire, change stream, transaction, snapshot, stats).AtKeyValueStore<K, V, T>extendsKeyValueStoreand adds the sync-coupled surface: the (nullable)commitLog,putMeta/putAll/getMeta, andqueryByPath/supportsPathQueries. scanKeys/KeyPatternlive onAtKeyValueStore, notKeyValueStore. Structured filtering (KeyPattern'ssharedBy/sharedWith/namespace/idPrefix) is atKey-shaped, so it belongs on the atKey-aware tier rather than the generic key-value contract.KeyValueStore.existsand the pre/post-remove hook callbacks are typed at the generic keyK(wasString), since they don't carry the atKey assumption. A newAtKeyValueStoreSnapshot extends KeyStoreSnapshotaddsscanKeyson top of the base snapshot for the same reason;HiveAtNotificationKeystore(and its snapshot) no longer carry the awkwardscanKeysimpl that only honouredidPrefix.- Model classes decoupled from Hive.
AtData,AtMetaData,CommitEntry,AccessLogEntryandAtNotificationno longer carry Hive's@HiveType/@HiveFieldannotations (they were dead — no codegen) orextends HiveObject. The hand-writtenTypeAdapters moved tolib/src/hive/adapters/(re-exported by the barrel; on-disk wire format unchanged).AtDataandCommitEntrykeep a transient, non-serializedkeyfield that the keystore populates on read, replacing theHiveObject.keythat Hive used to auto-stamp. The five models are now plain Dart objects — the seam a future SQLite/Postgres backend needs. HiveAtKeyValueStorevalue type tightened to non-nullAtData. The main keystore now implementsAtKeyValueStore<String, AtData, AtMetaData?>(was<String, AtData?, AtMetaData?>), andAtPersistenceBundlesurfaces it as such.put/create/putAllreject a null value at compile time instead of crashing on an internalvalue!;getManyreturnsMap<String, AtData>.getis unchanged — it still returnsFuture<AtData?>(nullfor an absent key). The metadata type parameter stays nullable (AtMetaData?) sincegetMetalegitimately returnsnull.- Keystore listing/existence APIs are now fully async, and
list-returning queries stream.
KeyValueStore.getKeys,getExpiredKeysandscanKeysnow returnFuture<Stream<…>>;LogKeyStore.getExpiredandAtCommitLog.getChangeslikewise returnFuture<Stream<…>>. TheFuturecompletes once the backend has accepted the request (so setup failures — store not open, invalid regex — reject eagerly rather than mid-stream); theStreamthen yields the results. The synchronousisKeyExistsis removed — use the asyncexists(the two were duplicates;existsis the backend-agnostic shape SQL backends need). AtKeyValueStore.commitLogis nullable, end to end. Server bundles hold a non-null commit log on the keystore; client bundles holdnull(sync via fsync or other mechanism).AtPersistenceConfig.enableCommitLog(defaulttrue;serverDefaults→true,clientDefaults→false) selects which — whenfalsethe factory builds the keystore commit-log-free and never opens the commit-log box.HiveAtKeyValueStorehonours anullcommit log throughout:put/create/putAll/putMeta/remove/removeManysucceed and returnnull(no sequence number), andcompact()is a no-op that yields nothing. The server's bootstrap asserts non-null once and binds to a non-nullable local for downstream consumers.- Bundle no longer exposes the commit log directly.
AtPersistenceBundle.commitLogis gone; reach it asbundle.keyValueStore.commitLog!. AtNotificationKeystorere-parented toKeyValueStore. No longer extends the AtKeyValueStore tier — notifications don't participate in the commit log. Drops the sixUnimplementedErrorstubs and the no-opcommitLogoverride that the old interface forced on it. Notification keystore implementations stop pretending to supportputMeta/putAll/getMeta/queryByPath. Now strongly typedKeyValueStore<String, AtNotification>(was<dynamic, dynamic>) — keys are notification ids, values areAtNotification; consumers no longer cast.- Compaction is intrinsic, not strategy-wrapped. The
Compactableinterface (one method:Stream<Object> compact(bool dryRun)) replacesAtCompactionStrategy,HiveCompactionStrategy,AtCompaction,AtLogType,AtCompactionConfig, andAtCompactionStats— all deleted.AtCommitLog,AtAccessLog,AtNotificationKeystore, andAtKeyValueStoreall implementCompactable. The Hive impls each carry their owncompactionPercentageconstructor parameter; oncompact(false)they yield the items removed,compact(true)yields what would be removed. - Compactor scheduling moves to
at_secondary_server. The persistence layer no longer schedules anything — the secondary server runs threeTimer.periodicticks with overlap guards.AtCompactionJobdeleted.AtCompactionStatsService.record()takes primitives (label,start,compactedCount,duration) instead of anAtCompactionStatsobject. AtPersistenceConfigcompactor flags removed.enableCommitLogCompactor/enableAccessLogCompactor/enableKeyStoreCompactormoved toAtSecondaryConfig(withenableKeyStoreCompactor→enableNotificationCompactor, matching the resource it actually gates).- Migrator-friendly walks.
replay(CommitEntry)anditerate({fromCommitId, where})onAtCommitLog, plusiterate()on access log + notification keystore. Lazy box- walks; no upfront map materialisation. - Commit log is one-entry-per-atKey by construction. Inline
single-atKey dedup in
CommitLogKeyStore.add()plus a startup dedup migration.CommitLogCompactionServiceandCompactionSortedListretired (their job is done eagerly by the write path). AtCommitLog.getEntriesretired. Migrate toiterate(fromCommitId, where: closure); the closure carries any caller-side filtering (regex, skipDeletesUntil, etc.).- Keystore signatures tightened to remove
dynamic. CRUD methods onKeyValueStorenow returnFuture<int?>(commit-log sequence number ornull) instead ofFuture<dynamic>.KeyValueStore.getisFuture<V?>instead ofFuture<V>?.LogKeyStore.addreturnsFuture<int>(Hive-assigned key);update/removereturnFuture<void>;getFirstNEntriesreturnsList<int>;getExpiredreturnsFuture<List<K>>.AtAccessLog'smostVisitedAtSigns/mostVisitedKeysreturnFuture<Map<String, int>>. Pre/post-remove hook callbacks areFuture<void> Function(...). Call sites can dropas int?/as AtData?/as Mapcasts. AtKeyValueStore.deleteExpiredKeysdropsskipCommit. Expiry is treated as backend-local maintenance: the sweep never advancescommitIdand never propagates via sync.AtKeyValueStore.commitLogtypedAtCommitLog?rather thanAtLogType?. Callers no longer needas AtCommitLogat every access site.HiveAtNotificationKeystore.commitLogis a no-op getter/setter instead of a mutable field — notifications never participate in the commit log.SyncProgressiveVerbHandlerempty-response wedge fixed. When every entry in a requested range failedisAuthorized(or another in-loop filter), the handler returned[]and the client could not advance itsfromwatermark. The switch toiterate(where:)makes the scan unbounded; the client now always sees forward progress. No wire-format change.AtConfigmoved out of this package intoat_secondary_server. Block-list writes passskipCommit: trueand don't bump the localcommitId.- Test-isolation primitive.
AtPersistenceBundle.clear()drops every entry from each store while keeping underlying boxes open. - Dependency on
at_persistence_specdropped. The interface types this package previously imported fromat_persistence_spec(AtKeyValueStore, exceptions, the@server/@clientannotations, and the new query / change-stream types —KeyEntry,KeyPattern,KeyStoreChange,KeyStoreSnapshot,KeyStoreStats,KeyStoreTxn,OrderByKey,Predicate) now live alongside the Hive implementation in this package. Future backend packages depend onat_persistence_secondary_serverfor the interface types they need to satisfy. - Factory close-and-reuse hardened.
AtPersistenceBundleexposesbool get isClosed.AtPersistenceFactorygainsFuture<void> closeFor(String atSign)— closes a single bundle and drops the factory's reference.initializeandbundleFornow treat a closed entry as absent (a closed bundle is dropped and rebuilt on nextinitialize, andbundleForreturnsnull), so a caller closing a bundle directly viabundle.close()can no longer cause the factory to hand out a stale closed reference. - Dead code removed. Deleted the unused
StoreTypeenum,AtCommitLog.firstCommittedSequenceNumber(no callers), theNullCommitEntrysentinel (the package returnsnull, never a sentinel), and the vestigialLogKeyStoreinterface — one implementer, no consumers — along with the orphaned keystore methods it carried (getExpired, and the commit-log keystore'sgetFirstNEntries).
See MIGRATION.md for the full migration guide:
what changed in this package (5.0.0 vs 4.3.5), how
at_secondary_server was reworked to consume it, and a
step-by-step guide for migrating at_client onto 5.0.0 and a
commit-log-free local keystore.
4.3.5 #
- perf:
NullCommitEntryis now a singleton — no freshDateTime.now()allocation per commit-log miss - perf:
HiveKeystore.getKeyscaches compiledRegExppatterns in a bounded LRU and capturesDateTime.timestamp()once per call, threading it into_isExpired/_isBorn/_isKeyAvailableso each key check no longer allocates two DateTime objects - perf:
DateTime.now().toUtc()replaced withDateTime.timestamp()(one allocation instead of two) on the keystore expiry, notification expiry, access-log and commit-log hot paths - perf:
HiveKeystore.createno longer builds a 17-elementSetper put just to ask "any metadata field non-null?" — replaced with a direct null-check chain
4.3.4 #
- fix: Make AtNotificationKeystore.getExpiredKeys more memory efficient
4.3.3 #
- fix: Fix the
expiresAtandttlrules inAtNotificationBuilder.build
4.3.2 #
- fix: fixes to
AtNotification.isExpired - fix: fixed use of
defaulTtlinAtNotificationBuilder.reset
4.3.1 #
- fix: backwards compatibility: revert AtNotificationKeystore.currentAtSign to a non-final instance variable
4.3.0 #
- feat: deprecated AtNotificationCallback class
- feat: deprecated use of AtNotificationKeystore singleton
- feat: deprecated NotificationManagerSpec
- fix: AtNotificationBuilder.build will update a null ttl to the default value
- fix: AtNotification.isExpired treats null expiry as expired, as the idea of notifications without expiration is a historical antipattern and is no longer possible
4.2.0 #
- chore(deps): bump uuid to
^4.0.0 - chore(deps): bump at_commons to
^5.5.0
4.1.0 #
- feat: Add
preRemoveHookandpostRemoveHookto KeyStore interfaces
4.0.0 #
- refactor: Take up new major version 3.0.0 of at_persistence_spec, update and simplify the HiveKeyStore implementation accordingly
- feat: (non-breaking) Add persistence support for the new
immutableflag
3.1.0 #
- feat: commit log changes for sync skipDeletesUntil feature
- build[deps]: Upgraded the following package:
- at_commons to v5.1.0
3.0.66 #
- feat: Add "PublicKeyHash" to the "AtMetadata" which holds the hash value of encryption public key
- build[deps]: Upgraded the following packages:
- at_commons to v5.0.2
- lints to v5.0.0
- test to v1.25.8
3.0.65 #
- fix: Modified checks in commit log keystore _alwaysIncludeInSync method to match only reserved shared_key, encryption public key and public key without namespace.
- build[deps]: Upgraded the following packages:
- at_commons to v5.0.1
3.0.64 #
- build[deps]: Upgraded the following packages:
- at_commons to v5.0.0
- at_utils to v3.0.19
3.0.63 #
- fix: Ensure only latest commitEntry for each present in CommitLogCache
3.0.62 #
- fix: Add check for hive key max length (255 chars)
- build[deps]: Upgraded the following packages:
- at_commons to v4.0.5
- hive to v2.2.3
- crypto to v3.0.3
3.0.61 #
- feat: delete entries for expired keys are not committed to the commitLog [feature not enabled yet]
3.0.60 #
- build[deps]: Upgraded the following packages:
- at_commons to v4.0.0
- at_utils to v3.0.16
3.0.59 #
- fix: When checking namespace authorization, gracefully handle any malformed keys which happen to be in the commit log for historical reasons
3.0.58 #
- fix: Modify "lastCommittedSequenceNumberWithRegex" to return highest commitId among enrolled namespaces
3.0.57 #
- fix: Refactor commit log keystore to optimize memory usage
3.0.56 #
- fix: Refactor Hive keystore to optimize memory usage
- fix: Apply Utf7.decode function to decode the keys and atSigns containing emojis.
- feat: add skipCommit flag to keystore implementation which enables skipping commit log for put/create/remove.
3.0.54 #
- fix: Add NotificationType.Self in read and write methods of at_notification.dart
3.0.53 #
- feat: Introduced self notification type in enum for apkam enrollment
- chore: upgraded at_commons to 3.0.50 and at_utils to 3.0.14
3.0.52 #
- feat: Add new encryption metadata fields to core persistence classes
3.0.51 #
- feat: Extend sanity-checking of server-side commitLog upon startup
3.0.50 #
- fix: AtMetaData.fromJson now preserves null values for ttl, ttb and ttr
- test: Add '==' & hashCode to AtMetaData in order to be able to test equality
- test: Added tests which verify JSON round-tripping of AtMetaData objects
- refactor: Deprecate at_metadata_adapter; extract the 'to' and 'from' commons Metadata methods from there into the AtMetaData class itself
3.0.49 #
- fix: AtData.toJson() now works when the key is null
3.0.48 #
- fix: Ensure HiveKeystore's metaDataCache's keys are in lower case
3.0.47 #
- feat: conform to at_persistence_spec 2.0.11
3.0.46 #
- fix: AtMetadata.version does not update on the update of a key
3.0.45 #
- fix: Introduce "isScheduled" method in "AtCompactionService" to know if the compaction job is running
3.0.44 #
- fix: Refactor AtCompaction job
3.0.43 #
- fix: Fetch only commit entries with 'null' commit-id for uncommitted entries in at_client persistence
3.0.42 #
- fix: rollback keystore delete KeyNotFoundException
3.0.41 #
- fix: store actual keys in hive keystore metadata cache instead of encoded keys
- feat: throw KeyNotFoundException if key to be removed is not present in keystore
3.0.40 #
- feat: Refrain adding local keys to commit log.
3.0.39 #
- fix: lastSyncedEntry to accept signing private key
3.0.38 #
- fix: Revert sync of signing keys and 'statsNotificationId'
3.0.37 #
- fix: skip commit id for the 'statsNotificationId'
3.0.36 #
- fix: skip commit id and sync for signing keys
- fix: dart analyzer issues
- chore: upgrade third party dependencies
3.0.35 #
- fix: Randomize the cron job's start interval
- fix: Reduce the default notification expiry duration
3.0.34 #
- fix: Reverted dependency on 'meta' package to ^1.7.0 as flutter_test package (currently) requires 1.7.0
3.0.33 #
- feat: added key validation to keystore put and create methods
- chore: upgraded at_commons version to 3.0.24
3.0.32 #
- Add 'encoding' to AtMetadata which represents the type of encoding
3.0.31 #
- Invalidate commit log cache on removing entry from commit log
3.0.30 #
- Enhance KeyNotFoundException to chain into exception hierarchy.
- Upgrade at_commons version to 3.0.20 to encrypt notify text
3.0.29 #
- Introduced option to stop current schedule of a compaction job
- Enable the public hidden keys to sync between local and cloud secondary
- Uptake at_commons to 3.0.18 to optionally display hidden keys in scan
3.0.28 #
- Updated lastSyncedEntryCacheMap regex to match the reserved keys
- Upgraded to version 2.0.6 of at_persistence_spec containing @server/@client annotations
3.0.27 #
- Downgrade meta package to 1.7.0(minimum) version
3.0.26 #
- Replace null commitId's with hive internal key on secondary server startup
- Return commit entry with highest commitId from lastSyncedEntry
- Upgrade at_commons version for AtException hierarchy
3.0.25 #
- To reduce latency on notifications, publish the event for the notification before persisting the notification
3.0.24 #
- Introduced a cache to speed up metaData retrieval.
- Removed unnecessary print statements
3.0.23 #
- Add remove method in NotificationManagerSpec.
3.0.22 #
- Bumped some dependencies
3.0.21 #
- Upgrade at_lookup and at_commons for NotifyRemove
3.0.20 #
- Upgrade Hive version to 2.1.0
3.0.19 #
- add encryption shared key and public key checksum to metadata
3.0.18 #
- Renamed compaction stats attributes
- Modified return type and added optional params in hive keystore put and create methods
3.0.17 #
- Support to collect and store compaction statistics
3.0.16 #
- at_lookup version upgrade for implementing server error responses
- at_commons version upgrade for AtTimeoutException
3.0.15 #
- at_utils version upgrade
3.0.14 #
- Fix commit log compaction issue.
3.0.13 #
- at_utils and at_commons version upgrade.
- Fix notification expiry bug.
3.0.12 #
- Changes to support reset of ttb
3.0.11 #
- Enhance commit log compaction service
3.0.10 #
- persistence spec version upgrade
3.0.9 #
- Added support for notification expiry based on ttl
3.0.8 #
- at_utils and at_commons version upgrade.
3.0.7 #
- compaction delete bug fix
- reduce compaction frequency to 12 hours
3.0.6 #
- Support for Hive lazy and in memory boxes
3.0.5 #
- Rollback hive lazy box
3.0.4 #
- Remove compaction strategy
3.0.3 #
- Fix for sync bug in commit log
3.0.2 #
- Add null check in commitLog KeyStore
3.0.1 #
- Change Hive box type to lazy box
3.0.0 #
- Sync pagination feature
2.0.6 #
- fix for hive closed box issue
2.0.5 #
- logs for hive closed box issue
2.0.4 #
- at_commons version change for last notification time in monitor
2.0.3 #
- at_commons version change for stream resume
2.0.2 #
- at_commons version change
2.0.1 #
- at_commons version change
2.0.0 #
- Null safety upgrade
1.0.1+8 #
- Refactor code with dart lint rules
- Fixed minor bug in secondary persistence store factory
1.0.1+7 #
- Third party package dependency upgrade
1.0.1+6 #
- Add await on close methods.
1.0.1+5 #
- Notification sub system changes
1.0.1+4 #
- Added Support for multiple AtSigns
- Introduced batch verb for sync
1.0.1+3 #
- Public data Signing
- Sync with regex
- at_persistence_spec changes
1.0.1+2 #
- Notifylist issue fix for atSigns with emojis Add close methods for keystore.
1.0.1+1 #
- at_persistence_spec version changes
1.0.1 #
- Documentation changes
1.0.0 #
- Initial version, created by Stagehand