localpocket library

LocalPocket — a local-first SQLite database with PocketBase sync.

One import gives you the whole destination API: open a LocalPocket, declare each store once as a StoreDef, and work with typed Stores, immutable Row snapshots, declarative QuerySpec/SearchSpecs, interactive Transactions, committed-change events, store-scoped Files/StoreConflicts, and the PocketBaseSync attachment. The same import compiles on mobile, desktop, and web — the facade runs over the direct runtime on native targets and the worker contract runtime on web.

import 'package:localpocket/localpocket.dart';

final db = await LocalPocket.open(
  LocalPocketOptions(path: 'app.db', stores: [Tasks.store]),
);
final tasks = db.store(Tasks.store);
await tasks.put([Tasks.title.set('Ship it')]);

Classes

AllCond<S>
A conjunction — the children AND together.
AnyCond<S>
A disjunction — the children OR together.
AppendOnlyLinesResolver
Append-only LINES resolver for string fields.
AppendOnlyListResolver
Append-only LIST resolver: base + local + remote with deduplication.
BackendCapabilities
Capabilities negotiated with a synchronization backend.
BackendHint
Backend event hint that triggers pull or fast-path processing.
BlobStore
BlobStore interface.
BoolFieldOpt<S>
Optional (nullable bool) boolean descriptor.
BoolFieldReq<S>
Required (non-nullable bool) boolean descriptor.
BootstrapOptions
Remote-runtime bootstrap: where the worker script and SQLite WebAssembly assets live, and how long a round-trip may take before it fails.
Cond<S>
One node of a typed predicate tree — a leaf predicate or a composed boolean expression.
Conflict<S extends StoreDef<S>>
{@template localpocket.conflict} One immutable open conflict snapshot for a store.
ConflictPolicy
Conflict resolution policy. Resolver implementations are provided by the sync layer; this type exists now so CollectionSchema can carry it.
ConflictResolver
Abstract interface for whole-record or field-level conflict resolution.
CounterResolver
Counter resolver: base + (local − base) + (remote − base).
Cursor<S extends StoreDef<S>>
{@template localpocket.cursor} An opaque continuation token minted by the kernel for one page of one query shape. It is meaningful only to the same store, order, and scope it was minted under — replaying it against a different shape fails with StaleCursorError. {@endtemplate}
CustomResolver
Custom resolver wrapping a user-supplied function.
Database
Database handle extending DatabaseExecutor with transaction and statement management.
DatabaseEncryptionConfig
Whole-database (file-level) at-rest encryption: the key the database ENGINE applies (SQLCipher / SQLite3MultipleCiphers), NOT a Dart-side encryptor. Field-level secrets stay in EncryptionConfig.
DatabaseRecordChange
A committed change to one record of one store.
DateFieldOpt<S>
Optional (nullable int) date descriptor.
DateFieldReq<S>
Required (non-nullable int) date descriptor.
DateTimeFieldOpt<S>
Optional (nullable DateTime) date-time descriptor.
DateTimeFieldReq<S>
Required (non-nullable DateTime) date-time descriptor.
DirectSqliteDatabase
A direct synchronous-backed implementation of Database wrapping CommonDatabase.
EncryptionConfig
At-rest encryption for declared SQLite field columns.
EngineCapabilities
What the underlying engine supports, as observed at open time — the active runtime's honest report; on web the worker's handshake is authoritative.
EnumFieldOpt<S, E extends Enum>
Optional (nullable E) enum descriptor.
EnumFieldReq<S, E extends Enum>
Required (non-nullable E) enum descriptor.
ExtraWrite<S extends StoreDef<S>>
An undeclared extra key write produced by Writes.extra. Keys are validated against the target store when the write is applied.
FieldCipher
App-supplied cipher interface for field-level at-rest encryption.
FieldCond<S>
One typed predicate operator over one field of one store.
FieldDef<S, T>
A typed field descriptor for store type S holding logical values of type T.
Fields<S>
The per-store field factory.
FieldWrite<S extends StoreDef<S>>
A declared-field write produced by field.set(value); encoded has already passed through the descriptor's boundary codec.
FileRef
One immutable file reference: the typed view of the contract's FileRefData — a wire-safe snapshot of one lp_file_refs row. Bytes live in the runtime's blob store; metadata lives in the kernel.
Files<S extends StoreDef<S>>
{@template localpocket.files} File attachments and blob lifecycle for one store.
FileSource
A bounded attachment source: the bytes to attach plus the optional declared length and display name.
FtsNormalization
Consumer-declared character parity rules for full-text search.
FtsSpec
Enables FTS5 over the declared text fields in fields.
IdWrite<S extends StoreDef<S>>
An explicit record id write produced by Writes.id. the database generates a [a-z0-9]{15} id when a put omits it; patch/patchAll reject this write because record ids are immutable.
IndexSpec
Declares a SQLite index for one or more fields.
IntFieldOpt<S>
Optional (nullable int) integer descriptor.
IntFieldReq<S>
Required (non-nullable int) integer descriptor.
JsonField<S>
JSON-object descriptor (Map<String, Object?>), optional by definition.
JsonListField<S, T>
JSON-array descriptor (List<T>), optional by definition.
Limits
Page-size sentinels for typed reads.
LocalPocket
{@template localpocket.local_pocket} A local-first database with PocketBase sync.
LocalPocketOptions
Everything LocalPocket.open needs to bring up a database.
LocalWinsResolver
Local wins: for concurrently modified fields, take local.
MemoryBlobStore
In-memory implementation of BlobStore, useful for hermetic testing and web mock.
MergeContext
Context passed to a ConflictResolver.
MergeResult
Result of a resolver or 3-way merge operation.
NativeBlobStore
Native filesystem implementation of BlobStore.
NotCond<S>
A negation — SQL NOT (...) around child.
NumericFieldDef<S>
Marker implemented only by descriptor kinds accepted by typed numeric aggregate terminals.
OrderTerm<S>
One ordering term, built through a descriptor's asc/desc getters. The database supplies its normal id tiebreaker.
Page<S extends StoreDef<S>>
The result of a paginated query.
PageCallbacks
Database-level container for everything the page executes on the worker runtime.
PocketBaseSync
{@template localpocket.pocket_base_sync} One synchronization host for a LocalPocket.
PocketBaseSyncOptions
Configuration for LocalPocket.attachPocketBaseSync.
PushOp
An outbox op encoded for a single push (create vs update by baseUpdated). One desired record state prepared for a backend push.
PushResult
Result of one remote push operation.
QuerySpec<S extends StoreDef<S>>
One declarative read: predicate, order, projection, scope, page size.
RealFieldOpt<S>
Optional (nullable num) real-number descriptor.
RealFieldReq<S>
Required (non-nullable num) real-number descriptor.
RefField<S>
Reference descriptor (a record id of type String), optional by definition.
RemoteRecord
A record received from or sent to a synchronization backend.
RemoteWinsResolver
Remote wins (default): for concurrently modified fields, take remote.
Row<S extends StoreDef<S>>
{@template localpocket.row} One immutable typed record snapshot.
SearchHit<S extends StoreDef<S>>
{@template localpocket.search_hit} One full-text search hit: the record id, its relevance score, and a lazy typed fetch of the record. {@endtemplate}
SearchSpec<S extends StoreDef<S>>
One declarative full-text search: term, page size, scope.
SettableFieldDef<S, T>
Marker for descriptors whose values are writable through field-native writes (field.set(value) collected into put([...]) / patch(...)).
SetUnionWithDeletionWinsResolver
Set union with deletion wins: base ∪ (local − base) ∪ (remote − base) minus deletions from either side. For list/set fields.
Store<S extends StoreDef<S>>
{@template localpocket.store} Typed CRUD, queries, search, and watches for one store.
StoreConflicts<S extends StoreDef<S>>
{@template localpocket.store_conflicts} Conflict listing, watching, and resolution for one store.
StoreDef<S extends StoreDef<S>>
The typed definition of one store: the consumer-facing home of the store's field descriptors and the schema extras (indexes, fts, migrations, conflictPolicy, documentMigrations, validator).
StoreMigration
A store schema migration step.
StorePageCallbacks
The page-declared callbacks one store's executable features resolve to.
StoreRecordChange<S extends StoreDef<S>>
A committed change to one record of one typed store, with typed row snapshots.
StreamFileUpload
Replayable file source for streamed backend uploads.
SyncBackend
Backend contract used by SyncEngine for pull, push, realtime, and files.
SyncBackendFactory
Builds a SyncBackend for the runtime's sync start command and releases adapter-owned state (realtime connection, HTTP client) on stop. The adapter layer supplies the implementation; the runtime depends only on this seam, never on a concrete adapter.
SyncTokenSource
The neutral credential source the runtime owns: adapters bridge it onto their own credential types. The bearer value never persists or logs.
TextFieldOpt<S>
Optional (nullable String) text descriptor.
TextFieldReq<S>
Required (non-nullable String) text descriptor.
Token
The sync-boundary token vocabulary.
TokenProvider
Supplies and refreshes authentication tokens for a synchronization backend. This is the vocabulary of the sync boundary — concrete backends implement it; the facade consumes it; the runtime owns the bridging onto SyncTokenSource.
Transaction
{@template localpocket.transaction} One open interactive transaction session. {@endtemplate}
WipeResult
Outcome of LocalPocket.wipe: how many domain rows and blob bytes were dropped.
Write<S extends StoreDef<S>>
One typed write: a declared-field assignment, an explicit record id, or an undeclared extra key.
Writes
Namespace for the non-field writes: explicit record ids and undeclared extra keys.

Enums

BackendHintKind
Kind of event signaled by a backend realtime hint.
ChangeAction
The specific mutation action performed on a record.
ChangeOrigin
The origin of a record mutation event.
DurabilityClass
Durability class for a transaction.
IndexScope
Controls which records are included in an index.
MissingRemotePolicy
Policy applied when a pushed update's target record no longer exists remotely (a remote deletion raced a local offline edit).
SyncEngineState
Lifecycle state of a SyncEngine.

Mixins

ComparableFieldDef<S, V>
Kind-scoped comparison operators mixed into integer, real, date, and date-time descriptors.
EnumCodec<E extends Enum>
Shared enum codec members for the optional/required enum descriptor pair: value snapshot, wire mapping, raw decode.
NullableFieldCond<S, V>
The null-testing member, mixed into every OPTIONAL (nullable) descriptor.
TextFieldDef<S, V extends String?>
Kind-scoped LIKE operators mixed into text descriptors.

Extensions

FieldSet on SettableFieldDef<S, V>
Builds one Write per assignment on every settable field descriptor.

Constants

pbMaxPage → const int
PocketBase's hard per-page ceiling: a list perPage above this is rejected with a 400 (and an absent perPage defaults to 30). The engine clamps every page size to this so a configured maxPage above the cap still converges.

Functions

decodeStored<V>(FieldDef<Object?, V> field, Object? raw) → V
Decodes raw through field and wraps any failure other than a ValidationException in one naming the field — a corrupt stored value never surfaces as a bare cast error.
ftsSpec<S>(List<FieldDef<S, Object?>> fields, {bool fuzzy = false, FtsNormalization normalize = const FtsNormalization()}) → FtsSpec
Builds an FTS declaration from store-owned field descriptors.
indexSpec<S>(List<FieldDef<S, Object?>> fields, {bool unique = false, IndexScope scope = IndexScope.live}) → IndexSpec
Builds an index declaration from store-owned field descriptors.
lowerAggregateSpec<S extends StoreDef<S>>(List<Cond<S>> where, S def, {bool includeArchived = false, bool includeHidden = false}) → QuerySpecData
Builds a no-page-size spec for the aggregate terminals (aggregates never paginate, so they always run unbounded).
lowerPredicate<S extends StoreDef<S>>(List<Cond<S>> where, S def) → PredicateSpecData?
Lowers an AND-list of condition trees into one serializable predicate tree. An empty list carries no predicate (match everything).
lowerQuerySpec<S extends StoreDef<S>>(QuerySpec<S> spec, S def, {bool requireLimit = false, String? cursor, bool backward = false}) → QuerySpecData
Lowers one spec into contract data. requireLimit marks the paging terminals: they refuse to run without a page size or an explicit unbounded, mirroring the kernel's own refusal to guess limits.
lowerSearchSpec<S extends StoreDef<S>>(SearchSpec<S> spec, S def, {bool requireLimit = false}) → SearchSpecData
Lowers one search spec into contract data.
projectedOf<S extends StoreDef<S>>(QuerySpec<S> spec) → Set<String>?
The projection set a spec implies: the selected field names, or null when the spec projects nothing (full rows).
translateConstraintError(Object e, {Map<String, Object?>? record}) → LocalPocketError
Translates a SQLite exception or error into a typed LocalPocketError. record (if given) is used to extract the offending value for unique violations.
typedStoreMismatch({required Object? owner, required String name, required Object? target, required String targetKind}) → TypedStoreMismatchError
The cross-store mismatch thrown when an identity check finds a foreign definition — the runtime backstop behind the compile-time phantom types.

Typedefs

FieldDecodeFn<T> = T Function(Object? raw)
Decodes a raw stored value into a value of type T.
FieldEncodeFn<T> = Object? Function(T value)
Encodes a value of type T into its raw logical-map form.
SyncReport = SyncReportData
Historical name for SyncReportData.
SyncStatus = SyncStatusData
Historical name for SyncStatusData.

Exceptions / Errors

AuthError
401 — refresh once, then AuthRequired (never rewrites rows).
BatchFailedError
A transactional batch failed as a whole (poison item).
CheckConstraintException
A SQLite CHECK constraint was violated.
ConflictBlockedError
A mutation was attempted on a record held in conflict.
ConflictNotFoundException
A conflict resolution was attempted for a record with no open conflict (or no record at all).
DestructiveMigrationRefusedError
A destructive migration was refused because the backup step is unavailable.
DuplicateIdError
A create retried after a lost response (duplicate-id).
FieldNotSelectedError
A field excluded by a projection (select) was read from a row snapshot.
ForbiddenError
403 — quarantine, no retry.
ForeignKeyConstraintException
A SQLite FOREIGN KEY constraint was violated.
FtsUnavailableError
FTS5 is not available on this SQLite engine or FTS is not configured for the store.
LocalPocketError
Root of all typed errors thrown by localpocket.
MissingLimitError
A query was executed without a limit and without .all().
NotFoundError
404 on a targeted fetch is AMBIGUOUS — never a delete.
NotNullConstraintException
A SQLite NOT NULL constraint was violated.
PayloadError
400 validation / too large — dead-letter with the server message.
PrimaryKeyConstraintException
A SQLite PRIMARY KEY constraint was violated.
ProtocolError
Unparseable / contract violation — log loudly.
ReadOnlyTxError
A write was attempted through a read-only Tx handle.
RecordNotFoundException
A record the caller expected to exist does not.
RemoteOnlyError
A file attachment's bytes are not local: the reference exists only as metadata (remote_only). Open it with files.download(ref) first, or enable prefetchFiles on the store and sync.
RemoteVersionConflict
A write was rejected because the record's remote version moved since the client's optimistic-concurrency read. The pusher re-fetches, re-merges against current, and retries instead of overwriting the concurrent edit.
SchemaRegistrationError
A schema declaration is invalid (reserved column, encrypted+indexed, ...).
SchemaTooNewError
The on-disk schema is newer than this package version supports.
ServerBusyError
408 / 429 — honor Retry-After; 429 throttles the whole lane.
ServerError
5xx — retry with backoff, escalate after N attempts.
StaleCursorError
A keyset cursor was replayed against a different query shape.
StorageError
Storage-level failure (SQLITE_FULL, IOERR, BUSY, CORRUPT, ...).
SyncError
Base class for typed synchronization failures.
SyncIdentityError
Sync start refused: no stable per-account identity is available. Sharing one sync scope across accounts would silently bleed cursors and watermarks, so the backend fails loudly instead.
TransientNetworkError
Timeout / connection reset / DNS — retry with backoff.
TypedStoreMismatchError
A store definition was bound under a name already owned by a different definition instance.
UniqueConstraintException
A SQLite unique constraint was violated.
UnsupportedSchemaFeatureError
A schema declared an executable feature the runtime cannot serve (a validator callback, a document-migration transform, a custom conflict resolver) without a callback channel that executes it. On the worker runtime this means the feature was not registered in the open call's page callbacks. Thrown BEFORE any DDL, migration, or worker registration — the schema is never silently reduced.
ValidationException
Caller bug / bad input — never retried.