I did a little testing, and this is something that seems to work.
Wrap the content of the XPage in a panel/set an id.
When it's detected that the document has changed, trigger a partial refresh on the wrapper panel. This could be done by executing a script in the browser that clicks a hidden button or something.
Execute this code on the server to "reset" the page (you have to alter the code if the document data source is connected to something other than the root node of the XPage):
var newViewRoot = facesContext.getApplication().getViewHandler().createView( facesContext, view.getPageName() );
facesContext.setViewRoot( newViewRoot );
newViewRoot.getData().get(0).setConcurrencyMode( 'force' );
The above code recreates the view, and sets the document so that save conflicts won't occur if the document is saved after the view tree is rebuilt. I couldn't find another way to avoid save conflicts.
If you want, you could probably trigger the server side code using the RPC module in the XPages Extension Library, or the EventDelegator technique I wrote about in my blog a while back.
http://dontpanic82.blogspot.com/2010/12/new-and-improved-eventdelegator-with.html
This isn't a complete solution, but at least you have something to test/go by :)