Primate LogoPrimate

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.

Previous
Errors