Documentation
¶
Overview ¶
Package settings persists values through registered, typed key declarations. Form presentation is separate from the value codec and grants no access rights.
Index ¶
- Constants
- func Migrations() []migrate.Definition
- type Batch
- type Cursor
- type Filter
- type Group
- type Key
- func (k Key[V]) Configure(ctx context.Context, m *Manager, p Presentation) error
- func (k Key[V]) Create(ctx context.Context, m *Manager, input V) error
- func (k Key[V]) Decode(ctx context.Context, r Record) (V, error)
- func (k Key[V]) Ensure(ctx context.Context, m *Manager, input V) error
- func (k Key[V]) EnsureIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error
- func (k Key[V]) Find(ctx context.Context, m *Manager) (value.Optional[Record], error)
- func (Key[V]) Format(s fmt.State, _ rune)
- func (k Key[V]) From(ctx context.Context, b Batch) (value.Optional[V], error)
- func (k Key[V]) FromOr(ctx context.Context, b Batch, fallback V) (V, error)
- func (k Key[V]) Get(ctx context.Context, m *Manager) (value.Optional[V], error)
- func (k Key[V]) GetOr(ctx context.Context, m *Manager, fallback V) (V, error)
- func (k Key[V]) Name() Name
- func (k Key[V]) Registration() Registration
- func (k Key[V]) RegistrationWith(options Options[V]) Registration
- func (k Key[V]) Remove(ctx context.Context, m *Manager) (bool, error)
- func (k Key[V]) ResetPresentation(ctx context.Context, m *Manager) error
- func (k Key[V]) Set(ctx context.Context, m *Manager, input V) error
- func (k Key[V]) SetIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error
- func (k Key[V]) Upsert(ctx context.Context, m *Manager, input V) error
- func (k Key[V]) UpsertIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error
- func (k Key[V]) Validate() error
- func (k Key[V]) Version() Version
- type Kind
- type Manager
- type Name
- type Options
- type Page
- type Presentation
- type Reconciliation
- type Record
- func (r Record) Configured() bool
- func (r Record) CreatedAt() temporal.DateTime
- func (r Record) DynamicValue() (json.RawMessage, error)
- func (Record) Format(s fmt.State, _ rune)
- func (Record) MarshalJSON() ([]byte, error)
- func (r Record) Name() Name
- func (r Record) Presentation() Presentation
- func (r Record) UpdatedAt() temporal.DateTime
- func (r Record) Version() Version
- type Registration
- type Selection
- type Upgrade
- type Version
Constants ¶
const ( MigrationOrigin migrate.Origin = "foundry.settings" CreateSettings migrate.ID = "000001_create_settings" AddPresentationOwnership migrate.ID = "000002_add_presentation_ownership" Introduced migrate.Version = "v0.1.0" )
const ( DefaultPageSize = 100 // MaxLoadBytes bounds the stored JSON retained by one List, Load or LoadGroup. // ListPage never fails on aggregate size: it ends a page early instead. MaxLoadBytes = 64 << 20 )
const MaxCacheTTL = time.Hour
MaxCacheTTL bounds how long a process may serve a cached setting. It is also the upper bound on staleness after a write made by another process.
Variables ¶
This section is empty.
Functions ¶
func Migrations ¶
func Migrations() []migrate.Definition
Migrations returns the settings table history. Rows existing before presentation ownership keep their stored presentation (declared=false); ResetPresentation hands a row back to its declaration explicitly.
Types ¶
type Batch ¶
type Batch struct {
// contains filtered or unexported fields
}
Batch is an immutable snapshot of selected settings. Values decode afresh on each access. Later writes do not change an existing Batch.
func Load ¶
Load reads the selected registered keys with at most one query. Cached keys are served from the manager's cache; the others are read in one snapshot and may populate it. The retained JSON is bounded by MaxLoadBytes.
type Cursor ¶
Cursor is the position after which ListPage continues: the group, sort order and name of the last record already returned. The zero Cursor starts at the beginning. It is a position, not a capability or a consistent snapshot.
type Key ¶
type Key[V any] struct { // contains filtered or unexported fields }
func (Key[V]) Configure ¶
Configure explicitly takes ownership of the persisted presentation. Later declaration changes no longer replace it until ResetPresentation is called.
func (Key[V]) Ensure ¶
Ensure creates a missing setting using its descriptor's presentation. An existing value remains unchanged, including its version. A presentation still owned by the declaration is refreshed from it; one changed by Configure stays.
func (Key[V]) EnsureIn ¶
EnsureIn applies Ensure within the caller's transaction through a savepoint. Parent rollback includes initialization and declaration-owned presentation changes.
func (Key[V]) Find ¶
Find reads one setting. With Options.Cache it is served from the manager's cache until the entry expires or a write through this manager invalidates it.
func (Key[V]) From ¶
From decodes this key from a Batch without I/O. A key that was not selected for the batch is an error rather than a silently missing value.
func (Key[V]) GetOr ¶
GetOr uses a validated, independently decoded fallback only when no row exists. Invalid stored values or versions never silently become defaults. With Options.Cache, repeated calls are served from the manager's cache.
func (Key[V]) Registration ¶
func (k Key[V]) Registration() Registration
func (Key[V]) RegistrationWith ¶
func (k Key[V]) RegistrationWith(options Options[V]) Registration
func (Key[V]) ResetPresentation ¶
ResetPresentation restores the declared presentation and returns its ownership to the declaration, so Ensure and Reconcile keep it current.
func (Key[V]) Upsert ¶
Upsert atomically creates or replaces the value/version. Existing presentation is preserved; Configure changes presentation explicitly.
type Kind ¶
type Kind string
const ( Text Kind = "text" Textarea Kind = "textarea" Number Kind = "number" Boolean Kind = "boolean" Select Kind = "select" Multiselect Kind = "multiselect" Email Kind = "email" URL Kind = "url" Color Kind = "color" Date Kind = "date" Datetime Kind = "datetime" File Kind = "file" Image Kind = "image" JSON Kind = "json" Password Kind = "password" Code Kind = "code" MaxKeys = 1000 MaxValueBytes = extensionvalue.MaxBytes MaxBatchBytes = extensionvalue.MaxBatchBytes )
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager borrows the extension Store, which owns admission and shutdown. Its optional read cache is owned by this manager instance only.
func New ¶
func New(store *extensions.Store, keys ...Registration) (*Manager, error)
func (*Manager) Invalidate ¶
Invalidate drops cached reads for the given keys in this manager. Writes made through the manager do this automatically; call it after changing a setting by other means, such as a migration or another process's notification.
type Options ¶
Options adds optional registration behavior. The zero value is Registration().
Cache enables the manager's per-process read cache for this key: Get, GetOr, Find and Load serve a validated snapshot for at most Cache, then read again. Writes through the same manager invalidate the entry immediately and again after commit. Other processes observe a write after at most Cache. Zero disables caching; the maximum is MaxCacheTTL.
Upgrades declare conversions for values stored by earlier versions.
type Page ¶
Page is one bounded ListPage result. Next is zero after the last page.
func ListPage ¶
func ListPage(ctx context.Context, m *Manager, filter Filter, after Cursor, limit int) (Page, error)
ListPage returns up to limit registered settings (DefaultPageSize when zero, at most MaxKeys) ordered by group, sort order and name, after the cursor. A page also ends early rather than retain more than MaxBatchBytes of JSON, so large settings never make the listing fail; continue with Page.Next. Each page is one bounded query in its own read snapshot.
type Presentation ¶
type Presentation struct {
Kind Kind
Group Group
Label string
Description string
Order int32
Public bool
Parameters value.JSON[json.RawMessage]
}
Presentation describes an administrative form. Password is only a masked widget; settings storage does not encrypt values. Parameters are explicitly dynamic JSON object data for the application's chosen widget.
func (Presentation) Validate ¶
func (p Presentation) Validate() error
type Reconciliation ¶
type Reconciliation struct {
// Upgraded values were rewritten from an earlier version by a declared upgrade.
Upgraded []Name
// Presented presentations still owned by their declaration were refreshed.
Presented []Name
// Incompatible rows have a newer version, or an older version without a
// declared upgrade. Their presence fails Reconcile without any write.
Incompatible []Name
}
Reconciliation reports what Reconcile changed, or which stored settings it could not accept. Names are registered setting names only, never values.
func Reconcile ¶
func Reconcile(ctx context.Context, m *Manager) (Reconciliation, error)
Reconcile brings stored settings in line with their registrations in one transaction: declared upgrades are applied and declaration-owned presentations are refreshed. Run it after migrations whenever a deployment changes setting versions or presentation, for example while starting serve and worker processes, and treat an error as a startup failure. An incompatible version fails with fault.Conflict, lists the settings in Incompatible and writes nothing, instead of letting every later Get fail. It reads presentation columns first and loads one value at a time for upgrades.
type Record ¶
type Record struct {
// contains filtered or unexported fields
}
Record's explicit dynamic export prevents accidental serialization of a private setting when an administrative record is logged or returned by HTTP.
func List ¶
List returns this manager's registered settings ordered by group, sort order and name by reading consecutive ListPage pages; pages are separate snapshots. Prefix is a literal string, not SQL LIKE syntax. PublicOnly is explicit; callers still own endpoint authorization. The complete result retains at most MaxLoadBytes of JSON; use ListPage for larger administrative listings.
func (Record) Configured ¶
Configured reports whether Configure took ownership of the presentation, so declaration changes no longer replace it.
func (Record) DynamicValue ¶
func (r Record) DynamicValue() (json.RawMessage, error)
func (Record) MarshalJSON ¶
func (Record) Presentation ¶
func (r Record) Presentation() Presentation
type Registration ¶
type Registration struct {
// contains filtered or unexported fields
}
type Selection ¶
type Selection interface {
// contains filtered or unexported methods
}
Selection names one registered key for a batched read. Key implements it; the declaration identity, not a lookalike name, selects the stored row.
type Upgrade ¶
type Upgrade[V any] struct { // contains filtered or unexported fields }
Upgrade converts a value persisted by an earlier declaration version. It is declared next to the key and applied by reads and by Reconcile.
func UpgradeFrom ¶
func UpgradeFrom[Old, V any](from Version, previous contract.JSON[Old], convert func(context.Context, Old) (V, error)) Upgrade[V]
UpgradeFrom decodes a stored value of an earlier version with that version's codec, then converts it. The result is re-encoded and validated by the current codec. convert is application code: it must be deterministic and must not perform I/O; panics are contained and reported as failures.