Skip to content

Commit 8b48cb7

Browse files
committed
Migrate datalayer specific components from jupyter-react to core
1 parent b92812b commit 8b48cb7

20 files changed

+711
-352
lines changed

CLAUDE.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# CLAUDE.md
2+
3+
Jupyter React UI - React components and utilities for building Jupyter-based applications.
4+
5+
## Architecture
6+
7+
**IMPORTANT**: Dependency direction is `@datalayer/core` depends on `@datalayer/jupyter-react`.
8+
- Core imports from jupyter-ui (NOT the other way around)
9+
- When migrating code, ensure jupyter-ui core is adapted so that it no longer depends on datalyer code.
10+
- Backward compatibility does not need to be preserved when migrating things from `@datalayer/jupyter-react` to `@datalayer/core`
11+
12+
## Development Commands
13+
14+
**Build**: `npm run build`
15+
**Test**: `npm run test`
16+
**Storybook**: `npm run storybook`
17+
**Docs**: `npm run build:docs`
18+
19+
## Key Components
20+
21+
- Jupyter components: Cell, Console, Notebook, Terminal, Viewer
22+
- Service providers: ServiceManagerProvider, utility functions for creating ServiceManagers
23+
- State management: Zustand stores for component state
24+
- JupyterLab integration: Support for extensions and themes
25+
26+
## Migration Notes
27+
28+
When migrating functionality:
29+
1. Core should import what it needs from jupyter-ui

examples/lexical/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ module.exports = {
5757
filename: '[name].[contenthash].jupyterReactLexicalExample.js',
5858
},
5959
resolve: {
60-
extensions: [ '.tsx', '.ts', 'jsx', '.js' ],
60+
extensions: [ '.tsx', '.ts', '.jsx', '.js', '.css' ],
6161
alias: {
6262
"stream": "stream-browserify",
6363
},

packages/react/src/components/notebook/Notebook.tsx

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
2020
import { jupyterReactStore, KernelTransfer, OnSessionConnection, } from '../../state';
2121
import { newUuid, sleep } from '../../utils';
2222
import { asObservable, Lumino } from '../lumino';
23-
import { COLLABORATION_ROOM_URL_PATH, requestDatalayerollaborationSessionId, ICollaborationProvider, Kernel, Lite, requestJupyterCollaborationSession, useJupyter } from './../../jupyter';
23+
import { COLLABORATION_ROOM_URL_PATH, ICollaborationProvider, Kernel, Lite, requestJupyterCollaborationSession, useJupyter } from './../../jupyter';
2424
import { CellMetadataEditor } from './cell/metadata';
2525
import { NotebookAdapter } from './NotebookAdapter';
2626
import { useNotebookStore } from './NotebookState';
@@ -303,27 +303,9 @@ export const Notebook = (props: INotebookProps) => {
303303
},
304304
awareness,
305305
});
306-
} else if (collaborative == 'datalayer') {
307-
const { runUrl, token } = jupyterReactStore.getState().datalayerConfig ?? {};
308-
const documentName = id;
309-
const documentURL = URLExt.join(runUrl!, `/api/spacer/v1/documents`);
310-
const sessionId = await requestDatalayerollaborationSessionId({
311-
url: URLExt.join(documentURL, documentName),
312-
token,
313-
});
314-
provider = new YWebsocketProvider(
315-
documentURL.replace(/^http/, 'ws'),
316-
documentName,
317-
ydoc,
318-
{
319-
disableBc: true,
320-
params: {
321-
sessionId,
322-
token: token!,
323-
},
324-
awareness,
325-
}
326-
);
306+
} else {
307+
// Other collaboration types can be handled by extensions
308+
console.warn(`Unsupported collaboration type: ${collaborative}`);
327309
}
328310
if (provider) {
329311
provider.on('sync', onSync);

packages/react/src/components/notebook/Notebook2Base.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { Box } from '@primer/react';
3232
import { Banner } from '@primer/react/experimental';
3333
import { EditorView } from 'codemirror';
3434
import { WebsocketProvider } from 'y-websocket';
35-
import { COLLABORATION_ROOM_URL_PATH, ICollaborationServer, requestDatalayerollaborationSessionId, requestJupyterCollaborationSession, WIDGET_MIMETYPE, WidgetLabRenderer, WidgetManager } from '../../jupyter';
35+
import { COLLABORATION_ROOM_URL_PATH, ICollaborationServer, requestJupyterCollaborationSession, WIDGET_MIMETYPE, WidgetLabRenderer, WidgetManager } from '../../jupyter';
3636
import type { OnSessionConnection } from '../../state';
3737
import { newUuid, remoteUserCursors } from '../../utils';
3838
import { Lumino } from '../lumino';
@@ -654,16 +654,9 @@ export function useNotebookModel(options: IOptions): NotebookModel | null {
654654
if (serverSettings.token) {
655655
params.token = serverSettings.token;
656656
}
657-
} else if (collaborationServer.type === 'datalayer') {
658-
const { baseURL, documentName: documentName_, token } = collaborationServer;
659-
documentName = documentName_; // Set non local variable.
660-
const serverURL = URLExt.join(baseURL, '/api/spacer/v1/documents');
661-
documentURL = serverURL.replace(/^http/, 'ws');
662-
params.sessionId = await requestDatalayerollaborationSessionId({
663-
url: URLExt.join(serverURL, documentName),
664-
token,
665-
});
666-
params.token = token;
657+
} else {
658+
// Other collaboration types can be handled by extensions
659+
console.warn(`Unsupported collaboration type: ${collaborationServer.type}`);
667660
}
668661

669662
if (params.sessionId) {

packages/react/src/examples/NotebookMutationsKernel.tsx

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import {
1313
createLiteServiceManager, createServerSettings, setJupyterServerUrl, getJupyterServerUrl,
1414
getJupyterServerToken, ServiceManagerLess, loadJupyterConfig, DEFAULT_JUPYTER_SERVER_URL,
1515
} from '../jupyter';
16-
import { useJupyterReactStore, OnSessionConnection } from '../state';
16+
import { OnSessionConnection } from '../state';
1717
import { useNotebookStore, Notebook, SpinnerCentered } from './../components';
1818
import { JupyterReactTheme } from '../theme';
19-
import { createDatalayerServiceManager } from './../providers';
2019

2120
import nbformatExample from './notebooks/NotebookExample1.ipynb.json';
2221

@@ -32,11 +31,10 @@ const NotebookMutationsKernel = () => {
3231
const [readonly, setReadonly] = useState(true);
3332
const [serverless, setServerless] = useState(true);
3433
const [kernelIndex, setKernelIndex] = useState(-1);
35-
const [waiting, setWaiting] = useState(false);
34+
const [waiting] = useState(false);
3635
const [lite, setLite] = useState(false);
3736
const [serviceManager, setServiceManager] = useState<ServiceManager.IManager>(SERVICE_MANAGER_LESS);
3837
const [sessions, setSessions] = useState<Array<Session.ISessionConnection>>([])
39-
const { datalayerConfig } = useJupyterReactStore();
4038
const notebookStore = useNotebookStore();
4139
const notebook = notebookStore.selectNotebook(NOTEBOOK_ID);
4240
const onSessionConnection: OnSessionConnection = (session: Session.ISessionConnection | undefined) => {
@@ -83,40 +81,6 @@ const NotebookMutationsKernel = () => {
8381
setServiceManager(serviceManager);
8482
break;
8583
}
86-
case 3: {
87-
// setWaiting(true);
88-
setLite(false);
89-
createDatalayerServiceManager(
90-
datalayerConfig?.cpuEnvironment || 'python-simple-env',
91-
datalayerConfig?.credits || 1,
92-
).then((serviceManager) => {
93-
(serviceManager as any)['__NAME__'] = 'DatalayerCPUServiceManager';
94-
setServiceManager(serviceManager);
95-
setServerless(false);
96-
setReadonly(false);
97-
setKernelIndex(0);
98-
setNbformat(notebook?.adapter?.notebookPanel?.content.model?.toJSON() as INotebookContent);
99-
// setWaiting(false);
100-
});
101-
break;
102-
}
103-
case 4: {
104-
setWaiting(true);
105-
setLite(false);
106-
createDatalayerServiceManager(
107-
datalayerConfig?.gpuEnvironment || 'pytorch-cuda-env',
108-
datalayerConfig?.credits || 1,
109-
).then((serviceManager) => {
110-
setKernelIndex(0);
111-
(serviceManager as any)['__NAME__'] = 'DatalayerGPUServiceManager';
112-
setServiceManager(serviceManager);
113-
setNbformat(notebook?.adapter?.notebookPanel?.content.model?.toJSON() as INotebookContent);
114-
setServerless(false);
115-
setReadonly(false);
116-
setWaiting(false);
117-
});
118-
break;
119-
}
12084
}
12185
}
12286
return (

packages/react/src/examples/NotebookMutationsServiceManager.tsx

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ import {
1414
getJupyterServerToken, ServiceManagerLess, loadJupyterConfig,
1515
DEFAULT_JUPYTER_SERVER_URL, Lite,
1616
} from '../jupyter';
17-
import { useJupyterReactStore, OnSessionConnection } from '../state';
17+
import { OnSessionConnection } from '../state';
1818
import { useNotebookStore, Notebook, SpinnerCentered } from './../components';
1919
import { JupyterReactTheme } from '../theme';
20-
import { createDatalayerServiceManager } from './../providers';
2120

2221
import nbformatExample from './notebooks/NotebookExample1.ipynb.json';
2322

@@ -34,11 +33,10 @@ const NotebookMutationsServiceManager = () => {
3433
const [serverless, setServerless] = useState(true);
3534
const [startDefaultKernel, setStartDefaultKernel] = useState(false);
3635
const [kernelIndex, setKernelIndex] = useState(-1);
37-
const [waiting, setWaiting] = useState(false);
36+
const [waiting] = useState(false);
3837
const [lite, setLite] = useState<Lite>(false);
3938
const [serviceManager, setServiceManager] = useState<ServiceManager.IManager>(SERVICE_MANAGER_LESS);
4039
const [sessions, setSessions] = useState<Array<Session.ISessionConnection>>([])
41-
const { datalayerConfig } = useJupyterReactStore();
4240
const notebookStore = useNotebookStore();
4341
const notebook = notebookStore.selectNotebook(NOTEBOOK_ID);
4442
const onSessionConnection: OnSessionConnection = (session: Session.ISessionConnection | undefined) => {
@@ -88,41 +86,6 @@ const NotebookMutationsServiceManager = () => {
8886
setServiceManager(serviceManager);
8987
break;
9088
}
91-
case 3: {
92-
createDatalayerServiceManager(
93-
datalayerConfig?.cpuEnvironment || 'python-simple-env',
94-
datalayerConfig?.credits || 1,
95-
).then((serviceManager) => {
96-
setLite(false);
97-
setServerless(false);
98-
setReadonly(false);
99-
setStartDefaultKernel(false);
100-
setKernelIndex(0);
101-
setNbformat(notebook?.adapter?.notebookPanel?.content.model?.toJSON() as INotebookContent);
102-
(serviceManager as any)['__NAME__'] = 'DatalayerCPUServiceManager';
103-
setServiceManager(serviceManager);
104-
// setWaiting(false);
105-
});
106-
break;
107-
}
108-
case 4: {
109-
setWaiting(true);
110-
setLite(false);
111-
createDatalayerServiceManager(
112-
datalayerConfig?.gpuEnvironment || 'pytorch-cuda-env',
113-
datalayerConfig?.credits || 1,
114-
).then((serviceManager) => {
115-
setNbformat(notebook?.adapter?.notebookPanel?.content.model?.toJSON() as INotebookContent);
116-
setServerless(false);
117-
setReadonly(false);
118-
setStartDefaultKernel(false);
119-
setWaiting(false);
120-
setKernelIndex(0);
121-
(serviceManager as any)['__NAME__'] = 'DatalayerGPUServiceManager';
122-
setServiceManager(serviceManager);
123-
});
124-
break;
125-
}
12689
}
12790
}
12891
return (

0 commit comments

Comments
 (0)