Pema and Stores
A Primate Store schema needs both validation behavior and a persistent datatype. Pema calls a schema with that contract Storable.
import db from "@/config/db";
import p from "pema";
import store from "primate/store";
export default store({
table: "article",
db,
schema: {
id: store.key.primary(p.uuid),
title: p.string.max(200),
published: p.boolean.default(false),
tags: p.json(p.array(p.string)),
},
});Pema parses and validates each value before a Store write. The database adapter
uses each field's datatype to map it to its own storage representation.
Compatibility
| Schema family | Direct Store field? | Datatype |
|---|---|---|
p.string |
Yes | string |
p.boolean |
Yes | boolean |
| Number and integer families | Yes | f32, f64, signed/unsigned widths |
p.date |
Yes | datetime |
p.url |
Yes | url |
p.uuid, .v4(), .v7() |
Yes | UUID datatype for that form |
p.blob, p.file |
Yes | blob |
p.enum(...) |
Yes | u8 |
p.json(...) |
Yes | json |
optional() / default() |
If the inner schema is Storable | Inner datatype |
| Object, partial, omit and async schemas | No | Use p.json(inner) if appropriate |
| Array, tuple, record and dictionary | No | Use p.json(inner) if appropriate |
| Union, literal, predicate and constructor | No | Validation-only |
| Pure, unknown, null, undefined, function, symbol | No | Validation-only |
derive() result |
No | Validation-only |
Do not infer Store suitability merely because a schema has parse() or a useful
TypeScript type. OptionalType and DefaultType forward the inner datatype; a
wrapper around a validation-only schema is still unsuitable and can fail when a
Store asks for its datatype.
Structured JSON
Use p.json(inner) to validate structured JSON and persist it as one field:
const Metadata = p.json(p({
labels: p.array(p.string),
featured: p.boolean.default(false),
}));The parsed output must be JSON-compatible. p.json does not turn Date, URL,
bigint or arbitrary class instances into JSON values.
Identifiers
Primate Store keys support unsigned integers, UUIDs and manually supplied strings:
id: store.key.primary(p.u32)
id: store.key.primary(p.uuid)
id: store.key.primary(p.uuid.v4())
id: store.key.primary(p.string, { generate: false })Generic p.uuid and explicit p.uuid.v7() generate UUIDv7 keys; explicit
p.uuid.v4() generates UUIDv4. See Primary keys for generation and foreign
key rules.
Store-facing types
Pema exports lower-level types used by Store implementations and generic code:
| Type | Purpose |
|---|---|
Storable |
Parsed schema with a persistent datatype |
DataKey |
Union of supported datatype names |
DataType |
Datatype-to-JavaScript-value map |
StoreSchema |
Property map whose values are Storable |
StoreId<S> |
Parsed non-nullable id type |
InferStore<S> |
Parsed Store shape with undefined fields optional |
InferStoreOut<S> |
Store output with required parsed id |
Id |
String identifier helper |
pema/StoreType is the public Store-schema class entrypoint used by Primate. It
parses complete records and exposes partial() for partial record parsing;
applications normally receive Store types through primate/store rather than
constructing StoreType directly. Its module also exports the Serialized
type.
This page covers schema compatibility. Continue to Stores for primary and foreign keys, insert/update operations, atomic batches, relations, lifecycle, migrations and raw database access.