A small storage runtime for applications.
SQL, key-value state, durable jobs, files, search, logs and metrics in one directory, with one lifecycle, one memory budget and one backup.
import { open } from '@tinyshed/tinystore'
await using store = await open('./data')
const db = await store.database('app', { migrations: './migrations' })
await db.exec`insert into users (id, name) values (${42}, ${'Ada'})`
const sessions = store.bucket<Session>('sessions', { idle: '30d' })
await sessions.set(digest(token), { userId: 42 })
const emails = store.queue<Email>('emails')
await emails.add({ to: 'ada@example.com' })
const avatars = store.files('avatars')
await avatars.put('42.png', Bun.file('avatar.png'))
store.logger('api').info('user created', { userId: 42 })
store.metrics.counter('signups_total').inc()async with await tinystore.open("data") as store:
db = await store.database("app", migrations="migrations")
await db.exec("insert into users (id, name) values (?, ?)", 42, "Ada")
sessions = store.bucket("sessions", Session, idle="30d")
await sessions.set(digest(token), Session(user_id=42))
emails = store.queue("emails", Email)
await emails.add(Email(to="ada@example.com"))
avatars = store.files("avatars")
await avatars.put("42.png", Path("avatar.png").read_bytes())
store.logger("api").info("user created", user_id=42)
store.metrics.counter("signups_total").inc()// errors left out
store, err := tinystore.Open(ctx, "data")
defer store.Close()
db, err := sqldb.Open(ctx, store, "app", sqldb.Migrations(os.DirFS("migrations")))
_, err = db.Exec(ctx, "insert into users (id, name) values (?, ?)", 42, "Ada")
sessions, err := kv.OpenBucket[Session](store, "sessions", kv.Idle(30*24*time.Hour))
err = sessions.Set(ctx, digest(token), Session{UserID: 42})
emails, err := jobs.OpenQueue[Email](store, "emails")
_, err = emails.Add(ctx, Email{To: "ada@example.com"})
avatars, err := blobs.OpenFiles(store, "avatars")
_, err = avatars.Put(ctx, "42.png", avatar)
slog.New(records.NewHandler(store, "api")).Info("user created", "userId", 42)
signups, err := metrics.OpenCounter(store, "signups_total")
signups.Inc()let store = Store::open("data", Options::default())?;
let db = store.database("app").migrations("migrations").open()?;
db.exec(tinystore::sql!("insert into users (id, name) values (?, ?)", 42, "Ada"))?;
let sessions = store.bucket::<Session>("sessions").idle(Duration::from_hours(24 * 30)).open()?;
sessions.set(digest(&token), &Session { user_id: 42 })?;
let emails = store.queue::<Email>("emails").open()?;
emails.add(&Email { to: "ada@example.com".into() })?;
let avatars = store.files("avatars").open()?;
avatars.put("42.png", &avatar)?;
tracing::info!(user_id = 42, "user created"); // through store.logger("api").layer()
store.metrics()?.counter("signups_total").open()?.inc();