orbitjs / orbit

Composable data framework for ambitious web applications.
https://orbitjs.com
MIT License
2.33k stars 134 forks source link

Provide context to live query subscriber callbacks re: the transaction that prompted the update #910

Open bradjones1 opened 2 years ago

bradjones1 commented 2 years ago

Thanks as always for the awesome package and responsiveness in the issue queue.

Curious if it's possible to pass additional context into a live query subscriber callback as to the nature of the update. I have a live query that updates my React Native app's context with the latest version of a json:api resource. When I do a PATCH on this resource (e.g., to update a field) the callback is called (with the "locally patched" data), and then when the object is updated with the field as it's sent back from the remote source (the API, over the wire) I get a second update.

Is it possible to somehow differentiate these updates within the callback? I understand I have other issues to think about regarding consistency and optimistic vs. pessimistic error handling, but I don't think those things would necessarily change how I handle this scenario? It seems like it "might," given what I'm reading here, but I'm not sure this is out of date?

Because all strategies are pessimistic (i.e. blocking: true) by default, data will only be persisted locally after it has been persisted remotely.

Not sure if the coordinator configuration is relevant to this, but here it is:

const coordinator = new Coordinator({
  sources: [memory, jsonapi]
});
// Query the remote server whenever the memory source is queried
coordinator.addStrategy(
  new RequestStrategy({
    source: "memory",
    on: "beforeQuery",
    target: "remote",
    action: "query",
    // Both below required to preserve ordering through from json:api.
    blocking: true,
    passHints: true,
  })
);
// Update the remote server whenever the memory source is updated
coordinator.addStrategy(
  new RequestStrategy({
    source: "memory",
    on: "beforeUpdate",
    target: "remote",
    action: "update",
    blocking: true,
  })
);
// Sync all changes received from the remote server to the memory source
coordinator.addStrategy(
  new SyncStrategy({
    source: "remote",
    target: "memory",
    blocking: true
  })
);