jazz-tools
CoValues
type ID
type ID<T> = CojsonInternalTypes.RawCoID & IDMarker<T>
class CoMap
CoMap
and assigning field schemas with co
.Optional
co.ref(...)
fields must be marked with { optional: true }
.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 });
}
CoMap.Record<Value>(value):
RecordLikeCoMap
value: IfCo<Value, Value>
CoMap.Record(...)
and passing the value schema using co
. Keys are always string
.import { co, CoMap } from "jazz-tools";
class ColorToFruitMap extends CoMap.Record(
co.ref(Fruit)
) {}
// assume we have map: ColorToFruitMap
// and strawberry: Fruit
map["red"] = strawberry;
CoMap
(using co
) as if they were normal properties on a plain object, using dot notation, Object.keys()
, etc.person.name;
person["age"];
person.age = 42;
person.pet?.name;
Object.keys(person);
// => ["name", "age", "pet"]
.id:
ID<CoMap>
CoMap
._refs:
{[Key in string]: IfCo<this[Key], RefIfCoValue<this[Key]>>}
prop
is a co.ref(...)
, you can use coMaps._refs.prop
to accessthe
Ref
instead of the potentially loaded/null value.This allows you to always get the ID or load the value manually.
person._refs.pet.id; // => ID<Animal>
person._refs.pet.value;
// => Animal | null
const pet = await person._refs.pet.load();
CoMap.create<M>(init, options):
M
M extends CoMap
this: CoValueClass<M>,
init: Simplify<CoMapInit<M>>,
options: { owner: Group | Account, unique: JsonValue }
The owner (a Group or Account) determines access rights to the CoMap.
The CoMap will immediately be persisted and synced to connected peers.
const person = Person.create({
name: "Alice",
age: 42,
pet: cat,
}, { owner: friendGroup });
CoMap.load<M, Depth>(id, as, depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>
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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.const person = await Person.load(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} }
);
CoMap.subscribe<M, Depth>(id, as, depth, listener):
() => void
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
with a given ID, as a given account.Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
depth
specifies which (if any) fields that reference other CoValues to load as well before calling listener
for the first time.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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.Returns an unsubscribe function that you should call when you no longer need updates.
Also see the
useCoState
hook to reactively subscribe to a CoValue in a React component.const unsub = Person.subscribe(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} },
(person) => console.log(person)
);
.ensureLoaded<M, Depth>(depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>
CoMap
, ensure that the specified fields are loaded to the specified depth.Works like
CoMap.load()
, but you don't need to pass the ID or the account to load as again..subscribe<M, Depth>(depth, listener):
() => void
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
, subscribe to updates to the CoMap
and ensure that the specified fields are loaded to the specified depth.Works like
CoMap.subscribe()
, but you don't need to pass the ID or the account to load as again.Returns an unsubscribe function that you should call when you no longer need updates.
._edits:
{[Key in string]: IfCo<this[Key], CoMapEdit<this[Key]>>}
._owner:
Group | Account
.toJSON(_key, seenAbove):
any[]
_key: string,
seenAbove: ID<CoValue>[]
.[inspect]():
any[]
CoMap.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawCoMap<{ undefined }, JsonObject | null>
._instanceID:
string
._type:
"CoMap"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
CoMap.findUnique<M>(unique, ownerID, as):
ID<M>
M extends CoMap
this: CoValueClass<M>,
unique: JsonValue,
ownerID: ID<Group> | ID<Account>,
as: AnonymousJazzAgent | Group | Account
.applyDiff<N>(newValues):
CoMap
N extends Partial<CoMapInit<CoMap>>
newValues: N
._loadedAs:
AnonymousJazzAgent | Account
class CoList<Item>
*
CoList.Of<Item>(item):
CoList
item: Item
CoList
by subclassing CoList.Of(...)
and passing the item schema using co
.class ColorList extends CoList.Of(
co.string
) {}
class AnimalList extends CoList.Of(
co.ref(Animal)
) {}
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.colorList[0];
colorList[3] = "yellow";
colorList.push("Kawazaki Green");
colorList.splice(1, 1);
.id:
ID<CoList<Item>>
CoList
._refs:
{ undefined } & { length: number, [iterator]: NO TYPE }
CoList
's items are a co.ref(...)
, you can use coList._refs[i]
to accessthe
Ref
instead of the potentially loaded/null value.This allows you to always get the ID or load the value manually.
animals._refs[0].id; // => ID<Animal>
animals._refs[0].value;
// => Animal | null
const animal = await animals._refs[0].load();
CoList.create<L>(items, options):
L
L extends CoList<any>
this: CoValueClass<L>,
items: UnCo<L[number]>[],
options: { owner: Group | Account }
The owner (a Group or Account) determines access rights to the CoMap.
The CoList will immediately be persisted and synced to connected peers.
const colours = ColorList.create(
["red", "green", "blue"],
{ owner: me }
);
const animals = AnimalList.create(
[cat, dog, fish],
{ owner: me }
);
CoList.load<L, Depth>(id, as, depth):
Promise<DeeplyLoaded<L, Depth> | undefined>
L extends CoList<any>
this: CoValueClass<L>,
id: ID<L>,
as: Account,
depth: Depth & DepthsIn<L>
CoList
with a given ID, as a given account.depth
specifies if item CoValue references should be loaded 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 CoList, or [itemDepth]
for recursively loading referenced CoValues.Check out the
load
methods on CoMap
/CoList
/CoStream
/Group
/Account
to see which depth structures are valid to nest.const animalsWithVets =
await ListOfAnimals.load(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
[{ vet: {} }]
);
CoList.subscribe<L, Depth>(id, as, depth, listener):
() => void
L extends CoList<any>
this: CoValueClass<L>,
id: ID<L>,
as: Account,
depth: Depth & DepthsIn<L>,
listener: (value: DeeplyLoaded<L, Depth>) => void
CoList
with a given ID, as a given account.Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
depth
specifies if item CoValue references should be loaded as well before calling listener
for the first time.The
DeeplyLoaded
return type guarantees that corresponding referenced CoValues are loaded to the specified depth.You can pass
[]
or for shallowly loading only this CoList, or [itemDepth]
for recursively loading referenced CoValues.Check out the
load
methods on CoMap
/CoList
/CoStream
/Group
/Account
to see which depth structures are valid to nest.Returns an unsubscribe function that you should call when you no longer need updates.
Also see the
useCoState
hook to reactively subscribe to a CoValue in a React component.const unsub = ListOfAnimals.subscribe(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ vet: {} },
(animalsWithVets) => console.log(animalsWithVets)
);
.ensureLoaded<L, Depth>(depth):
Promise<DeeplyLoaded<L, Depth> | undefined>
L extends CoList<any>
this: L,
depth: Depth & DepthsIn<L>
CoList
, ensure that items are loaded to the specified depth.Works like
CoList.load()
, but you don't need to pass the ID or the account to load as again..subscribe<L, Depth>(depth, listener):
() => void
L extends CoList<any>
this: L,
depth: Depth & DepthsIn<L>,
listener: (value: DeeplyLoaded<L, Depth>) => void
CoList
, subscribe to updates to the CoList
and ensure that items are loaded to the specified depth.Works like
CoList.subscribe()
, but you don't need to pass the ID or the account to load as again.Returns an unsubscribe function that you should call when you no longer need updates.
._owner:
Group | Account
.toJSON(_key, seenAbove):
any[]
_key: string,
seenAbove: ID<CoValue>[]
.[inspect]():
any[]
CoList.fromRaw<V>(raw):
V & CoList<any>
V extends CoList<any>
this: CoValueClass<V> & CoList,
raw: RawCoList<JsonValue, JsonObject | null>
._raw:
RawCoList<JsonValue, JsonObject | null>
._instanceID:
string
._type:
"CoList"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
CoList[species]:
ArrayConstructor
CoList.isArray(arg):
arg is any[]
arg: any
CoList.from<T>(arrayLike):
T[]
arrayLike: ArrayLike<T>
CoList.from<T, U>(arrayLike, mapfn, thisArg):
U[]
arrayLike: ArrayLike<T>,
mapfn: (v: T, k: number) => U,
thisArg: any
CoList.from<T>(iterable):
T[]
iterable: ArrayLike<T> | Iterable<T>
CoList.from<T, U>(iterable, mapfn, thisArg):
U[]
iterable: ArrayLike<T> | Iterable<T>,
mapfn: (v: T, k: number) => U,
thisArg: any
.constructor:
NO TYPE
._edits:
{ undefined }
._loadedAs:
AnonymousJazzAgent | Account
.push(items):
number
items: Item[]
.unshift(items):
number
items: Item[]
.pop():
Item | undefined
.shift():
Item | undefined
.splice(start, deleteCount, items):
Item[]
start: number,
deleteCount: number,
items: Item[]
.length:
number
.toString():
string
.toLocaleString():
string
.concat(items):
Item[]
items: ConcatArray<Item>[]
This method returns a new array without modifying any existing arrays.
.concat(items):
Item[]
items: ConcatArray<Item> | Item[]
This method returns a new array without modifying any existing arrays.
.join(separator):
string
separator: string
.reverse():
Item[]
This method mutates the array and returns a reference to the same array.
.slice(start, end):
Item[]
start: number,
end: number
For both start and end, a negative index can be used to indicate an offset from the end of the array.
For example, -2 refers to the second to last element of the array.
.sort(compareFn):
this
compareFn: (a: Item, b: Item) => number
This method mutates the array and returns a reference to the same array.
.indexOf(searchElement, fromIndex):
number
searchElement: Item,
fromIndex: number
.lastIndexOf(searchElement, fromIndex):
number
searchElement: Item,
fromIndex: number
.every<S>(predicate, thisArg):
this is S[]
predicate: (value: Item, index: number, array: Item[]) => value is S,
thisArg: any
.every(predicate, thisArg):
boolean
predicate: (value: Item, index: number, array: Item[]) => unknown,
thisArg: any
.some(predicate, thisArg):
boolean
predicate: (value: Item, index: number, array: Item[]) => unknown,
thisArg: any
.forEach(callbackfn, thisArg):
void
callbackfn: (value: Item, index: number, array: Item[]) => void,
thisArg: any
.map<U>(callbackfn, thisArg):
U[]
callbackfn: (value: Item, index: number, array: Item[]) => U,
thisArg: any
.filter<S>(predicate, thisArg):
S[]
predicate: (value: Item, index: number, array: Item[]) => value is S,
thisArg: any
.filter(predicate, thisArg):
Item[]
predicate: (value: Item, index: number, array: Item[]) => unknown,
thisArg: any
.reduce(callbackfn):
Item
callbackfn: (previousValue: Item, currentValue: Item, currentIndex: number, array: Item[]) => Item
.reduce(callbackfn, initialValue):
Item
callbackfn: (previousValue: Item, currentValue: Item, currentIndex: number, array: Item[]) => Item,
initialValue: Item
.reduce<U>(callbackfn, initialValue):
U
callbackfn: (previousValue: U, currentValue: Item, currentIndex: number, array: Item[]) => U,
initialValue: U
.reduceRight(callbackfn):
Item
callbackfn: (previousValue: Item, currentValue: Item, currentIndex: number, array: Item[]) => Item
.reduceRight(callbackfn, initialValue):
Item
callbackfn: (previousValue: Item, currentValue: Item, currentIndex: number, array: Item[]) => Item,
initialValue: Item
.reduceRight<U>(callbackfn, initialValue):
U
callbackfn: (previousValue: U, currentValue: Item, currentIndex: number, array: Item[]) => U,
initialValue: U
.find<S>(predicate, thisArg):
S | undefined
predicate: (value: Item, index: number, obj: Item[]) => value is S,
thisArg: any
otherwise.
.find(predicate, thisArg):
Item | undefined
predicate: (value: Item, index: number, obj: Item[]) => unknown,
thisArg: any
.findIndex(predicate, thisArg):
number
predicate: (value: Item, index: number, obj: Item[]) => unknown,
thisArg: any
otherwise.
.fill(value, start, end):
this
value: Item,
start: number,
end: number
start
to end
index to a static value
and returns the modified array.copyWithin(target, start, end):
this
target: number,
start: number,
end: number
to the same array starting at position target
.entries():
IterableIterator<[number, Item]>
.keys():
IterableIterator<number>
.values():
IterableIterator<Item>
.includes(searchElement, fromIndex):
boolean
searchElement: Item,
fromIndex: number
.flatMap<U, This>(callback, thisArg):
U[]
callback: (this: This, value: Item, index: number, array: Item[]) => TODO type typeOperator | U,
thisArg: This
a new array.
This is identical to a map followed by flat with depth 1.
.flat<A, D>(depth):
FlatArray<A, D>[]
D extends number
this: A,
depth: D
specified depth.
.at(index):
Item | undefined
index: number
.findLast<S>(predicate, thisArg):
S | undefined
predicate: (value: Item, index: number, array: Item[]) => value is S,
thisArg: any
otherwise.
.findLast(predicate, thisArg):
Item | undefined
predicate: (value: Item, index: number, array: Item[]) => unknown,
thisArg: any
.findLastIndex(predicate, thisArg):
number
predicate: (value: Item, index: number, array: Item[]) => unknown,
thisArg: any
otherwise.
.toReversed():
Item[]
.toSorted(compareFn):
Item[]
compareFn: (a: Item, b: Item) => number
.toSpliced(start, deleteCount, items):
Item[]
start: number,
deleteCount: number,
items: Item[]
.toSpliced(start, deleteCount):
Item[]
start: number,
deleteCount: number
.with(index, value):
Item[]
index: number,
value: Item
given value. If the index is negative, then it replaces from the end
of the array.
.[iterator]():
IterableIterator<Item>
[unscopables]:
{ length: boolean, toString: NO TYPE, toLocaleString: NO TYPE, pop: NO TYPE, push: NO TYPE, concat: NO TYPE, join: NO TYPE, reverse: NO TYPE, shift: NO TYPE, slice: NO TYPE, sort: NO TYPE, splice: NO TYPE, unshift: NO TYPE, indexOf: NO TYPE, lastIndexOf: NO TYPE, every: NO TYPE, some: NO TYPE, forEach: NO TYPE, map: NO TYPE, filter: NO TYPE, reduce: NO TYPE, reduceRight: NO TYPE, find: NO TYPE, findIndex: NO TYPE, fill: NO TYPE, copyWithin: NO TYPE, entries: NO TYPE, keys: NO TYPE, values: NO TYPE, includes: NO TYPE, flatMap: NO TYPE, flat: NO TYPE, at: NO TYPE, findLast: NO TYPE, findLastIndex: NO TYPE, toReversed: NO TYPE, toSorted: NO TYPE, toSpliced: NO TYPE, with: NO TYPE, [iterator]: NO TYPE, [unscopables]: boolean }
when they will be absent when used in a 'with' statement.
class CoStream<Item>
.id:
ID<CoStream<Item>>
CoStream.load<S, Depth>(id, as, depth):
Promise<DeeplyLoaded<S, Depth> | undefined>
S extends CoStream<any>
this: CoValueClass<S>,
id: ID<S>,
as: Account,
depth: Depth & DepthsIn<S>
CoStream.subscribe<S, Depth>(id, as, depth, listener):
() => void
S extends CoStream<any>
this: CoValueClass<S>,
id: ID<S>,
as: Account,
depth: Depth & DepthsIn<S>,
listener: (value: DeeplyLoaded<S, Depth>) => void
.ensureLoaded<S, Depth>(depth):
Promise<DeeplyLoaded<S, Depth> | undefined>
S extends CoStream<any>
this: S,
depth: Depth & DepthsIn<S>
.subscribe<S, Depth>(depth, listener):
() => void
S extends CoStream<any>
this: S,
depth: Depth & DepthsIn<S>,
listener: (value: DeeplyLoaded<S, Depth>) => void
._owner:
Group | Account
.toJSON():
{ in: { undefined }, id: ID<CoStream<Item>>, _type: "CoStream" }
.[inspect]():
{ in: { undefined }, id: ID<CoStream<Item>>, _type: "CoStream" }
CoStream.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawCoStream<JsonValue, JsonObject | null>
._instanceID:
string
._type:
"CoStream"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
CoStream.Of<Item>(item):
CoStream
item: IfCo<Item, Item>
CoStream._schema:
any
CoStream.create<S>(init, options):
S
S extends CoStream<any>
this: CoValueClass<S>,
init: TODO type conditional,
options: { owner: Group | Account }
CoStream.schema<V>(def):
void
V extends CoStream<any>
this: TODO reflection type 512 & CoStream,
def: { [ItemsSym]: V["_schema"][ItemsSym] }
.constructor:
NO TYPE
._schema:
{ [ItemsSym]: SchemaFor<Item> }
.byMe:
CoStreamEntry<Item> | undefined
.perSession:
{ undefined }
.inCurrentSession:
CoStreamEntry<Item> | undefined
.push(items):
void
items: Item[]
.pushItem(item):
void
item: Item
._loadedAs:
AnonymousJazzAgent | Account
class BinaryCoStream
.id:
ID<BinaryCoStream>
BinaryCoStream.load<B, Depth>(id, as, depth):
Promise<DeeplyLoaded<B, Depth> | undefined>
B extends BinaryCoStream
this: CoValueClass<B>,
id: ID<B>,
as: Account,
depth: Depth & DepthsIn<B>
BinaryCoStream.subscribe<B, Depth>(id, as, depth, listener):
() => void
B extends BinaryCoStream
this: CoValueClass<B>,
id: ID<B>,
as: Account,
depth: Depth & DepthsIn<B>,
listener: (value: DeeplyLoaded<B, Depth>) => void
.ensureLoaded<B, Depth>(depth):
Promise<DeeplyLoaded<B, Depth> | undefined>
B extends BinaryCoStream
this: B,
depth: Depth & DepthsIn<B>
.subscribe<B, Depth>(depth, listener):
() => void
B extends BinaryCoStream
this: B,
depth: Depth & DepthsIn<B>,
listener: (value: DeeplyLoaded<B, Depth>) => void
._owner:
Group | Account
.toJSON():
{ id: ID<BinaryCoStream>, _type: "BinaryCoStream", mimeType: string, fileName: string, totalSizeBytes: number, chunks: Uint8Array[], finished: boolean }
.[inspect]():
{ id: ID<BinaryCoStream>, _type: "BinaryCoStream", mimeType: string, fileName: string, totalSizeBytes: number, chunks: Uint8Array[], finished: boolean }
BinaryCoStream.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawBinaryCoStream<{ type: "binary" }>
._instanceID:
string
._type:
"BinaryCoStream"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
BinaryCoStream.create<S>(options):
S
S extends BinaryCoStream
this: CoValueClass<S>,
options: { owner: Group | Account }
BinaryCoStream.loadAsBlob(id, as, options):
Promise<Blob | undefined>
id: ID<BinaryCoStream>,
as: Account,
options: { allowUnfinished: boolean }
BinaryCoStream.createFromBlob(blob, options):
Promise<BinaryCoStream>
blob: File | Blob,
options: { owner: Group | Account, onProgress: (progress: number) => void }
.constructor:
NO TYPE
.getChunks(options):
BinaryStreamInfo & { chunks: Uint8Array[], finished: boolean } | undefined
options: { allowUnfinished: boolean }
.isBinaryStreamEnded():
boolean
.start(options):
void
options: BinaryStreamInfo
.push(data):
void
data: Uint8Array
.end():
void
.toBlob(options):
Blob | undefined
options: { allowUnfinished: boolean }
._loadedAs:
AnonymousJazzAgent | Account
Identity & Permissions
class Group
.id:
ID<Group>
Group.load<G, Depth>(id, as, depth):
Promise<DeeplyLoaded<G, Depth> | undefined>
G extends Group
this: CoValueClass<G>,
id: ID<G>,
as: Account,
depth: Depth & DepthsIn<G>
Group.subscribe<G, Depth>(id, as, depth, listener):
() => void
G extends Group
this: CoValueClass<G>,
id: ID<G>,
as: Account,
depth: Depth & DepthsIn<G>,
listener: (value: DeeplyLoaded<G, Depth>) => void
.ensureLoaded<G, Depth>(depth):
Promise<DeeplyLoaded<G, Depth> | undefined>
G extends Group
this: G,
depth: Depth & DepthsIn<G>
.subscribe<G, Depth>(depth, listener):
() => void
G extends Group
this: G,
depth: Depth & DepthsIn<G>,
listener: (value: DeeplyLoaded<G, Depth>) => void
._owner:
Group | Account
.toJSON():
any[] | string | object
.[inspect]():
any[] | string | object
Group.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawGroup<JsonObject | null>
._instanceID:
string
._type:
"Group"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
Group._schema:
any
Group.create<G>(options):
G
G extends Group
this: CoValueClass<G>,
options: { owner: Account }
.constructor:
NO TYPE
._schema:
{ profile: Schema, root: Schema, [MembersSym]: RefEncoded<Account> }
.profile:
Profile | null
.root:
CoMap | null
._refs:
{ profile: (TODO type conditional) | undefined, root: (TODO type conditional) | undefined }
.myRole():
Role | undefined
.addMember(member, role):
Group
member: Account | "everyone",
role: Role
.members:
{ id: ID<this[MembersSym]> | "everyone", role: Role | undefined, ref: Ref<NonNullable<this[MembersSym]>> | undefined, account: NO TYPE }[]
[MembersSym]:
Account | null
._loadedAs:
AnonymousJazzAgent | Account
class Profile
Profile.Record<Value>(value):
RecordLikeCoMap
value: IfCo<Value, Value>
CoMap.Record(...)
and passing the value schema using co
. Keys are always string
.import { co, CoMap } from "jazz-tools";
class ColorToFruitMap extends CoMap.Record(
co.ref(Fruit)
) {}
// assume we have map: ColorToFruitMap
// and strawberry: Fruit
map["red"] = strawberry;
.id:
ID<Profile>
CoMap
._refs:
{[Key in string]: IfCo<this[Key], RefIfCoValue<this[Key]>>}
prop
is a co.ref(...)
, you can use coMaps._refs.prop
to accessthe
Ref
instead of the potentially loaded/null value.This allows you to always get the ID or load the value manually.
person._refs.pet.id; // => ID<Animal>
person._refs.pet.value;
// => Animal | null
const pet = await person._refs.pet.load();
Profile.create<M>(init, options):
M
M extends CoMap
this: CoValueClass<M>,
init: Simplify<CoMapInit<M>>,
options: { owner: Group | Account, unique: JsonValue }
The owner (a Group or Account) determines access rights to the CoMap.
The CoMap will immediately be persisted and synced to connected peers.
const person = Person.create({
name: "Alice",
age: 42,
pet: cat,
}, { owner: friendGroup });
Profile.load<M, Depth>(id, as, depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>
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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.const person = await Person.load(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} }
);
Profile.subscribe<M, Depth>(id, as, depth, listener):
() => void
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
with a given ID, as a given account.Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
depth
specifies which (if any) fields that reference other CoValues to load as well before calling listener
for the first time.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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.Returns an unsubscribe function that you should call when you no longer need updates.
Also see the
useCoState
hook to reactively subscribe to a CoValue in a React component.const unsub = Person.subscribe(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} },
(person) => console.log(person)
);
.ensureLoaded<M, Depth>(depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>
CoMap
, ensure that the specified fields are loaded to the specified depth.Works like
CoMap.load()
, but you don't need to pass the ID or the account to load as again..subscribe<M, Depth>(depth, listener):
() => void
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
, subscribe to updates to the CoMap
and ensure that the specified fields are loaded to the specified depth.Works like
CoMap.subscribe()
, but you don't need to pass the ID or the account to load as again.Returns an unsubscribe function that you should call when you no longer need updates.
._edits:
{[Key in string]: IfCo<this[Key], CoMapEdit<this[Key]>>}
._owner:
Group | Account
.toJSON(_key, seenAbove):
any[]
_key: string,
seenAbove: ID<CoValue>[]
.[inspect]():
any[]
Profile.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawCoMap<{ undefined }, JsonObject | null>
._instanceID:
string
._type:
"CoMap"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
Profile.findUnique<M>(unique, ownerID, as):
ID<M>
M extends CoMap
this: CoValueClass<M>,
unique: JsonValue,
ownerID: ID<Group> | ID<Account>,
as: AnonymousJazzAgent | Group | Account
.name:
co<string>
.applyDiff<N>(newValues):
Profile
N extends Partial<CoMapInit<Profile>>
newValues: N
._loadedAs:
AnonymousJazzAgent | Account
class Account
.id:
ID<Account>
Account.load<A, Depth>(id, as, depth):
Promise<DeeplyLoaded<A, Depth> | undefined>
A extends Account
this: CoValueClass<A>,
id: ID<A>,
as: Account,
depth: Depth & DepthsIn<A>
Account.subscribe<A, Depth>(id, as, depth, listener):
() => void
A extends Account
this: CoValueClass<A>,
id: ID<A>,
as: Account,
depth: Depth & DepthsIn<A>,
listener: (value: DeeplyLoaded<A, Depth>) => void
.ensureLoaded<A, Depth>(depth):
Promise<DeeplyLoaded<A, Depth> | undefined>
A extends Account
this: A,
depth: Depth & DepthsIn<A>
.subscribe<A, Depth>(depth, listener):
() => void
A extends Account
this: A,
depth: Depth & DepthsIn<A>,
listener: (value: DeeplyLoaded<A, Depth>) => void
._owner:
Account
.toJSON():
any[] | object
.[inspect]():
any[] | object
Account.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawControlledAccount<AccountMeta> | RawAccount<AccountMeta>
._instanceID:
string
._type:
"Account"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
Account._schema:
any
Account.create<A>(options):
Promise<A>
A extends Account
this: CoValueClass<A> & Account,
options: { creationProps: { name: string }, crypto: CryptoProvider<any>, initialAgentSecret: TODO type templateLiteral, peersToLoadFrom: Peer[] }
Account.createAs<A>(as, options):
Promise<A>
A extends Account
this: CoValueClass<A> & Account,
as: Account,
options: { creationProps: { name: string } }
Account.fromNode<A>(node):
A
A extends Account
this: CoValueClass<A>,
node: LocalNode
.constructor:
NO TYPE
._schema:
{ profile: Schema, root: Schema }
._loadedAs:
AnonymousJazzAgent | Account
.profile:
Profile | null
.root:
CoMap | null
._refs:
{ profile: RefIfCoValue<this["profile"]> | undefined, root: RefIfCoValue<this["root"]> | undefined }
.isMe:
boolean
.sessionID:
TODO type templateLiteral | TODO type templateLiteral | undefined
.myRole():
"admin" | undefined
.acceptInvite<V>(valueID, inviteSecret, coValueClass):
Promise<(TODO type conditional) | undefined>
V extends CoValue
valueID: ID<V>,
inviteSecret: TODO type templateLiteral,
coValueClass: CoValueClass<V>
.migrate(creationProps):
Promise<void> | void
this: Account,
creationProps: { name: string }
isControlledAccount(account):
account is Account & { isMe: true, sessionID: TODO type templateLiteral | TODO type templateLiteral, _raw: RawControlledAccount<AccountMeta> }
account: Account
Schema definition
Encoders reflection
co reflection
type co
type co<T> = T & CoMarker | T
Abstract interfaces
interface CoValue
.id:
ID<CoValue>
._owner:
Group | Account
.toJSON(key, seenAbove):
any[] | string | object
key: string,
seenAbove: ID<CoValue>[]
.[inspect]():
any
._raw:
RawCoValue
._type:
string
Media
class ImageDefinition
ImageDefinition.Record<Value>(value):
RecordLikeCoMap
value: IfCo<Value, Value>
CoMap.Record(...)
and passing the value schema using co
. Keys are always string
.import { co, CoMap } from "jazz-tools";
class ColorToFruitMap extends CoMap.Record(
co.ref(Fruit)
) {}
// assume we have map: ColorToFruitMap
// and strawberry: Fruit
map["red"] = strawberry;
.id:
ID<ImageDefinition>
CoMap
._refs:
{[Key in string]: IfCo<this[Key], RefIfCoValue<this[Key]>>}
prop
is a co.ref(...)
, you can use coMaps._refs.prop
to accessthe
Ref
instead of the potentially loaded/null value.This allows you to always get the ID or load the value manually.
person._refs.pet.id; // => ID<Animal>
person._refs.pet.value;
// => Animal | null
const pet = await person._refs.pet.load();
ImageDefinition.create<M>(init, options):
M
M extends CoMap
this: CoValueClass<M>,
init: Simplify<CoMapInit<M>>,
options: { owner: Group | Account, unique: JsonValue }
The owner (a Group or Account) determines access rights to the CoMap.
The CoMap will immediately be persisted and synced to connected peers.
const person = Person.create({
name: "Alice",
age: 42,
pet: cat,
}, { owner: friendGroup });
ImageDefinition.load<M, Depth>(id, as, depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>
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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.const person = await Person.load(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} }
);
ImageDefinition.subscribe<M, Depth>(id, as, depth, listener):
() => void
M extends CoMap
this: CoValueClass<M>,
id: ID<M>,
as: Account,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
with a given ID, as a given account.Automatically also subscribes to updates to all referenced/nested CoValues as soon as they are accessed in the listener.
depth
specifies which (if any) fields that reference other CoValues to load as well before calling listener
for the first time.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
/CoStream
/Group
/Account
to see which depth structures are valid to nest.Returns an unsubscribe function that you should call when you no longer need updates.
Also see the
useCoState
hook to reactively subscribe to a CoValue in a React component.const unsub = Person.subscribe(
"co_zdsMhHtfG6VNKt7RqPUPvUtN2Ax",
me,
{ pet: {} },
(person) => console.log(person)
);
.ensureLoaded<M, Depth>(depth):
Promise<DeeplyLoaded<M, Depth> | undefined>
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>
CoMap
, ensure that the specified fields are loaded to the specified depth.Works like
CoMap.load()
, but you don't need to pass the ID or the account to load as again..subscribe<M, Depth>(depth, listener):
() => void
M extends CoMap
this: M,
depth: Depth & DepthsIn<M>,
listener: (value: DeeplyLoaded<M, Depth>) => void
CoMap
, subscribe to updates to the CoMap
and ensure that the specified fields are loaded to the specified depth.Works like
CoMap.subscribe()
, but you don't need to pass the ID or the account to load as again.Returns an unsubscribe function that you should call when you no longer need updates.
._edits:
{[Key in string]: IfCo<this[Key], CoMapEdit<this[Key]>>}
._owner:
Group | Account
.toJSON(_key, seenAbove):
any[]
_key: string,
seenAbove: ID<CoValue>[]
.[inspect]():
any[]
ImageDefinition.fromRaw<V>(raw):
V
V extends CoValue
this: CoValueClass<V>,
raw: RawCoValue
._raw:
RawCoMap<{ undefined }, JsonObject | null>
._instanceID:
string
._type:
"CoMap"
.castAs<Cl>(cl):
InstanceType<Cl>
Cl extends CoValueClass<CoValue> & CoValueFromRaw<CoValue>
cl: Cl
ImageDefinition.findUnique<M>(unique, ownerID, as):
ID<M>
M extends CoMap
this: CoValueClass<M>,
unique: JsonValue,
ownerID: ID<Group> | ID<Account>,
as: AnonymousJazzAgent | Group | Account
.originalSize:
co<[number, number]>
.highestResAvailable(options):
{ res: TODO type templateLiteral, stream: BinaryCoStream } | undefined
options: { maxWidth: number }
[ItemsSym]:
co<BinaryCoStream | null>
.applyDiff<N>(newValues):
ImageDefinition
N extends Partial<CoMapInit<ImageDefinition>>
newValues: N
._loadedAs:
AnonymousJazzAgent | Account
.placeholderDataURL:
co<string>
Other
MAX_RECOMMENDED_TX_SIZE intrinsic
type InviteSecret
type InviteSecretundefined = TODO type templateLiteral
type SessionID
type SessionIDundefined = TODO type templateLiteral
type AgentID
type AgentIDundefined = TODO type templateLiteral
type SyncMessage
type SyncMessageundefined = DoneMessage | NewContentMessage | KnownStateMessage | LoadMessage
type CoValueUniqueness
type CoValueUniquenessundefined = { uniqueness: JsonValue, createdAt: null | TODO type templateLiteral }
type CoMapInit
type CoMapInit<Map extends object> = {[Key in CoKeys<Map>]: ForceRequiredRef<Map[Key]>} & {[Key in CoKeys<Map>]: ForceRequiredRef<Map[Key]>}
type AccountClass
type AccountClass<Acc extends Account> = CoValueClass<Acc> & { fromNode: Account["fromNode"] }
type DepthsIn
type DepthsIn<V, DepthLimit extends number, CurrentDepth extends number[]> = never[] | (TODO type conditional)
type DeeplyLoaded
type DeeplyLoaded<V, Depth, DepthLimit extends number, CurrentDepth extends number[]> = TODO type conditional
loadCoValue<V, Depth>(cls, id, as, depth):
Promise<DeeplyLoaded<V, Depth> | undefined>
cls: CoValueClass<V>,
id: ID<V>,
as: AnonymousJazzAgent | Account,
depth: Depth & DepthsIn<V>
subscribeToCoValue<V, Depth>(cls, id, as, depth, listener, onUnavailable):
() => void
cls: CoValueClass<V>,
id: ID<V>,
as: AnonymousJazzAgent | Account,
depth: Depth & DepthsIn<V>,
listener: (value: DeeplyLoaded<V, Depth>) => void,
onUnavailable: () => void
type AuthResult
type AuthResultundefined = { type: "new", creationProps: { name: string }, saveCredentials: (credentials: { accountID: ID<Account>, secret: AgentSecret }) => Promise<void>, onSuccess: () => void, onError: (error: Error | string) => void, logOut: () => void, initialSecret: AgentSecret } | { type: "existing", credentials: { accountID: ID<Account>, secret: AgentSecret }, onSuccess: () => void, onError: (error: Error | string) => void, logOut: () => void }
createJazzContext<Acc>(__namedParameters):
Promise<JazzContextWithAccount<Acc>>
ContextParamsWithAuth<Acc>
createJazzContext(__namedParameters):
Promise<JazzContextWithAgent>
BaseContextParams
createJazzContext<Acc>(options):
Promise<JazzContext<Acc>>
options: ContextParamsWithAuth<Acc> | BaseContextParams
fixedCredentialsAuth(credentials):
AuthMethod
credentials: { accountID: ID<Account>, secret: TODO type templateLiteral }
ephemeralCredentialsAuth():
AuthMethod
createAnonymousJazzContext({ peersToLoadFrom, crypto }):
Promise<JazzContextWithAgent>
{ peersToLoadFrom: Peer[], crypto: CryptoProvider<any> }
randomSessionProvider(accountID, crypto):
Promise<{ sessionID: TODO type templateLiteral | TODO type templateLiteral, sessionDone: () => void }>
accountID: ID<Account>,
crypto: CryptoProvider<any>