kinto.js
kinto.js copied to clipboard
What to do after received data from Websocket?
What should we do after received the changes from Websocket? Trigger collection.sync would be inefficient for me (data is already available in the websocket message)
//sample repsonse
{
channel: "94b660c6-68f3-83c4-97fa-8e8ac4715204-kinto_demo_calendar-record",
data: "the data that changes",
event: "update"
}
I think we could create/update/delete record manually. But how to best update the lastModified time is still mysterious.
Good question!
You are right, triggering a sync() is very inefficient. That's we did on the 'calendar' demo here because it was easy for demonstration purposes.
You must store the data locally instead.
If you have chosen to go with the SERVER_WINS approach, it is even simpler, you just stick the incoming data into the local database, like this:
channel.onChange((response) => {
if (response.event == "create") {
store.create(response.data, {synced: true})
}
});
The response.data should contain the last_modified attribute from the server, so — as far as I understand — you shouldn't worry about it.
If you want to detect conflicts, you'll have to go with code like:
channel.onChange((response) => {
if (response.event == "update") {
store.get(response.data.id)
.then(function (existing) {
if (existing.data._status != 'synced')
// This was changed locally and not yet synced.
// compare `existing` and `response.data`
// or just ignore change (ie. CLIENT_WINS)
}
});
}
});
Tell us what you find out along the way! It would be nice to add info about that in the documentation!
Thanks @leplatrem for the detailed response. I'll try to do what you suggested.
However, I think it would be perfect if the kintojs client can just provide a simple API to work with for eg.
collection.syncIncomming(dataFromWebsocket, strategy)
which will return a SyncResultObject just like sync()
Good idea!
In your example dataFromWebsocket is what comes from kinto-pusher I guess.
What about something more generic like applyChange(action, data, strategy) ? (disclaimer: I'm not good at naming things)
If you have a draft of some working don't hesitate to share it as a start ;)
Hey @leplatrem, I detected that you guys have a very similar function in collection.js already: https://github.com/Kinto/kinto.js/blob/master/src/collection.js#L621 ;) Maybe we could make a public API for that?
Btw, I'm writing an Ember Data adapter to work with Kinto api: https://github.com/ptgamr/ember-kinto . There is a live demo at: https://ember-kinto-demo.herokuapp.com/
Here is the changes based on what you suggested above: https://github.com/ptgamr/ember-kinto/commit/354c9f59a3b918768013af051763987405f4a39c#diff-1551788d4134d14f484faa251ebee47eR103
Until now I saw that the concept of kinto fits quite nicely with Ember Data ;) Thanks for that!
Maybe we could make a public API for that?
It's actually part of the public API, though it's not documented in the user docs. Could you please tell if using the method works for your use case? If so we may want to document it better. If not we can still improve it :)
@n1k0 Sadly that I haven't figured out how to construct a SyncResultObject
import { SyncResultObject } from 'npm:kinto';
new SyncResultObject();
throws me an error:
TypeError: _npmKinto.SyncResultObject is not a constructor
Try
import { SyncResultObject } from "kinto/lib/collection"
Hint: you have sample import statements on top of each esdoc pages (for instance) :)
@n1k0 it's really hard for me to figure out what is inside the changeObject. Would you mind give me a hint?
@ptgamr Yeah, that's poorly documented, I agree. The change object contains two properties:
changes, an array exposing the list of changes that occurred on the server since the last successful synchronization (basically the list of updated and/or deleted records);lastModified: the last modified timestamp of the remote collection.
I should probably add what I just wrote into the docs.
Thanks @n1k0 ...
import { SyncResultObject } from "kinto/lib/collection" doesn't work for me... As I'm using Browserify to import the script into my ember page ember-browserify.
Does const {SyncResultObject} = require("kinto/lib/collection") work?
Nope. I guess I have to find another way to import kinto.js
That's very strange

@n1k0 for your references, this is the way I'm currently using to import kinto to ember: http://www.jimmylauzau.com/blog/2016/03/22/importing-node-modules-in-ember-js
Oh. It's probably an issue to file against ember-browserify then.
Yes.
Ember-browserify cannot be used with named imports e.g. import { foo } from 'bar'; as we have no way of knowing at the time of browserifying what portions of the import are being used.
@n1k0 I made a work around to copy the implementation of SyncResultObject class into my project (as it's fairy simple). And importChanges works like a charm! You can see the latest demo here: https://ember-kinto-demo.herokuapp.com/lists
Awesome :)
@ptgamr can we close this issue, or should further action be taken to fully address it?
@n1k would be nice if we could add one more section to the Tutorial (https://kintojs.readthedocs.io/en/latest/tutorial/#synchronizing-tasks) to explain how to deal with real-time changes from websocket. Cause I think this is a fairly common use-case, it will make life easier for other developers.
Regarding the importChanges api, it still a hack to re-implement the SyncResultObject. And I think even in the case when you include kinto.js script in your page, it's not possible to construct a new SyncResultObject() because the only reference we have on the page is Kinto, users are not able to access other parts of the lib very easily.
Would it be useful if we could add support for an API call which do not require users to pass in a SyncResultObject ? The api will create one internally.
would be nice if we could add one more section to the Tutorial
@ptgamr Would you be interested in writing it? :)
Would it be useful if we could add support for an API call which do not require users to pass in a SyncResultObject
Yeah probably. It's somewhat of a pain to figure out how to expose things in the compiled file though. If you have suggestions, I take them!
@n1k0 yes, I can find sometime prepare the PR this week. Cheers ;)
@ptgamr awesome, thank you 👍
Wouldn't it make sense for this (both on the Kinto and the Kinto.js side) to make core?
Sorry, what do you mean «for this» ? Websockets? If so yes, it would make sense indeed. We took our time because we wanted a pluggable solution that is not tight to a commercial service, nor reimplementing a whole WS backend... It's very probable that the kinto-webpush plugin goes into core once it's stable and accepted.
Websockets/Webpush is exactly what I meant. As far as I understand there is however no direct (automatic) handling of pushed changes in Kintojs. Will this be addressed as well?
We need to wait for the plugin to be working before doing that. For now there are two ways of handling that:
- Either the push notification is just a trigger for a sync
- Or the push notification contains the changes.
In the first case you can already use Kinto.JS with it. The second case is nice but if you miss a push message you start to be outdated.