jupyterlab-plugin-playground icon indicating copy to clipboard operation
jupyterlab-plugin-playground copied to clipboard

Allowing exploring docs, source links for core (and extension) modules

Open bollwyvl opened this issue 2 years ago • 2 comments

Problem

While it's possible to load modules, discovering them, and then learning about them, is a bit harder.

Proposed Solution

Surface known module information in a new button, Open JS Explorer (next to Load Current File as Extension), which opens a new MainAreaWidget (or sidebar).

Populate the panel with expanded templated metadata.

Lazily do best-effort discovery of extensions via PageConfig.getOption('federated_extension'). Use these to further discover sharedPackages from package.json, and/or novel #/jupyterlab/playground metadata.

Offer this as public API which allows for registering new known modules, including links to (versioned) source and docs.

Additional context

Typing

// tokens.ts
export interface IKnownModule {
  name: string;
  load: () => Promise<any>;
  urls?: {
    sourceHtml?: string;
    docHtml?: string;
    typeDocJson?: string;
  }
};

export interface IPluginPlayground {
  registerKnownModule(known: IKnownModule): void;
}

URLs

For known @jupyterlab stuff, the patterns is pretty formulaic:

https://jupyterlab.readthedocs.io/en/${labMinor}.x/api/modules/${name}.html
https://github.com/jupyterlab/jupyterlab/tree/${labMinor}.x/packages/{name}/src

(this even works for independently-versioned ones like services, which is great)

as with @lumino:

https://lumino.readthedocs.io/en/${luminoMajor}.x/api/{name}/
https://github.com/jupyterlab/lumino/tree/${luminoMajor}.x/packages/${name}/src

The others are... well, the others.

Core

// modules.ts
const LAB_MODULES_NAMES: string[] = [
  // ...
];
const LUMINO_MODULE_NAMES: string[] = [
  // ...
];
const THIRD_PARTY_MODULES: IKnownModule[] = [
  // ...
];

export coreKnownModules(playground: IPluginPlayground):  {
  LAB_MODULE_NAMES.map((name: string) => {
    playground.registerKnownModule({
      id: `jupyterlab/${name}`,
      load: () => import(`@jupyterlab/${name}`),
      // ...
    });
  }
}

Discovery

While other extensions could make use of this, directly... the lower-entropy route would be to scrape PageConfig.getOption('federated_extensions'), fetch all the package.json files, and read all this stuff directly from the source of truth, as it would be able to harvest:

  • the package itself
  • name, homepage, and repository would at least be starting points
  • all the #/jupyterlab/sharePackages for name
    • from the names, derive the npmjs.org page

UI

As a first cut, the UI panel wouldn't deviate too far from zeal, offering best-effort search of, at least initially, the package name.

To really drive a zeal-like UI, however, one would need the typedoc JSON output, a la typedoc's own... which is another couple issues on at least two other repos, and then a bunch of backport PRs, but probably worth it.

bollwyvl avatar Nov 17 '22 13:11 bollwyvl

Closely related to #27. Sounds like good way forward.

"dynamic dynamic imports" (import('@jupyterlab/' + name)) are trickier than "dynamic imports", I did not get them to work but did not try very hard either - but would need thorough testing and it did not seem worth the maintenance burden risk.

krassowski avatar Nov 17 '22 14:11 krassowski

cool, so the template could just build a partial IKnownModule, or just the import, even if the rest can be templated/computed.

bollwyvl avatar Nov 17 '22 19:11 bollwyvl