NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #2071 most downloaded on pub.dev
A Dart library with the implementation classes for the persistence layer of the secondary server.
Last release 1 months ago
06 Sep 2026
Release timing varies
gaps range from 3 weeks to 7 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
6 years old
98 releases · first in 2020
fix: the fold that decides which record a key names has ONE definition, canonicalAtKey, exported from the keystore spec and called by HiveKeyStoreHelp
fix: the fold that decides which record a key names has ONE definition,
canonicalAtKey, exported from the keystore spec and called by
HiveKeyStoreHelper.prepareKey and 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 storagePath it is given. Hive keeps its box
registry and home path on a HiveImpl instance, and this package ran
everything through the one global instance package:hive exposes — 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 own storagePath reached nothing
but the encryption-secret file beside it. Box lifecycle and type-adapter
registration now run on a HiveInstances.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.
HiveInstances is exported from package:at_persistence_secondary_server/hive.dart,
alongside closeAll() / closeFor(path) for tearing storage down: a global
Hive.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; forPath creates
the directory in order to resolve it, and refuses with a StateError while
that path's instance is being closed.
fix: AtPersistenceFactory.initialize no longer ignores the storage
locations it is handed. A factory caches one bundle per atSign — bundleFor
and closeFor key 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 second storagePath reached nothing at all: its
directory was never created. Asking for an atSign that already has an open
bundle rooted somewhere else now throws a StateError naming 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, since DualWritePersistenceConfig delegates 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 a FileSystemException, so
the fallback caught it and p.canonicalize('') returned the CWD — a server
handed secondaryStoragePath= (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.closeFor no
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. backendMarkerPath is no longer
among the compared locations — both config classes derive it from
storagePath, 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 than storagePath, 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 iterate skips an entry whose commitId is
still null — add stores the entry and stamps its commitId in 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/putMeta store an asserted
createdAt/updatedAt/expiresAt/availableAt faithfully instead of
rederiving, and an asserted expiresAt/availableAt suppresses the
ttl/ttb derivation for that write only. remove accepts deletedAt.
AtMetadataBuilder also derives the inverse on request
(AtAssertedTimestamps.deriveTtl/deriveTtb, set by callers whose own
request supplied the absolute without its relative): an asserted
expiresAt stores the ttl it implies (measured from the stored
updatedAt — from the asserted availableAt when that lies ahead of it),
and an asserted availableAt stores 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 nullable
AtMetaData fields, so internal callers that recycle stored metadata keep
today's server-derived stamping. NOTE for the next release: these are new
named parameters on the AtKeyValueStore interface methods — breaking for
external implementers of the interface (none known besides test mocks,
which tolerate it), fine for callers.
feat: AtCommitLog.commit accepts an opTime (caller-asserted operation
time — a delete's deletedAt, an update's asserted updatedAt), recorded
on the commit entry; and AtCommitLog.removeEntryFor removes a key's
commit entry on both backends (previously reachable only through
backend-specific escape hatches).
feat: put/create/putMeta with skipCommit: true now purge the key's
existing commit entry as well as writing none, matching remove's
established skipCommit behaviour; putMeta gains skipCommit.
fix: the Hive expiry cache tracks keys by their stored
expiresAt/availableAt rather than by ttl/ttb presence, so a record
whose only expiry signal is an asserted expiresAt is swept and stops
being served at its expiry instead of living forever.
fix: Hive remove/removeMany passed 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.
One column per quarter.
feat: AtCommitLog.iterate accepts skipDeletesUntil/latestCommitId, pushing sync's delete-skip into the query. Previously sync fetched every commit ent
feat: AtCommitLog.iterate accepts skipDeletesUntil/latestCommitId,
pushing sync's delete-skip into the query. Previously sync fetched every
commit entry from fromCommitId and discarded below-watermark DELETE entries
in a Dart filter; now the backend excludes them at the source — SQLite in the
SQL WHERE, 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 (no skipDeletesUntil) 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 a NOT (operation = '-' ...) filter over the full commit_id index. The filter form is correct
but its plan walks every row from fromCommitId to 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 by CREATE INDEX IF NOT EXISTS on open, with
no contract-version bump — an existing database acquires it on next start.
perf: SqliteAtCommitLog.iterate streams rows through a prepared cursor
rather than an eager select() that materialised the whole result set before
the caller saw a row. Callers stop early (sync breaks after one page), so an
ordinary sync returning 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: PersistenceMigrator now 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, and PersistenceSnapshot filters 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 as MigrationReport.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
AT0015 until 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
feat: dual-write persistence layer (lib/dual.dart) — serves reads from a primary backend while mirroring every write byte-exactly into a secondary (vi
lib/dual.dart) — serves reads from a
primary backend while mirroring every write byte-exactly into a secondary
(via restore/replay, not operation-replay, so server-stamped timestamps
and commit ids stay identical). Run a real workload once, compare after.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 by
PersistenceSnapshot.differencesFrom (all differences, not just the first).lib/sqlite.dart) implementing the
same spec interfaces as Hive — SqliteAtKeyValueStore (with full-
fidelity supportsSnapshots / supportsPathQueries / true
transactions), SqliteAtCommitLog (dense/gapless counters-based
commit ids), SqliteAtNotificationKeystore, SqliteAtAccessLog,
SqliteAtPersistenceFactory. One atsign.db per atSign; the schema
is a stable per-atSign interchange contract.AtKeyValueStore.restore
and AtAccessLog.replay (symmetric to AtCommitLog.replay) — plus
PersistenceMigrator (backend-agnostic Hive↔SQLite copy) and
PersistenceSnapshot (canonical bundle comparator). AtPersistenceBackendId
gains sqlite. Covered by a conversion-integrity gate:
hive→sqlite→hive→sqlite→hive→sqlite round-trips byte-identically.PersistenceSnapshot tolerates Hive's non-deterministic commit-log
orphans — a non-delete commit entry whose key is absent or expired is skipped.
After a TTL-expiry skipCommit sweep, Hive can leave a stale commit entry in
its box (its cache-based getLatestCommitEntry purge 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 with AT0015. 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.feat: new persistence field AtMetaData.appMetadata carrying the provider-owned AppMetadata from at_commons (opaque to the server). Stored by AtMetaDat
AtMetaData.appMetadata carrying the
provider-owned AppMetadata from at_commons (opaque to the
server). Stored by AtMetaDataAdapter as a JSON-encoded string
(hive field 26); records written before the field existed read
back with appMetadata == null. Mapped in
fromCommonsMetadata / toCommonsMetadata and toJson /
fromJson (the latter accepts both the Map and base64 wire
forms).Major release: persistence-overhaul. Themes:
Major release: persistence-overhaul. Themes:
AtPersistenceFactory / AtPersistenceBundle replace every
legacy getInstance() shim. Backend-pluggable by design.HiveAtCommitLog / HiveAtAccessLog /
HiveAtNotificationKeystore / HiveAtKeyValueStore
implement abstract AtCommitLog / AtAccessLog /
AtNotificationKeystore / AtKeyValueStore. Bundles type
at the abstracts.keyValueStore (core) plus accessLog? and
notificationKeystore? (optional capabilities gated by
AtPersistenceConfig toggles). serverDefaults opts into
every capability; clientDefaults opts into the keystore only.KeyValueStore gains nextExpiresAt / peekExpired (expiry
wake-up + bounded ascending-order drain, on both the main and
notification keystores); AtKeyValueStore gains
nextAvailableAt / peekNewlyAvailable (TTB wake-up + a
caller-side-watermark sweep window); AtCommitLog gains
firstCommittedSequenceNumber (the log's floor, pairing with
lastCommittedSequenceNumber so sync clients can detect
"server no longer retains my delta"). The Hive notification
keystore now maintains an in-memory effective-expiry index
(folding expiresAt, the notificationDateTime + maxTtl
guard, and already-expired-by-shape entries into one
comparable instant), which also backs getExpiredKeys
without 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.AtKeyValueStore widened with ten new primitives for
at_client adoption: exists, scanKeys (with
KeyPattern + ordering + pagination), getMany,
removeMany, changes stream, transaction,
queryByPath (+ supportsPathQueries), snapshot
(+ supportsSnapshots), and stats. Capability flags let a
future SQL backend light up native indexed query / MVCC paths
while Hive falls back gracefully.SecondaryKeyStore renamed to AtKeyValueStore;
HiveSecondaryKeyStore renamed to HiveAtKeyValueStore.
Bundle field keyStore renamed to keyValueStore.
Keystore (read-only), WritableKeystore, and
SynchronizableKeyStore collapsed into a single
KeyValueStore<K, V> interface that holds the merged
CRUD + rich surface (scan, bulk, expire, change stream,
transaction, snapshot, stats). AtKeyValueStore<K, V, T>
extends KeyValueStore and adds the sync-coupled surface:
the (nullable) commitLog, putMeta / putAll /
getMeta, and queryByPath / supportsPathQueries.scanKeys / KeyPattern live on AtKeyValueStore, not
KeyValueStore. Structured filtering (KeyPattern's
sharedBy / sharedWith / namespace / idPrefix) is
atKey-shaped, so it belongs on the atKey-aware tier rather than
the generic key-value contract. KeyValueStore.exists and the
pre/post-remove hook callbacks are typed at the generic key K
(was String), since they don't carry the atKey assumption. A
new AtKeyValueStoreSnapshot extends KeyStoreSnapshot adds
scanKeys on top of the base snapshot for the same reason;
HiveAtNotificationKeystore (and its snapshot) no longer carry
the awkward scanKeys impl that only honoured idPrefix.AtData, AtMetaData,
CommitEntry, AccessLogEntry and AtNotification no longer
carry Hive's @HiveType / @HiveField annotations (they were
dead — no codegen) or extends HiveObject. The hand-written
TypeAdapters moved to lib/src/hive/adapters/ (re-exported by
the barrel; on-disk wire format unchanged). AtData and
CommitEntry keep a transient, non-serialized key field that
the keystore populates on read, replacing the HiveObject.key
that Hive used to auto-stamp. The five models are now plain Dart
objects — the seam a future SQLite/Postgres backend needs.HiveAtKeyValueStore value type tightened to non-null
AtData. The main keystore now implements
AtKeyValueStore<String, AtData, AtMetaData?> (was
<String, AtData?, AtMetaData?>), and AtPersistenceBundle
surfaces it as such. put / create / putAll reject a
null value at compile time instead of crashing on an internal
value!; getMany returns Map<String, AtData>. get is
unchanged — it still returns Future<AtData?> (null for an
absent key). The metadata type parameter stays nullable
(AtMetaData?) since getMeta legitimately returns null.KeyValueStore.getKeys,
getExpiredKeys and scanKeys now return
Future<Stream<…>>; LogKeyStore.getExpired and
AtCommitLog.getChanges likewise return Future<Stream<…>>.
The Future completes once the backend has accepted the
request (so setup failures — store not open, invalid regex —
reject eagerly rather than mid-stream); the Stream then
yields the results. The synchronous isKeyExists is removed —
use the async exists (the two were duplicates; exists is
the backend-agnostic shape SQL backends need).AtKeyValueStore.commitLog is nullable, end to end.
Server bundles hold a non-null commit log on the keystore;
client bundles hold null (sync via fsync or other
mechanism). AtPersistenceConfig.enableCommitLog (default
true; serverDefaults → true, clientDefaults → false)
selects which — when false the factory builds the keystore
commit-log-free and never opens the commit-log box.
HiveAtKeyValueStore honours a null commit log throughout:
put / create / putAll / putMeta / remove /
removeMany succeed and return null (no sequence number),
and compact() 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.AtPersistenceBundle.commitLog is gone; reach it as
bundle.keyValueStore.commitLog!.AtNotificationKeystore re-parented to KeyValueStore.
No longer extends the AtKeyValueStore tier — notifications
don't participate in the commit log. Drops the six
UnimplementedError stubs and the no-op commitLog
override that the old interface forced on it. Notification
keystore implementations stop pretending to support
putMeta / putAll / getMeta / queryByPath. Now
strongly typed KeyValueStore<String, AtNotification>
(was <dynamic, dynamic>) — keys are notification ids,
values are AtNotification; consumers no longer cast.Compactable interface (one method: Stream<Object> compact(bool dryRun)) replaces AtCompactionStrategy,
HiveCompactionStrategy, AtCompaction, AtLogType,
AtCompactionConfig, and AtCompactionStats — all
deleted. AtCommitLog, AtAccessLog,
AtNotificationKeystore, and AtKeyValueStore all
implement Compactable. The Hive impls each carry their
own compactionPercentage constructor parameter; on
compact(false) they yield the items removed,
compact(true) yields what would be removed.at_secondary_server.
The persistence layer no longer schedules anything — the
secondary server runs three Timer.periodic ticks with
overlap guards. AtCompactionJob deleted.
AtCompactionStatsService.record() takes primitives
(label, start, compactedCount, duration) instead
of an AtCompactionStats object.AtPersistenceConfig compactor flags removed.
enableCommitLogCompactor / enableAccessLogCompactor /
enableKeyStoreCompactor moved to AtSecondaryConfig
(with enableKeyStoreCompactor → enableNotificationCompactor,
matching the resource it actually gates).replay(CommitEntry) and
iterate({fromCommitId, where}) on AtCommitLog, plus
iterate() on access log + notification keystore. Lazy box-
walks; no upfront map materialisation.CommitLogKeyStore.add() plus a
startup dedup migration. CommitLogCompactionService and
CompactionSortedList retired (their job is done eagerly by
the write path).AtCommitLog.getEntries retired. Migrate to
iterate(fromCommitId, where: closure); the closure carries
any caller-side filtering (regex, skipDeletesUntil, etc.).dynamic. CRUD
methods on KeyValueStore now return Future<int?>
(commit-log sequence number or null) instead of
Future<dynamic>. KeyValueStore.get is Future<V?>
instead of Future<V>?. LogKeyStore.add returns
Future<int> (Hive-assigned key); update/remove return
Future<void>; getFirstNEntries returns List<int>;
getExpired returns Future<List<K>>. AtAccessLog's
mostVisitedAtSigns / mostVisitedKeys return
Future<Map<String, int>>. Pre/post-remove hook callbacks
are Future<void> Function(...). Call sites can drop
as int? / as AtData? / as Map casts.AtKeyValueStore.deleteExpiredKeys drops skipCommit.
Expiry is treated as backend-local maintenance: the sweep
never advances commitId and never propagates via sync.AtKeyValueStore.commitLog typed AtCommitLog? rather
than AtLogType?. Callers no longer need as AtCommitLog
at every access site.HiveAtNotificationKeystore.commitLog is a no-op
getter/setter instead of a mutable field — notifications
never participate in the commit log.SyncProgressiveVerbHandler empty-response wedge fixed.
When every entry in a requested range failed isAuthorized
(or another in-loop filter), the handler returned [] and
the client could not advance its from watermark. The
switch to iterate(where:) makes the scan unbounded; the
client now always sees forward progress. No wire-format
change.AtConfig moved out of this package into
at_secondary_server. Block-list writes pass
skipCommit: true and don't bump the local commitId.AtPersistenceBundle.clear()
drops every entry from each store while keeping underlying
boxes open.at_persistence_spec dropped. The
interface types this package previously imported from
at_persistence_spec (AtKeyValueStore, exceptions, the
@server/@client annotations, 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 on
at_persistence_secondary_server for the interface types
they need to satisfy.AtPersistenceBundle
exposes bool get isClosed. AtPersistenceFactory gains
Future<void> closeFor(String atSign) — closes a single bundle
and drops the factory's reference. initialize and bundleFor
now treat a closed entry as absent (a closed bundle is dropped
and rebuilt on next initialize, and bundleFor returns
null), so a caller closing a bundle directly via
bundle.close() can no longer cause the factory to hand out a
stale closed reference.StoreType enum,
AtCommitLog.firstCommittedSequenceNumber (no callers), the
NullCommitEntry sentinel (the package returns null, never a
sentinel), and the vestigial LogKeyStore interface — one
implementer, no consumers — along with the orphaned keystore
methods it carried (getExpired, and the commit-log keystore's
getFirstNEntries).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.
perf: NullCommitEntry is now a singleton — no fresh DateTime.now() allocation per commit-log miss
NullCommitEntry is now a singleton — no fresh DateTime.now()
allocation per commit-log missHiveKeystore.getKeys caches compiled RegExp patterns in a
bounded LRU and captures DateTime.timestamp() once per call,
threading it into _isExpired / _isBorn / _isKeyAvailable so each
key check no longer allocates two DateTime objectsDateTime.now().toUtc() replaced with DateTime.timestamp()
(one allocation instead of two) on the keystore expiry, notification
expiry, access-log and commit-log hot pathsHiveKeystore.create no longer builds a 17-element Set per
put just to ask "any metadata field non-null?" — replaced with a
direct null-check chainfix: Make AtNotificationKeystore.getExpiredKeys more memory efficient
fix: Fix the expiresAt and ttl rules in AtNotificationBuilder.build
expiresAt and ttl rules in AtNotificationBuilder.buildfix: backwards compatibility: revert AtNotificationKeystore.currentAtSign to a non-final instance variable
feat: deprecated AtNotificationCallback class
chore(deps): bump uuid to ^4.0.0
^4.0.0^5.5.0feat: Add preRemoveHook and postRemoveHook to KeyStore interfaces
preRemoveHook and postRemoveHook to KeyStore interfacesrefactor: Take up new major version 3.0.0 of at_persistence_spec, update and simplify the HiveKeyStore implementation accordingly
immutable flagfeat: commit log changes for sync skipDeletesUntil feature
feat: Add "PublicKeyHash" to the "AtMetadata" which holds the hash value of encryption public key
fix: Modified checks in commit log keystore _alwaysIncludeInSync method to match only reserved shared_key, encryption public key and public key withou
build[deps]: Upgraded the following packages:
fix: Ensure only latest commitEntry for each present in CommitLogCache
fix: Add check for hive key max length (255 chars)
feat: delete entries for expired keys are not committed to the commitLog [feature not enabled yet]
build[deps]: Upgraded the following packages:
fix: When checking namespace authorization, gracefully handle any malformed keys which happen to be in the commit log for historical reasons
fix: Modify "lastCommittedSequenceNumberWithRegex" to return highest commitId among enrolled namespaces
fix: Refactor commit log keystore to optimize memory usage
fix: Refactor Hive keystore to optimize memory usage
Nothing published for this version
fix: Add NotificationType.Self in read and write methods of at_notification.dart
feat: Introduced self notification type in enum for apkam enrollment
feat: Add new encryption metadata fields to core persistence classes
feat: Extend sanity-checking of server-side commitLog upon startup
refactor: Deprecate at_metadata_adapter; extract the 'to' and 'from' commons Metadata methods from there into the AtMetaData class itself
fix: AtData.toJson() now works when the key is null
fix: Ensure HiveKeystore's metaDataCache's keys are in lower case
feat: conform to at_persistence_spec 2.0.11
fix: AtMetadata.version does not update on the update of a key
fix: Introduce "isScheduled" method in "AtCompactionService" to know if the compaction job is running
- fix: Refactor AtCompaction job
fix: Fetch only commit entries with 'null' commit-id for uncommitted entries in at_client persistence
fix: rollback keystore delete KeyNotFoundException
fix: store actual keys in hive keystore metadata cache instead of encoded keys
feat: Refrain adding local keys to commit log.
fix: lastSyncedEntry to accept signing private key
fix: Revert sync of signing keys and 'statsNotificationId'
fix: skip commit id for the 'statsNotificationId'
fix: skip commit id and sync for signing keys
fix: Randomize the cron job's start interval
fix: Reverted dependency on 'meta' package to ^1.7.0 as flutter_test package (currently) requires 1.7.0
feat: added key validation to keystore put and create methods
Add 'encoding' to AtMetadata which represents the type of encoding
Invalidate commit log cache on removing entry from commit log
Enhance KeyNotFoundException to chain into exception hierarchy.
Introduced option to stop current schedule of a compaction job
Updated lastSyncedEntryCacheMap regex to match the reserved keys
Downgrade meta package to 1.7.0(minimum) version
Replace null commitId's with hive internal key on secondary server startup
To reduce latency on notifications, publish the event for the notification before persisting the notification
Introduced a cache to speed up metaData retrieval.
Add remove method in NotificationManagerSpec.
- Bumped some dependencies
Upgrade at_lookup and at_commons for NotifyRemove
Your coding agent can read these notes before it upgrades. Set up the MCP server →