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 coco,import zz,Loaded,type Loaded<T extends CoValueClassOrSchema, R extends ResolveQuery<T> = SchemaResolveQuery<T>> = R extends true | undefined ? LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>> : [LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly (Exclude<...> | OnErrorResolvedValue ...class GroupGroup,class AccountAccount } from "jazz-tools"; export constLocation =const Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group, true>import coco.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, true> export mapcity: z.z.ZodStringcity:import zz.string(),function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringcountry: z.z.ZodStringcountry:import zz.string(), }); export typefunction string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringLocation =type Location = { readonly city: string; readonly country: string; } & CoMapimport coco.loaded<typeoftype loaded<T extends CoValueClassOrSchema, R extends ResolveQuery<T> = SchemaResolveQuery<T>> = R extends true | undefined ? LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>> : [LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly (Exclude<...> | OnErrorResolvedValue ... export loadedLocation>; // co.ref can be used within CoMap fields to point to other CoValues constconst Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group, true>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, true>import coco.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: { ...; }): co.Map<...> export mapname: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 zz.string,function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringimageURL: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 zz.string,function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringbirthplace:birthplace: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group, true>Location // Links directly to the Location CoMap above. }) export typeconst Location: co.Map<{ city: z.z.ZodString; country: z.z.ZodString; }, unknown, Account | Group, true>Actor =type Actor = { readonly name: never; readonly imageURL: never; readonly birthplace: MaybeLoaded<{ readonly city: string; readonly country: string; } & CoMap>; } & CoMapimport coco.loaded<typeoftype loaded<T extends CoValueClassOrSchema, R extends ResolveQuery<T> = SchemaResolveQuery<T>> = R extends true | undefined ? LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>> : [LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly (Exclude<...> | OnErrorResolvedValue ... export loadedActor>; // actual actor data is stored in the separate Actor CoValue constconst 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, true>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, true>import coco.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: { ...; }): co.Map<...> export maptitle: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 zz.string,function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringdirector: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 zz.string,function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringcast: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, true>, true>import coco.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, true>>(element: co.Map<...>): co.List<...> export listActor), // ordered, mutable }) export typeconst 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, true>Movie =type Movie = { readonly title: never; readonly director: never; readonly cast: MaybeLoaded<CoList<MaybeLoaded<{ readonly name: never; readonly imageURL: never; readonly birthplace: MaybeLoaded<{ readonly city: string; readonly country: string; } & CoMap>; } & CoMap>>>; } & CoMapimport coco.loaded<typeoftype loaded<T extends CoValueClassOrSchema, R extends ResolveQuery<T> = SchemaResolveQuery<T>> = R extends true | undefined ? LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>> : [LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly (Exclude<...> | OnErrorResolvedValue ... export loadedMovie>; // A User CoMap can maintain a CoFeed of co.ref(Movie) to track their favorite movies constconst 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, true>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, true>import coco.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: { ...; }): co.Map<...> export mapusername: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 zz.string,function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString (+1 overload) export stringfavoriteMovies: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, true>, true>import coco.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, true>>(element: co.Map<...>): co.Feed<...> export feedMovie), // append-only }) export typeconst 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, true>User =type User = { readonly username: never; readonly favoriteMovies: MaybeLoaded<CoFeed<MaybeLoaded<{ readonly title: never; readonly director: never; readonly cast: MaybeLoaded<CoList<MaybeLoaded<{ readonly name: never; readonly imageURL: never; readonly birthplace: MaybeLoaded<{ readonly city: string; readonly country: string; } & CoMap>; } & CoMap>>>; } & CoMap>>>; } & CoMapimport coco.loaded<typeoftype loaded<T extends CoValueClassOrSchema, R extends ResolveQuery<T> = SchemaResolveQuery<T>> = R extends true | undefined ? LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>> : [LoadedAndRequired<InstanceOfSchemaCoValuesMaybeLoaded<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly ((ItemDepth extends true | undefined ? Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends { ...; } ? readonly (Exclude<...> | OnErrorResolvedValue ... export loadedUser>;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, true>
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.