Skip to content

Commit

Permalink
🛠 fixes cross-ref bug #59
Browse files Browse the repository at this point in the history
  • Loading branch information
stevejpurves committed May 29, 2023
1 parent d5836b1 commit 7cd25a3
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 52 deletions.
57 changes: 5 additions & 52 deletions packages/jupyter/src/jupyter.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,13 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useEffect, useState } from 'react';
import type { IOutput } from '@jupyterlab/nbformat';
import { useFetchAnyTruncatedContent } from './hooks';
import type { MinifiedOutput } from 'nbtx';
import { convertToIOutputs } from 'nbtx';
import { fetchAndEncodeOutputImages } from './convertImages';
import type { ThebeCore } from 'thebe-core';
import { useThebeCore } from 'thebe-react';
import { useCellRef, useCellRefRegistry, useNotebookCellExecution } from './providers';
import { useCellRefRegistry, useNotebookCellExecution } from './providers';
import { SourceFileKind } from 'myst-common';
import { useXRefState } from '@myst-theme/providers';

function ActiveOutputRenderer({ id, data }: { id: string; data: IOutput[] }) {
const ref = useCellRef(id);
const exec = useNotebookCellExecution(id);

useEffect(() => {
if (!ref?.el || !exec?.cell) {
console.debug(`No cell ref available for cell ${exec?.cell?.id}`);
return;
}
console.debug(`Attaching cell ${exec.cell.id} to DOM at:`, {
el: ref.el,
connected: ref.el.isConnected,
data,
});
exec.cell.attachToDOM(ref.el);
exec.cell.render(data);
}, [ref?.el, exec?.cell]);

return null;
}

function PassiveOutputRenderer({
id,
data,
core,
kind,
}: {
id: string;
data: IOutput[];
core: ThebeCore;
kind: SourceFileKind;
}) {
const [cell] = useState(new core.PassiveCellRenderer(id, undefined, undefined));
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
cell.render(data, kind === SourceFileKind.Article);
}, [data, cell]);
useEffect(() => {
if (!ref.current) return;
cell.attachToDOM(ref.current, true);
}, [ref]);
return <div ref={ref} data-thebe-passive-ref="true" />;
}

const MemoPassiveOutputRenderer = React.memo(PassiveOutputRenderer);
import { ActiveOutputRenderer, PassiveOutputRenderer } from './renderers';

export const JupyterOutputs = ({ id, outputs }: { id: string; outputs: MinifiedOutput[] }) => {
const { core, load } = useThebeCore();
Expand Down Expand Up @@ -96,12 +49,12 @@ export const JupyterOutputs = ({ id, outputs }: { id: string; outputs: MinifiedO
<>
{!fullOutputs && <div className="p-2.5">Loading...</div>}
{fullOutputs && core && (
<MemoPassiveOutputRenderer
<PassiveOutputRenderer
id={id}
data={fullOutputs}
core={core}
kind={exec?.kind ?? SourceFileKind.Notebook}
></MemoPassiveOutputRenderer>
></PassiveOutputRenderer>
)}
</>
);
Expand Down
57 changes: 57 additions & 0 deletions packages/jupyter/src/renderers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React, { useEffect, useRef, useState } from 'react';
import type { IOutput } from '@jupyterlab/nbformat';
import { useFetchAnyTruncatedContent } from './hooks';
import type { MinifiedOutput } from 'nbtx';
import { convertToIOutputs } from 'nbtx';
import { fetchAndEncodeOutputImages } from './convertImages';
import type { ThebeCore } from 'thebe-core';
import { useThebeCore } from 'thebe-react';
import { useCellRef, useCellRefRegistry, useNotebookCellExecution } from './providers';
import { SourceFileKind } from 'myst-common';
import { useXRefState } from '@myst-theme/providers';

export function ActiveOutputRenderer({ id, data }: { id: string; data: IOutput[] }) {
const ref = useCellRef(id);
const exec = useNotebookCellExecution(id);

useEffect(() => {
if (!ref?.el || !exec?.cell) {
console.debug(`No cell ref available for cell ${exec?.cell?.id}`);
return;
}
console.debug(`Attaching cell ${exec.cell.id} to DOM at:`, {
el: ref.el,
connected: ref.el.isConnected,
data,
});
exec.cell.attachToDOM(ref.el);
exec.cell.render(data);
}, [ref?.el, exec?.cell]);

return null;
}

function PassiveOutputRendererFn({
id,
data,
core,
kind,
}: {
id: string;
data: IOutput[];
core: ThebeCore;
kind: SourceFileKind;
}) {
const [cell] = useState(new core.PassiveCellRenderer(id, undefined, undefined));
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
cell.render(data, kind === SourceFileKind.Article);
}, [data, cell]);
useEffect(() => {
if (!ref.current) return;
cell.attachToDOM(ref.current, true);
}, [ref]);
return <div ref={ref} data-thebe-passive-ref="true" />;
}

export const PassiveOutputRenderer = React.memo(PassiveOutputRendererFn);

0 comments on commit 7cd25a3

Please sign in to comment.