Provides a high-level interface to access data below a given root path.
A BaseClient deals with three types of data: folders, objects and files.
getListing returns a mapping of all items within a folder. Items that end with a forward slash (“/”) are child folders. For instance: { ‘folder/’: true, ‘document.txt’: true }
getObject / storeObject operate on JSON objects. Each object has a type.
getFile / storeFile operates on files. Each file has a MIME type.
remove operates on either objects or files (but not folders, folders are created and removed implictly).
RemoteStorage. | Provides a high-level interface to access data below a given root path. |
Properties | |
storage | The RemoteStorage instance this BaseClient operates on. |
base | Base path this BaseClient operates on. |
schemas | Contains schema objects of all types known to the BaseClient instance |
Events | |
change | Emitted when a node changes |
Functions | |
scope | Returns a new BaseClient operating on a subpath of the current base path. |
getListing | Get a list of child nodes below a given path. |
getAll | Get all objects directly below a given path. |
getFile | Get the file at the given path. |
storeFile | Store raw data at a given path. |
getObject | Get a JSON object from given path. |
storeObject | Store object at given path. |
remove | Remove node at given path from storage. |
getItemURL | Retrieve full URL of item |
RS#scope | Returns a new <RS.BaseClient> scoped to the given path. |
declareType | Declare a remoteStorage object type using a JSON schema. |
The RemoteStorage instance this BaseClient operates on.
Base path this BaseClient operates on.
For the module’s privateClient this would be /<moduleName>/, for the corresponding publicClient /public/<moduleName>/.
Emitted when a node changes
event | Event object containing information about the changed node |
{ path: path, // Absolute path of the changed node, from the storage root relativePath: relativePath, // Path of the changed node, relative to this baseclient's scope root origin: 'window', 'local', 'remote', or 'conflict' // emitted by user action within the app, local data store, remote sync, or versioning conflicts oldValue: oldBody, // Old body of the changed node (local version in conflicts; undefined if creation) newValue: newBody, // New body of the changed node (remote version in conflicts; undefined if deletion) lastCommonValue: lastCommonValue, //most recent known common ancestor body of 'yours' and 'theirs' in case of conflict oldContentType: oldContentType, // Old contentType of the changed node ('yours' for conflicts; undefined if creation) newContentType: newContentType, // New contentType of the changed node ('theirs' for conflicts; undefined if deletion) lastCommonContentType: lastCommonContentType // Most recent known common ancestor contentType of 'yours' and 'theirs' in case of conflict }
{ path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'local', oldValue: undefined, newValue: 'white', oldContentType: undefined, newContentType: 'text/plain' }
Say you changed ‘color.txt’ from ‘white’ to ‘blue’; if you have set `RemoteStorage.config.changeEvents.window` to `true`, then you will receive:
{ path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'window', oldValue: 'white', newValue: 'blue', oldContentType: 'text/plain', newContentType: 'text/plain' }
But when this change is pushed out by asynchronous synchronization, this change may rejected by the server, if the remote version has in the meantime changed from ‘white’ to for instance ‘red’; this will then lead to a change event with origin ‘conflict’ (usually a few seconds after the event with origin ‘window’, if you had that activated). Note that since you already changed it from ‘white’ to ‘blue’ in the local version a few seconds ago, `oldValue` is now your local value of ‘blue’:
{ path: '/public/design/color.txt', relativePath: 'color.txt', origin: 'conflict', oldValue: 'blue', newValue: 'red', lastCommonValue: 'white', oldContentType: 'text/plain, newContentType: 'text/plain' lastCommonContentType: 'text/plain' }
In practice, you should always redraw your views to display the content of the `newValue` field when a change event is received, regardless of its origin. Events with origin ‘local’ are fired conveniently during the page load, so that you can fill your views when the page loads. Events with origin ‘window’ are fired whenever you change a value by calling a method on the baseClient; these are disabled by default. Events with origin ‘remote’ are fired when remote changes are discovered during sync (only for caching startegies ‘SEEN’ and ‘ALL’). Events with origin ‘conflict’ are fired when a conflict occurs while pushing out your local changes to the remote store in asynchronous synchronization (see example above).
scope: function( path )
Returns a new BaseClient operating on a subpath of the current base path.
getListing: function( path, maxAge )
Get a list of child nodes below a given path.
The callback semantics of getListing are identical to those of getObject.
path | The path to query. It MUST end with a forward slash. |
maxAge | Either false or the maximum age of cached listing in milliseconds. Defaults to false in anonymous mode and to 2*syncInterval in connected mode. |
A promise for an object, representing child nodes. If the maxAge requirement cannot be met because of network problems, this promise will be rejected. If the maxAge requirement is set to false, the promise will always be fulfilled with data from the local store.
Keys ending in a forward slash represent folder nodes, while all other keys represent data nodes.
For spec versions <= 01, the data node information will contain only the item’s ETag. For later spec versions, it will also contain the content type and -length of the item.
client.getListing('', false).then(function(listing) { // listing is for instance: // { // 'folder/': true, // 'document.txt': true // } });
getAll: function( path, maxAge )
Get all objects directly below a given path.
path | Path to the folder. |
maxAge | Either false or the maximum age of cached objects in milliseconds. Defaults to false in anonymous mode and to 2*syncInterval in connected mode. |
A promise for an object in the form { path : object, ... }. If the maxAge requirement cannot be met because of network problems, this promise will be rejected. If the maxAge requirement is set to false, the promise will always be fulfilled with data from the local store.
For items that are not JSON-stringified objects (e.g. stored using `storeFile` instead of `storeObject`), the object’s value is filled in with `true`.
client.getAll('', false).then(function(objects) { for (var key in objects) { console.log('- ' + key + ': ', objects[key]); } });
getFile: function( path, maxAge )
Get the file at the given path. A file is raw data, as opposed to a JSON object (use getObject for that).
Except for the return value structure, getFile works exactly like getObject.
path | See getObject. |
maxAge | Either false or the maximum age of cached file in milliseconds. Defaults to false in anonymous mode and to 2*syncInterval in connected mode. |
A promise for an object:
mimeType | String representing the MIME Type of the document. |
data | Raw data of the document (either a string or an ArrayBuffer) |
If the maxAge requirement cannot be met because of network problems, this promise will be rejected. If the maxAge requirement is set to false, the promise will always be fulfilled with data from the local store.
// Display an image: client.getFile('path/to/some/image', false).then(function(file) { var blob = new Blob([file.data], { type: file.mimeType }); var targetElement = document.findElementById('my-image-element'); targetElement.src = window.URL.createObjectURL(blob); });
storeFile: function( mimeType, path, body )
Store raw data at a given path.
mimeType | MIME media type of the data being stored |
path | path relative to the module root. MAY NOT end in a forward slash. |
data | string, ArrayBuffer or ArrayBufferView of raw data to store |
The given mimeType will later be returned, when retrieving the data using getFile.
client.storeFile('text/html', 'index.html', '<h1>Hello World!</h1>');
// MARKUP: <input type="file" id="file-input"> // CODE: var input = document.getElementById('file-input'); var file = input.files[0]; var fileReader = new FileReader(); fileReader.onload = function() { client.storeFile(file.type, file.name, fileReader.result); }; fileReader.readAsArrayBuffer(file);
getObject: function( path, maxAge )
Get a JSON object from given path.
path | Relative path from the module root (without leading slash). |
maxAge | Either false or the maximum age of cached object in milliseconds. Defaults to false in anonymous mode and to 2*syncInterval in connected mode. |
A promise for the object. If the maxAge requirement cannot be met because of network problems, this promise will be rejected. If the maxAge requirement is set to false, the promise will always be fulfilled with data from the local store.
client.getObject('/path/to/object', false). then(function(object) { // object is either an object or null });
storeObject: function( typeAlias, path, object )
Store object at given path. Triggers synchronization.
type | unique type of this object within this module. See description below. |
path | path relative to the module root. |
object | an object to be saved to the given node. It must be serializable as JSON. |
A promise to store the object. The promise fails with a ValidationError, when validations fail.
A great thing about having data on the web, is to be able to link to it and rearrange it to fit the current circumstances. To facilitate that, eventually you need to know how the data at hand is structured. For documents on the web, this is usually done via a MIME type. The MIME type of JSON objects however, is always application/json. To add that extra layer of “knowing what this object is”, remoteStorage aims to use JSON-LD. A first step in that direction, is to add a @context attribute to all JSON data put into remoteStorage. Now that is what the type is for.
http://remotestorage.io/spec/modules/ | A prefix to guarantee uniqueness |
the module name | module names should be unique as well |
the type given here | naming this particular kind of object within this module |
In retrospect that means, that whenever you introduce a new “type” in calls to storeObject, you should make sure that once your code is in the wild, future versions of the code are compatible with the same JSON structure.
See declareType for examples.
Returns a new <RS.BaseClient> scoped to the given path.
path | Root path of new BaseClient. |
var foo = remoteStorage.scope('/foo/'); // PUTs data "baz" to path /foo/bar foo.storeFile('text/plain', 'bar', 'baz'); var something = foo.scope('something/'); // GETs listing from path /foo/something/bla/ something.getListing('bla/');
Declare a remoteStorage object type using a JSON schema. See RemoteStorage.BaseClient.Types
Returns a new BaseClient operating on a subpath of the current base path.
scope: function( path )
Get a list of child nodes below a given path.
getListing: function( path, maxAge )
Get all objects directly below a given path.
getAll: function( path, maxAge )
Get the file at the given path.
getFile: function( path, maxAge )
Store raw data at a given path.
storeFile: function( mimeType, path, body )
Get a JSON object from given path.
getObject: function( path, maxAge )
Store object at given path.
storeObject: function( typeAlias, path, object )
Remove node at given path from storage.
remove: function( path )
Retrieve full URL of item
getItemURL: function( path )