rozek
June 27, 2023, 10:44am
#1
doc.on('update',...)
can be used to detect changes within a given Y.Doc.
Is it possible to find out (from this update
event) which “shared type” has been changed (and, perhaps, in what way)? And, if yes, how?
Or will I always have to observe every “shared type” individually?
raine
June 27, 2023, 1:39pm
#2
It may be possible to extract the shared types from transaction.change
, provided as the fourth parameter to the update event handler.
You might also consider observeDeep
on a root Y.Map
.
rozek
June 27, 2023, 2:31pm
#3
oh, there is a fourth parameter? good to know, thanks!
raine
June 27, 2023, 2:34pm
#4
The secret fourth parameter. Advanced users only!
rozek
June 27, 2023, 2:40pm
#5
Damn…I’m still a Yjs newbie
rozek
June 27, 2023, 3:07pm
#6
Oh, I misunderstood - I know the transaction
parameter - and already inspected its changed
property, but that structure seems to lack important information (such as the name of the top-level Y.Doc entry that was changed…
[Edit] the key
of a transaction.changed
entry seems to be the changed structure itself?
raine
June 27, 2023, 7:46pm
#7
I’m not sure. Usually I do shared-type specific behavior in the observe
or deepObserve
events, not the update event.
rozek
June 28, 2023, 5:25am
#8
by the way: I am now able to inspect updates to top-level Y.Map
s, but not to top-level Y.Array
s or Y.Text
s
observe
and deepObserve
work on Y.Doc
entries only, not on Y.Doc
s themselves.
For scalability reasons, I would prefer a single handler for the main Y.Doc
rather than many handlers for every single Y.Doc
entry or SubDoc…
If you want to see some code:
const sharedDoc = new Y.Doc()
sharedDoc.on('update',(Update,Origin,Doc,Transaction) => {
console.log('new transaction')
Transaction.changed.forEach((ChangeSet,Container) => {
if (
(Container instanceof Y.Map) ||
(Container._map instanceof Map) && (Container._map.size > 0)
) {
console.log('- Y.Map:')
ChangeSet.forEach((Value,Key) => {
console.log(' -',Key,'=',Value)
})
return
}
if (
(Container instanceof Y.Array) ||
(Container._start != null) && ('arr' in Container._start.content)
) {
console.log('- Y.Array:',Transaction)
return
}
if (
(Container instanceof Y.Text) ||
(Container._start != null) && ('str' in Container._start.content)
) {
console.log('- Y.Text:',Transaction)
return
}
if (
(Container instanceof Y.XmlFragment) ||
(Container._start != null) && ('type' in Container._start.content)
) {
console.log('- Y.XmlFragment:',Transaction)
return
}
console.log('Transaction',Transaction)
})
})
Those strange type detection expressions are needed since updates from a provider seem to look different than updates from business logic…(sigh)
raine
June 28, 2023, 3:54pm
#9
If you have a single root
Map, it’s only a one observeDeep
for all shared types.
transaction.origin
might help you differentiate transactions originating on a local doc (which is usually set to doc.clientID
) and transactions synced over a provider (which is usually set to the provider instance).
rozek
June 28, 2023, 5:00pm
#10
Indeed,
while Y.Doc
look a bit like (top-level) maps with an additional sub-doc registry, it might be better to always add a first indirection in form of a top-level Y.Map
or Y.Array
which could then be (deeply) observed more easily…
raine
June 29, 2023, 12:45pm
#11
Yes. Unfortunately subdoc support is severely lacking. But nested shared types work well across providers.