Skip to content

Ref

import { Ref } from '@dxos/echo';

A reference is a field that points at another entity. It stores the target’s DXN, not a copy, and resolves the target only when you ask. org.dxos.echo#F-4.1 References and DXNs explains the model; this page is the API.

Ref.Ref(Type) is the schema of a field that points at that type. Use it inside Schema.optional or Schema.Array like any other field schema. The tutorial’s Person and Event declare both:

src/schema.ts
import * as
import Schema
Schema
from 'effect/Schema';
import {
import Annotation
Annotation
,
import DXN
DXN
,
import Format
Format
,
import Ref
Ref
,
import Type
Type
} from '@dxos/echo';
15 collapsed lines
export class
class Organization
Organization
extends
import Type
Type
.
const makeObject: <Organization>(dxn: DXN.DXN, options?: {
id?: EntityId;
}) => Type.MakeObject<Organization>

Factory function to create an ECHO object type.

Returns a Type.Type entity — a live, in-memory TypeSchema instance, NOT a Schema.Schema. Use Type.InstanceType<typeof Foo> for the instance type and Type.getSchema(Foo) to obtain the underlying Effect Schema.

The entity's id defaults to EntityId.deterministic(typename, version) so constructing a type never reaches crypto.getRandomValues() — required for Cloudflare workerd, which forbids RNG calls in global (module-evaluation) scope. Pass { id } to override (e.g. with EntityId.random() from a request handler).

Giving the type a nominal class name keeps its inferred type portable for declaration emit: structural expansion (which can pull in unnameable union members from referenced schemas) is replaced by a reference to the class.

The second call takes either a schema, or struct fields (wrapped in Schema.Struct) with an optional function that pipes annotations onto the struct.

@example

export class Person extends Type.makeObject<Person>(DXN.make('com.example.type.myType', '0.1.0'))(Schema.Struct({
name: Schema.String,
})) {}
export class Tag extends Type.makeObject<Tag>(DXN.make('com.example.type.tag', '0.1.0'))(
{ label: Schema.String },
Annotation.LabelAnnotation.set(['label']),
) {}

@performance ― O(schema size) once at definition time; builds the type entity eagerly, so call it at module scope, not per use.

makeObject
<
class Organization
Organization
>(
import DXN
DXN
.
const make: <"com.example.type.organization">(nsid: "com.example.type.organization", version?: string) => DXN.DXN

Constructs a DXN from an NSID (and optional version). Throws if the result is not a valid DXN. Use tryMake for non-throwing string parsing.

Static NSID strings are validated at compile time via

Name

: the final segment must be camelCase (no hyphens). Template-literal strings with a runtime prefix are accepted here but still validated at runtime.

@example make('org.dxos.type.calendar') → 'dxn:org.dxos.type.calendar'

@example make('org.dxos.type.calendar', '1.0.0') → 'dxn:org.dxos.type.calendar:1.0.0'

make
('com.example.type.organization', '0.1.0'),
)(
import Schema
Schema
.
function Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>(fields: {
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}): Schema.Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>

Defines a struct schema from a map of field schemas.

Details

Each field value is a schema. Use

optionalKey

or

optional

to mark fields as optional, and

mutableKey

to mark them as mutable.

The resulting schema's Type is a readonly object type with the fields' decoded types. The Encoded form mirrors the field schemas' encoded types. Declared fields may be inherited and are copied to own properties in the output. The __proto__ field is accepted only when it is an own property. Parsing does not guarantee that output keys retain their input order.

Example (Defining a basic struct)

import { Schema } from "effect"
const Person = Schema.Struct({
name: Schema.String,
age: Schema.Number,
email: Schema.optionalKey(Schema.String)
})
// { readonly name: string; readonly age: number; readonly email?: string }
type Person = typeof Person.Type
Schema.decodeUnknownSync(Person)({ name: "Alice", age: 30 }) // => { name: "Alice", age: 30 }

@stability ― stable

@category ― constructors

@since ― 3.10.0

Struct
({
name: Schema.String
name
:
import Schema
Schema
.
const String: Schema.String

Type-level representation of

String

.

Schema for string values. Validates that the input is typeof "string".

@stability ― stable

@category ― models

@since ― 4.0.0

@stability ― stable

@category ― schemas

@since ― 4.0.0

String
,
website: Schema.optional<Schema.String>
website
:
import Schema
Schema
.
const optional: optionalLambda
<Schema.String>(self: Schema.String) => Schema.optional<Schema.String>

Type-level representation returned by

optional

.

Marks a struct field as optional, allowing the key to be absent or undefined.

Details

The resulting property may be absent or explicitly set to undefined. Equivalent to optionalKey(UndefinedOr(S)).

Use

optionalKey

instead if you want exact optional semantics (absent only, not undefined).

Example (Defining an optional field accepting undefined)

import { Schema } from "effect"
const schema = Schema.Struct({
name: Schema.String,
age: Schema.optional(Schema.Number)
})
// { readonly name: string; readonly age?: number | undefined }
type Person = typeof schema.Type

@stability ― stable

@category ― models

@since ― 3.10.0

@stability ― stable

@category ― combinators

@since ― 3.10.0

optional
(
import Format
Format
.URL),
}).
Pipeable.pipe<Schema.Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>, Schema.Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>) => Schema.Struct<{
readonly name: Schema.String;
readonly website: Schema.optional<Schema.String>;
}>): Schema.Struct<...> (+21 overloads)
pipe
(
import Annotation
Annotation
.
const IconAnnotation: Annotation.Annotation<Annotation.IconAnnotation>
export IconAnnotation

Icon to render in the UI.

IconAnnotation
.
Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <S extends Schema.Top>(schema: S) => S

Set the annotation on an Effect schema.

Only accepts Schema.Top — annotations must be applied to the source schema BEFORE wrapping it with Type.makeObject / Type.makeRelation. In a pipe, place every Annotation.X.set(...) before the Type.make... step.

@performance ― O(value size) encode, once at schema-definition time.

set
({
icon: string

Sprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').

ph--* is Phosphor; px--* and dx--* are brand glyphs, which are sprite-only and carry no weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic session, a GitHub repo — has no honest Phosphor equivalent.

icon
: 'ph--buildings--regular',
hue?: string | undefined

Color name.

List of colors:

  • 'red'
  • 'orange'
  • 'amber'
  • 'yellow'
  • 'lime'
  • 'green'
  • 'emerald'
  • 'teal'
  • 'cyan'
  • 'violet'
  • 'purple'
  • 'fuchsia'
  • 'pink'
  • 'rose'

hue
: 'amber',
}),
),
) {}
export class
class Person
Person
extends
import Type
Type
.
const makeObject: <Person>(dxn: DXN.DXN, options?: {
id?: EntityId;
}) => Type.MakeObject<Person>

Factory function to create an ECHO object type.

Returns a Type.Type entity — a live, in-memory TypeSchema instance, NOT a Schema.Schema. Use Type.InstanceType<typeof Foo> for the instance type and Type.getSchema(Foo) to obtain the underlying Effect Schema.

The entity's id defaults to EntityId.deterministic(typename, version) so constructing a type never reaches crypto.getRandomValues() — required for Cloudflare workerd, which forbids RNG calls in global (module-evaluation) scope. Pass { id } to override (e.g. with EntityId.random() from a request handler).

Giving the type a nominal class name keeps its inferred type portable for declaration emit: structural expansion (which can pull in unnameable union members from referenced schemas) is replaced by a reference to the class.

The second call takes either a schema, or struct fields (wrapped in Schema.Struct) with an optional function that pipes annotations onto the struct.

@example

export class Person extends Type.makeObject<Person>(DXN.make('com.example.type.myType', '0.1.0'))(Schema.Struct({
name: Schema.String,
})) {}
export class Tag extends Type.makeObject<Tag>(DXN.make('com.example.type.tag', '0.1.0'))(
{ label: Schema.String },
Annotation.LabelAnnotation.set(['label']),
) {}

@performance ― O(schema size) once at definition time; builds the type entity eagerly, so call it at module scope, not per use.

makeObject
<
class Person
Person
>(
import DXN
DXN
.
const make: <"com.example.type.person">(nsid: "com.example.type.person", version?: string) => DXN.DXN

Constructs a DXN from an NSID (and optional version). Throws if the result is not a valid DXN. Use tryMake for non-throwing string parsing.

Static NSID strings are validated at compile time via

Name

: the final segment must be camelCase (no hyphens). Template-literal strings with a runtime prefix are accepted here but still validated at runtime.

@example make('org.dxos.type.calendar') → 'dxn:org.dxos.type.calendar'

@example make('org.dxos.type.calendar', '1.0.0') → 'dxn:org.dxos.type.calendar:1.0.0'

make
('com.example.type.person', '0.1.0'),
)(
import Schema
Schema
.
function Struct<{
readonly name: Schema.String;
readonly email: Schema.optional<Schema.String>;
readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;
}>(fields: {
readonly name: Schema.String;
readonly email: Schema.optional<Schema.String>;
readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;
}): Schema.Struct<...>

Defines a struct schema from a map of field schemas.

Details

Each field value is a schema. Use

optionalKey

or

optional

to mark fields as optional, and

mutableKey

to mark them as mutable.

The resulting schema's Type is a readonly object type with the fields' decoded types. The Encoded form mirrors the field schemas' encoded types. Declared fields may be inherited and are copied to own properties in the output. The __proto__ field is accepted only when it is an own property. Parsing does not guarantee that output keys retain their input order.

Example (Defining a basic struct)

import { Schema } from "effect"
const Person = Schema.Struct({
name: Schema.String,
age: Schema.Number,
email: Schema.optionalKey(Schema.String)
})
// { readonly name: string; readonly age: number; readonly email?: string }
type Person = typeof Person.Type
Schema.decodeUnknownSync(Person)({ name: "Alice", age: 30 }) // => { name: "Alice", age: 30 }

@stability ― stable

@category ― constructors

@since ― 3.10.0

Struct
({
name: Schema.String
name
:
import Schema
Schema
.
const String: Schema.String

Type-level representation of

String

.

Schema for string values. Validates that the input is typeof "string".

@stability ― stable

@category ― models

@since ― 4.0.0

@stability ― stable

@category ― schemas

@since ― 4.0.0

String
,
email: Schema.optional<Schema.String>
email
:
import Schema
Schema
.
const optional: optionalLambda
<Schema.String>(self: Schema.String) => Schema.optional<Schema.String>

Type-level representation returned by

optional

.

Marks a struct field as optional, allowing the key to be absent or undefined.

Details

The resulting property may be absent or explicitly set to undefined. Equivalent to optionalKey(UndefinedOr(S)).

Use

optionalKey

instead if you want exact optional semantics (absent only, not undefined).

Example (Defining an optional field accepting undefined)

import { Schema } from "effect"
const schema = Schema.Struct({
name: Schema.String,
age: Schema.optional(Schema.Number)
})
// { readonly name: string; readonly age?: number | undefined }
type Person = typeof schema.Type

@stability ― stable

@category ― models

@since ― 3.10.0

@stability ― stable

@category ― combinators

@since ― 3.10.0

optional
(
import Format
Format
.
const Email: Schema.String

Email address (RFC 5321). The local part also allows an apostrophe, which real mail carries (o'day@corp.com). https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.2

Email
),
employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>
employer
:
import Schema
Schema
.
const optional: optionalLambda
<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>(self: Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>) => Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>

Type-level representation returned by

optional

.

Marks a struct field as optional, allowing the key to be absent or undefined.

Details

The resulting property may be absent or explicitly set to undefined. Equivalent to optionalKey(UndefinedOr(S)).

Use

optionalKey

instead if you want exact optional semantics (absent only, not undefined).

Example (Defining an optional field accepting undefined)

import { Schema } from "effect"
const schema = Schema.Struct({
name: Schema.String,
age: Schema.optional(Schema.Number)
})
// { readonly name: string; readonly age?: number | undefined }
type Person = typeof schema.Type

@stability ― stable

@category ― models

@since ― 3.10.0

@stability ― stable

@category ― combinators

@since ― 3.10.0

optional
(
import Ref
Ref
.
const Ref: <typeof Organization>(type: typeof Organization) => Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown> (+3 overloads)
Ref
(
class Organization
Organization
)),
}).
Pipeable.pipe<Schema.Struct<{
readonly name: Schema.String;
readonly email: Schema.optional<Schema.String>;
readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;
}>, Schema.Struct<{
readonly name: Schema.String;
readonly email: Schema.optional<Schema.String>;
readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;
}>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<...>) => Schema.Struct<...>): Schema.Struct<...> (+21 overloads)
pipe
(
import Annotation
Annotation
.
const IconAnnotation: Annotation.Annotation<Annotation.IconAnnotation>
export IconAnnotation

Icon to render in the UI.

IconAnnotation
.
Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <S extends Schema.Top>(schema: S) => S

Set the annotation on an Effect schema.

Only accepts Schema.Top — annotations must be applied to the source schema BEFORE wrapping it with Type.makeObject / Type.makeRelation. In a pipe, place every Annotation.X.set(...) before the Type.make... step.

@performance ― O(value size) encode, once at schema-definition time.

set
({
icon: string

Sprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').

ph--* is Phosphor; px--* and dx--* are brand glyphs, which are sprite-only and carry no weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic session, a GitHub repo — has no honest Phosphor equivalent.

icon
: 'ph--user--regular',
hue?: string | undefined

Color name.

List of colors:

  • 'red'
  • 'orange'
  • 'amber'
  • 'yellow'
  • 'lime'
  • 'green'
  • 'emerald'
  • 'teal'
  • 'cyan'
  • 'violet'
  • 'purple'
  • 'fuchsia'
  • 'pink'
  • 'rose'

hue
: 'cyan' }),
),
) {}

Ref.make takes an object you already hold. db.makeRef takes a URI and returns a reference bound to the database, so it can load its target. Ref.fromURI also takes a URI, but its reference has nothing to load from until a database binds it.

import {
import Obj
Obj
,
import Ref
Ref
} from '@dxos/echo';
import {
class Event
Event
,
class Organization
Organization
,
class Person
Person
} from './schema.ts';
const
const acme: BaseObj & Organization & OfKind<EntityKind.Object>
acme
=
const db: Database.Database
db
.
Database.add<BaseObj & Organization & OfKind<EntityKind.Object>>(obj: BaseObj & Organization & OfKind<EntityKind.Object>, opts?: Database.AddOptions): BaseObj & Organization & OfKind<EntityKind.Object>

Adds an object or relation to the database.

Only Object and Relation entities are accepted. To persist a Type definition use

addType

— passing a Type entity is rejected at compile time (and at runtime).

Pass { to: feed } to append to a feed instead (synchronous; confirm with

flush

).

@performance ― Synchronous; O(n) in object size to write it into a new linked document (or the root), persisted in the background.

add
(
import Obj
Obj
.
function make<typeof Organization>(type: typeof Organization, props: NoInfer<Obj.MakeProps<typeof Organization>>, options?: Obj.MakeOptions): Obj.OfShape<Organization & OfKind<EntityKind.Object>>

Creates a new echo object of the given schema or Type.Type.

@param ― typeOrSchema - A static object schema (Type.makeObject(...)) or a Type.Type entity (e.g. one returned by db.addType(schemaEntity)).

@param ― props - Object properties.

@param ―

options - See MakeOptions.

Meta can be passed as a symbol in props.

Example:

const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });

Note: Only accepts object schemas / object-kind types, not relation schemas. Use Relation.make for relations.

@performance ― O(n) in props size; validates props against the schema and allocates a reactive proxy, with no database I/O.

make
(
class Organization
Organization
, {
name: string
name
: 'Acme' }));
const
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
=
const db: Database.Database
db
.
Database.add<BaseObj & Person & OfKind<EntityKind.Object>>(obj: BaseObj & Person & OfKind<EntityKind.Object>, opts?: Database.AddOptions): BaseObj & Person & OfKind<EntityKind.Object>

Adds an object or relation to the database.

Only Object and Relation entities are accepted. To persist a Type definition use

addType

— passing a Type entity is rejected at compile time (and at runtime).

Pass { to: feed } to append to a feed instead (synchronous; confirm with

flush

).

@performance ― Synchronous; O(n) in object size to write it into a new linked document (or the root), persisted in the background.

add
(
import Obj
Obj
.
function make<typeof Person>(type: typeof Person, props: NoInfer<Obj.MakeProps<typeof Person>>, options?: Obj.MakeOptions): Obj.OfShape<Person & OfKind<EntityKind.Object>>

Creates a new echo object of the given schema or Type.Type.

@param ― typeOrSchema - A static object schema (Type.makeObject(...)) or a Type.Type entity (e.g. one returned by db.addType(schemaEntity)).

@param ― props - Object properties.

@param ―

options - See MakeOptions.

Meta can be passed as a symbol in props.

Example:

const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });

Note: Only accepts object schemas / object-kind types, not relation schemas. Use Relation.make for relations.

@performance ― O(n) in props size; validates props against the schema and allocates a reactive proxy, with no database I/O.

make
(
class Person
Person
, {
name: string
name
: 'Ada',
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefined
employer
:
import Ref
Ref
.
const make: <BaseObj & Organization & OfKind<EntityKind.Object>>(object: BaseObj & Organization & OfKind<EntityKind.Object>) => Ref<BaseObj & Organization & OfKind<EntityKind.Object>>

Create a reference to an entity.

@performance ― O(1); allocates a ref that inlines the target, with no lookup.

make
(
const acme: BaseObj & Organization & OfKind<EntityKind.Object>
acme
) }));
const
const launch: BaseObj & Event & OfKind<EntityKind.Object>
launch
=
const db: Database.Database
db
.
Database.add<BaseObj & Event & OfKind<EntityKind.Object>>(obj: BaseObj & Event & OfKind<EntityKind.Object>, opts?: Database.AddOptions): BaseObj & Event & OfKind<EntityKind.Object>

Adds an object or relation to the database.

Only Object and Relation entities are accepted. To persist a Type definition use

addType

— passing a Type entity is rejected at compile time (and at runtime).

Pass { to: feed } to append to a feed instead (synchronous; confirm with

flush

).

@performance ― Synchronous; O(n) in object size to write it into a new linked document (or the root), persisted in the background.

add
(
import Obj
Obj
.
function make<typeof Event>(type: typeof Event, props: NoInfer<Obj.MakeProps<typeof Event>>, options?: Obj.MakeOptions): Obj.OfShape<Event & OfKind<EntityKind.Object>>

Creates a new echo object of the given schema or Type.Type.

@param ― typeOrSchema - A static object schema (Type.makeObject(...)) or a Type.Type entity (e.g. one returned by db.addType(schemaEntity)).

@param ― props - Object properties.

@param ―

options - See MakeOptions.

Meta can be passed as a symbol in props.

Example:

const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });

Note: Only accepts object schemas / object-kind types, not relation schemas. Use Relation.make for relations.

@performance ― O(n) in props size; validates props against the schema and allocates a reactive proxy, with no database I/O.

make
(
class Event
Event
, {
title: string
title
: 'Launch',
attendees?: readonly Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[] | undefined
attendees
: [
import Ref
Ref
.
const make: <BaseObj & Person & OfKind<EntityKind.Object>>(object: BaseObj & Person & OfKind<EntityKind.Object>) => Ref<BaseObj & Person & OfKind<EntityKind.Object>>

Create a reference to an entity.

@performance ― O(1); allocates a ref that inlines the target, with no lookup.

make
(
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
)] }),
);
// From a URI: bound to the database, so it can load.
const
const again: Ref<Person>
again
=
const db: Database.Database
db
.
Database.makeRef<Person>(uri: URI): Ref<Person>

Creates a reference to an existing object in the database.

NOTE: The reference may be dangling if the object is not present in the database. NOTE: Difference from Ref.fromURI Ref.fromURI(dxn) returns an unhydrated reference. The .load and .target APIs will not work. db.makeRef(dxn) is preferable in cases with access to the database.

@performance ― O(1); allocates a resolver-bound ref without looking the target up.

makeRef
<
class Person
Person
>(
import Obj
Obj
.
const getURI: (entity: Obj.Unknown | Obj.Snapshot, options?: Obj.GetURIOptions) => URI

Get the URI of the object. Accepts both reactive objects and snapshots.

@param ― options.prefer - Controls the URI form (see GetURIOptions ).

@performance ― O(1); returns the stored URI, constructing (and allocating) one only when options.prefer asks for another form.

getURI
(
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
));

peek returns the target if it is already in memory and never starts a load. load waits for the target, reading it from disk or the network, and throws if it cannot be found; tryLoad returns undefined instead. Ref.loadAll loads an array of references at once.

Avoid ref.target. It is deprecated because reading it starts a load as a side effect and can throw.

import {
import Ref
Ref
} from '@dxos/echo';
import {
class Organization
Organization
} from './schema.ts';
const
const loaded: (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefined
loaded
=
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefined
employer
?.
Ref<Organization & OfKind<EntityKind.Object> & Unknown>.peek(): (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefined

@returns ― The target when it is already materialized: the pinned target, or a side-effect-free working-set lookup. Never throws and never triggers loading — the synchronous counterpart of tryLoad . A just-added object can resolve here before it has settled into its own document; callers that need a settled document must load instead.

@performance ― O(1) working-set lookup; never loads and never throws.

peek
(); // Organization | undefined, never loads
// loads from disk or the network if needed
const
const employer: (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefined
employer
= await
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefined
employer
?.
Ref<Organization & OfKind<EntityKind.Object> & Unknown>.load(options?: LoadOptions): Promise<Organization & OfKind<EntityKind.Object> & Obj.Unknown>

@returns ― Promise that will resolves with the target object. Will load the object from disk if it is not present in the working set. Short-circuits immediately when the target is already loaded.

@throws ― If the object is not available locally.

@idiom ― org.dxos.echo.refLoad applies: Resolving a ref inside an async function or Effect handler — guarantees the object is available before proceeding instead-of: ref.target — not guaranteed to be defined in async contexts; use await ref.load() (or yield* Database.load(ref) in Effect) to ensure the target is present uses: load related: org.dxos.echo-react.useObjectReactive

@performance ― Async; resolves immediately for an inlined or loaded target, otherwise loads from disk or the network.

load
();
// undefined instead of throwing when the target is missing
const
const maybe: Person | undefined
maybe
= await
const again: Ref<Person>
again
.
Ref<Person>.tryLoad(options?: LoadOptions): Promise<Person | undefined>

@returns ― Promise that will resolves with the target object or undefined if the object is not loaded locally.

@performance ― Async; resolves immediately for an inlined or loaded target, otherwise loads from disk or the network.

tryLoad
();
// missing and deleted targets are left out
const
const attendees: (Person & OfKind<EntityKind.Object> & Obj.Unknown)[]
attendees
= await
import Ref
Ref
.
const loadAll: <Person & OfKind<EntityKind.Object> & Obj.Unknown>(refs: readonly Ref.Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[], options?: Ref.LoadOptions) => Promise<(Person & OfKind<EntityKind.Object> & Obj.Unknown)[]>

Loads the targets of refs in ref order, omitting missing targets and, unless { deleted: 'include' } asks for them, deleted ones.

@performance ― Async; issues every tryLoad concurrently, O(n) in refs.

loadAll
(
const launch: BaseObj & Event & OfKind<EntityKind.Object>
launch
.
attendees?: readonly Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[] | undefined
attendees
?? []);

Each read of a reference field returns a new wrapper, so === never matches. Compare with Ref.equals, or test the target id with Ref.hasEntityId.

import {
import Ref
Ref
} from '@dxos/echo';
const
const same: boolean
same
=
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefined
employer
!==
var undefined
undefined
&&
import Ref
Ref
.
const equals: (a: Ref.Ref<any> | readonly Ref.Ref<any>[], b: Ref.Ref<any> | readonly Ref.Ref<any>[]) => boolean

Whether two refs, or two ref arrays element by element, point at the same target: the same URI and the same inlined target. Every read of a ref property mints a new wrapper, so identity never matches.

@performance ― O(n) in the array length; no allocation.

equals
(
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown>
employer
,
import Ref
Ref
.
const make: <BaseObj & Organization & OfKind<EntityKind.Object>>(object: BaseObj & Organization & OfKind<EntityKind.Object>) => Ref<BaseObj & Organization & OfKind<EntityKind.Object>>

Create a reference to an entity.

@performance ― O(1); allocates a ref that inlines the target, with no lookup.

make
(
const acme: BaseObj & Organization & OfKind<EntityKind.Object>
acme
));
const
const attending: boolean
attending
= (
const launch: BaseObj & Event & OfKind<EntityKind.Object>
launch
.
attendees?: readonly Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[] | undefined
attendees
?? []).
ReadonlyArray<Ref<Person & OfKind<EntityKind.Object> & Unknown>>.some(predicate: (value: Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>, index: number, array: readonly Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[]) => unknown, thisArg?: any): boolean

Determines whether the specified callback function returns true for any element of an array.

@param ― predicate A function that accepts up to three arguments. The some method calls the predicate function for each element in the array until the predicate returns a value which is coercible to the Boolean value true, or until the end of the array.

@param ― thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

some
(
import Ref
Ref
.
const hasEntityId: (id: import("@dxos/keys").EntityId) => (ref: Ref<any>) => boolean

Create a predicate that tests whether a ref points to the given entity id.

@performance ― O(1) per call of the returned predicate (parses the ref URI).

hasEntityId
(
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
id: string
id
));
import Ref
Ref
.
const isRef: (value: unknown) => value is Ref.Unknown

Type guard for refs.

@performance ― O(1) brand check; no allocation.

isRef
(
const ada: BaseObj & Person & OfKind<EntityKind.Object>
ada
.
employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefined
employer
); // true
Member Summary
Ref(Type) Schema of a reference field
Array(Type) Schema of an array of references
make A reference to an object you hold
fromURI An unbound reference from a URI
loadAll Load many targets, skipping missing and deleted ones
equals hasEntityId Compare references
isRef Predicate
ref.peek() ref.load() ref.tryLoad() Read the target in memory, or load it

The full list is in the API reference.