Sharing data through Organizations

Organizations are a way to share a set of data between users. Different apps have different names for this concept, such as "teams" or "workspaces".

We'll use the term Organization.

See the full example here.

Defining the schema for an Organization

Create a CoMap shared by the users of the same organization to act as a root (or "main database") for the shared data within an organization.

For this example, users within an Organization will be sharing Projects.

// schema.ts
export class class ProjectProject extends class CoMap
CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
@categoryDescriptionDeclaration Declare your own CoMap schemas by subclassing `CoMap` and assigning field schemas with `co`. Optional `co.ref(...)` fields must be marked with `{ optional: true }`. ```ts import { co, CoMap } from "jazz-tools"; class Person extends CoMap { name = co.string; age = co.number; pet = co.ref(Animal); car = co.ref(Car, { optional: true }); } ```@categoryDescriptionContent You can access properties you declare on a `CoMap` (using `co`) as if they were normal properties on a plain object, using dot notation, `Object.keys()`, etc. ```ts person.name; person["age"]; person.age = 42; person.pet?.name; Object.keys(person); // => ["name", "age", "pet"] ```@categoryCoValues
CoMap
{
Project.name: co<string>name =
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.string: co<string>string;
} export class class ListOfProjectsListOfProjects extends class CoList<Item = any>
CoLists are collaborative versions of plain arrays.
@categoryDescriptionContent You can access items on a `CoList` as if they were normal items on a plain array, using `[]` notation, etc. Since `CoList` is a subclass of `Array`, you can use all the normal array methods like `push`, `pop`, `splice`, etc. ```ts colorList[0]; colorList[3] = "yellow"; colorList.push("Kawazaki Green"); colorList.splice(1, 1); ```@categoryCoValues
CoList
.
CoList<Item = any>.Of<co<Project | null>>(item: co<Project | null>): {
    new (options: {
        fromRaw: RawCoList;
    } | undefined): CoList<co<Project | null>>;
    ... 12 more ...;
    fromAsync<T>(iterableOrArrayLike: AsyncIterable<T> | Iterable<T | PromiseLike<T>> | ArrayLike<T | PromiseLike<T>>): Promise<T[]>;
    fromAsync<T, U>(iterableOrArrayLike: AsyncIterable<T> | Iterable<T> | ArrayLike<T>, mapFn: (value: Awaited<T>, index: number) => U, thisArg?: any): Promise<Awaited<U>[]>;
}
Declare a `CoList` by subclassing `CoList.Of(...)` and passing the item schema using `co`.
@example```ts class ColorList extends CoList.Of( co.string ) {} class AnimalList extends CoList.Of( co.ref(Animal) ) {} ```@categoryDeclaration
Of
(
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.
ref: <typeof Project>(arg: typeof Project | ((_raw: RawCoMap<{
    [key: string]: JsonValue | undefined;
}, JsonObject | null>) => typeof Project), options?: never) => co<...> (+1 overload)
ref
(class ProjectProject)) {}
export class class OrganizationOrganization extends class CoMap
CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
@categoryDescriptionDeclaration Declare your own CoMap schemas by subclassing `CoMap` and assigning field schemas with `co`. Optional `co.ref(...)` fields must be marked with `{ optional: true }`. ```ts import { co, CoMap } from "jazz-tools"; class Person extends CoMap { name = co.string; age = co.number; pet = co.ref(Animal); car = co.ref(Car, { optional: true }); } ```@categoryDescriptionContent You can access properties you declare on a `CoMap` (using `co`) as if they were normal properties on a plain object, using dot notation, `Object.keys()`, etc. ```ts person.name; person["age"]; person.age = 42; person.pet?.name; Object.keys(person); // => ["name", "age", "pet"] ```@categoryCoValues
CoMap
{
Organization.name: co<string>name =
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.string: co<string>string;
// shared data between users of each organization Organization.projects: co<ListOfProjects | null>projects =
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.ref: <typeof ListOfProjects>(arg: typeof ListOfProjects | ((_raw: RawCoList<JsonValue, null>) => typeof ListOfProjects), options?: never) => co<...> (+1 overload)ref(class ListOfProjectsListOfProjects);
} export class class ListOfOrganizationsListOfOrganizations extends class CoList<Item = any>
CoLists are collaborative versions of plain arrays.
@categoryDescriptionContent You can access items on a `CoList` as if they were normal items on a plain array, using `[]` notation, etc. Since `CoList` is a subclass of `Array`, you can use all the normal array methods like `push`, `pop`, `splice`, etc. ```ts colorList[0]; colorList[3] = "yellow"; colorList.push("Kawazaki Green"); colorList.splice(1, 1); ```@categoryCoValues
CoList
.
CoList<Item = any>.Of<co<Organization | null>>(item: co<Organization | null>): {
    new (options: {
        fromRaw: RawCoList;
    } | undefined): CoList<...>;
    ... 12 more ...;
    fromAsync<T>(iterableOrArrayLike: AsyncIterable<T> | Iterable<T | PromiseLike<T>> | ArrayLike<T | PromiseLike<T>>): Promise<T[]>;
    fromAsync<T, U>(iterableOrArrayLike: AsyncIterable<T> | Iterable<T> | ArrayLike<T>, mapFn: (value: Awaited<T>, index: number) => U, thisArg?: any): Promise<Awaited<U>[]>;
}
Declare a `CoList` by subclassing `CoList.Of(...)` and passing the item schema using `co`.
@example```ts class ColorList extends CoList.Of( co.string ) {} class AnimalList extends CoList.Of( co.ref(Animal) ) {} ```@categoryDeclaration
Of
(
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.
ref: <typeof Organization>(arg: typeof Organization | ((_raw: RawCoMap<{
    [key: string]: JsonValue | undefined;
}, JsonObject | null>) => typeof Organization), options?: never) => co<...> (+1 overload)
ref
(class OrganizationOrganization)) {}

Learn more about defining schemas.

Adding a list of Organizations to the user's Account

Let's add the list of Organizations to the user's Account root so they can access them.

// schema.ts
export class class JazzAccountRootJazzAccountRoot extends class CoMap
CoMaps are collaborative versions of plain objects, mapping string-like keys to values.
@categoryDescriptionDeclaration Declare your own CoMap schemas by subclassing `CoMap` and assigning field schemas with `co`. Optional `co.ref(...)` fields must be marked with `{ optional: true }`. ```ts import { co, CoMap } from "jazz-tools"; class Person extends CoMap { name = co.string; age = co.number; pet = co.ref(Animal); car = co.ref(Car, { optional: true }); } ```@categoryDescriptionContent You can access properties you declare on a `CoMap` (using `co`) as if they were normal properties on a plain object, using dot notation, `Object.keys()`, etc. ```ts person.name; person["age"]; person.age = 42; person.pet?.name; Object.keys(person); // => ["name", "age", "pet"] ```@categoryCoValues
CoMap
{
JazzAccountRoot.organizations: co<ListOfOrganizations | null>organizations =
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.ref: <typeof ListOfOrganizations>(arg: typeof ListOfOrganizations | ((_raw: RawCoList<JsonValue, null>) => typeof ListOfOrganizations), options?: never) => co<...> (+1 overload)ref(class ListOfOrganizationsListOfOrganizations);
} export class class JazzAccountJazzAccount extends class Account
@categoryIdentity & Permissions
Account
{
JazzAccount.root: co<JazzAccountRoot | null>root =
const co: {
    string: co<string>;
    number: co<number>;
    boolean: co<boolean>;
    null: co<null>;
    Date: co<Date>;
    literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number]>;
    json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T>;
    encoded<T>(arg: Encoder<T>): co<T>;
    ref: {
        ...;
    };
    items: ItemsSym;
    optional: {
        ref: <C extends CoValueClass>(arg: C | ((_raw: InstanceType<C>["_raw"]) => C)) => co<InstanceType<C> | null | undefined>;
        json<T extends CojsonInternalTypes.CoJsonValue<T>>(): co<T | undefined>;
        encoded<T>(arg: OptionalEncoder<T>): co<T | undefined>;
        string: co<string | undefined>;
        number: co<number | undefined>;
        boolean: co<boolean | undefined>;
        null: co<null | undefined>;
        Date: co<Date | undefined>;
        literal<T extends (string | number | boolean)[]>(..._lit: T): co<T[number] | undefined>;
    };
}
@categorySchema definition@categorySchema definition
co
.
ref: <typeof JazzAccountRoot>(arg: typeof JazzAccountRoot | ((_raw: RawCoMap<{
    [key: string]: JsonValue | undefined;
}, JsonObject | null>) => typeof JazzAccountRoot), options?: never) => co<...> (+1 overload)
ref
(class JazzAccountRootJazzAccountRoot);
async JazzAccount.migrate(): Promise<void>migrate() { if (this.JazzAccount.root: co<JazzAccountRoot | null>root === var undefinedundefined) { // Using a Group as an owner allows you to give access to other users const const organizationGroup: GrouporganizationGroup = class Group
@categoryIdentity & Permissions
Group
.
Group.create<Group>(this: CoValueClass<Group>, options?: {
    owner: Account;
} | Account): Group
create
();
const const organizations: ListOfOrganizationsorganizations = class ListOfOrganizationsListOfOrganizations.
CoList<Item>.create<ListOfOrganizations>(this: CoValueClass<ListOfOrganizations>, items: (Organization | null)[], options?: {
    owner: Account | Group;
} | Account | Group): ListOfOrganizations
Create a new CoList with the given initial values and owner. The owner (a Group or Account) determines access rights to the CoMap. The CoList will immediately be persisted and synced to connected peers.
@example```ts const colours = ColorList.create( ["red", "green", "blue"], { owner: me } ); const animals = AnimalList.create( [cat, dog, fish], { owner: me } ); ```@categoryCreation
create
(
[ // Create the first Organization so users can start right away class OrganizationOrganization.
CoMap.create<Organization>(this: CoValueClass<...>, init: {
    name: co<string> & (co<string> | undefined);
    projects: (ListOfProjects | NonNullable<ListOfProjects & CoMarker>) & (ListOfProjects | ... 1 more ... | undefined);
}, options?: {
    owner: Account | Group;
    unique?: CoValueUniqueness["uniqueness"];
} | Account | Group): Organization
Create a new CoMap with the given initial values and owner. The owner (a Group or Account) determines access rights to the CoMap. The CoMap will immediately be persisted and synced to connected peers.
@example```ts const person = Person.create({ name: "Alice", age: 42, pet: cat, }, { owner: friendGroup }); ```@categoryCreation
create
(
{ name: co<string> & (co<string> | undefined)name: "My organization", projects: (ListOfProjects | NonNullable<ListOfProjects & CoMarker>) & (ListOfProjects | NonNullable<ListOfProjects & CoMarker> | undefined)projects: class ListOfProjectsListOfProjects.
CoList<Item>.create<ListOfProjects>(this: CoValueClass<ListOfProjects>, items: (Project | null)[], options?: {
    owner: Account | Group;
} | Account | Group): ListOfProjects
Create a new CoList with the given initial values and owner. The owner (a Group or Account) determines access rights to the CoMap. The CoList will immediately be persisted and synced to connected peers.
@example```ts const colours = ColorList.create( ["red", "green", "blue"], { owner: me } ); const animals = AnimalList.create( [cat, dog, fish], { owner: me } ); ```@categoryCreation
create
([], const organizationGroup: GrouporganizationGroup),
}, const organizationGroup: GrouporganizationGroup, ), ], ); this.JazzAccount.root: co<JazzAccountRoot | null>root = class JazzAccountRootJazzAccountRoot.
CoMap.create<JazzAccountRoot>(this: CoValueClass<...>, init: {
    organizations: (ListOfOrganizations | NonNullable<ListOfOrganizations & CoMarker>) & (ListOfOrganizations | ... 1 more ... | undefined);
}, options?: {
    owner: Account | Group;
    unique?: CoValueUniqueness["uniqueness"];
} | Account | Group): JazzAccountRoot
Create a new CoMap with the given initial values and owner. The owner (a Group or Account) determines access rights to the CoMap. The CoMap will immediately be persisted and synced to connected peers.
@example```ts const person = Person.create({ name: "Alice", age: 42, pet: cat, }, { owner: friendGroup }); ```@categoryCreation
create
(
{ organizations: (ListOfOrganizations | NonNullable<ListOfOrganizations & CoMarker>) & (ListOfOrganizations | NonNullable<...> | undefined)organizations }, ); } } }

This schema now allows users to create Organizations and add Projects to them.

See the schema for the example app here.

Adding other users to an Organization

To give users access to an Organization, you can either send them an invite link, or add their Account manually.

Here's how you can generate an invite link.

When the user accepts the invite, add the Organization to the user's organizations list.

export function function AcceptInvitePage(): React.JSX.ElementAcceptInvitePage() {
  const { 
const me: ({
    root: {
        organizations: (Organization | null)[] & ListOfOrganizations;
    } & JazzAccountRoot;
} & JazzAccount) | null | undefined
me
} =
useAccount<JazzAccount, {
    root: {
        organizations: {
            $each: {
                $onError: null;
            };
        };
    };
}>(options?: {
    resolve?: RefsToResolve<JazzAccount, 10, []> | undefined;
} | undefined): {
    ...;
} (+1 overload)
useAccount
({
resolve?: RefsToResolve<JazzAccount, 10, []> | undefinedresolve: { root?: RefsToResolve<JazzAccountRoot, 10, [0]> | undefinedroot: { organizations?: RefsToResolve<ListOfOrganizations, 10, [0, 0]> | undefinedorganizations: { $each: RefsToResolve<Organization, 10, [0, 0, 0]>$each: { $onError?: null | undefined$onError: null } } } }, }); const const onAccept: (organizationId: ID<Organization>) => voidonAccept = (organizationId: ID<Organization>organizationId: type ID<T> = `co_z${string}` & IDMarker<T>
IDs are unique identifiers for `CoValue`s. Can be used with a type argument to refer to a specific `CoValue` type.
@example```ts type AccountID = ID<Account>; ```@categoryCoValues
ID
<class OrganizationOrganization>) => {
if (
const me: ({
    root: {
        organizations: (Organization | null)[] & ListOfOrganizations;
    } & JazzAccountRoot;
} & JazzAccount) | null | undefined
me
) {
class OrganizationOrganization.
CoMap.load<Organization, true>(this: CoValueClass<...>, id: ID<Organization>, options?: {
    resolve?: RefsToResolve<Organization, 10, []> | undefined;
    loadAs?: Account | AnonymousJazzAgent;
} | undefined): Promise<...>
Load a `CoMap` with a given ID, as a given account. `depth` specifies which (if any) fields that reference other CoValues to load as well before resolving. The `DeeplyLoaded` return type guarantees that corresponding referenced CoValues are loaded to the specified depth. You can pass `[]` or `{}` for shallowly loading only this CoMap, or `{ fieldA: depthA, fieldB: depthB }` for recursively loading referenced CoValues. Check out the `load` methods on `CoMap`/`CoList`/`CoFeed`/`Group`/`Account` to see which depth structures are valid to nest.
@example```ts const person = await Person.load( "co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax", { pet: {} } ); ```@categorySubscription & Loading
load
(organizationId: ID<Organization>organizationId).Promise<Organization | null>.then<void, never>(onfulfilled?: ((value: Organization | null) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<...>
Attaches callbacks for the resolution and/or rejection of the Promise.
@paramonfulfilled The callback to execute when the Promise is resolved.@paramonrejected The callback to execute when the Promise is rejected.@returnsA Promise for the completion of which ever callback is executed.
then
((organization: Organization | nullorganization) => {
if (organization: Organization | nullorganization) { // avoid duplicates const const ids: (ID<Organization> | undefined)[]ids =
const me: {
    root: {
        organizations: (Organization | null)[] & ListOfOrganizations;
    } & JazzAccountRoot;
} & JazzAccount
me
.
JazzAccount.root: {
    organizations: (Organization | null)[] & ListOfOrganizations;
} & JazzAccountRoot & co<JazzAccountRoot | null>
root
.JazzAccountRoot.organizations: (Organization | null)[] & ListOfOrganizations & co<ListOfOrganizations | null>organizations.Array<T>.map<ID<Organization> | undefined>(callbackfn: (value: Organization | null, index: number, array: (Organization | null)[]) => ID<Organization> | undefined, thisArg?: any): (ID<...> | undefined)[] (+1 overload)
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
(
(organization: Organization | nullorganization) => organization: Organization | nullorganization?.CoMap.id: ID<Organization> | undefined
The ID of this `CoMap`
@categoryContent
id
,
); if (const ids: (ID<Organization> | undefined)[]ids.Array<ID<Organization> | undefined>.includes(searchElement: ID<Organization> | undefined, fromIndex?: number): boolean
Determines whether an array includes a certain element, returning true or false as appropriate.
@paramsearchElement The element to search for.@paramfromIndex The position in this array at which to begin searching for searchElement.
includes
(organizationId: ID<Organization>organizationId)) return;
const me: {
    root: {
        organizations: (Organization | null)[] & ListOfOrganizations;
    } & JazzAccountRoot;
} & JazzAccount
me
.
JazzAccount.root: {
    organizations: (Organization | null)[] & ListOfOrganizations;
} & JazzAccountRoot & co<JazzAccountRoot | null>
root
.JazzAccountRoot.organizations: (Organization | null)[] & ListOfOrganizations & co<ListOfOrganizations | null>organizations.function push(...items: (Organization | null)[]): number (+1 overload)
Appends new elements to the end of an array, and returns the new length of the array.
@paramitems New elements to add to the array.
push
(organization: Organizationorganization);
} }); } };
useAcceptInvite<Organization>({ invitedObjectSchema, onAccept, forValueHint, }: {
    invitedObjectSchema: CoValueClass<Organization>;
    onAccept: (projectID: ID<Organization>) => void;
    forValueHint?: string;
}): void
useAcceptInvite
({
invitedObjectSchema: CoValueClass<Organization>invitedObjectSchema: class OrganizationOrganization, onAccept: (projectID: ID<Organization>) => voidonAccept, }); return <JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>p>Accepting invite...</JSX.IntrinsicElements.p: React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>p>; }

Adding users through their Account ID

...more on this coming soon