question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

consider removing `slate-schema`

See original GitHub issue

Right now we have a slate-schema package with the goal of helping people write “normalizations” for their editor, to ensure it’s always in a valid state. This is something that existing in the older versions of Slate and was preserved.

Thing is, I’m not really convinced that it’s totally necessary. With the much more readable helpers (especially the iterables) in the newer version of Slate, I think there’s no longer as big of a win from the schema rules conciseness.

It used to be that schema rules were absolutely more concise than writing the imperative alternative. Now that’s not so true.

For example, here’s the forced-layout written using slate-schema:

const withSchema = defineSchema([
  {
    for: 'node',
    match: 'editor',
    validate: {
      children: [
        { match: { type: 'title' }, min: 1, max: 1 },
        { match: { type: 'paragraph' }, min: 1 },
      ],
    },
    normalize: (editor, error) => {
      const { code, path } = error
      const [index] = path
      const type = index === 0 ? 'title' : 'paragraph'

      switch (code) {
        case 'child_invalid': 
        case 'child_max_invalid': {
          Editor.setNodes(editor, { type }, { at: path })
          break
        }
        
        case 'child_min_invalid': {
          const block = { type, children: [{ text: '' }] }
          Editor.insertNodes(editor, block, { at: path })
          break
        }
      }
    },
  },
])

And here it is using just a plain plugin:

const withSchema = editor => {
  const { normalizeNode } = editor

  editor.normalizeNode = path => {
    if (path.length === 0) {
      if (editor.children.length < 1) {
        const title = { type: 'title', children: [{ text: 'Untitled' }] }
        Editor.insertNodes(editor, title, { at: path.concat(0) })
      }

      if (editor.children.length < 2) {
        const paragraph = { type: 'paragraph', children: [{ text: '' }] }
        Editor.insertNodes(editor, paragraph, { at: path.concat(1) })
      }

      for (const [child, childPath] of Node.children(editor, path)) {
        const type = childPath[0] === 0 ? 'title' : 'paragraph'

        if (child.type !== type) {
          Editor.setNodes(editor, { type }, { at: childPath })
        }
      }
    }

    return normalizeNode(path)
  }

  return editor
}

Both similar in LOC.

The slate-schema version is definitely more declarative. With the benefit of guaranteeing that as long as you write the validate dictionary correctly at least you won’t have invalid nodes.

But there are also downsides…

  • If you write the validate dictionary incorrectly it can be hard to figure out what’s going wrong.
  • And when you need to debug why a specific schema error is triggering the callstack for doing that is very convoluted.
  • And it requires learning a whole new SchemaError and SchemaRule interface.
  • And when writing more complex rules, the errors often have different properties depending on the failure, which you have to work around.
  • And there are many situations that aren’t able to be expressed by the declarative schema at all.

There’s a few cases which get trickier without the declarative schema. The parent validation is definitely easily to write declaratively, since otherwise you need to enforce it while iterating the parent itself.

But even that one isn’t a clear win, because understanding when the parent rule fires takes extra knowledge. And it doesn’t allow you to do grandparent, or cousin, or any number of slightly different needs.

I think a case could be made for dropping the slate-schema package entirely and just telling people to use normalizeNode instead. And cases which are hard to model are either (a) that way because they are in fact very complex, or (b) could benefit from additional helper functions in one of the interfaces.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:7
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
DamareYohcommented, Dec 8, 2019

Something to chew on for sure. I feel like to a degree having it as a first class feature is good for advertising that it exists and sets it apart from other editors that arent as good at dealing with this problem.

From an api perspective while theres more of a learning curve for a new user, the schema does add a structure and organization that I think people are unlikely to be able to achieve with just using normalizeNode. My normalizations tend to be much sloppier when done via the latter.

Id like to see schema stay in but wont be upset if it gets dropped.

1reaction
PeterKottascommented, Dec 8, 2019

Never really understood schema either. I know that might not be the go-to reason to drop something, but for me personally, it was always confusing. If the same functionality can be achieved by other means, I don’t see a reason to keep it. Just my 2 cents.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Changelog - Slate
The slate-schema package has been removed! This decision was made because with ... Now any non-defined properties are considered invalid.
Read more >
golery-slate-code-block - npm package - Snyk
An important project maintenance signal to consider for ... Pressing Delete remove the indentation before cursor if possible ...
Read more >
Schemas · Slate
For example, with the above schema, if a block that isn't a paragraph or an image is discovered in the document, Slate will...
Read more >
SQL Server Reporting Services - From query to report!
Some of you may be already considering security: should I make my company's ... figures with the finished report is the Slate schema)...
Read more >
packages/slate/Changelog.md · Gitee 极速下载/Slate-js
Node.removeDescendant was removed. There's no reason you should have been using this, since it was an undocumented and unused method that was left...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found