Cycle detected - nb:tracker / nb:widget-factory / rendermime:plugin

Hi, I’m trying to enhance the mathjax3-extension under jupyter-renderers so one can call mathjax menu options via the jupyterlab context menu. I’m struggling with import cycle and I’m not sure how to deal with it (typescript/javascript isn’t my expertise). I’m using the following code (simplified):

import { JupyterFrontEndPlugin, JupyterFrontEnd } from '@jupyterlab/application';

import { ILatexTypesetter } from '@jupyterlab/rendermime';

import { INotebookTracker } from '@jupyterlab/notebook';

export class MathJax3Typesetter implements ILatexTypesetter {
  constructor(app: JupyterFrontEnd, tracker: INotebookTracker ) {
    this._mathDocument = null; // ...

    const mj1: string = 'mathjax:zoom1';

    app.commands.addCommand(mj1, {
      execute: (args: any) => {
        console.log('menu item pressed');
        //const currentWidget = tracker.currentWidget;
      },
      label: 'MathJax Menu'
    });
  
    app.contextMenu.addItem({
      type: 'separator',
      selector: '.jp-Notebook .jp-Cell',
      rank: 12
    });
  
     app.contextMenu.addItem({
      command: mj1,
      selector: '.MathJax',
      rank: 13
     });

  }

  typeset(node: HTMLElement): void {
    // ...
  }

  private _mathDocument: ReturnType<any>; // mathjax.document
  
}

const mathJax3Plugin: JupyterFrontEndPlugin<ILatexTypesetter> = {
  id: '@jupyterlab/mathjax3-extension:plugin',
  requires: [INotebookTracker],
  provides: ILatexTypesetter,
  activate: (app: JupyterFrontEnd, tracker: INotebookTracker) => new MathJax3Typesetter(app, tracker),
  autoStart: true,
};

export default mathJax3Plugin;

The plan is to use a tracker to access the underlying widget containing the mathjax element then hopefully call mathjax commands for zooming/copying latex etc via the jupyterlab menu.

What’s happening is once I introduce the INotebookTracker into my plugin’s activate property I get a cycle detection error when loading the notebook service:

Error Registering Plugins
Cycle detected: @jupyterlab/mathjax3-extension:plugin -> @jupyterlab/notebook-extension:tracker -> @jupyterlab/notebook-extension:widget-factory -> @jupyterlab/rendermime-extension:plugin.

I’m not sure how to deal with this as the cycle is happening via 3rd party packages. I had a hunt around to see if perhaps I could just import INotebookTracker and access the ILatexTypesetter class indirectly from there but couldn’t find anything.

Any suggestions would be greatly appreciated.

1 Like

Do you need to depend on INotebookTracker? If you just need the current widget, you could get it from JupyterFrontEnd like: app.shell.currentWidget and then check if it looks like a notebook.

Thanks - that works! Actually I thought I tried something similar using the dev console in chrome and it was returning null. Now it works if I add that code line to typescript and compile.