pycrdt
pycrdt copied to clipboard
XmlText.insert_embed() doesn't seem to work
Description
Hi,
I'm trying to use pycrdt to interop with a yjs backed lexical editor, however it looks as though the insert_embed() function of the XmlText class does not work.
Reproduce
the following code:
import pycrdt
def print_events(events: list):
for event in events:
print(event)
doc = pycrdt.Doc()
xml_frag = pycrdt.XmlFragment()
doc['root'] = xml_frag
xml_frag.observe_deep(print_events)
xml_text = pycrdt.XmlText()
xml_frag.children.append(xml_text)
xml_text.insert(0, 'the fish was delish')
outputs:
{children_changed: True, target: , path: [], delta: [{'insert': [<pycrdt._xml.XmlText object at 0x1036850d0>]}], keys: {}}
{children_changed: None, target: the fish was delish, path: [0], delta: [{'insert': 'the fish was delish'}], keys: {}}
so far so good ... if i continue:
>>> xml_text.insert_embed(0, pycrdt.Map({"__style":"","__type":"text","__mode":0,"__detail":0,"__format":0}))
{children_changed: None, target: undefinedthe fish was delish, path: [0], delta: [{'insert': None}], keys: {}}
and:
>>> xml_text.diff()
[(None, None), ('the fish was delish', None)]
Expected behavior
the reason i expect something different is because lexical does this with yjs, calling .insertEmbed()
https://github.com/facebook/lexical/blob/main/packages/lexical-yjs/src/CollabElementNode.ts#L602
if i perform the same edit with lexical, apply those changes to the pycrdt doc with doc.apply_update(), i get
>>> xml_text.diff()
[(<builtins.Map object at 0x40260f9ad0>, None), ('the fish was delish', None)]
Context
i'm not actually sure if lexical and yjs are actually behaving correctly here ... insertEmbed() doesn't look to be a documented function ... and so i'm inferring all this from behaviour.
with thanks
found other people grappling with this
https://github.com/y-crdt/ypy/discussions/143
Hmm I think that @ColonelThirtyTwo, @dmonad or @Horusiath can best answer this question.
Do we have any more insight into this? A solution would be helpful.
A first step could be to convert that example to Rust using Yrs, and see if it behaves differently.
@jonathon-love Do you really want to insert a pycrdt.Map, or just a dict? This seems to work fine:
xml_text.insert_embed(0, {"__style":"","__type":"text","__mode":0,"__detail":0,"__format":0})
if i insert a dict, is it represented in the ydoc as a YMap?
if that's a workaround then that could work -- but i'm pretty confident it does need to represented with a YMap in order for lexical to be happy with it.
with thanks
if i insert a dict, is it represented in the ydoc as a
YMap?
No, it wouldn't be a shared type.
I opened #270 but there are things I'm not sure about. Would you be able to test it?
sure. will take a look in the next couple of days.
@jonathon-love did you get a chance to try it out?
sorry! i'll try soon!