diff --git a/packages/editor/src/extensions/paging/__tests__/paging.test.ts b/packages/editor/src/extensions/paging/__tests__/paging.test.ts index de5e6da13..4f420fa68 100644 --- a/packages/editor/src/extensions/paging/__tests__/paging.test.ts +++ b/packages/editor/src/extensions/paging/__tests__/paging.test.ts @@ -27,10 +27,12 @@ import { countPages, flattenBlocks, fromFlatPosition, + serializeDocumentHTML, toFlatPosition } from "../index.js"; import { BlockId } from "../../block-id/block-id.js"; import { getTableOfContents } from "../../../utils/toc.js"; +import { profiler } from "../../../utils/profiler.js"; const PagedDocument = Node.create({ name: "doc", @@ -266,3 +268,58 @@ describe("paging", () => { editor.destroy(); }); }); + +describe("serialization cache", () => { + test("matches the plain serializer exactly", async () => { + const editor = createEditor(savedNoteHTML(BLOCKS)); + await created(); + + expect(serializeDocumentHTML(editor.state.doc, editor.schema)).toBe( + editor.getHTML() + ); + editor.destroy(); + }); + + test("reuses unedited pages and re-serializes only the edited one", async () => { + const editor = createEditor(savedNoteHTML(BLOCKS)); + await created(); + + serializeDocumentHTML(editor.state.doc, editor.schema); + profiler.enable(); + editor.commands.setTextSelection(3); + editor.commands.insertContent("edited "); + serializeDocumentHTML(editor.state.doc, editor.schema); + + const counters = profiler.report().counters; + expect(counters["serialize.cacheMiss"]).toBe(1); + expect(counters["serialize.cacheHit"]).toBe(2); + profiler.disable(); + profiler.reset(); + editor.destroy(); + }); + + test("still reflects the edit", async () => { + const editor = createEditor(savedNoteHTML(BLOCKS)); + await created(); + + serializeDocumentHTML(editor.state.doc, editor.schema); + editor.commands.setTextSelection(3); + editor.commands.insertContent("edited "); + + const html = serializeDocumentHTML(editor.state.doc, editor.schema); + expect(html).toContain("edited"); + expect(html).toBe(editor.getHTML()); + expect(html.match(/
{
+ const editor = createEditor(savedNoteHTML(20), false);
+ await created();
+
+ expect(serializeDocumentHTML(editor.state.doc, editor.schema)).toBe(
+ editor.getHTML()
+ );
+ editor.destroy();
+ });
+});
diff --git a/packages/editor/src/extensions/paging/index.ts b/packages/editor/src/extensions/paging/index.ts
index c55846ca5..a0841cdc8 100644
--- a/packages/editor/src/extensions/paging/index.ts
+++ b/packages/editor/src/extensions/paging/index.ts
@@ -87,3 +87,4 @@ export {
export { installFlatteningSerializer } from "./serializer.js";
export { installPagingParser, uninstallPagingParser } from "./parser.js";
export { fromFlatPosition, toFlatPosition } from "./positions.js";
+export { serializeDocumentHTML } from "./serialize.js";
diff --git a/packages/editor/src/extensions/paging/serialize.ts b/packages/editor/src/extensions/paging/serialize.ts
new file mode 100644
index 000000000..4b09191f8
--- /dev/null
+++ b/packages/editor/src/extensions/paging/serialize.ts
@@ -0,0 +1,72 @@
+/*
+This file is part of the Notesnook project (https://notesnook.com/)
+
+Copyright (C) 2023 Streetwriters (Private) Limited
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see