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 6, 2023
1 parent 8ffa607 commit 127f108
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 53 deletions.
60 changes: 7 additions & 53 deletions packages/jupyter/src/jupyter.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +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';

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 All @@ -69,13 +23,13 @@ export const JupyterOutputs = ({ id, outputs }: { id: string; outputs: MinifiedO
}, [core, load]);

useEffect(() => {
if (!data || loaded) return;
if (!data || loaded || fullOutputs != null) return;
setLoaded(true);
fetchAndEncodeOutputImages(data).then((out) => {
const compactOutputs = convertToIOutputs(out, {});
setFullOutputs(compactOutputs);
});
}, [id, data]);
}, [id, data, fullOutputs]);

if (error) {
return <div className="text-red-500">Error rendering output: {error.message}</div>;
Expand All @@ -94,12 +48,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 127f108

Please sign in to comment.