Skip to content

Commit e362d8d

Browse files
committed
More collaborative work
1 parent 11f0b71 commit e362d8d

34 files changed

+1234
-910
lines changed

CLAUDE.md

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
## Quick Overview
44

5-
React component library for Jupyter notebooks. Monorepo with 4 packages managed by Lerna.
5+
React component library for Jupyter notebooks. Monorepo with 5 packages managed by Lerna.
66

77
## Core Packages
88

9-
- `@datalayer/jupyter-react` - React components for notebooks, cells, terminals
9+
- `@datalayer/jupyter-react` - Generic React components for notebooks, cells, terminals
1010
- `@datalayer/jupyter-lexical` - Rich text editor integration
1111
- `@datalayer/jupyter-docusaurus-plugin` - Docusaurus plugin
1212
- `datalayer-jupyter-vscode` - VS Code extension
@@ -50,7 +50,7 @@ npm run start-local:webpack # Start only webpack with local config
5050
- `packages/react/public/index-local.html` - Local server config
5151
- `dev/config/jupyter_server_config.py` - Jupyter server settings
5252

53-
## Recent Fixes (2024-2025)
53+
## Recent Changes (2024-2025)
5454

5555
- MDX comments: `{/_``{/** **/}` in 13 files
5656
- Node requirement: 18 → 20+
@@ -61,6 +61,14 @@ npm run start-local:webpack # Start only webpack with local config
6161
- Storybook CI: Added wait-on and --url for test reliability
6262
- Terminal component: Fixed BoxPanel initialization issue
6363
- **Collaboration fix**: Updated WebSocket room path from `api/collaboration/document` to `api/collaboration/room` for jupyter-collaboration v4.x compatibility
64+
- **Architecture refactor**: Cleaned up to maintain generic, reusable components only
65+
- **Provider system**: Implemented pluggable collaboration provider architecture
66+
- **Clean API**: Removed deprecated `collaborative` prop in favor of `collaborationProvider`
67+
- **Notebook2 support**: Added collaboration provider support to Notebook2 component
68+
- **Simplified provider API**: JupyterCollaborationProvider no longer requires `type` in config
69+
- **Path flexibility**: Notebook path prop takes precedence over provider config
70+
- **Factory pattern removed**: Simplified collaboration API - components now only accept provider instances, not configurations
71+
- **Direct instantiation**: Providers are now instantiated directly by users (e.g., `new JupyterCollaborationProvider()`)
6472

6573
## Common Issues
6674

@@ -107,11 +115,47 @@ const ENTRY = './src/examples/NotebookCollaborative'; // Change this line
107115

108116
Then restart webpack.
109117

118+
## Architecture
119+
120+
### Package Structure
121+
122+
- `@datalayer/jupyter-react` - Generic, reusable Jupyter components
123+
- Designed to be extended by external packages for platform-specific implementations
124+
125+
### Collaboration Provider System
126+
127+
- Interface: `ICollaborationProvider` in `packages/react/src/jupyter/collaboration/`
128+
- Built-in providers:
129+
- `JupyterCollaborationProvider` - WebSocket-based with Y.js for Jupyter servers
130+
- `NoOpCollaborationProvider` - No-op provider for non-collaborative mode
131+
- Direct instantiation pattern (factory pattern removed for simplicity)
132+
- Usage:
133+
134+
```tsx
135+
// Generic Jupyter collaboration
136+
const provider = new JupyterCollaborationProvider();
137+
<Notebook collaborationProvider={provider} path="notebook.ipynb" />;
138+
139+
// Or with configuration
140+
const provider = new JupyterCollaborationProvider({
141+
path: 'my-notebook.ipynb',
142+
serverSettings: myServerSettings,
143+
});
144+
<Notebook collaborationProvider={provider} />;
145+
```
146+
147+
### Key Components
148+
149+
- `Notebook` - Base notebook component (accepts `collaborationProvider` prop)
150+
- `Notebook2` - Alternative notebook implementation with collaboration support
151+
- Extensible through `ICollaborationProvider` interface
152+
110153
## AI Assistant Notes
111154

112155
- Always use npm, not yarn
113156
- Prefer editing over creating files
114-
- Run lint/type checks before committing
157+
- Run lint/format/type-check checks after finishing a round of changes
115158
- Comment out old code instead of deleting when making changes
116-
117-
- Use the playwright MCP server when you need to actually see how the frendered pages look
159+
- Use the playwright MCP server when you need to actually see how the rendered pages look
160+
- Follow composition over inheritance pattern
161+
- Maintain clean separation between generic and platform-specific code

README.md

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ Jupyter UI is a set of [React.js](https://react.dev) components that allow a fro
2020

2121
## 📦 Packages
2222

23-
| Package | Version | Description |
24-
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
25-
| [@datalayer/jupyter-react](./packages/react) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-react)](https://www.npmjs.com/package/@datalayer/jupyter-react) | Core React components for Jupyter integration |
26-
| [@datalayer/jupyter-lexical](./packages/lexical) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-lexical)](https://www.npmjs.com/package/@datalayer/jupyter-lexical) | Rich text editor with Lexical framework |
27-
| [@datalayer/jupyter-docusaurus-plugin](./packages/docusaurus-plugin) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-docusaurus-plugin)](https://www.npmjs.com/package/@datalayer/jupyter-docusaurus-plugin) | Docusaurus plugin for Jupyter notebooks |
28-
| [datalayer-jupyter-vscode](./packages/vscode) | [![marketplace](https://img.shields.io/visual-studio-marketplace/v/datalayer.datalayer-jupyter-vscode)](https://marketplace.visualstudio.com/items?itemName=datalayer.datalayer-jupyter-vscode) | VS Code extension |
23+
| Package | Version | Description |
24+
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
25+
| [@datalayer/jupyter-react](./packages/react) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-react)](https://www.npmjs.com/package/@datalayer/jupyter-react) | Generic React components for Jupyter |
26+
| [@datalayer/jupyter-lexical](./packages/lexical) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-lexical)](https://www.npmjs.com/package/@datalayer/jupyter-lexical) | Rich text editor with Lexical framework |
27+
| [@datalayer/jupyter-docusaurus-plugin](./packages/docusaurus-plugin) | [![npm](https://img.shields.io/npm/v/@datalayer/jupyter-docusaurus-plugin)](https://www.npmjs.com/package/@datalayer/jupyter-docusaurus-plugin) | Docusaurus plugin for Jupyter notebooks |
28+
| [datalayer-jupyter-vscode](./packages/vscode) | [![marketplace](https://img.shields.io/visual-studio-marketplace/v/datalayer.datalayer-jupyter-vscode)](https://marketplace.visualstudio.com/items?itemName=datalayer.datalayer-jupyter-vscode) | VS Code extension |
2929

3030
## 🚀 Quick Start
3131

@@ -53,6 +53,54 @@ function App() {
5353
}
5454
```
5555

56+
### Collaborative Editing
57+
58+
Jupyter UI supports real-time collaboration through a pluggable provider system:
59+
60+
```tsx
61+
import {
62+
Notebook,
63+
JupyterCollaborationProvider,
64+
} from '@datalayer/jupyter-react';
65+
66+
function CollaborativeNotebook() {
67+
const collaborationProvider = new JupyterCollaborationProvider();
68+
69+
return (
70+
<Notebook
71+
path="notebook.ipynb"
72+
collaborationProvider={collaborationProvider}
73+
/>
74+
);
75+
}
76+
```
77+
78+
#### Creating Custom Collaboration Providers
79+
80+
You can create your own collaboration provider by extending `CollaborationProviderBase`:
81+
82+
```tsx
83+
import { CollaborationProviderBase } from '@datalayer/jupyter-react';
84+
85+
class MyCustomProvider extends CollaborationProviderBase {
86+
constructor(config) {
87+
super('my-provider-type');
88+
// Initialize your provider
89+
}
90+
91+
async connect(sharedModel, documentId, options) {
92+
// Implement your connection logic
93+
// Set up WebSocket, authenticate, etc.
94+
}
95+
}
96+
97+
// Use it with any Notebook component
98+
const provider = new MyCustomProvider({
99+
/* config */
100+
});
101+
<Notebook collaborationProvider={provider} path="notebook.ipynb" />;
102+
```
103+
56104
### Development Setup
57105

58106
As a developer start with the [setup of your environment](https://jupyter-ui.datalayer.tech/docs/develop/setup) and try [one of the examples](https://jupyter-ui.datalayer.tech/docs/category/examples). We have [documentation](https://jupyter-ui.datalayer.tech) for more details.
@@ -100,17 +148,26 @@ We host a Storybook on ✨ https://jupyter-ui-storybook.datalayer.tech that show
100148
### Advanced Features
101149

102150
- **🔌 IPyWidgets Support** - Full support for interactive widgets
103-
- **👥 Collaborative Editing** - Real-time collaboration using Y.js
151+
- **👥 Collaborative Editing** - Pluggable provider system supporting:
152+
- Jupyter collaboration (WebSocket-based with Y.js)
153+
- Custom providers via `ICollaborationProvider` interface
104154
- **🎨 Theming** - JupyterLab theme support with dark/light modes
105155
- **🔧 Extensible** - Plugin system for custom functionality
106156
- **🚀 Performance** - Virtual scrolling, lazy loading, and optimizations
107157
- **🔒 Security** - Token authentication, CORS, XSS protection
108158

159+
### Architecture Highlights
160+
161+
- **🏗️ Clean Architecture** - Modular, composable components with clear interfaces
162+
- **🔄 Composition Pattern** - Components compose rather than inherit for maximum flexibility
163+
- **🔌 Provider System** - Pluggable collaboration providers for different backends
164+
- **📦 One-way Dependencies** - Core depends on jupyter-react, not vice versa
165+
109166
<div align="center" style="text-align: center">
110167
<img alt="Jupyter UI Gallery" src="https://datalayer-jupyter-examples.s3.amazonaws.com/jupyter-react-gallery.gif" />
111168
</div>
112169

113-
The above image shows a gallery of the available React.js components ready to be used in you custom application. These open source components are used to build [Datalayer](https://datalayer.io), a collaborative platform for data analysis.
170+
The above image shows a gallery of the available React.js components ready to be used in your custom application.
114171

115172
## Why?
116173

@@ -151,7 +208,7 @@ We maintain a plugin for [Docusaurus](https://docusaurus.io) in the [docusaurus-
151208

152209
## 📋 Requirements
153210

154-
- **Node.js** >= 18.0.0
211+
- **Node.js** >= 20.0.0
155212
- **npm** >= 8.0.0
156213
- **Python** >= 3.8 (for Jupyter server)
157214
- **JupyterLab** >= 4.0.0

SUMMARY.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
Jupyter UI is an open-source React.js component library that bridges the gap between the Jupyter ecosystem and modern web development frameworks. It provides React components that are 100% compatible with Jupyter, allowing developers to build custom data products without being constrained by the traditional JupyterLab interface.
66

7+
## Recent Updates (January 2025)
8+
9+
### Collaboration Provider System
10+
11+
- Implemented plugin-based architecture for extensible collaboration
12+
- Built-in providers: `JupyterCollaborationProvider`, `NoOpCollaborationProvider`
13+
- Direct instantiation pattern for simplicity
14+
- Added collaboration support to `Notebook2` component
15+
716
### Core Problem Solved
817

918
Traditional JupyterLab uses the Lumino widget toolkit, an imperative UI framework that isn't compatible with modern declarative frameworks like React. This forces developers to either:
@@ -23,7 +32,7 @@ The project uses Lerna to manage a monorepo structure with the following organiz
2332
```
2433
jupyter-ui/
2534
├── packages/ # Core library packages
26-
│ ├── react/ # Main React component library
35+
│ ├── react/ # Main React component library (generic)
2736
│ ├── lexical/ # Rich text editor integration
2837
│ ├── docusaurus-plugin/ # Docusaurus integration
2938
│ └── vscode/ # VS Code extension
@@ -60,12 +69,15 @@ The main package providing React components for Jupyter functionality.
6069
- Provides React context providers for state management
6170
- Supports both local and remote Jupyter servers
6271
- Implements WebSocket communication for real-time updates
72+
- Plugin-based collaboration provider system
73+
- Extensible without platform-specific code
6374

6475
**Key Files:**
6576

6677
- `src/jupyter/JupyterContext.tsx` - Core context provider
67-
- `src/components/notebook/Notebook.tsx` - Main notebook component
78+
- `src/components/notebook/Notebook.tsx` - Main notebook component (accepts collaborationProvider)
6879
- `src/providers/ServiceManagerProvider.tsx` - Service management
80+
- `src/jupyter/collaboration/ICollaborationProvider.ts` - Provider interface
6981

7082
### 2. @datalayer/jupyter-lexical (v1.0.3)
7183

@@ -454,7 +466,6 @@ The repository includes several example implementations:
454466

455467
## Community & Ecosystem
456468

457-
- Active development by Datalayer, Inc.
458469
- MIT licensed
459470
- Integration with major React frameworks
460471
- Storybook for component documentation

dev/notebooks/collaboration.ipynb

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,27 @@
1010
},
1111
{
1212
"cell_type": "code",
13-
"execution_count": null,
14-
"metadata": {},
15-
"outputs": [],
13+
"execution_count": 1,
14+
"metadata": {
15+
"execution": {
16+
"iopub.execute_input": "2025-08-18T03:45:22.030426Z",
17+
"iopub.status.busy": "2025-08-18T03:45:22.030160Z",
18+
"iopub.status.idle": "2025-08-18T03:45:22.036464Z",
19+
"shell.execute_reply": "2025-08-18T03:45:22.036172Z",
20+
"shell.execute_reply.started": "2025-08-18T03:45:22.030412Z"
21+
}
22+
},
23+
"outputs": [
24+
{
25+
"name": "stdout",
26+
"output_type": "stream",
27+
"text": [
28+
"Hello from collaboration notebook!\n"
29+
]
30+
}
31+
],
1632
"source": [
17-
"print('Hello from collaboration notebook!')"
33+
"print('Hello from collaboration notebook!') hola"
1834
]
1935
},
2036
{
@@ -24,10 +40,17 @@
2440
"outputs": [],
2541
"source": [
2642
"# Test collaboration by editing this cell\n",
27-
"x = 10a\n",
43+
"x = 10aas test hello\n",
2844
"y = 20asd\n",
29-
"print(f'x + y = {x + y}') asass"
45+
"print(f'x + y = {x + y}') asass boo oom"
3046
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"execution_count": null,
51+
"metadata": {},
52+
"outputs": [],
53+
"source": []
3154
}
3255
],
3356
"metadata": {
@@ -46,7 +69,7 @@
4669
"name": "python",
4770
"nbconvert_exporter": "python",
4871
"pygments_lexer": "ipython3",
49-
"version": "3.13.5"
72+
"version": "3.12.7"
5073
}
5174
},
5275
"nbformat": 4,

packages/react/src/components/codemirror/CodeMirrorDatalayerEditor.tsx renamed to packages/react/src/components/codemirror/CodeMirrorEditor.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import useOutputsStore from '../output/OutputState';
1616
import codeMirrorTheme from './CodeMirrorTheme';
1717
import CodeMirrorOutputToolbar from './CodeMirrorOutputToolbar';
1818

19-
export const CodeMirrorDatalayerEditor = (props: {
19+
export const CodeMirrorEditor = (props: {
2020
code: string;
2121
codePre?: string;
2222
outputAdapter: OutputAdapter;
@@ -147,4 +147,7 @@ export const CodeMirrorDatalayerEditor = (props: {
147147
);
148148
};
149149

150-
export default CodeMirrorDatalayerEditor;
150+
// Deprecated: Use CodeMirrorEditor instead of CodeMirrorDatalayerEditor
151+
export const CodeMirrorDatalayerEditor = CodeMirrorEditor;
152+
153+
export default CodeMirrorEditor;

packages/react/src/components/codemirror/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* MIT License
55
*/
66

7-
export * from './CodeMirrorDatalayerEditor';
7+
export * from './CodeMirrorEditor';
8+
// Deprecated: CodeMirrorDatalayerEditor is now CodeMirrorEditor
9+
export { CodeMirrorDatalayerEditor } from './CodeMirrorEditor';
810
export * from './CodeMirrorOutputToolbar';
911
export * from './CodeMirrorTheme';

packages/react/src/components/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
export * from './button';
88
export * from './cell';
9-
// export * from './codemirror';
9+
export * from './codemirror';
1010
export * from './commands';
1111
export * from './console';
1212
export * from './dialog';

0 commit comments

Comments
 (0)