Skip to content

Commit cec980a

Browse files
committed
ENG-1716: Extend buffer->legacy mirror to handle add/delete
Mirror now creates legacy children when buffer has extras and deletes legacy children when buffer has fewer, in addition to in-place block.update for matching positions. Replaces the prior length-match guard which caused dual-write to silently skip whenever the user added or removed template lines.
1 parent e868c9f commit cec980a

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

apps/roam/src/components/settings/components/EphemeralBlocksPanel.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,48 @@ const serializeBlockTree = (children: TreeNode[]): RoamNodeType[] =>
3333
}),
3434
}));
3535

36+
const treeNodeToInputTextNode = (node: TreeNode): InputTextNode => ({
37+
text: node.text,
38+
...(node.heading && { heading: node.heading as 0 | 1 | 2 | 3 }),
39+
...(node.open === false && { open: false }),
40+
...(node.children.length > 0 && {
41+
children: [...node.children]
42+
.sort((a, b) => a.order - b.order)
43+
.map(treeNodeToInputTextNode),
44+
}),
45+
});
46+
3647
const mirrorBufferToLegacyChildren = (
3748
bufferChildren: TreeNode[],
3849
legacyChildren: TreeNode[],
50+
legacyParentUid: string,
3951
): void => {
40-
if (bufferChildren.length !== legacyChildren.length) {
41-
console.warn(
42-
"[Template-Block-props] mirror skipped: tree length mismatch (expected only during testing or manual divergence)",
43-
{ buffer: bufferChildren.length, legacy: legacyChildren.length },
44-
);
45-
return;
46-
}
4752
const sortedBuffer = [...bufferChildren].sort((a, b) => a.order - b.order);
4853
const sortedLegacy = [...legacyChildren].sort((a, b) => a.order - b.order);
49-
for (let i = 0; i < sortedBuffer.length; i++) {
54+
const minLen = Math.min(sortedBuffer.length, sortedLegacy.length);
55+
56+
for (let i = 0; i < minLen; i++) {
5057
const bufferNode = sortedBuffer[i];
5158
const legacyNode = sortedLegacy[i];
5259
if (bufferNode.text !== legacyNode.text) {
5360
void window.roamAlphaAPI.data.block.update({
5461
block: { uid: legacyNode.uid, string: bufferNode.text },
5562
});
5663
}
57-
mirrorBufferToLegacyChildren(bufferNode.children, legacyNode.children);
64+
mirrorBufferToLegacyChildren(
65+
bufferNode.children,
66+
legacyNode.children,
67+
legacyNode.uid,
68+
);
69+
}
70+
71+
for (let i = minLen; i < sortedBuffer.length; i++) {
72+
const node = treeNodeToInputTextNode(sortedBuffer[i]);
73+
void createBlock({ node, parentUid: legacyParentUid, order: i });
74+
}
75+
76+
for (let i = minLen; i < sortedLegacy.length; i++) {
77+
void deleteBlock(sortedLegacy[i].uid);
5878
}
5979
};
6080

@@ -96,7 +116,7 @@ const DualWriteBlocksPanel = ({
96116
setBufferUid(null);
97117
void deleteBlock(newUid);
98118
};
99-
}, [useNewStore, nodeType]);
119+
}, [useNewStore, nodeType, uid]);
100120

101121
const handleChange = useCallback(() => {
102122
if (!renderUid) return;
@@ -107,7 +127,7 @@ const DualWriteBlocksPanel = ({
107127
setDiscourseNodeSetting(nodeType, settingKeys, serialized);
108128
if (useNewStore && renderUid !== uid) {
109129
const legacyTree = getFullTreeByParentUid(uid);
110-
mirrorBufferToLegacyChildren(tree.children, legacyTree.children);
130+
mirrorBufferToLegacyChildren(tree.children, legacyTree.children, uid);
111131
}
112132
}, DEBOUNCE_MS);
113133
}, [renderUid, uid, useNewStore, nodeType, settingKeys]);

0 commit comments

Comments
 (0)