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 + remotewith 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
CollectionSchemacan 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
DatabaseExecutorwith 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
extrakey 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
Sholding logical values of typeT. -
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 onelp_file_refsrow. 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/descgetters. 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 intoput([...])/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
SyncEnginefor 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
extrakey. - Writes
-
Namespace for the non-field writes: explicit record ids and undeclared
extrakeys.
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
Functions
-
decodeStored<
V> (FieldDef< Object?, V> field, Object? raw) → V -
Decodes
rawthroughfieldand 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< fields, {bool fuzzy = false, FtsNormalization normalize = const FtsNormalization()}) → FtsSpecS, Object?> > - Builds an FTS declaration from store-owned field descriptors.
-
indexSpec<
S> (List< FieldDef< fields, {bool unique = false, IndexScope scope = IndexScope.live}) → IndexSpecS, Object?> > - Builds an index declaration from store-owned field descriptors.
-
lowerAggregateSpec<
S extends StoreDef< (S> >List< Cond< where, S def, {bool includeArchived = false, bool includeHidden = false}) → QuerySpecDataS> > - 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< where, S def) → PredicateSpecData?S> > - 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.
requireLimitmarks 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
nullwhen 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
Tinto 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.
- 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 withfiles.download(ref)first, or enableprefetchFileson 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.