@@ -6,20 +6,24 @@ import {
66 JupyterFrontEndPlugin ,
77 JupyterFrontEnd
88} from '@jupyterlab/application' ;
9-
109import {
1110 MainAreaWidget ,
1211 IToolbarWidgetRegistry ,
1312 showErrorMessage
1413} from '@jupyterlab/apputils' ;
15-
1614import { listIcon , ToolbarButton } from '@jupyterlab/ui-components' ;
17-
1815import { IRenderMimeRegistry } from '@jupyterlab/rendermime' ;
19-
2016import { LoggerRegistry , LogConsolePanel } from '@jupyterlab/logconsole' ;
21-
2217import { NotebookPanel } from '@jupyterlab/notebook' ;
18+ import { PageConfig , URLExt } from '@jupyterlab/coreutils' ;
19+
20+ import { IServiceWorkerManager } from '@jupyterlite/server' ;
21+ import { IBroadcastChannelWrapper } from '@jupyterlite/contents' ;
22+ import { IKernel , IKernelSpecs } from '@jupyterlite/kernel' ;
23+
24+ const xeus = await import ( '@jupyterlite/xeus' ) ;
25+
26+ import { IEmpackEnvMetaFile } from './tokens' ;
2327
2428enum KernelStatus {
2529 None = 0 ,
@@ -28,6 +32,122 @@ enum KernelStatus {
2832 Error = 3
2933}
3034
35+ /**
36+ * Fetches JSON data from the specified URL asynchronously.
37+ *
38+ * This function constructs the full URL using the base URL from the PageConfig and
39+ * the provided relative URL. It then performs a GET request using the Fetch API
40+ * and returns the parsed JSON data.
41+ *
42+ * @param {string } url - The relative URL to fetch the JSON data from.
43+ * @returns {Promise<any> } - A promise that resolves to the parsed JSON data.
44+ * @throws {Error } - Throws an error if the HTTP request fails.
45+ *
46+ */
47+ async function getJson ( url : string ) {
48+ const jsonUrl = URLExt . join ( PageConfig . getBaseUrl ( ) , url ) ;
49+ const response = await fetch ( jsonUrl , { method : 'GET' } ) ;
50+
51+ if ( ! response . ok ) {
52+ throw new Error ( `HTTP error! status: ${ response . status } ` ) ;
53+ }
54+
55+ const data = await response . json ( ) ;
56+ return data ;
57+ }
58+
59+ const kernelPlugin : JupyterFrontEndPlugin < void > = {
60+ id : '@jupyterlite/xeus-kernel:register' ,
61+ autoStart : true ,
62+ requires : [ IKernelSpecs ] ,
63+ optional : [
64+ IServiceWorkerManager ,
65+ IBroadcastChannelWrapper ,
66+ IEmpackEnvMetaFile
67+ ] ,
68+ activate : async (
69+ app : JupyterFrontEnd ,
70+ kernelspecs : IKernelSpecs ,
71+ serviceWorker ?: IServiceWorkerManager ,
72+ broadcastChannel ?: IBroadcastChannelWrapper ,
73+ empackEnvMetaFile ?: IEmpackEnvMetaFile
74+ ) => {
75+ // Fetch kernel list
76+ let kernelList : string [ ] = [ ] ;
77+ try {
78+ kernelList = await getJson ( 'xeus/kernels.json' ) ;
79+ } catch ( err ) {
80+ console . log ( `Could not fetch xeus/kernels.json: ${ err } ` ) ;
81+ throw err ;
82+ }
83+ const contentsManager = app . serviceManager . contents ;
84+
85+ for ( const kernel of kernelList ) {
86+ // Fetch kernel spec
87+ const kernelspec = await getJson (
88+ 'xeus/kernels/' + kernel + '/kernel.json'
89+ ) ;
90+ kernelspec . name = kernel ;
91+ kernelspec . dir = kernel ;
92+ for ( const [ key , value ] of Object . entries ( kernelspec . resources ) ) {
93+ kernelspec . resources [ key ] = URLExt . join (
94+ PageConfig . getBaseUrl ( ) ,
95+ value as string
96+ ) ;
97+ }
98+ kernelspecs . register ( {
99+ spec : kernelspec ,
100+ create : async ( options : IKernel . IOptions ) : Promise < IKernel > => {
101+ const mountDrive = ! ! (
102+ ( serviceWorker ?. enabled && broadcastChannel ?. enabled ) ||
103+ crossOriginIsolated
104+ ) ;
105+
106+ if ( mountDrive ) {
107+ console . info (
108+ `${ kernelspec . name } contents will be synced with Jupyter Contents`
109+ ) ;
110+ } else {
111+ console . warn (
112+ `${ kernelspec . name } contents will NOT be synced with Jupyter Contents`
113+ ) ;
114+ }
115+ const link = empackEnvMetaFile
116+ ? await empackEnvMetaFile . getLink ( kernelspec )
117+ : '' ;
118+
119+ return new xeus . WebWorkerKernel ( {
120+ ...options ,
121+ contentsManager,
122+ mountDrive,
123+ kernelSpec : kernelspec ,
124+ empackEnvMetaLink : link
125+ } ) ;
126+ }
127+ } ) ;
128+ }
129+ await app . serviceManager . kernelspecs . refreshSpecs ( ) ;
130+ }
131+ } ;
132+
133+ const empackEnvMetaPlugin : JupyterFrontEndPlugin < IEmpackEnvMetaFile > = {
134+ id : '@jupyterlite/xeus:empack-env-meta' ,
135+ autoStart : true ,
136+ provides : IEmpackEnvMetaFile ,
137+ activate : ( ) : IEmpackEnvMetaFile => {
138+ return {
139+ getLink : async ( kernelspec : Record < string , any > ) => {
140+ const kernelName = kernelspec . name ;
141+ const kernel_root_url = URLExt . join (
142+ PageConfig . getBaseUrl ( ) ,
143+ `xeus/kernels/${ kernelName } `
144+ ) ;
145+ return `${ kernel_root_url } ` ;
146+ }
147+ } ;
148+ }
149+ } ;
150+
31151const kernelStatusPlugin : JupyterFrontEndPlugin < void > = {
32152 id : '@jupyterlite/xeus-extension:xeus-kernel-status' ,
33153 autoStart : true ,
@@ -190,4 +310,5 @@ const kernelStatusPlugin: JupyterFrontEndPlugin<void> = {
190310 }
191311} ;
192312
193- export default [ kernelStatusPlugin ] ;
313+ export default [ kernelStatusPlugin , empackEnvMetaPlugin , kernelPlugin ] ;
314+ export { IEmpackEnvMetaFile } ;
0 commit comments