Skip to content

Commit

Permalink
Kernel state for Cell and Output (#282)
Browse files Browse the repository at this point in the history
* chore: use id instead of uid prop

* fix: build

* output: fix nbgrader

* chore: cell to use kernel executor

* chore: output and cell to use kernel executor

* chore: simplify output state

* chore: kernel state

* chore: kernel phase

* chore: lint

* fix: build

* chore: relax kernel executor constructor

* chore: output state code

* chore: add completed_with_error execution phase

* chore: disconnect signals

* Update packages/react/src/components/output/Output.tsx

Co-authored-by: Frédéric Collonval <[email protected]>

---------

Co-authored-by: Frédéric Collonval <[email protected]>
  • Loading branch information
echarles and fcollonval authored Jul 31, 2024
1 parent bbc2378 commit f58506b
Show file tree
Hide file tree
Showing 82 changed files with 987 additions and 633 deletions.
2 changes: 1 addition & 1 deletion attic/prosemirror/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"dependencies": {
"@codemirror/lang-python": "6.0.1",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@prosemirror-adapter/react": "0.2.4",
"@types/orderedmap": "1.0.0",
"codemirror": "6.0.1",
Expand Down
2 changes: 1 addition & 1 deletion examples/cra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@datalayer/icons-react": "^0.3.0",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@datalayer/primer-addons": "0.3.0",
"jupyterlab-plotly": "^5.17.0",
"plotly.js": "^2.26.2",
Expand Down
4 changes: 2 additions & 2 deletions examples/cra/src/examples/cell/CellComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* MIT License
*/

import { useCellStore, Cell } from "@datalayer/jupyter-react";
import { useCellsStore, Cell } from "@datalayer/jupyter-react";
import CellToolbar from './CellToolbar';

const SOURCE_EXAMPLE = `"""
Expand Down Expand Up @@ -36,7 +36,7 @@ ax2.set_ylabel('Undamped')
plt.show()`;

const CellPreview = () => {
const cellStore = useCellStore();
const cellStore = useCellsStore();
return (
<>
<div>source: {cellStore.source}</div>
Expand Down
4 changes: 2 additions & 2 deletions examples/cra/src/examples/cell/CellToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import React from 'react';
import { Box, IconButton, Text, Tooltip } from '@primer/react';
import { PlayIcon, ReplyIcon, ThreeBarsIcon } from '@primer/octicons-react';
import { useCellStore } from '@datalayer/jupyter-react';
import { useCellsStore } from '@datalayer/jupyter-react';

const CellToolbar: React.FC = () => {
const cellStore = useCellStore();
const cellStore = useCellsStore();
const outputsCount = cellStore.outputsCount;
return (
<>
Expand Down
2 changes: 1 addition & 1 deletion examples/next-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"dependencies": {
"@datalayer/icons-react": "^0.3.0",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@datalayer/primer-addons": "0.3.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.40.0",
Expand Down
2 changes: 1 addition & 1 deletion examples/slate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"@datalayer/icons-react": "^0.3.0",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@datalayer/primer-addons": "0.3.0",
"@emotion/css": "^11.1.3",
"@emotion/react": "^11.10.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"dependencies": {
"@datalayer/icons-react": "^0.3.0",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@datalayer/primer-addons": "0.3.0",
"@docusaurus/core": "^2.4.0",
"@docusaurus/types": "^2.1.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
},
"dependencies": {
"@datalayer/icons-react": "^0.3.0",
"@datalayer/jupyter-react": "^0.12.0",
"@datalayer/jupyter-react": "^0.15.0",
"@datalayer/primer-addons": "0.3.0",
"@jupyterlab/application": "^4.0.0",
"@jupyterlab/coreutils": "^6.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical/src/components/JupyterOutputComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const JupyterOutputComponent = (props: Props) => {
adapter={outputAdapter}
showEditor={false}
autoRun={autoRun}
sourceId={outputNodeUuid}
id={outputNodeUuid}
executeTrigger={executeTrigger}
lumino={false}
/>
Expand Down
2 changes: 1 addition & 1 deletion packages/lexical/src/examples/App2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const Tabs = () => {
<StyledNotebook>
<Box mb={3}>
<Notebook
uid={NOTEBOOK_UID}
id={NOTEBOOK_UID}
nbformat={notebookContent}
CellSidebar={CellSidebar}
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/lexical/src/nodes/JupyterOutputNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LexicalEditor, EditorConfig, DecoratorNode, LexicalNode, NodeKey, Sprea
import { UUID } from '@lumino/coreutils';
import { IOutput } from '@jupyterlab/nbformat';
import { OUTPUT_UUID_TO_CODE_UUID, CODE_UUID_TO_OUTPUT_KEY, CODE_UUID_TO_OUTPUT_UUID, OUTPUT_UUID_TO_OUTPUT_KEY } from "../plugins/JupyterPlugin";
import { OutputAdapter } from "@datalayer/jupyter-react";
import { OutputAdapter, newUuid } from "@datalayer/jupyter-react";
import JupyterOutputComponent from "../components/JupyterOutputComponent";

export type SerializedJupyterOutputNode = Spread<
Expand Down Expand Up @@ -52,7 +52,7 @@ export class JupyterOutputNode extends DecoratorNode<JSX.Element> {

/** @override */
static importJSON(serializedNode: SerializedJupyterOutputNode): JupyterOutputNode {
return $createJupyterOutputNode(serializedNode.source, new OutputAdapter(undefined, []), serializedNode.outputs, false, serializedNode.codeNodeUuid, serializedNode.outputNodeUuid);
return $createJupyterOutputNode(serializedNode.source, new OutputAdapter(newUuid(), undefined, []), serializedNode.outputs, false, serializedNode.codeNodeUuid, serializedNode.outputNodeUuid);
}

/** @override */
Expand Down
6 changes: 3 additions & 3 deletions packages/lexical/src/plugins/JupyterPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { $getNodeByKey, $createNodeSelection, $setSelection } from "lexical";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { $setBlocksType } from "@lexical/selection";
import { $insertNodeToNearestRoot } from '@lexical/utils';
import { OutputAdapter } from '@datalayer/jupyter-react';
import { OutputAdapter, newUuid } from '@datalayer/jupyter-react';
import { UUID } from '@lumino/coreutils';
import { IOutput } from '@jupyterlab/nbformat';
import { $createJupyterCodeNode, JupyterCodeNode, $isJupyterCodeNode } from "../nodes/JupyterCodeNode";
Expand Down Expand Up @@ -77,7 +77,7 @@ export const JupyterPlugin = () => {
return true;
}
}
const jupyterOutputNode = $createJupyterOutputNode(code, new OutputAdapter(undefined, []), [], true, codeNodeUuid, UUID.uuid4());
const jupyterOutputNode = $createJupyterOutputNode(code, new OutputAdapter(newUuid(), undefined, []), [], true, codeNodeUuid, UUID.uuid4());
$insertNodeToNearestRoot(jupyterOutputNode);
const nodeSelection = $createNodeSelection();
nodeSelection.add(parentNode.__key);
Expand Down Expand Up @@ -163,7 +163,7 @@ export const JupyterPlugin = () => {
} else {
selection.insertNodes([jupyterCodeNode]);
}
const outputAdapter = new OutputAdapter(undefined, outputs);
const outputAdapter = new OutputAdapter(newUuid(), undefined, outputs);
const jupyterOutputNode = $createJupyterOutputNode(code, outputAdapter, outputs || [], false, jupyterCodeNode.getCodeNodeUuid(), UUID.uuid4()) ;
outputAdapter.outputArea.model.changed.connect((outputModel, args) => {
editor.update(() => {
Expand Down
1 change: 0 additions & 1 deletion packages/react/jupyter_react/static/README.md

This file was deleted.

5 changes: 3 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@datalayer/jupyter-react",
"version": "0.14.0",
"version": "0.17.0",
"description": "Jupyter React - React.js components 100% compatible with Jupyter.",
"license": "MIT",
"main": "lib/index.js",
Expand Down Expand Up @@ -73,7 +73,7 @@
"@jupyter-widgets/output": "^6.0.0",
"@jupyter/collaboration-extension": "^1.0.0",
"@jupyter/web-components": "^0.15.3",
"@jupyter/ydoc": "^1.0.0",
"@jupyter/ydoc": "^2.0.1",
"@jupyterlab/application": "^4.0.0",
"@jupyterlab/application-extension": "^4.0.0",
"@jupyterlab/apputils": "^4.0.0",
Expand Down Expand Up @@ -146,6 +146,7 @@
"react-sparklines": "^1.7.0",
"rxjs": "^6.6.0",
"styled-components": "^5.3.10",
"ulid": "^2.3.0",
"usehooks-ts": "^2.9.1",
"utf-8-validate": "^6.0.3",
"wildcard-match": "^5.1.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const NotebookComponent = () => {
{/*
<Notebook
nbformat={nbformat}
uid="notebook-uid"
id="notebook-id"
cellSidebarMargin={60}
height="calc(100vh - 2.6rem)" // (Height - Toolbar Height).
CellSidebar={CellSidebarNew}
Expand Down
45 changes: 21 additions & 24 deletions packages/react/src/components/cell/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import { useState, useEffect } from 'react';
import { CodeCell, MarkdownCell } from '@jupyterlab/cells';
import { Box } from '@primer/react';
import CellAdapter from './CellAdapter';
import Lumino from '../lumino/Lumino';
import { useJupyter } from './../../jupyter/JupyterContext';
import useCellStore from './CellState';
import CellAdapter from './CellAdapter';
import useCellsStore from './CellState';
import { newUuid } from '../../utils';

export type ICellProps = {
Expand All @@ -37,49 +37,45 @@ export type ICellProps = {
};

export const Cell = (props: ICellProps) => {
const { type='code', source = '', autoStart, showToolbar=true } = props;
const { serverSettings, defaultKernel } = useJupyter();
const {
autoStart,
showToolbar=true,
source = '',
type='code',
} = props;
const { defaultKernel, serverSettings } = useJupyter();

const [id] = useState(props.id || newUuid());
const [adapter, setAdapter] = useState<CellAdapter>();
const cellStore = useCellStore();

const cellsStore = useCellsStore();

const handleCellInitEvents = (adapter: CellAdapter) => {
adapter.cell.model.contentChanged.connect(
(cellModel, changedArgs) => {
cellStore.setSource(id, cellModel.sharedModel.getSource());
cellsStore.setSource(id, cellModel.sharedModel.getSource());
}
);

if (adapter.cell instanceof CodeCell) {
adapter.cell.outputArea.outputLengthChanged?.connect(
(outputArea, outputsCount) => {
cellStore.setOutputsCount(id, outputsCount);
cellsStore.setOutputsCount(id, outputsCount);
}
);
}

adapter.sessionContext.initialize().then(() => {
if (!autoStart || !adapter.cell.model) {
return;
}

// Perform auto-start for code or markdown cells
if (adapter.cell instanceof CodeCell) {
CodeCell.execute(
adapter.cell,
adapter.sessionContext
);
}

if (adapter.cell instanceof MarkdownCell) {
adapter.cell.rendered = true;
if (autoStart && adapter.cell.model) {
// Perform auto-start for code or markdown cells.
adapter.execute();
}
});

adapter.sessionContext.kernelChanged.connect(() => {
void adapter.sessionContext.session?.kernel?.info.then(info => {
// Set that session/kernel is ready for this cell when the kernel is guaranteed to be connected
cellStore.setIsKernelSessionAvailable(id, true);
cellsStore.setKernelSessionAvailable(id, true);
})
});
}
Expand All @@ -88,14 +84,15 @@ export const Cell = (props: ICellProps) => {
if (id && defaultKernel && serverSettings) {
defaultKernel.ready.then(() => {
const adapter = new CellAdapter({
id,
type,
source,
serverSettings,
kernel: defaultKernel,
boxOptions: {showToolbar}
});
cellStore.setAdapter(id, adapter);
cellStore.setSource(id, source);
cellsStore.setAdapter(id, adapter);
cellsStore.setSource(id, source);
handleCellInitEvents(adapter);
setAdapter(adapter);

Expand Down
Loading

0 comments on commit f58506b

Please sign in to comment.