authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-19 23:30:39-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-20 01:17:10-07:00
log7cbbaedd32edafc10c7c0b128461dc123771c5e0
tree2be45fe9ecf34ae60fc250116b5f77731b3db5eb
parent9aff7edf050088cee3bc2d69cc5a6c4f4d512704
signaturebadge-check Signed by SSH key SHA256:xbd+BjjhyBfwk7GVoURf9Yx0gzDerHbvYv7SddNWmAs

fix: don't need to call `memo()` on every component


1 files changed, 4 insertions(+), 11 deletions(-)

src/Memoizer.ts+4-11
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1import { ASSERT, UNWRAP } from "@clo/lib/assert.ts";1import { ASSERT, UNWRAP } from "@clo/lib/assert.ts";
2import { type JSX, type Key, memo, type ReactNode } from "react";2import { type JSX, type Key, type ReactNode } from "react";
3import { type Components } from "rehype-react";3import { type Components } from "rehype-react";
4import remarkRehype from "remark-rehype";4import remarkRehype from "remark-rehype";
5import { Fragment, jsx } from "react/jsx-runtime";5import { Fragment, jsx } from "react/jsx-runtime";
...@@ -29,10 +29,9 @@ type AstProcessor = Processor<Parent, Parent, Parent, Parent, Parent>;...@@ -29,10 +29,9 @@ type AstProcessor = Processor<Parent, Parent, Parent, Parent, Parent>;
29 */29 */
30export class Memoizer {30export class Memoizer {
31 // options incrementally updated via `reconfigure`31 // options incrementally updated via `reconfigure`
32 #baseProcessor: BaseProcessor = defaultProcessor as BaseProcessor;32 #baseProcessor: BaseProcessor = defaultProcessor;
33 #astProcessor: AstProcessor | null = null;33 #astProcessor: AstProcessor | null = null;
34 #components: Partial<Components> = {};34 #components: Partial<Components> = {};
35 #previousComponents: Partial<Components> = {};
3635
37 // incremental parsing graph, structure of arrays36 // incremental parsing graph, structure of arrays
38 #predict: Predict | null = null;37 #predict: Predict | null = null;
...@@ -50,7 +49,7 @@ export class Memoizer {...@@ -50,7 +49,7 @@ export class Memoizer {
50 if (49 if (
51 this.#astProcessor !== null &&50 this.#astProcessor !== null &&
52 this.#baseProcessor === processor &&51 this.#baseProcessor === processor &&
53 componentsAreEqual(this.#previousComponents, components) &&52 componentsAreEqual(this.#components, components) &&
54 !!this.#predict === predict53 !!this.#predict === predict
55 ) {54 ) {
56 return;55 return;
...@@ -64,13 +63,7 @@ export class Memoizer {...@@ -64,13 +63,7 @@ export class Memoizer {
64 }63 }
6564
66 this.#astProcessor = processor as unknown as AstProcessor;65 this.#astProcessor = processor as unknown as AstProcessor;
67 // Memoize every component. We want to ensure that React doesn't re-render66 this.#components = components;
68 // components for no reason. Just because the parent renders doesn't mean
69 // the children should.
70 this.#components = Object.fromEntries(
71 Object.entries(components).map(([k, v]) => [k, typeof v === "function" ? memo(v) : v]),
72 ) as Partial<Components>;
73 this.#previousComponents = components;
74 this.#content = "";67 this.#content = "";
75 this.#positions = [];68 this.#positions = [];
76 this.#parsed = [];69 this.#parsed = [];