-
-
Notifications
You must be signed in to change notification settings - Fork 267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A new util method proxyWithHistory
with history support
#89
Comments
If we had a way to plug a global listener on the snapshot: const snapshot = useProxy(state)
const history = []
snapshot.on('global', (newValue, oldValue) => {
// store the diff between newValue and oldValue in a history array
history.push(diff(newValue, oldValue))
}) |
Maybe even use automerge for efficient storage https://github.com/automerge/automerge |
Note that snapshot is already efficient. It shares sub-tree unless it's mutated. |
I mean efficient storage of the history, automerge has deltas |
Is it about serializing? doesn't seem so. |
no, I mean...if you want history you need to develop some kind of event sourcing with the snapshot...that doesn't need to be within valtio, but the event store needs efficient storage for all the diffs of the state object |
I'm not sure, but as long as you understand how valtio's snapshot works, I'm fine. const state = proxy({ a: 1, b: { c: 2 } })
const snap1 = snapshot(state)
state.a++
const snap2 = snapshot(state)
// snap1 !== snap2
// snap1.b === snap2.b I can't imagine more efficient storage than this. |
I don't think we are talking about the same thing, to provide a history you probably need an immutable sequence of events on the state so you can undo/redo the actions. Snapshot is an efficient way of providing a point in time for the state, so what is missing is a event store maybe having frozen snapshots in the right sequence. |
Okay, what I was thinking was something about history in redux context. |
Now #177 is merged, let's revisit this. @thelinuxlich It should be close to what you meant by event sourcing. @redbar0n I would still like to hear about the API idea. @zcaudate If you are interested in working on it, please go ahead. |
@dai-shi: Hahaha. I don't really know what needs to be done. Reading the post, it seems like the guys here have a fair idea of what they want. I'm very in favour of an event sourcing model (with history being a side effect) but I think it'd be better to come up with a couple of use cases first. ie. can I use it for websockets? Like it I wanted to implement a stock ticker, how might that work? it's also interesting that the proxies don't need react to work so it can be used on the server end as well. |
For this, the issue is serialization. For example, how to serialize a symbol. What we've done in #177 is very primitive, and I'm not sure how it works for history support. If I were to implement history, I'd just use snapshots. |
In my case, json is good enough representation for data so serialisation is not really an issue. Where would there be a need to serialise a symbol? |
It's your use case. I mean from the library perspective, objects are not guaranteed to be JSON serializable. circular structure is not JSON serializable. we have |
This is how I implement const proxyWithHistory = (initialValue) => {
const p = proxy({})
const history = []
let index = -1
let wip
const undo = () => {
if (index > 0) {
p.value = wip = history[--index]
}
}
const redo = () => {
if (index < history.length - 1) {
p.value = wip = history[++index]
}
}
subscribe(p, (ops) => {
if (ops.some((op) => op[1][0] === 'value' && (op[0] !== 'set' || op[2] !== wip))) {
history.splice(index + 1)
history.push(snapshot(p).value)
++index
}
}
p.undo = undo
p.redo = redo
p.value = initialValue
return p
} |
it looks pretty sweet with the new subscribe mechanism. it might also be interesting to take in the methods |
We could also make it to have |
yep. So maybe then and then the package will also provide methods like:
and maybe even:
btw are the new subscribe changes released on npm? I'd like to start playing around with it. |
I also took a look at valtio-yjs. that might also be a good target for a history store. I did some OT previously on the Atlassian Confluence editor (the syncing on the backend). |
I prefer keeping it in valtio/utils. (unless we need an extra dependency)
Hm, getting your ideas. I guess such extensions are provided by 3rd-party packages
No, it's not yet. Please use codesandbox build for now.
valtio-yjs uses the new subscribe. Note: |
I don't think I need yjs at the moment but it's definitely a good library if the need arises. I'm not sure what you guys are doing at pnmdrs but looking at your libraries, you can may do a collaborative 3d editor or something with it. |
Please explain the use of the |
Without |
Cool got it, in the subscribe method it prevents saveHistory to prevent the infinite loop. Am I correct? |
Hey, I created proxyWithHistoryWithPersist function for a project. Do you want me to add it? |
Please create a third-party package, and let's add a link in https://github.com/pmndrs/valtio/blob/main/docs/resources/libraries.mdx. |
ref: https://twitter.com/dai_shi/status/1361147616000544769
It would be nice. I don't have any idea yet.
The text was updated successfully, but these errors were encountered: