Documentation
¶
Overview ¶
Package localstore is the naming, existence and tag fence for the server's device-local any-store collections (task-local-store.md).
Local collections are plain any-store collections — no CRDT, no handler, never synced — that live in the SDK's own sdk.db so that a pipeline can one day join or roll synced data into them. They share the file under one contract: every local collection carries the "l_" tag, the SDK never emits a tagged name, and nothing in this package can address an untagged one. ParseRef / ParseStorageName are that contract's single chokepoint; the tag is applied by Ref.StorageName and nowhere else.
The store owns no lifecycle: the SDK opens and closes the DB, the store borrows the handle.
Index ¶
- Constants
- Variables
- type ImportError
- type Info
- type Manifest
- type ManifestCollection
- type ManifestIndex
- type Ref
- type Scope
- type Store
- func (s *Store) Collection(ctx context.Context, ref Ref) (anystore.Collection, error)
- func (s *Store) Drop(ctx context.Context, ref Ref) error
- func (s *Store) Ensure(ctx context.Context, ref Ref, indexes []anystore.IndexInfo) (created bool, err error)
- func (s *Store) Export(ctx context.Context, refs []Ref, w io.Writer) error
- func (s *Store) Import(ctx context.Context, r io.Reader) ([]Info, error)
- func (s *Store) List(ctx context.Context, scope Scope, spaceId string) ([]Info, error)
Constants ¶
const ( // FormatName / FormatVersion identify the manifest. A reader // refuses any other pair — there is no compatibility promise // across versions. FormatName = "any-local-export" FormatVersion = 1 )
Variables ¶
var ( // ErrBadName reports a scope / spaceId / name that fails validation. ErrBadName = errors.New("localstore: bad collection reference") // ErrNotFound reports a reference whose collection has not been ensured. ErrNotFound = errors.New("localstore: collection not found") // ErrNotLocal reports a storage name that does not carry the local tag — // an SDK-owned collection this package refuses to address. ErrNotLocal = errors.New("localstore: not a local collection") )
var ErrBadExport = errors.New("localstore: bad export file")
ErrBadExport reports a file that is not an export this version reads: not gzip, not an anyenc stream, a foreign or newer manifest, a section shorter than its count, a non-object document, or bytes past the last section.
Functions ¶
This section is empty.
Types ¶
type ImportError ¶
ImportError names the collection an import failed on. Sections before it are committed (chunked writes, like every /v1/local write); the failing collection may be partially written.
func (*ImportError) Error ¶
func (e *ImportError) Error() string
func (*ImportError) Unwrap ¶
func (e *ImportError) Unwrap() error
type Manifest ¶
type Manifest struct {
Format string
Version int
// ExportedAt is unix milliseconds, informational.
ExportedAt int64
Collections []ManifestCollection
}
Manifest is the stream's first value.
type ManifestCollection ¶
type ManifestCollection struct {
Ref
StorageName string
Count int
Indexes []ManifestIndex
}
ManifestCollection describes one section: the collection's ref, its tagged storage name (informational — import re-derives it), the exact number of documents that follow, and the range indexes to recreate.
type ManifestIndex ¶
ManifestIndex is a range index: the only kind the local store exposes, and the only kind import will create.
type Ref ¶
Ref addresses one local collection.
func ParseRef ¶
ParseRef validates the wire triple and returns the Ref. It is the one chokepoint every path goes through — wire bodies, internal Drop, and $out / $merge / $lookup targets (via SinkTarget).
func ParseStorageName ¶
ParseStorageName is the inverse of StorageName: the fixed-segment split of an any-store collection name. ok is false for every untagged name (SDK collections included) and for a tagged name that does not re-validate through ParseRef.
func SinkTarget ¶
SinkTarget validates a collection name a client put INSIDE a pipeline ($out / $merge target, $lookup from) — the one place a raw storage name arrives from the wire. It must be a tagged name that round-trips through ParseRef; anything else is ErrNotLocal.
func (Ref) StorageName ¶
StorageName is the tagged any-store name — the only place the tag is applied. Exposed for callers that must hand a name to any-store themselves (sink-target rewriting).
type Scope ¶
type Scope string
Scope is where a local collection is bound.
const ( // ScopeAccount lives as long as the account dir. Storage name "l_a_<name>". ScopeAccount Scope = "account" // ScopeSpace is bound to a space by id. Storage name // "l_s_<spaceId>_<name>". Nothing drops it when the space goes — a // space-scoped collection outlives its space (task-local-store.md). ScopeSpace Scope = "space" )
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store fences a borrowed any-store DB to the local tag.
func (*Store) Collection ¶
Collection returns the handle for an ensured collection, ErrNotFound otherwise. The DB caches open handles; callers do not close them.
func (*Store) Ensure ¶
func (s *Store) Ensure(ctx context.Context, ref Ref, indexes []anystore.IndexInfo) (created bool, err error)
Ensure creates the collection if absent and ensures the given indexes on it, atomically: create and index DDL share one write transaction, so a rejected index never leaves a freshly created, index-less collection behind. created reports whether this call made it.
func (*Store) Export ¶
Export streams the named collections to w as one gzip'd anyenc stream. Everything is resolved before the first byte — a missing collection is ErrNotFound (wrapped with its storage name), never a truncated stream. Duplicates in refs are exported once.
func (*Store) Import ¶
Import loads an export into this store: each collection is ensured with the file's indexes (idempotent — an existing collection keeps its documents, a different definition under the same index name is any-store's ErrIndexMismatch) and its documents are upserted 256 per transaction, so re-importing the same file is a no-op and a newer export of the same collections overlays the older. No space pre-flight: the file's spaces need not exist here — that is the point (a reporter's traces on a developer's scratch server). The returned Infos cover the collections written, in file order; on an error they are the ones completed before the *ImportError.