Schemas
Hooks to list, load, create and delete Seed schemas from React components, for schema editors and admin screens.
These hooks return Schema instances from @seedprotocol/sdk. Most apps never need them: you pass your schema to the client in config.schema and work with items. Reach for them when you build a schema editor or an admin view of the schemas on the device.
import {
useSchemas,
useSchema,
useCreateSchema,
useDestroySchema,
useAllSchemaVersions,
useSeedProtocolSchema,
} from '@seedprotocol/react'All of them wait for the client to be ready before they query. Until then, useSchemas returns [] with isLoading: false, useSchema returns schema: null with isLoading: false (after a first render at true when you pass an identifier), and useAllSchemaVersions returns undefined. Only useSchemas uses React Query: outside SeedProvider it falls back to a shared client with Seed's defaults, and development builds log a warning, so keep it inside SeedProvider (which hooks need it). The Schema class itself (its getters, validate(), saveNewVersion() and so on) is covered in Schema.
useSchemas
Lists the latest version of each schema on the device.
function useSchemas(): {
schemas: Schema[]
isLoading: boolean
error: Error | null
}Returns
| Field | Type | Description |
|---|---|---|
schemas | Schema[] | One instance per schema name, at its latest version, from Schema.all(). The SDK's internal Seed Protocol schema is left out. [] until loaded |
isLoading | boolean | true during the first load |
error | Error | null | The query's error, if Schema.all() failed |
useSchemas caches its result in React Query under ['seed', 'schemas']. It refetches when a schema is written to the database or deleted from it. While mounted, it holds each schema it lists, and fetches the list again when a listed schema is destroyed or evicted, or the client stops.
Example
import { useSchemas } from '@seedprotocol/react'
export function SchemaList() {
const { schemas, isLoading, error } = useSchemas()
if (isLoading) return <p>Loading schemas…</p>
if (error) return <p>{error.message}</p>
return (
<ul>
{schemas.map((schema) => (
<li key={schema.id ?? schema.schemaName}>
{schema.schemaName} (v{schema.version})
</li>
))}
</ul>
)
}useSchema
Loads one schema as a reactive Schema instance. Assigning to its tracked fields (schema.name = 'New name') saves a draft and re-renders components that use it; see Saving and conflicts.
function useSchema(schemaIdentifier: string | null | undefined): {
schema: Schema | null
isLoading: boolean
error: Error | null
}Parameters
| Name | Type | Description |
|---|---|---|
schemaIdentifier | string | null | undefined | A schema name (the latest version is used) or a schema file ID. Pass null or undefined to load nothing |
Returns
| Field | Type | Description |
|---|---|---|
schema | Schema | null | The instance. null (not undefined) before the client is ready, with no identifier, when no schema has that name or ID, or when creating the instance throws |
isLoading | boolean | true while the hook checks that the schema exists and while the schema's status is 'loading'. false once it's 'ready' or 'error' |
error | Error | null | Set if creating the instance throws, or when the schema's status turns 'error' (its loading error, or Failed to load schema "<name>"). Cleared when it's 'ready' |
The instance is shared: every useSchema('blog') gets the same object from the SDK's cache. Each hook holds it while mounted and releases its hold on unmount and when schemaIdentifier changes. A schema stays cached after its last hold is released, until it's destroyed or evicted or the client stops.
Example
import { useSchema } from '@seedprotocol/react'
export function SchemaTitle({ name }: { name: string }) {
const { schema, isLoading } = useSchema(name)
if (isLoading || !schema) return null
return <h2>{schema.metadata?.name} has {schema.models.length} models</h2>
}useSchema only loads schemas that exist: it checks the schemas table for the name or schema file ID first. For an unknown name, such as a typo, it returns schema: null with isLoading: false and error: null, and creates nothing. Use useCreateSchema to create one.
useCreateSchema
Creates a schema and tracks its progress.
function useCreateSchema(): {
createSchema: (schemaName: string) => Schema
isLoading: boolean
error: Error | null
resetError: () => void
}Returns
| Field | Type | Description |
|---|---|---|
createSchema | (schemaName: string) => Schema | Returns the schema's instance synchronously. A new schema is still loading |
isLoading | boolean | true from the call until the schema's status is 'ready' or 'error'. A schema that's already loaded clears it at once, and so does a throw |
error | Error | null | The error createSchema threw, or the schema's loading error if its status turns 'error' |
resetError | () => void | Clears error |
createSchema(name) goes through Schema.create(), so it's find-or-create: if a schema with that name exists, you get that one back instead of a new one. A new schema is saved as a local draft. If schemaName is empty, it sets error and throws Schema name is required.
Example
import { useCreateSchema } from '@seedprotocol/react'
export function NewSchemaButton() {
const { createSchema, isLoading, error } = useCreateSchema()
return (
<>
<button disabled={isLoading} onClick={() => createSchema('newsletter')}>
{isLoading ? 'Creating…' : 'New schema'}
</button>
{error && <p>{error.message}</p>}
</>
)
}Only the most recent call is tracked. Calling createSchema again stops tracking the previous schema.
useDestroySchema
Deletes a schema, with its models and properties, from the local database. unload and destroy lists what destroy() deletes and what it keeps.
function useDestroySchema(): UseDestroySchemaReturn
type UseDestroySchemaReturn = {
destroy: (schema: Schema) => Promise<void>
isLoading: boolean
error: Error | null
resetError: () => void
}Returns
| Field | Type | Description |
|---|---|---|
destroy | (schema: Schema) => Promise<void> | Calls schema.destroy(). Resolves when it's done. Does nothing if schema is falsy |
isLoading | boolean | true while destroy runs |
error | Error | null | Set if schema.destroy() rejects |
resetError | () => void | Clears error |
When schema.destroy() fails, including when the database delete fails, error is set and the promise rejects, so catch it.
Example
import type { Schema } from '@seedprotocol/sdk'
import { useDestroySchema } from '@seedprotocol/react'
export function DeleteSchemaButton({ schema }: { schema: Schema }) {
const { destroy, isLoading, error, resetError } = useDestroySchema()
return (
<>
<button disabled={isLoading} onClick={() => destroy(schema).catch(() => {})}>
Delete
</button>
{error && <p onClick={resetError}>{error.message}</p>}
</>
)
}useAllSchemaVersions
Loads a Schema instance for every schema name in the database.
function useAllSchemaVersions(): Schema[] | null | undefinedReturns
The array itself, not an object:
| Value | Meaning |
|---|---|
undefined | Not loaded yet (or the client isn't ready) |
null | Loading failed |
Schema[] | One instance per schema name |
Despite the name, you get one instance per schema, not one per version. Unlike useSchemas, it doesn't leave out the internal Seed Protocol schema. It loads once when the client is ready and doesn't refresh after that, so prefer useSchemas for lists. It holds each schema while mounted, and on unmount calls unload() on its instances, which releases only this hook's holds. The schemas stay cached after that.
import { useAllSchemaVersions } from '@seedprotocol/react'
export function AllSchemas() {
const schemas = useAllSchemaVersions()
if (schemas === undefined) return <p>Loading…</p>
if (schemas === null) return <p>Could not load schemas</p>
return <p>{schemas.map((s) => s.schemaName).join(', ')}</p>
}useSeedProtocolSchema
Loads the SDK's internal Seed Protocol schema. It's the same as useSchema('Seed Protocol'), with the same return shape.
function useSeedProtocolSchema(): {
schema: Schema | null
isLoading: boolean
error: Error | null
}The SDK manages this schema. Read it (for example to show its version), but don't edit it.
import { useSeedProtocolSchema } from '@seedprotocol/react'
export function SeedProtocolVersion() {
const { schema } = useSeedProtocolSchema()
return <span>{schema?.version}</span>
}Related
- Schema: the
Schemaclass these hooks return - Models: hooks for the models in a schema
- Your first schema: the schema file format
- Define a schema and add to it: editing the file, raising its version and restarting