Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
Why does the deployment fail? |
No idea - it looks like playwright download failed during the npm install part of the build. A retry might succeed. I don't think it was anything you did. |
The only problem now is that the unit test I tried to replace the update editor with this, but it didn't work: editor.update(() => {
const root = $getRoot();
const paragraph = $createParagraphNode();
const a = $createTextNode('a');
const bb = $createTextNode('bb');
const empty = $createTextNode('');
const cc = $createTextNode('cc');
const d = $createTextNode('d');
root.append(paragraph.append(a, bb, empty, cc, d));
setAnchorPoint({
key: bb.getKey(),
offset: 1,
type: 'text',
});
setFocusPoint({
key: cc.getKey(),
offset: 1,
type: 'text',
});
}); |
|
Closing this PR due to staleness! If there are new updates, please reopen the PR. |
|
@potatowagon At the time, the Lexical team had decided to merge this PR, but for reasons of time it became outdated. As you can see in the comments, I had found a super-performing cloning method, but then I realized that it did not clone the properties, but the references in memory, which can cause problems. My conclusion as of today is that if you want to resume this feature, the way to do it would be with JSON.parse(JSON.stringify). This would make the DX better, but effectively the performance would be a little lower. An intermediate compromise would be to leave manual cloning as it is now in the codebase, and for the rest of the users to use JSON.parse(JSON.stringify) when the clone method is not defined. Food for thought. I leave you with my conclusions so that you can decide what seems best to you. I am okay with any decision. The same thing applies to #3931 |
|
I do think we should go with this sort of approach eventually, but maybe a phased approach makes sense? Or at least something with a codemod? I think the most important thing to do is to require all node classes to allow for a 0-argument constructor and then we can move all of the important and awkward static stuff to instances (clone, importJSON) post-construction. Passing the NodeKey on construction can be deprecated and then later removed. We could set and reset a module global on clone to seed |
I'm not sure what you mean by phased approach. A codemod shouldn't be necessary since the idea of this feature is to be backwards compatible. Only if the user does NOT define clone method (or import/exportJSON in the other PR), the generic one is used.
That shouldn't be necessary for cloning either. A combination of However I did think that some static methods might not be static to make it easier to extend node classes, but I don't know if it would be worth it or if performance might suffer. |
|
This PR changes all of the constructor signatures and anyone subclassing them is going to have to change their super calls and constructor signatures accordingly to be compliant with the types. Object.create/assign and JSON.parse/stringify are simply not sound solutions in the general case, it adds extra limitations on what properties are allowed and how the subclasses need to be implemented (private properties aren't enumerable or serialized by default for example). There are of course ways to work around that with the sort of boilerplate overrides that we do now, but I am very hesitant to propose a situation where the constructor code does not run for clones. |
That's fine. The goal of this PR was that for non-JSON serializable nodes (which is the great minority), the user can continue using the manual method |
This is the first of a series of changes I proposed in #3763 to simplify Lexical, remove code duplication, and improve DX.
In short, thanks to this PR no node needs to define a static clone() method.
The most important thing (and the first thing I recommend to check), is the (non-static) clone method that I put in LexicalNode.ts.
Almost whenever the clone() method was used, the __parent, __next, etc. properties were also copied. This was done with $cloneWithProperties or simply by repeating its logic as in getWritable(). The new clone() method I've implemented brings this in for free.
The only part of the repository where these properties are required to be "empty" is in $copyNode, so I set them to null there.
Based on my testing, in the most common case where those properties are required to be cloned, the new implementation is almost 60X faster.