Connecting CoValues with direct linking
CoValues can form relationships with each other by linking directly to other CoValues. This creates a powerful connection where one CoValue can point to the unique identity of another. Instead of embedding all the details of one CoValue directly within another, you use its Jazz-Tools schema as the field type. This allows multiple CoValues to point to the same piece of data effortlessly.
import {
import co
co,import z
z,Loaded,
type Loaded<T extends CoValueClassOrSchema, 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<...
class Group
Group,class Account
Account } from "jazz-tools"; export constLocation =
const Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group>
import co
co.map({
map<{ city: z.z.ZodString; country: z.z.ZodString; }>(shape: { city: z.z.ZodString; country: z.z.ZodString; }): co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group> export map
city: z.z.ZodString
city:import z
z.string(),
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
country: z.z.ZodString
country:import z
z.string(), }); export type
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
Location =
type Location = { city: string; country: string; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClassOrSchema, 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
Location>; // co.ref can be used within CoMap fields to point to other CoValues const
const Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group>
Actor =
const Actor: co.Map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }, unknown, Account | Group>
import co
co.map({
map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }>(shape: { name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }): co.Map<...> export map
name:
name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }
import z
z.string,
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
imageURL:
imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }
import z
z.string,
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
birthplace:
birthplace: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group>
Location // Links directly to the Location CoMap above. }) export type
const Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group>
Actor =
type Actor = { name: never; imageURL: never; birthplace: ({ city: string; country: string; } & CoMap) | null; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClassOrSchema, 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
Actor>; // actual actor data is stored in the separate Actor CoValue const
const Actor: co.Map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }, unknown, Account | Group>
Movie =
const Movie: co.Map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }, unknown, Account | Group>
import co
co.map({
map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }>(shape: { title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }): co.Map<...> export map
title:
title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }
import z
z.string,
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
director:
director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }
import z
z.string,
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
cast:
cast: co.List<co.Map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }, unknown, Account | Group>>
import co
co.list(
list<co.Map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }, unknown, Account | Group>>(element: co.Map<...>): co.List<...> export list
Actor), // ordered, mutable }) export type
const Actor: co.Map<{ name: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; imageURL: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; birthplace: co.Map<...>; }, unknown, Account | Group>
Movie =
type Movie = { title: never; director: never; cast: CoList<({ name: never; imageURL: never; birthplace: ({ city: string; country: string; } & CoMap) | null; } & CoMap) | null> | null; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClassOrSchema, 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
Movie>; // A User CoMap can maintain a CoFeed of co.ref(Movie) to track their favorite movies const
const Movie: co.Map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }, unknown, Account | Group>
User =
const User: co.Map<{ username: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; favoriteMovies: co.Feed<...>; }, unknown, Account | Group>
import co
co.map({
map<{ username: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; favoriteMovies: co.Feed<...>; }>(shape: { username: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; favoriteMovies: co.Feed<...>; }): co.Map<...> export map
username:
username: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }
import z
z.string,
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export string
favoriteMovies:
favoriteMovies: co.Feed<co.Map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }, unknown, Account | Group>>
import co
co.feed(
feed<co.Map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }, unknown, Account | Group>>(element: co.Map<...>): co.Feed<...> export feed
Movie), // append-only }) export type
const Movie: co.Map<{ title: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; director: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; cast: co.List<...>; }, unknown, Account | Group>
User =
type User = { username: never; favoriteMovies: CoFeed<({ title: never; director: never; cast: CoList<({ name: never; imageURL: never; birthplace: ({ city: string; country: string; } & CoMap) | null; } & CoMap) | null> | null; } & CoMap) | null> | null; } & CoMap
import co
co.loaded<typeof
type loaded<T extends CoValueClassOrSchema, 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
User>;
const User: co.Map<{ username: { (params?: string | z.z.core.$ZodStringParams): z.z.ZodString; <T extends string>(params?: string | z.z.core.$ZodStringParams): z.z.core.$ZodType<T, T>; }; favoriteMovies: co.Feed<...>; }, unknown, Account | Group>
Understanding CoList and CoFeed
- CoList is a collaborative list where each item is a reference to a CoValue
- CoFeed contains an append-only list of references to CoValues.
This direct linking approach offers a single source of truth. When you update a referenced CoValue, all other CoValues that point to it are automatically updated, ensuring data consistency across your application.
By connecting CoValues through these direct references, you can build robust and collaborative applications where data is consistent, efficient to manage, and relationships are clearly defined. The ability to link different CoValue types to the same underlying data is fundamental to building complex applications with Jazz.