Skip to content

define_store

function define_store<Id extends string, T>(
id: Id,
codec: Codec<T>,
opts?: DefineStoreOpts | string
): StoreDefinition<Id, T>

Creates a type-safe store definition that can be passed to create_corpus().with_store(). The store ID becomes the key used to access the store, and the codec determines how data is serialized.

Usage

import { define_store, json_codec, text_codec, binary_codec } from '@f0rbit/corpus'
import { z } from 'zod'
// JSON store with Zod validation
const UserSchema = z.object({
name: z.string(),
email: z.string().email(),
})
const users = define_store('users', json_codec(UserSchema))
// Plain text store
const logs = define_store('logs', text_codec())
// Binary store for files
const images = define_store('images', binary_codec())

Parameters

ParameterTypeDescription
idstringUnique identifier for the store
codecCodec<T>Serialization codec for the data
optsDefineStoreOpts | string?Options object or description string

Types

type DefineStoreOpts = {
description?: string
data_key_fn?: (ctx: DataKeyContext) => string
}
type DataKeyContext = {
store_id: string // The store's id
version: string // Version string passed to put()
content_hash: string // SHA-256 hash of serialized content
tags?: string[] // Optional tags passed to put()
}

Custom Storage Paths

By default, corpus stores data at {store_id}/{content_hash}. The data_key_fn option lets you customize this path based on version, tags, or content hash.

When to Use

  • Organizing by date: Group snapshots by date tags for easier browsing
  • Namespace prefixes: Add project or environment prefixes
  • Human-readable paths: Use version strings instead of content hashes
  • Hierarchical storage: Create folder structures based on metadata

Example: Organizing by Date Tags

const hansard = define_store('hansard', text_codec(), {
data_key_fn: (ctx) => {
const date = ctx.tags?.find(t => t.startsWith('date:'))?.slice(5) ?? 'unknown'
return `australia-house/raw/${date}/${ctx.version}`
}
})
// Usage
await corpus.stores.hansard.put(transcript, {
version: 'v1',
tags: ['date:2024-03-15', 'chamber:house']
})
// Stored at: australia-house/raw/2024-03-15/v1

Example: Custom Namespace Prefixes

const configs = define_store('configs', json_codec(ConfigSchema), {
description: 'Application configs',
data_key_fn: (ctx) => `myapp/prod/configs/${ctx.version}/${ctx.content_hash.slice(0, 8)}`
})
// Stored at: myapp/prod/configs/v2/a1b2c3d4

Default Behavior

Without data_key_fn, the default path is {store_id}/{content_hash}:

const logs = define_store('logs', text_codec())
// Stored at: logs/abc123def456...

With create_corpus

Store definitions are passed to the corpus builder:

const corpus = create_corpus()
.with_backend(create_memory_backend())
.with_store(users) // Access via corpus.stores.users
.with_store(logs) // Access via corpus.stores.logs
.with_store(images) // Access via corpus.stores.images
.build()
// Type-safe access
await corpus.stores.users.put({ name: 'Alice', email: 'alice@example.com' })
await corpus.stores.logs.put('User Alice created')

See Also