Sources provide access to data. They vary widely in their capabilities: some support interfaces for updating and/or querying records, while others simply broadcast changes.
Orbit includes a number of “standard” sources:
@orbit/store- an in-memory store
@orbit/jsonapi- a JSON API client
@orbit/indexeddb- for accessing IndexedDB databases
@orbit/local-storage- for accessing LocalStorage
Custom sources can also be written to access to virtually any source of data.
Every source derives from an abstract base class,
Source, which has a core
set of capabilities.
Sources must be instantiated with a schema. A schema provides sources with an understanding of the domain-specific data they manage.
Let’s create a simple schema and store:
All sources can be mutated, although not all sources support requests to mutate. Some sources may only reflect mutations that come from elsewhere, such as a source that wraps server-sent events.
Because all mutations in Orbit are trackable, sources maintain a log of changes, or “transforms”. This log represents an ordered history of transforms that have been applied to a source. The size of this log can be kept in check by truncating it after related sources have been synchronized.
Sources are also all “evented”, meaning that they can emit events which
listeners can subscribe to. All sources support an event,
transform, that is
emitted when that source changes. Most sources emit additional events as well
(the specifics depend upon their capabilities).
Let’s look at an example of a simple mutation triggered by a call to
The following should be logged as a result:
Want to learn more about updating data? See the guide
Orbit includes a number of standard interfaces that may be implemented by sources:
Updatable- Allows sources to be updated via an
updatemethod that takes a transform and returns the updated records that result.
Queryable- Allows sources to be queried via a
querymethod that receives a query expression and returns a recordset as a result.
Pushable- Allows sources to be updated via a
pushmethod that takes a a transform and returns the results of the change and its side effects as an array of transforms.
Pullable- Allows sources to be queried via a
pullmethod that takes a query expression and returns the results as an array of transforms.
Syncable- Applies a transform or transforms to a source via a
All of the interfaces above emit events that share a common pattern. For an
interface with a given method
x, the following events will be emitted:
xFail. For example, updatable sources have an
method and can emit
In addition, any mutations caused by calling
x will also be emitted with the
Processing occurs as follows (feel free to substitute
xis called on a source.
beforeXevent is emitted by the source. Any promises that are returned from listeners will be settled serially. Any errors encountered will prevent further processing and cause the source to emit the
xis processed internally by the source. Any errors encountered will prevent further processing and cause the source to emit the
transformevent is emitted if
xresulted in any mutations. Any promises that are returned from listeners will be settled serially. Errors will NOT prevent further processing.
xevent is emitted. Any promises that are returned from listeners will be settled serially. Errors will NOT prevent further processing.
There’s a clear turning point after
x has been processed internally by the
source. While listeners can block processing of
x in the
beforeX event by
returning a promise that fails, after
x has been processed such failures will
be ignored by the emitter.
Pullable interfaces all
participate in the “request flow”, in which requests are made upstream and data
flows back down.
Syncable interface participates in the “sync flow”, in which data flowing
downstream is synchronized with other sources.
Want to learn more about data flows? See the guide
Generally speaking, only the
Queryable interfaces are designed
to be used directly by developers in most applications. The other interfaces are
used to coordinate data requests and synchronization between sources.