2026-03-22 01:27:35 +00:00
[](https://pkg.go.dev/dappco.re/go/core/store)
2026-02-23 06:45:49 +00:00
[](LICENSE.md)
[](go.mod)
2026-02-20 15:11:20 +00:00
# go-store
2026-03-30 17:02:21 +00:00
Group-namespaced SQLite key-value store with TTL expiry, namespace isolation, quota enforcement, and a reactive event system. Backed by a pure-Go SQLite driver (no CGO), uses WAL mode for concurrent reads, and enforces a single connection to keep pragma settings consistent. Supports scoped stores for multi-tenant use, Watch/Unwatch subscriptions, and OnChange callbacks for downstream event consumers.
2026-02-20 15:11:20 +00:00
2026-03-22 01:27:35 +00:00
**Module**: `dappco.re/go/core/store`
2026-02-20 15:11:20 +00:00
**Licence**: EUPL-1.2
2026-03-30 16:41:56 +00:00
**Language**: Go 1.26
2026-02-20 15:11:20 +00:00
## Quick Start
```go
2026-03-30 14:22:49 +00:00
package main
2026-02-20 15:11:20 +00:00
2026-03-30 14:22:49 +00:00
import (
"fmt"
"time"
2026-02-20 15:11:20 +00:00
2026-03-30 14:22:49 +00:00
"dappco.re/go/core/store"
)
2026-02-20 15:11:20 +00:00
2026-03-30 14:22:49 +00:00
func main() {
2026-04-03 07:48:47 +00:00
// Configure a persistent store with "/tmp/go-store.db", or use ":memory:" for ephemeral data.
storeInstance, err := store.NewConfigured(store.StoreConfig{
DatabasePath: "/tmp/go-store.db",
2026-04-04 11:13:36 +00:00
Journal: store.JournalConfiguration{
EndpointURL: "http://127.0.0.1:8086",
Organisation: "core",
BucketName: "events",
},
2026-04-03 07:48:47 +00:00
PurgeInterval: 30 * time.Second,
2026-04-04 19:45:52 +00:00
WorkspaceStateDirectory: "/tmp/core-state",
2026-04-03 07:48:47 +00:00
})
2026-03-30 14:22:49 +00:00
if err != nil {
2026-03-30 16:41:56 +00:00
return
2026-03-30 14:22:49 +00:00
}
2026-03-30 15:02:28 +00:00
defer storeInstance.Close()
2026-02-20 15:11:20 +00:00
2026-03-30 18:49:17 +00:00
if err := storeInstance.Set("config", "colour", "blue"); err != nil {
2026-03-30 16:41:56 +00:00
return
}
if err := storeInstance.SetWithTTL("session", "token", "abc123", 24*time.Hour); err != nil {
return
}
2026-03-30 18:49:17 +00:00
colourValue, err := storeInstance.Get("config", "colour")
2026-03-30 16:41:56 +00:00
if err != nil {
return
}
2026-03-30 18:49:17 +00:00
fmt.Println(colourValue)
2026-03-30 14:22:49 +00:00
2026-03-30 18:49:17 +00:00
// Watch "config" mutations and print each event as it arrives.
2026-04-03 04:44:45 +00:00
events := storeInstance.Watch("config")
defer storeInstance.Unwatch("config", events)
2026-03-30 14:22:49 +00:00
go func() {
2026-04-03 04:44:45 +00:00
for event := range events {
2026-03-30 16:13:55 +00:00
fmt.Println(event.Type, event.Group, event.Key, event.Value)
2026-03-30 14:22:49 +00:00
}
}()
2026-03-30 18:49:17 +00:00
// Store tenant-42 preferences under the "tenant-42:" prefix.
2026-04-04 11:13:36 +00:00
scopedStore, err := store.NewScopedConfigured(storeInstance, store.ScopedStoreConfig{
Namespace: "tenant-42",
Quota: store.QuotaConfig{MaxKeys: 100, MaxGroups: 10},
})
if err != nil {
2026-03-30 16:41:56 +00:00
return
}
2026-04-03 05:45:24 +00:00
if err := scopedStore.SetIn("preferences", "locale", "en-GB"); err != nil {
2026-03-30 16:41:56 +00:00
return
}
2026-03-30 14:22:49 +00:00
}
2026-02-20 15:11:20 +00:00
```
## Documentation
2026-03-30 15:16:16 +00:00
- [Agent Conventions ](CODEX.md ) - Codex-facing repo rules and AX notes
2026-03-30 18:12:28 +00:00
- [AX RFC ](docs/RFC-CORE-008-AGENT-EXPERIENCE.md ) - naming, comment, and path conventions for agent consumers
2026-02-20 15:11:20 +00:00
- [Architecture ](docs/architecture.md ) — storage layer, group/key model, TTL expiry, event system, namespace isolation
- [Development Guide ](docs/development.md ) — prerequisites, test patterns, benchmarks, adding methods
- [Project History ](docs/history.md ) — completed phases, known limitations, future considerations
## Build & Test
```bash
go test ./...
go test -race ./...
go test -bench=. ./...
go build ./...
```
## Licence
European Union Public Licence 1.2 — see [LICENCE ](LICENCE ) for details.