Skip to content

Update to JupyterLab 4 #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,33 @@

<!-- <START NEW CHANGELOG ENTRY> -->

## 0.3.0

### Features

- Support for JupyterLab 4.x [#39](https://github.com/jupyterlab-contrib/jupyterlab-plugin-graph/issues/39)

### Breaking Changes

- Minimum JupyterLab version is now 4.0 (previously 2.0)

### Maintenance and upkeep improvements

- Update all dependencies to JupyterLab 4.x compatible versions
- Migrate from private `_pluginMap` API to hybrid public/private approach
- Fix TypeScript compilation issues with newer versions
- Update React types to v18
- Replace `jlpm` with `yarn` in build scripts
- Add proper TypeScript lib configuration for modern JavaScript features

### Developer improvements

- Add `skipLibCheck` to TypeScript configuration for better compatibility
- Fix ESLint/Prettier formatting issues
- Improve plugin metadata extraction with fallback mechanism

<!-- <END NEW CHANGELOG ENTRY> -->

## 0.2.1

([Full Changelog](https://github.com/jupyterlab-contrib/jupyterlab-plugin-graph/compare/0.2.0...0023aa04765b20cccd4b23787c23d047081781e0))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ JupyterLab extension to show an interactive dependency graph of all the installe

## Requirements

- JupyterLab >= 2.0
- JupyterLab >= 4.0

## Install

Expand Down
56 changes: 30 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jupyterlab-plugin-graph",
"version": "0.2.1",
"version": "0.3.0",
"description": "JupyterLab extension to show an interactive dependency graph of the installed plugins",
"keywords": [
"jupyter",
Expand All @@ -25,50 +25,54 @@
"url": "https://github.com/jupyterlab-contrib/jupyterlab-plugin-graph.git"
},
"scripts": {
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
"build": "yarn run build:lib && yarn run build:labextension:dev",
"build:labextension": "jupyter labextension build .",
"build:labextension:dev": "jupyter labextension build --development True .",
"build:lib": "tsc",
"build:prod": "jlpm run build:lib && jlpm run build:labextension",
"clean": "jlpm run clean:lib",
"clean:all": "jlpm run clean:lib && jlpm run clean:labextension",
"build:prod": "yarn run build:lib && yarn run build:labextension",
"clean": "yarn run clean:lib",
"clean:all": "yarn run clean:lib && yarn run clean:labextension",
"clean:labextension": "rimraf jupyterlab_plugin_graph/labextension",
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
"eslint": "eslint . --ext .ts,.tsx --fix",
"eslint:check": "eslint . --ext .ts,.tsx",
"install:extension": "jupyter labextension develop --overwrite .",
"prepare": "jlpm run clean && jlpm run build:prod",
"prepare": "yarn run clean && yarn run build:prod",
"prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
"prettier:check": "prettier --list-different \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
"watch": "run-p watch:src watch:labextension",
"watch:labextension": "jupyter labextension watch .",
"watch:src": "tsc -w"
},
"dependencies": {
"@jupyterlab/application": "^3.0.0",
"@jupyterlab/apputils": "^3.0.0",
"@jupyterlab/ui-components": "^3.0.0",
"@lumino/signaling": "^1.4.3",
"@lumino/widgets": "^1.14.0",
"@jupyterlab/application": "^4.0.0",
"@jupyterlab/apputils": "^4.0.0",
"@jupyterlab/ui-components": "^4.0.0",
"@lumino/signaling": "^2.1.2",
"@lumino/widgets": "^2.3.0",
"cytoscape": "^3.14.0",
"react": "^17.0.1",
"react-dom": "^17.0.1"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@jupyterlab/builder": "^3.0.0",
"@jupyterlab/builder": "^4.0.0",
"@types/cytoscape": "^3.8.8",
"@types/react": "~17.0.22",
"@types/react-dom": "~17.0.9",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"@types/react": "~18.0.0",
"@types/react-dom": "~18.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.25.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.1",
"rimraf": "^3.0.2",
"typescript": "~4.2.0"
"prettier": "^3.0.0",
"rimraf": "^5.0.0",
"typescript": "~5.0.0"
},
"resolutions": {
"@types/react": "~18.0.0",
"@types/react-dom": "~18.0.0"
},
"sideEffects": [
"style/*.css"
Expand All @@ -80,8 +84,8 @@
"jupyter-releaser": {
"hooks": {
"before-build-npm": [
"python -m pip install jupyterlab~=3.1",
"jlpm"
"python -m pip install jupyterlab~=4.0",
"yarn"
]
}
},
Expand Down
46 changes: 45 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,50 @@ import { Model } from './model';

import { GraphContainer } from './widget';

/**
* Create a plugins map using the public API
*/
function createPluginsMap(app: JupyterFrontEnd): any {
const plugins: any = {};

// Get all plugin IDs
const pluginIds = app.listPlugins();

// For each plugin, create a minimal structure
// Note: We can't access the full plugin metadata through public APIs,
// so we'll access the private _pluginMap as a fallback
for (const id of pluginIds) {
plugins[id] = {
id,
description: app.getPluginDescription(id),
activated: app.isPluginActivated(id),
// We'll need to access the private plugin map to get requires/optional/provides
requires: [],
optional: [],
provides: null,
};
}

// Access the private plugin map for full metadata
// This is a temporary workaround until JupyterLab provides a public API
try {
const privatePluginMap = (app as any)._pluginMap;
if (privatePluginMap) {
for (const id of pluginIds) {
if (privatePluginMap[id]) {
plugins[id].requires = privatePluginMap[id].requires || [];
plugins[id].optional = privatePluginMap[id].optional || [];
plugins[id].provides = privatePluginMap[id].provides || null;
}
}
}
} catch (error) {
console.warn('Could not access plugin metadata:', error);
}

return plugins;
}

/**
* Initialization data for the jupyterlab-plugin-graph extension.
*/
Expand All @@ -21,7 +65,7 @@ const extension: JupyterFrontEndPlugin<void> = {
activate: (app: JupyterFrontEnd, palette: ICommandPalette | null) => {
const { commands, shell } = app;
app.restored.then(() => {
const plugins = app['_pluginMap'];
const plugins = createPluginsMap(app);
const model = new Model({ plugins });

const command = 'jupyterlab-plugin-graph:open';
Expand Down
12 changes: 6 additions & 6 deletions src/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class Graph extends Widget {
width: 'label',
shape: 'rectangle',
content: 'data(name)',
'padding-bottom': '10px',
padding: '10px',
'text-valign': 'center',
'background-color': '#81bc00',
'background-opacity': 0.4,
Expand Down Expand Up @@ -187,7 +187,7 @@ const FilterComponent = (props: { model: Model }): JSX.Element => {
const [value, setValue] = useState(model.filter);

const handleFilterChange = (
event: React.ChangeEvent<HTMLInputElement>
event: React.ChangeEvent<HTMLInputElement>,
): void => {
const filter = event.target.value;
setValue(filter);
Expand Down Expand Up @@ -226,7 +226,7 @@ export class GraphContainer extends MainAreaWidget<Graph> {
}}
/>
Requires
</label>
</label>,
);
this.toolbar.addItem('requires', requires);

Expand All @@ -242,7 +242,7 @@ export class GraphContainer extends MainAreaWidget<Graph> {
}}
/>
Optional
</label>
</label>,
);
this.toolbar.addItem('optional', optional);

Expand All @@ -253,7 +253,7 @@ export class GraphContainer extends MainAreaWidget<Graph> {
{(): JSX.Element => (
<div style={{ marginRight: '5px' }}>{this.content.V} plugins</div>
)}
</UseSignal>
</UseSignal>,
);
this.toolbar.addItem('nodes', nodes);

Expand All @@ -262,7 +262,7 @@ export class GraphContainer extends MainAreaWidget<Graph> {
{(): JSX.Element => (
<div style={{ marginRight: '5px' }}>{this.content.E} connections</div>
)}
</UseSignal>
</UseSignal>,
);
this.toolbar.addItem('edges', edges);
}
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"esModuleInterop": true,
"incremental": true,
"jsx": "react",
"lib": ["es2018", "dom"],
"module": "esnext",
"moduleResolution": "node",
"noEmitOnError": true,
Expand All @@ -15,9 +16,10 @@
"resolveJsonModule": true,
"outDir": "lib",
"rootDir": "src",
"skipLibCheck": true,
"strict": true,
"strictNullChecks": false,
"target": "es2017",
"target": "es2018",
"types": []
},
"include": ["src/*"]
Expand Down
Loading
Loading