Confirmed users
1,340
edits
No edit summary |
No edit summary |
||
(22 intermediate revisions by 3 users not shown) | |||
Line 63: | Line 63: | ||
== Interface == | == Interface == | ||
typedef (DOMString or unsigned long) DataStoreKey; | |||
interface DataStore : EventTarget { | interface DataStore : EventTarget { | ||
// Returns the label of the DataSource. | // Returns the label of the DataSource. | ||
readonly attribute DOMString name; | readonly attribute DOMString name; | ||
// Returns the origin of the DataSource (e.g., 'facebook.com'). | // Returns the origin of the DataSource (e.g., 'facebook.com'). | ||
// This value is the manifest URL of the owner app. | // This value is the manifest URL of the owner app. | ||
Line 73: | Line 75: | ||
// is readOnly a F(current_app, datastore) function? yes | // is readOnly a F(current_app, datastore) function? yes | ||
readonly attribute boolean readOnly; | readonly attribute boolean readOnly; | ||
Promise< | // Promise<any> | ||
Promise<void> | Promise get(DataStoreKey... id); | ||
Promise< | |||
Promise<boolean> remove( | // Promise<void> | ||
Promise<void> | Promise put(any obj, DataStoreKey id, optional DOMString revisionId = ""); | ||
// Promise<DataStoreKey> | |||
Promise add(any obj, optional DataStoreKey id, optional DOMString revisionId = ""); | |||
// Promise<boolean> | |||
Promise remove(DataStoreKey id, optional DOMString revisionId = ""); | |||
// Promise<void> | |||
Promise clear(optional DOMString revisionId = ""); | |||
readonly attribute DOMString revisionId; | readonly attribute DOMString revisionId; | ||
attribute EventHandler onchange; | attribute EventHandler onchange; | ||
// | // Promise<unsigned long> | ||
Promise getLength(); | |||
DataStoreCursor sync(optional DOMString revisionId = ""); | |||
}; | }; | ||
interface | interface DataStoreCursor { | ||
// the DataStore | |||
readonly attribute DataStore store; | |||
// Promise<DataStoreTask> | |||
Promise next(); | |||
void close(); | |||
}; | |||
enum DataStoreOperation { | |||
"add", | |||
"update", | |||
"remove", | |||
"clear", | |||
"done" | |||
}; | |||
dictionary DataStoreTask { | |||
DOMString revisionId; | |||
DataStoreOperation operation; | |||
DataStoreKey id; | |||
any data; | |||
}; | |||
dictionary DataStoreChangeEventInit : EventInit { | |||
DOMString revisionId = ""; | |||
DataStoreKey id = 0; | |||
DOMString operation = ""; | |||
DOMStirng owner = ""; | |||
}; | |||
[Constructor(DOMString type, optional DataStoreChangeEventInit eventInitDict)] | |||
interface DataStoreChangeEvent : Event { | |||
readonly attribute DOMString revisionId; | readonly attribute DOMString revisionId; | ||
readonly attribute | readonly attribute DataStoreKey id; | ||
readonly attribute | readonly attribute DOMString operation; | ||
readonly attribute | readonly attribute DOMString owner; | ||
}; | }; | ||
Line 106: | Line 150: | ||
datastores-owned: { | datastores-owned: { | ||
"contacts": { | "contacts": { | ||
"readonly" | "access": "readonly", | ||
"description": | "description": ... | ||
} | } | ||
}, | }, | ||
Line 118: | Line 162: | ||
datastores-access: { | datastores-access: { | ||
"contacts": { | "contacts": { | ||
" | "readonly": true, | ||
"description": | "description": "Facebook contacts", | ||
} | } | ||
}, | }, | ||
Line 127: | Line 171: | ||
== Revisions and changes == | == Revisions and changes == | ||
The revisionId is a UUID and it can be used to retrieve the delta between a particular revisionId and the current one | The revisionId is a UUID and it can be used to retrieve the delta between a particular revisionId and the current one using |sync()| | ||
== Examples == | == Examples == | ||
Line 147: | Line 191: | ||
// Update an object | // Update an object | ||
obj.nick = 'baku'; | obj.nick = 'baku'; | ||
stores[0]. | stores[0].put(obj, 42).then(function(id) { | ||
// id == 42 | // id == 42 | ||
// ... | // ... | ||
Line 163: | Line 207: | ||
} | } | ||
}); | }); | ||
// Storing a new object | // Storing a new object | ||
stores[0].add({ "nick": "baku", "email" : "a@b.c" }).then(function(id) { | stores[0].add({ "nick": "baku", "email" : "a@b.c" }).then(function(id) { | ||
Line 170: | Line 214: | ||
}); | }); | ||
=== | === Sync === | ||
The synchronization of a DataStore with a 'private' app storage can be done using the 'sync' method. Calling this method, DataStore creates a DataStoreCursor that helps the app with the synchronization starting from scratch or for a valid revisionId. The sync operation can be terminated calling cursor.close(). If something changes in the DataStore when the cursor is synchronize the app, all the changes will be managed by the cursor as additional operation: this means that when the cursor completes its tasks, the app will be always in sync with the current revisionId of the DataStore. | |||
The basic usage of the cursor is this: | |||
// | navigator.getDataStores('contacts').then(functions(stores) { | ||
if (!stores.length) return; | |||
let cursor = stores[0].sync(/* a revisionId can be used here. If it's invalid it'll be ignored */); | |||
function cursorResolve(task) { | |||
// task.operation describes what the app has to do in order to be in sync with the current revision of this datastore. | |||
switch (task.operation) { | |||
case 'done': | |||
// No additional operation has to be done. | |||
dump("The current revision ID is: " + task.revisionId + "\n"); | |||
return; | |||
case 'clear': | |||
// All the data you have are out-of-sync. Delete all of them. | |||
break; | |||
case 'add': | |||
// A new object has to be inserted | |||
dump("Adding id: " + task.id + " data: " + task.data + "\n"); | |||
break; | |||
case 'update': | |||
// Something has to be updated | |||
dump("Updating id: " + task.id + " data: " + task.data + "\n"); | |||
break; | |||
case 'remove': | |||
dump("Record: " + task.id + " must be removed\n"); | |||
break; | |||
} | |||
cursor.next().then(cursorResolve); | |||
} | |||
// Cursor.next() always returns a promise. | |||
cursor.next().then(cursorResolve); | |||
}); | }); | ||
Line 186: | Line 262: | ||
* {name, owner, value} is a complicated key. | * {name, owner, value} is a complicated key. | ||
* UI: what to do when we have multiple access requests? | * UI: what to do when we have multiple access requests? | ||
* Should all data stores with the same name share a schema? | * Should all data stores with the same name share a schema? | ||
* Enforcing types can be a footgun. What should a data provider do if it decides some key should have a different type? | * Enforcing types can be a footgun. What should a data provider do if it decides some key should have a different type? | ||
[[Category:Web APIs]] |