facebook / lexical

Lexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.
https://lexical.dev
MIT License
17.5k stars 1.45k forks source link

Bug: PlainTextPlugin initialEditorState string throws error #2186

Closed always-maap closed 2 years ago

always-maap commented 2 years ago

lexical PlainTextPlugin initialEditorState doesn't accept string

2022-05-16-183914_1920x1080_scrot

Lexical version:0.2.9

Steps To Reproduce

use PlainTextPlugin with initialEditorState set to a string

The current behavior

Unexpected token e in JSON at position 1

The expected behavior

either support converting string to lexical data structure or removing the type

always-maap commented 2 years ago

I can work on the pr. please decide the direction

trueadm commented 2 years ago

It does accept a string. It’s likely that your input is incorrect? Can you paste it in the issue?

always-maap commented 2 years ago

It does accept a string. It’s likely that your input is incorrect? Can you paste it in the issue?

I did

always-maap commented 2 years ago

also, I think the serializing is too complicated. I trying to convince our team to migrate to lexical but the expected editorState is too complicated.

for single line of text

"editorState": {
    "_nodeMap": [
      [
        "root",
        {
          "__children": ["791"],
          "__dir": "ltr",
          "__format": 0,
          "__indent": 0,
          "__key": "root",
          "__parent": null,
          "__type": "root"
        }
      ],
      [
        "791",
        {
          "__type": "paragraph",
          "__parent": "root",
          "__key": "791",
          "__children": ["797"],
          "__format": 0,
          "__indent": 0,
          "__dir": "ltr"
        }
      ],
      [
        "797",
        {
          "__type": "text",
          "__parent": "791",
          "__key": "797",
          "__text": "test",
          "__format": 0,
          "__style": "",
          "__mode": 0,
          "__detail": 0
        }
      ]
    ],
    "_selection": {
      "anchor": { "key": "797", "offset": 4, "type": "text" },
      "focus": { "key": "797", "offset": 4, "type": "text" },
      "type": "range"
    }
  },

IMO it's unnecessary to save this much data to db for millions of comments and migrate to it

trueadm commented 2 years ago

The reason it is failing is because it’s not wrapped in curly braces. If you do that it will work. How are you getting the JSON?

You don’t need to serialize this to your database. You can easily traverse through and define your own format. We do this internally at Meta - we basically construct a single string and mark the ranges for the basic cases.

The editor state is just a raw output of the internals, we’re currently looking at making this format less based on intervals, but it’ll still be of similar shape.

always-maap commented 2 years ago

The reason it is failing is because it’s not wrapped in curly braces. If you do that it will work. How are you getting the JSON?

You don’t need to serialize this to your database. You can easily traverse through and define your own format. We do this internally at Meta - we basically construct a single string and mark the ranges for the basic cases.

The editor state is just a raw output of the internals, we’re currently looking at making this format less based on intervals, but it’ll still be of similar shape.

I'm confused by "it’s not wrapped in curly braces"

yes. that was my plan. but to represent it to lexical, I need to play with lexical rules and eventually convert it to this representation

always-maap commented 2 years ago

How are you getting the JSON?

you mean editorState.toJSON().editorState ?

trueadm commented 2 years ago

You just need to do JSON.stringify(editorState).

always-maap commented 2 years ago

You just need to do JSON.stringify(editorState).

yeah I know but it was the recommended way in doc https://lexical.dev/docs/concepts/editor-state

trueadm commented 2 years ago

We should fix that! Edit: fixed!

always-maap commented 2 years ago

You don’t need to serialize this to your database. You can easily traverse through and define your own format. We do this internally at Meta - we basically construct a single string and mark the ranges for the basic cases.

I learned how facebook converts lexical internal representation. something like this

"message":{
  "ranges":[{"entity":{"id":"149980285694976"},"length":11,"offset":13}],
  "text":"lexical test Always MAAP this is\npretty cool"
}

but still, we need to convert it back to lexical representation for editing. is there any easy internal way of doing it or just creating the object with ranges and messages?

acywatson commented 2 years ago

@fantactuka might have insight

fantactuka commented 2 years ago

@fantactuka might have insight

"message":{ "ranges":[{"entity":{"id":"149980285694976"},"length":11,"offset":13}], "text":"lexical test Always MAAP this is\npretty cool" }

Dominic pretty much answered that: it seem reasonable to serialize to a single string + entity ranges for plain text given it's expected to be very simple. And it'll be a different story if you use lexical for rich text, then ranges for entities and styles would become more complex to convert to/from so might want to stick to something more tree-like

acywatson commented 2 years ago

@always-maap let's continue discussion in #2197 and close this one out. That way we can get more discovery/input from the community.