Jazz 0.14.0 Introducing Zod-based schemas
We're excited to move from our own schema syntax to using Zod v4.
This is the first step in a series of releases to make Jazz more familiar and to make CoValues look more like regular data structures.
Note: This is a huge release that we're still cleaning up and documenting.
We're still in the process of:
- updating all our docs
- double-checking all our framework bindings
- completing all the details of this upgrade guide
If you see something broken, please let us know on Discord and check back in a couple hours.
Thanks for your patience!
Overview:
So far, Jazz has relied on our own idiosyncratic schema definition syntax where you had to extend classes and be careful to use co.ref
for references.
// BEFORE import { co, CoMap, CoList, CoPlainText, ImageDefinition } from "jazz-tools"; export class Message extends CoMap { text = co.ref(CoPlainText); image = co.optional.ref(ImageDefinition); important = co.boolean; } export class Chat extends CoList.Of(co.ref(Message)) {}
While this had certain ergonomic benefits it relied on unclean hacks to work.
In addition, many of our adopters expressed a preference for avoiding class syntax, and LLMs consistently expected to be able to use Zod.
For this reason, we completely overhauled how you define and use CoValue schemas:
// AFTER import {
import co
co,import z
z } from "jazz-tools"; export constMessage =
const Message: CoMapSchema<{ text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }>
import co
co.map({
map<{ text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }>(shape: { text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }): CoMapSchema<...> export map
text: PlainTextSchema
text:import co
co.plainText(),
function plainText(): PlainTextSchema export plainText
image:
image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>
import z
z.optional(
optional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>(innerType: WithHelpers<...>): z.ZodOptional<...> export optional
import co
co.image()),
function image(): typeof ImageDefinition export image
important: z.z.ZodBoolean
important:import z
z.boolean(), }); export const
function boolean(params?: string | z.z.core.$ZodBooleanParams): z.z.ZodBoolean export boolean
Chat =
const Chat: CoListSchema<CoMapSchema<{ text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }>>
import co
co.list(
list<CoMapSchema<{ text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }>>(element: CoMapSchema<...>): CoListSchema<...> export list
Message);
const Message: CoMapSchema<{ text: PlainTextSchema; image: z.ZodOptional<WithHelpers<CoMapSchema<{ originalSize: z.z.ZodTuple<[z.z.ZodNumber, z.z.ZodNumber], null>; placeholderDataURL: z.ZodOptional<z.z.ZodString>; }, z.z.core.$catchall<...>, Account | Group>, { ...; }>>; important: z.z.ZodBoolean; }>
Major breaking changes
Schema definitions
You now define CoValue schemas using two new exports from jazz-tools
:
- a new
co
definer that mirrors Zod's object/record/array syntax to define CoValue typesco.map()
,co.record()
,co.list()
,co.feed()
co.account()
,co.profile()
co.plainText()
,co.richText()
,co.fileStream()
,co.image()
- see the updated Defining CoValue Schemas
z
re-exported from Zod v4- primitives like
z.string()
,z.number()
,z.literal()
- note: additional constraints like
z.min()
andz.max()
are not yet enforced, we'll add validation in future releases
- note: additional constraints like
- complex types like
z.object()
andz.array()
to define JSON-like fields without internal collaboration - combinators like
z.optional()
andz.discriminatedUnion()
- these also work on CoValue types!
- see the updated Docs on Primitive Fields, Docs on Optional References and Docs on Unions of CoMaps
- primitives like
Similar to Zod v4's new object syntax, recursive and mutually recursive types are now much easier to express.
How to pass loaded CoValues
We've removed the useCoState
, useAccount
and useAccountOrGuest
hooks.
You should now use the CoState
and AccountCoState
reactive classes instead. These provide greater stability and are significantly easier to work with.
Calls to new CoState()
work just the same, but they return a slightly different type than before.
And while you can still read from the type just as before...
// @filename: schema.ts import {
import z
z,import co
co } from "jazz-tools"; constPet =
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
import co
co.map({
map<{ name: z.z.ZodString; age: z.z.ZodNumber; }>(shape: { name: z.z.ZodString; age: z.z.ZodNumber; }): CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }> export map
name: z.z.ZodString
name:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
age: z.z.ZodNumber
age:import z
z.number(), }); type
function number(params?: string | z.z.core.$ZodNumberParams): z.z.ZodNumber export number
Pet =
type Pet = { name: string; age: number; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<... export loaded
Pet>; const
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
Person =
const Person: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
import co
co.map({
map<{ name: z.z.ZodString; age: z.z.ZodNumber; pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>(shape: { name: z.z.ZodString; age: z.z.ZodNumber; pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }): CoMapSchema<...> export map
name: z.z.ZodString
name:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
age: z.z.ZodNumber
age:import z
z.number(),
function number(params?: string | z.z.core.$ZodNumberParams): z.z.ZodNumber export number
pets:
pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>
import co
co.list(
list<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>(element: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>): CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>> export list
Pet), }); type
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
Person =
type Person = { name: string; age: number; pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<... export loaded
Person>;
const Person: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
// @filename: app.svelte <script lang="ts"> import { CoState } from "jazz-svelte"; import { Person } from "./schema"; const person = new CoState(Person, id); </script> <div> {person.current?.name} </div>
co.loaded
can also take a second argument to specify the loading depth of the expected CoValue, mirroring the resolve
options for CoState
, load
, subscribe
, etc.
<script lang="ts" module> export type Props = { person: co.loaded<typeof Person, { pets: { $each: true } }>; }; </script> <script lang="ts"> import { Person } from './schema'; let props: Props = $props(); </script> <div> {props.person.name} </div> <ul> {#each props.person.pets as pet} <li>{pet.name}</li> {/each} </ul>
Removing AccountSchema registration
We have removed the Typescript AccountSchema registration.
It was causing some deal of confusion to new adopters so we have decided to replace the magic inference with a more explicit approach.
When using AccountCoState
you should now pass the Account
schema directly:
<script lang="ts"> import { AccountCoState } from "jazz-svelte"; import { MyAccount } from "./schema"; const account = new AccountCoState(MyAccount, { resolve: { profile: true, }, }); </script> <div> {account.current?.profile.name} </div>
Defining migrations
Now account schemas need to be defined with co.account()
and migrations can be declared using withMigration()
:
import {
import co
co,import z
z,class Group
Group } from "jazz-tools"; constPet =
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
import co
co.map({
map<{ name: z.z.ZodString; age: z.z.ZodNumber; }>(shape: { name: z.z.ZodString; age: z.z.ZodNumber; }): CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }> export map
name: z.z.ZodString
name:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
age: z.z.ZodNumber
age:import z
z.number(), }); const
function number(params?: string | z.z.core.$ZodNumberParams): z.z.ZodNumber export number
MyAppRoot =
const MyAppRoot: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
import co
co.map({
map<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>(shape: { pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }): CoMapSchema<...> export map
pets:
pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>
import co
co.list(
list<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>(element: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>): CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>> export list
Pet), }); const
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
MyAppProfile =
const MyAppProfile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; }>
import co
co.profile({
profile<{ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; }>(shape?: ({ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; } & { name?: z.z.core.$ZodString<string>; inbox?: z.z.core.$ZodOptional<z.z.core.$ZodString>; inboxInvite?: z.z.core.$ZodOptional<z.z.core.$ZodString>; }) | undefined): CoProfileSchema<...> export profile
name: z.z.ZodString & z.z.core.$ZodString<string>
name:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
age: z.ZodOptional<z.z.ZodNumber>
age:import z
z.number().
function number(params?: string | z.z.core.$ZodNumberParams): z.z.ZodNumber export number
ZodType<unknown, unknown>.optional(): z.ZodOptional<z.z.ZodNumber>
optional(), }); export constMyAppAccount =
const MyAppAccount: AccountSchema<{ root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>; profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<...>; }>; }>
import co
co.account({
account<{ root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>; profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<...>; }>; }>(shape?: { root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>; profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<...>; }>; } | undefined): AccountSchema<...> export account
root:
root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
MyAppRoot,
const MyAppRoot: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
profile:
profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; }>
MyAppProfile, }).
const MyAppProfile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; }>
withMigration((
function withMigration(migration: (account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account, creationProps?: { name: string; }) => void): AccountSchema<...>
account,
account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account
creationProps?: {
creationProps: { name: string; } | undefined
name: string
name: string }) => { if (account.
account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account
root ===
Account.root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null
var undefined
undefined) {account.
account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account
root =
Account.root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null
MyAppRoot.
const MyAppRoot: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>
create({
create: (init: { pets: CoList<({ name: string; age: number; } & CoMap) | null>; }, options?: Group | Account | { owner: Group | Account; unique?: CoValueUniqueness["uniqueness"]; } | undefined) => { ...; } & CoMap
pets:
pets: CoList<({ name: string; age: number; } & CoMap) | null>
import co
co.list(
list<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>(element: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>): CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>> export list
Pet).
const Pet: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
create([]), }); } if (
create: (items: CoListInit<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>, options?: { owner: Account | Group; } | Account | Group) => CoList<...>
account.
account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account
profile ===
Account.profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile) | null
var undefined
undefined) { constconst profileGroup: Group
profileGroup =class Group
Group.create();
Group.create<Group>(this: CoValueClass<Group>, options?: { owner: Account; } | Account): Group
const profileGroup: Group
profileGroup.Group.addMember(member: Everyone, role: "writer" | "reader" | "writeOnly"): void (+1 overload)
addMember("everyone", "reader");account.
account: { root: ({ pets: CoList<({ name: string; age: number; } & CoMap) | null> | null; } & CoMap) | null; profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap) | null; } & Account
profile =
Account.profile: ({ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile) | null
MyAppProfile.
const MyAppProfile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<z.z.ZodNumber>; }>
create({
create: (init: { age?: number | undefined; inbox?: string | undefined; inboxInvite?: string | undefined; name: string; }, options?: Group | { owner: Group; unique?: CoValueUniqueness["uniqueness"]; } | undefined) => { ...; } & CoMap
name: string
name:creationProps?.
creationProps: { name: string; } | undefined
name: string | undefined
name ?? "New user", },const profileGroup: Group
profileGroup); } });
Defining Schema helper methods
TODO
Minor breaking changes
_refs
and _edits
are now potentially null
The type of _refs
and _edits
is now nullable.
const
Person =
const Person: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
import co
co.map({
map<{ name: z.z.ZodString; age: z.z.ZodNumber; }>(shape: { name: z.z.ZodString; age: z.z.ZodNumber; }): CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }> export map
name: z.z.ZodString
name:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString export string
age: z.z.ZodNumber
age:import z
z.number(), }); const
function number(params?: string | z.z.core.$ZodNumberParams): z.z.ZodNumber export number
person =
const person: { name: string; age: number; } & CoMap
Person.
const Person: CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>
create({
create: (init: { name: string; age: number; }, options?: Account | Group | { owner: Account | Group; unique?: CoValueUniqueness["uniqueness"]; } | undefined) => { ...; } & CoMap
name: string
name: "John",age: number
age: 30 });person.
const person: { name: string; age: number; } & CoMap
CoMap._refs: {}
If property `prop` is a `coField.ref(...)`, you can use `coMaps._refs.prop` to access the `Ref` instead of the potentially loaded/null value. This allows you to always get the ID or load the value manually._refs; // now nullableperson.
const person: { name: string; age: number; } & CoMap
_edits; // now nullable
CoMap._edits: { name?: LastAndAllCoMapEdits<string> | undefined; age?: LastAndAllCoMapEdits<number> | undefined; }
members
and by
now return basic Account
We have removed the Account schema registration, so now members
and by
methods now always return basic Account
.
This means that you now need to rely on useCoState
on them to load their using your account schema.
function
GroupMembers({
function GroupMembers({ group }: { group: Group; }): React.JSX.Element
group: Group
group }: {group: Group
group:class Group
Group }) { constmembers =
const members: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }[]
group: Group
group.members; return ( <
Group.members: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }[]
JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> {members.
const members: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }[]
Array<{ id: string; role: AccountRole; ref: Ref<Account>; account: Account; }>.map<React.JSX.Element>(callbackfn: (value: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }, index: number, array: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }[]) => React.JSX.Element, thisArg?: any): React.JSX.Element[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((member) => ( <
member: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }
GroupMemberDetails
function GroupMemberDetails({ accountId }: { accountId: string; }): React.JSX.Element
accountId: string
accountId={member.
member: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }
account: Account
account.Account.id: string
id}React.Attributes.key?: React.Key | null | undefined
key={member.
member: { id: string; role: AccountRole; ref: Ref<Account>; account: Account; }
account: Account
account.Account.id: string
id} /> ))} </JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> ); } functionGroupMemberDetails({
function GroupMemberDetails({ accountId }: { accountId: string; }): React.JSX.Element
accountId: string
accountId }: {accountId: string
accountId: string }) { constaccount =
const account: ({ profile: { name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile; root: { pets: ({ name: string; age: number; } & CoMap)[] & CoList<...>; } & { ...; } & CoMap; } & { ...; } & Account) | null | undefined
useCoState(
useCoState<AccountSchema<{ root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>; profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<...>; }>; }>, { ...; }>(Schema: AccountSchema<...>, id: string | undefined, options?: { ...; } | undefined): ({ ...; } & ... 1 more ... & Account) | ... 1 more ... | undefined
MyAppAccount,
const MyAppAccount: AccountSchema<{ root: CoMapSchema<{ pets: CoListSchema<CoMapSchema<{ name: z.z.ZodString; age: z.z.ZodNumber; }>>; }>; profile: CoProfileSchema<{ name: z.z.ZodString; age: z.ZodOptional<...>; }>; }>
accountId: string
accountId, {resolve: {
resolve?: RefsToResolve<{ ...; } & Account, 10, []> | undefined
profile: true,
profile?: RefsToResolve<{ name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile, 10, [0]> | undefined
root: {
root?: RefsToResolve<{ pets: CoList<...> | null; } & CoMap, 10, [...]> | undefined
pets: {
pets?: RefsToResolve<CoList<({ name: string; age: number; } & CoMap) | null>, 10, [0, 0]> | undefined
$each: true }, }, }, }); return ( <
$each: RefsToResolve<{ name: string; age: number; } & CoMap, 10, [0, 0, 0]>
JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{account?.
const account: ({ profile: { name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile; root: { pets: ({ name: string; age: number; } & CoMap)[] & CoList<...>; } & { ...; } & CoMap; } & { ...; } & Account) | null | undefined
profile.
Account.profile: { name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile
Profile.name: string | undefined
name}</JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul>{account?.
const account: ({ profile: { name: string; age: number | undefined; inbox: string | undefined; inboxInvite: string | undefined; } & CoMap & Profile; root: { pets: ({ name: string; age: number; } & CoMap)[] & CoList<...>; } & { ...; } & CoMap; } & { ...; } & Account) | null | undefined
root.
Account.root: { pets: ({ name: string; age: number; } & CoMap)[] & CoList<...>; } & { pets: CoList<...> | null; } & CoMap
pets.
pets: ({ name: string; age: number; } & CoMap)[] & CoList<({ name: string; age: number; } & CoMap) | null>
Array<T>.map<U>(callbackfn: (value: { name: string; age: number; } & CoMap, index: number, array: ({ name: string; age: number; } & CoMap)[]) => U, thisArg?: any): U[] (+1 overload)
Calls a defined callback function on each element of an array, and returns an array that contains the results.map((pet) => <
pet: { name: string; age: number; } & CoMap
JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>{pet.
pet: { name: string; age: number; } & CoMap
name: string
name}</JSX.IntrinsicElements.li: React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>
li>)}</JSX.IntrinsicElements.ul: React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>
ul> </JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> ); }