@datalayer/jupyter-react 1.2.3 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/README.md +10 -0
  2. package/lib/app/tabs/components/FileBrowserComponent.js +1 -1
  3. package/lib/app/tabs/components/FileBrowserComponent.js.map +1 -1
  4. package/lib/app/tabs/components/NotebookComponent.js +10 -4
  5. package/lib/app/tabs/components/NotebookComponent.js.map +1 -1
  6. package/lib/components/console/Console.js +1 -1
  7. package/lib/components/console/Console.js.map +1 -1
  8. package/lib/components/filemanager/FileManagerJupyterLab.js +1 -1
  9. package/lib/components/filemanager/FileManagerJupyterLab.js.map +1 -1
  10. package/lib/components/jupyterlab/JupyterLabApp.js +1 -1
  11. package/lib/components/jupyterlab/JupyterLabApp.js.map +1 -1
  12. package/lib/components/kernel/KernelSelector.js +1 -1
  13. package/lib/components/kernel/KernelSelector.js.map +1 -1
  14. package/lib/components/kernel/Kernels.js +1 -1
  15. package/lib/components/kernel/Kernels.js.map +1 -1
  16. package/lib/components/notebook/Notebook.d.ts +95 -41
  17. package/lib/components/notebook/Notebook.js +57 -276
  18. package/lib/components/notebook/Notebook.js.map +1 -1
  19. package/lib/components/notebook/NotebookAdapter.d.ts +294 -65
  20. package/lib/components/notebook/NotebookAdapter.js +692 -583
  21. package/lib/components/notebook/NotebookAdapter.js.map +1 -1
  22. package/lib/components/notebook/{Notebook2Base.d.ts → NotebookBase.d.ts} +16 -14
  23. package/lib/components/notebook/{Notebook2Base.js → NotebookBase.js} +33 -32
  24. package/lib/components/notebook/NotebookBase.js.map +1 -0
  25. package/lib/components/notebook/NotebookState.d.ts +45 -10
  26. package/lib/components/notebook/NotebookState.js +118 -58
  27. package/lib/components/notebook/NotebookState.js.map +1 -1
  28. package/lib/components/notebook/index.d.ts +2 -6
  29. package/lib/components/notebook/index.js +2 -6
  30. package/lib/components/notebook/index.js.map +1 -1
  31. package/lib/components/notebook/toolbar/NotebookToolbar.js +4 -13
  32. package/lib/components/notebook/toolbar/NotebookToolbar.js.map +1 -1
  33. package/lib/components/output/Output.js +1 -1
  34. package/lib/components/output/Output.js.map +1 -1
  35. package/lib/components/terminal/Terminal.js +1 -1
  36. package/lib/components/terminal/Terminal.js.map +1 -1
  37. package/lib/examples/Bokeh.js +6 -2
  38. package/lib/examples/Bokeh.js.map +1 -1
  39. package/lib/examples/Bqplot.js +7 -3
  40. package/lib/examples/Bqplot.js.map +1 -1
  41. package/lib/examples/Cell.js +1 -1
  42. package/lib/examples/Cell.js.map +1 -1
  43. package/lib/examples/CellLite.js +1 -1
  44. package/lib/examples/CellLite.js.map +1 -1
  45. package/lib/examples/Cells.js +1 -1
  46. package/lib/examples/Cells.js.map +1 -1
  47. package/lib/examples/CellsExecute.js +1 -1
  48. package/lib/examples/CellsExecute.js.map +1 -1
  49. package/lib/examples/ConsoleLite.js +2 -2
  50. package/lib/examples/ConsoleLite.js.map +1 -1
  51. package/lib/examples/Dashboard.js +7 -3
  52. package/lib/examples/Dashboard.js.map +1 -1
  53. package/lib/examples/Deno.js +8 -3
  54. package/lib/examples/Deno.js.map +1 -1
  55. package/lib/examples/Examples.js +7 -15
  56. package/lib/examples/Examples.js.map +1 -1
  57. package/lib/examples/FileBrowser.js +1 -1
  58. package/lib/examples/FileBrowser.js.map +1 -1
  59. package/lib/examples/GeoJson.js +9 -5
  60. package/lib/examples/GeoJson.js.map +1 -1
  61. package/lib/examples/IPyLeaflet.js +7 -3
  62. package/lib/examples/IPyLeaflet.js.map +1 -1
  63. package/lib/examples/IPyReact.js +6 -2
  64. package/lib/examples/IPyReact.js.map +1 -1
  65. package/lib/examples/IPyWidgets.js +7 -3
  66. package/lib/examples/IPyWidgets.js.map +1 -1
  67. package/lib/examples/IPyWidgetsState.js +13 -4
  68. package/lib/examples/IPyWidgetsState.js.map +1 -1
  69. package/lib/examples/JupyterContext.js +45 -22
  70. package/lib/examples/JupyterContext.js.map +1 -1
  71. package/lib/examples/JupyterLabTheme.js +4 -3
  72. package/lib/examples/JupyterLabTheme.js.map +1 -1
  73. package/lib/examples/KernelExecute.js +1 -1
  74. package/lib/examples/KernelExecute.js.map +1 -1
  75. package/lib/examples/KernelExecuteLite.js +1 -1
  76. package/lib/examples/KernelExecuteLite.js.map +1 -1
  77. package/lib/examples/KernelExecutor.js +1 -1
  78. package/lib/examples/KernelExecutor.js.map +1 -1
  79. package/lib/examples/KernelExecutorLite.js +1 -1
  80. package/lib/examples/KernelExecutorLite.js.map +1 -1
  81. package/lib/examples/Kernels.js +1 -1
  82. package/lib/examples/Kernels.js.map +1 -1
  83. package/lib/examples/Matplotlib.js +6 -2
  84. package/lib/examples/Matplotlib.js.map +1 -1
  85. package/lib/examples/Notebook.js +19 -8
  86. package/lib/examples/Notebook.js.map +1 -1
  87. package/lib/examples/{Notebook2Actions.js → NotebookActions.js} +6 -6
  88. package/lib/examples/NotebookActions.js.map +1 -0
  89. package/lib/examples/NotebookCellSidebar.js +17 -4
  90. package/lib/examples/NotebookCellSidebar.js.map +1 -1
  91. package/lib/examples/NotebookCellToolbar.js +7 -3
  92. package/lib/examples/NotebookCellToolbar.js.map +1 -1
  93. package/lib/examples/NotebookCollaborative.js +6 -9
  94. package/lib/examples/NotebookCollaborative.js.map +1 -1
  95. package/lib/examples/NotebookColormode.js +2 -2
  96. package/lib/examples/NotebookColormode.js.map +1 -1
  97. package/lib/examples/NotebookExtension.js +6 -2
  98. package/lib/examples/NotebookExtension.js.map +1 -1
  99. package/lib/examples/NotebookExternalContent.js +22 -14
  100. package/lib/examples/NotebookExternalContent.js.map +1 -1
  101. package/lib/examples/NotebookInit.js +14 -45
  102. package/lib/examples/NotebookInit.js.map +1 -1
  103. package/lib/examples/NotebookKernel.js +7 -16
  104. package/lib/examples/NotebookKernel.js.map +1 -1
  105. package/lib/examples/NotebookKernelChange.js +21 -8
  106. package/lib/examples/NotebookKernelChange.js.map +1 -1
  107. package/lib/examples/NotebookLess.js +13 -4
  108. package/lib/examples/NotebookLess.js.map +1 -1
  109. package/lib/examples/NotebookLite.js +21 -10
  110. package/lib/examples/NotebookLite.js.map +1 -1
  111. package/lib/examples/NotebookLocalServer.js +15 -6
  112. package/lib/examples/NotebookLocalServer.js.map +1 -1
  113. package/lib/examples/NotebookNbformat.js +2 -2
  114. package/lib/examples/NotebookNbformat.js.map +1 -1
  115. package/lib/examples/NotebookNbformatChange.js +6 -2
  116. package/lib/examples/NotebookNbformatChange.js.map +1 -1
  117. package/lib/examples/NotebookNoContext.js +10 -2
  118. package/lib/examples/NotebookNoContext.js.map +1 -1
  119. package/lib/examples/NotebookNoPrimer.js +11 -3
  120. package/lib/examples/NotebookNoPrimer.js.map +1 -1
  121. package/lib/examples/NotebookOnSessionConnection.js +13 -5
  122. package/lib/examples/NotebookOnSessionConnection.js.map +1 -1
  123. package/lib/examples/NotebookPath.js +13 -5
  124. package/lib/examples/NotebookPath.js.map +1 -1
  125. package/lib/examples/NotebookPathChange.js +7 -3
  126. package/lib/examples/NotebookPathChange.js.map +1 -1
  127. package/lib/examples/NotebookReadonly.js +6 -2
  128. package/lib/examples/NotebookReadonly.js.map +1 -1
  129. package/lib/examples/NotebookServiceManager.js +12 -6
  130. package/lib/examples/NotebookServiceManager.js.map +1 -1
  131. package/lib/examples/NotebookSkeleton.js +14 -4
  132. package/lib/examples/NotebookSkeleton.js.map +1 -1
  133. package/lib/examples/NotebookTOC.js +7 -3
  134. package/lib/examples/NotebookTOC.js.map +1 -1
  135. package/lib/examples/NotebookTheme.js +7 -3
  136. package/lib/examples/NotebookTheme.js.map +1 -1
  137. package/lib/examples/NotebookThemeColormode.js +2 -2
  138. package/lib/examples/NotebookThemeColormode.js.map +1 -1
  139. package/lib/examples/NotebookURL.js +11 -3
  140. package/lib/examples/NotebookURL.js.map +1 -1
  141. package/lib/examples/NotebookUnmount.js +8 -6
  142. package/lib/examples/NotebookUnmount.js.map +1 -1
  143. package/lib/examples/ObservableHQ.js +8 -3
  144. package/lib/examples/ObservableHQ.js.map +1 -1
  145. package/lib/examples/OutputWithMonitoring.js +11 -5
  146. package/lib/examples/OutputWithMonitoring.js.map +1 -1
  147. package/lib/examples/Outputs.js +13 -8
  148. package/lib/examples/Outputs.js.map +1 -1
  149. package/lib/examples/OutputsIpynb.js +3 -3
  150. package/lib/examples/OutputsIpynb.js.map +1 -1
  151. package/lib/examples/Panel.js +8 -4
  152. package/lib/examples/Panel.js.map +1 -1
  153. package/lib/examples/Plotly.js +7 -3
  154. package/lib/examples/Plotly.js.map +1 -1
  155. package/lib/examples/PyGWalker.js +13 -4
  156. package/lib/examples/PyGWalker.js.map +1 -1
  157. package/lib/examples/RunningSessions.js +5 -5
  158. package/lib/examples/RunningSessions.js.map +1 -1
  159. package/lib/examples/Vega.js +11 -3
  160. package/lib/examples/Vega.js.map +1 -1
  161. package/lib/examples/Viewer.js +2 -2
  162. package/lib/examples/Viewer.js.map +1 -1
  163. package/lib/examples/extensions/celltoolbar/CellToolbarComponent.js +6 -24
  164. package/lib/examples/extensions/celltoolbar/CellToolbarComponent.js.map +1 -1
  165. package/lib/examples/extensions/toc/ReactLayoutFactory.js +3 -3
  166. package/lib/examples/extensions/toc/ReactLayoutFactory.js.map +1 -1
  167. package/lib/examples/extensions/toc/TocComponent.d.ts +1 -1
  168. package/lib/examples/extensions/toc/TocComponent.js +1 -1
  169. package/lib/examples/extensions/toc/TocComponent.js.map +1 -1
  170. package/lib/examples/extensions/toc/TocExtension.d.ts +1 -3
  171. package/lib/examples/extensions/toc/TocExtension.js +28 -11
  172. package/lib/examples/extensions/toc/TocExtension.js.map +1 -1
  173. package/lib/jupyter/JupyterConfig.d.ts +9 -2
  174. package/lib/jupyter/JupyterConfig.js.map +1 -1
  175. package/lib/jupyter/{JupyterContext.d.ts → JupyterUse.d.ts} +3 -26
  176. package/lib/jupyter/JupyterUse.js +26 -0
  177. package/lib/jupyter/JupyterUse.js.map +1 -0
  178. package/lib/jupyter/index.d.ts +1 -3
  179. package/lib/jupyter/index.js +1 -3
  180. package/lib/jupyter/index.js.map +1 -1
  181. package/lib/jupyter/lite/contents/broadcast.js +5 -2
  182. package/lib/jupyter/lite/contents/broadcast.js.map +1 -1
  183. package/lib/jupyter/lite/contents/contents.js +5 -0
  184. package/lib/jupyter/lite/contents/contents.js.map +1 -1
  185. package/lib/jupyter/lite/contents/drivecontents.js +5 -0
  186. package/lib/jupyter/lite/contents/drivecontents.js.map +1 -1
  187. package/lib/jupyter/lite/contents/drivefs.js +5 -2
  188. package/lib/jupyter/lite/contents/drivefs.js.map +1 -1
  189. package/lib/jupyter/lite/contents/emscripten.js +5 -2
  190. package/lib/jupyter/lite/contents/emscripten.js.map +1 -1
  191. package/lib/jupyter/lite/contents/index.js +5 -0
  192. package/lib/jupyter/lite/contents/index.js.map +1 -1
  193. package/lib/jupyter/lite/contents/tokens.js +5 -0
  194. package/lib/jupyter/lite/contents/tokens.js.map +1 -1
  195. package/lib/jupyter/lite/javascript-kernel/comlink.worker.js +15 -0
  196. package/lib/jupyter/lite/javascript-kernel/comlink.worker.js.map +1 -0
  197. package/lib/jupyter/lite/javascript-kernel/index.d.ts +2 -0
  198. package/lib/jupyter/lite/javascript-kernel/index.js +10 -0
  199. package/lib/jupyter/lite/javascript-kernel/index.js.map +1 -0
  200. package/lib/jupyter/lite/javascript-kernel/kernel.d.ts +121 -0
  201. package/lib/jupyter/lite/javascript-kernel/kernel.js +239 -0
  202. package/lib/jupyter/lite/javascript-kernel/kernel.js.map +1 -0
  203. package/lib/jupyter/lite/javascript-kernel/tokens.d.ts +27 -0
  204. package/lib/jupyter/lite/javascript-kernel/tokens.js +7 -0
  205. package/lib/jupyter/lite/javascript-kernel/tokens.js.map +1 -0
  206. package/lib/jupyter/lite/javascript-kernel/worker.d.ts +37 -0
  207. package/lib/jupyter/lite/javascript-kernel/worker.js +117 -0
  208. package/lib/jupyter/lite/javascript-kernel/worker.js.map +1 -0
  209. package/lib/jupyter/lite/javascript-kernel-extension/index.d.ts +3 -0
  210. package/lib/jupyter/lite/javascript-kernel-extension/index.js +37 -0
  211. package/lib/jupyter/lite/javascript-kernel-extension/index.js.map +1 -0
  212. package/lib/jupyter/lite/kernel/index.js +5 -0
  213. package/lib/jupyter/lite/kernel/index.js.map +1 -1
  214. package/lib/jupyter/lite/kernel/kernel.js +5 -0
  215. package/lib/jupyter/lite/kernel/kernel.js.map +1 -1
  216. package/lib/jupyter/lite/kernel/kernels.js +5 -0
  217. package/lib/jupyter/lite/kernel/kernels.js.map +1 -1
  218. package/lib/jupyter/lite/kernel/kernelspecs.js +5 -0
  219. package/lib/jupyter/lite/kernel/kernelspecs.js.map +1 -1
  220. package/lib/jupyter/lite/kernel/tokens.js +5 -2
  221. package/lib/jupyter/lite/kernel/tokens.js.map +1 -1
  222. package/lib/jupyter/lite/licenses/index.js +5 -0
  223. package/lib/jupyter/lite/licenses/index.js.map +1 -1
  224. package/lib/jupyter/lite/licenses/licenses.js +5 -0
  225. package/lib/jupyter/lite/licenses/licenses.js.map +1 -1
  226. package/lib/jupyter/lite/licenses/tokens.js +5 -0
  227. package/lib/jupyter/lite/licenses/tokens.js.map +1 -1
  228. package/lib/jupyter/lite/localforage/index.js +5 -0
  229. package/lib/jupyter/lite/localforage/index.js.map +1 -1
  230. package/lib/jupyter/lite/localforage/memory.js +5 -2
  231. package/lib/jupyter/lite/localforage/memory.js.map +1 -1
  232. package/lib/jupyter/lite/localforage/tokens.js +5 -2
  233. package/lib/jupyter/lite/localforage/tokens.js.map +1 -1
  234. package/lib/jupyter/lite/pyodide-kernel/_pypi.js +5 -0
  235. package/lib/jupyter/lite/pyodide-kernel/_pypi.js.map +1 -1
  236. package/lib/jupyter/lite/pyodide-kernel/coincident.worker.js +5 -0
  237. package/lib/jupyter/lite/pyodide-kernel/coincident.worker.js.map +1 -1
  238. package/lib/jupyter/lite/pyodide-kernel/comlink.worker.js +5 -0
  239. package/lib/jupyter/lite/pyodide-kernel/comlink.worker.js.map +1 -1
  240. package/lib/jupyter/lite/pyodide-kernel/index.js +5 -0
  241. package/lib/jupyter/lite/pyodide-kernel/index.js.map +1 -1
  242. package/lib/jupyter/lite/pyodide-kernel/kernel.js +5 -0
  243. package/lib/jupyter/lite/pyodide-kernel/kernel.js.map +1 -1
  244. package/lib/jupyter/lite/pyodide-kernel/tokens.js +5 -2
  245. package/lib/jupyter/lite/pyodide-kernel/tokens.js.map +1 -1
  246. package/lib/jupyter/lite/pyodide-kernel/worker.js +5 -2
  247. package/lib/jupyter/lite/pyodide-kernel/worker.js.map +1 -1
  248. package/lib/jupyter/lite/pyodide-kernel-extension/index.js +6 -1
  249. package/lib/jupyter/lite/pyodide-kernel-extension/index.js.map +1 -1
  250. package/lib/jupyter/lite/server/app.js +5 -0
  251. package/lib/jupyter/lite/server/app.js.map +1 -1
  252. package/lib/jupyter/lite/server/index.js +5 -0
  253. package/lib/jupyter/lite/server/index.js.map +1 -1
  254. package/lib/jupyter/lite/server/router.js +5 -0
  255. package/lib/jupyter/lite/server/router.js.map +1 -1
  256. package/lib/jupyter/lite/server/service-manager.js +5 -0
  257. package/lib/jupyter/lite/server/service-manager.js.map +1 -1
  258. package/lib/jupyter/lite/server/service-worker.js +5 -0
  259. package/lib/jupyter/lite/server/service-worker.js.map +1 -1
  260. package/lib/jupyter/lite/server/status.js +5 -0
  261. package/lib/jupyter/lite/server/status.js.map +1 -1
  262. package/lib/jupyter/lite/server/tokens.js +5 -0
  263. package/lib/jupyter/lite/server/tokens.js.map +1 -1
  264. package/lib/jupyter/lite/server-extension/index.js +5 -0
  265. package/lib/jupyter/lite/server-extension/index.js.map +1 -1
  266. package/lib/jupyter/lite/session/index.js +5 -0
  267. package/lib/jupyter/lite/session/index.js.map +1 -1
  268. package/lib/jupyter/lite/session/sessions.js +5 -0
  269. package/lib/jupyter/lite/session/sessions.js.map +1 -1
  270. package/lib/jupyter/lite/session/tokens.js +5 -0
  271. package/lib/jupyter/lite/session/tokens.js.map +1 -1
  272. package/lib/jupyter/lite/settings/index.js +5 -0
  273. package/lib/jupyter/lite/settings/index.js.map +1 -1
  274. package/lib/jupyter/lite/settings/settings.js +5 -0
  275. package/lib/jupyter/lite/settings/settings.js.map +1 -1
  276. package/lib/jupyter/lite/settings/tokens.js +5 -0
  277. package/lib/jupyter/lite/settings/tokens.js.map +1 -1
  278. package/lib/jupyter/lite/translation/index.js +5 -0
  279. package/lib/jupyter/lite/translation/index.js.map +1 -1
  280. package/lib/jupyter/lite/translation/tokens.js +5 -0
  281. package/lib/jupyter/lite/translation/tokens.js.map +1 -1
  282. package/lib/jupyter/lite/translation/translation.js +5 -0
  283. package/lib/jupyter/lite/translation/translation.js.map +1 -1
  284. package/lib/jupyter/lite/types/index.js +5 -0
  285. package/lib/jupyter/lite/types/index.js.map +1 -1
  286. package/lib/jupyter/lite/types/tokens.js +5 -2
  287. package/lib/jupyter/lite/types/tokens.js.map +1 -1
  288. package/lib/state/JupyterReactState.d.ts +2 -2
  289. package/lib/state/JupyterReactState.js +3 -1
  290. package/lib/state/JupyterReactState.js.map +1 -1
  291. package/lib/tools/core/executor.d.ts +4 -4
  292. package/lib/tools/core/executor.js +2 -2
  293. package/lib/tools/core/executor.js.map +1 -1
  294. package/lib/utils/Utils.d.ts +7 -0
  295. package/lib/utils/Utils.js +32 -0
  296. package/lib/utils/Utils.js.map +1 -1
  297. package/package.json +42 -3
  298. package/style/icons/javascript/logo-32x32.png +0 -0
  299. package/style/icons/javascript/logo-64x64.png +0 -0
  300. package/lib/components/notebook/Notebook2.d.ts +0 -112
  301. package/lib/components/notebook/Notebook2.js +0 -121
  302. package/lib/components/notebook/Notebook2.js.map +0 -1
  303. package/lib/components/notebook/Notebook2Adapter.d.ts +0 -269
  304. package/lib/components/notebook/Notebook2Adapter.js +0 -688
  305. package/lib/components/notebook/Notebook2Adapter.js.map +0 -1
  306. package/lib/components/notebook/Notebook2Base.js.map +0 -1
  307. package/lib/components/notebook/Notebook2State.d.ts +0 -59
  308. package/lib/components/notebook/Notebook2State.js +0 -122
  309. package/lib/components/notebook/Notebook2State.js.map +0 -1
  310. package/lib/examples/Notebook2.js +0 -30
  311. package/lib/examples/Notebook2.js.map +0 -1
  312. package/lib/examples/Notebook2Actions.js.map +0 -1
  313. package/lib/examples/Notebook2Collaborative.d.ts +0 -1
  314. package/lib/examples/Notebook2Collaborative.js +0 -23
  315. package/lib/examples/Notebook2Collaborative.js.map +0 -1
  316. package/lib/examples/Notebook2Lite.d.ts +0 -1
  317. package/lib/examples/Notebook2Lite.js +0 -39
  318. package/lib/examples/Notebook2Lite.js.map +0 -1
  319. package/lib/examples/NotebookLiteContext.d.ts +0 -1
  320. package/lib/examples/NotebookLiteContext.js +0 -24
  321. package/lib/examples/NotebookLiteContext.js.map +0 -1
  322. package/lib/examples/toolbars/NotebookToolbarAutoSave.d.ts +0 -4
  323. package/lib/examples/toolbars/NotebookToolbarAutoSave.js +0 -70
  324. package/lib/examples/toolbars/NotebookToolbarAutoSave.js.map +0 -1
  325. package/lib/examples/toolbars/NotebookToolbarStatus.d.ts +0 -4
  326. package/lib/examples/toolbars/NotebookToolbarStatus.js +0 -15
  327. package/lib/examples/toolbars/NotebookToolbarStatus.js.map +0 -1
  328. package/lib/jupyter/Jupyter.d.ts +0 -18
  329. package/lib/jupyter/Jupyter.js +0 -38
  330. package/lib/jupyter/Jupyter.js.map +0 -1
  331. package/lib/jupyter/JupyterContext.js +0 -99
  332. package/lib/jupyter/JupyterContext.js.map +0 -1
  333. /package/lib/examples/{Notebook2.d.ts → NotebookActions.d.ts} +0 -0
  334. /package/lib/{examples/Notebook2Actions.d.ts → jupyter/lite/javascript-kernel/comlink.worker.d.ts} +0 -0
  335. /package/style/icons/{pyodide.svg → pyodide/pyodide.svg} +0 -0
@@ -3,630 +3,739 @@
3
3
  *
4
4
  * MIT License
5
5
  */
6
- import { WIDGET_MIMETYPE } from '@jupyter-widgets/html-manager/lib/output_renderers';
7
- import { CodeMirrorEditorFactory, CodeMirrorMimeTypeService, EditorExtensionRegistry, EditorLanguageRegistry, EditorThemeRegistry, ybinding, } from '@jupyterlab/codemirror';
8
- import { Completer, CompleterModel, CompletionHandler, KernelCompleterProvider, ProviderReconciliator, } from '@jupyterlab/completer';
9
- import { Context, DocumentRegistry } from '@jupyterlab/docregistry';
10
- import { rendererFactory as javascriptRendererFactory } from '@jupyterlab/javascript-extension';
11
- import { rendererFactory as jsonRendererFactory } from '@jupyterlab/json-extension';
12
- import { MathJaxTypesetter } from '@jupyterlab/mathjax-extension';
13
- import { NotebookTracker, NotebookWidgetFactory, StaticNotebook, } from '@jupyterlab/notebook';
14
- import { RenderMimeRegistry, standardRendererFactories, } from '@jupyterlab/rendermime';
15
- import { find } from '@lumino/algorithm';
16
- import { CommandRegistry } from '@lumino/commands';
17
- import { BoxPanel, Widget } from '@lumino/widgets';
18
- import { WidgetLabRenderer, WidgetManager } from '../../jupyter';
19
- import { newUuid } from '../../utils';
20
- import { JupyterReactContentFactory } from './content/JupyterReactContentFactory';
21
- import { getMarked } from './marked/marked';
22
- import { JupyterReactNotebookModelFactory } from './model/JupyterReactNotebookModelFactory';
23
- import { addNotebookCommands, NotebookPanelProvider } from './NotebookCommands';
24
- const FALLBACK_NOTEBOOK_PATH = '.datalayer/ping.ipynb';
6
+ import { NotebookActions, } from '@jupyterlab/notebook';
7
+ import { NotebookCommandIds } from './NotebookCommands';
8
+ import * as Diff from 'diff';
25
9
  export class NotebookAdapter {
26
- _boxPanel;
27
10
  _commands;
28
- _contentFactory;
11
+ _panel;
12
+ _notebook;
29
13
  _context;
30
- _documentRegistry;
31
- _iPyWidgetsManager;
32
- _id;
33
- _kernel;
34
- _kernelConnection;
35
- _kernelClients;
36
- _kernelTransfer;
37
- _lite;
38
- _mimeTypeService;
39
- _nbformat;
40
- _notebookModelFactory;
41
- _notebookPanel;
42
- _onSessionConnection;
43
- _panelProvider;
44
- _path;
45
- _readonly;
46
- _renderers;
47
- _rendermime;
48
- _serverless;
49
- _serviceManager;
50
- _tracker;
51
- _url;
52
- _useVSCodeTheme;
53
- constructor(props) {
54
- console.log('Creating a new Notebook Adapter.');
55
- this._id = props.id ?? newUuid();
56
- this._kernel = props.kernel;
57
- this._kernelClients = props.kernelClients ?? [];
58
- this._lite = props.lite;
59
- this._nbformat = props.nbformat;
60
- this._path = props.path;
61
- this._readonly = props.readonly ?? false;
62
- this._renderers = props.renderers ?? [];
63
- this._serverless = props.serverless ?? false;
64
- this._serviceManager = props.serviceManager;
65
- this._url = props.url;
66
- this._useVSCodeTheme = props.useVSCodeTheme ?? true; // Default to true for backwards compatibility
67
- this._kernelTransfer = props.kernelTransfer;
68
- this._onSessionConnection = props.onSessionConnection;
69
- this._boxPanel = new BoxPanel();
70
- this._boxPanel.addClass('dla-Jupyter-Notebook');
71
- this._boxPanel.spacing = 0;
72
- this._commands = new CommandRegistry();
73
- this._panelProvider = new NotebookPanelProvider();
74
- if (props.url) {
75
- this.loadFromUrl(props.url).then(nbformat => {
76
- this._nbformat = nbformat;
77
- this.setupAdapter();
78
- });
79
- }
80
- else {
81
- this.setupAdapter();
82
- }
14
+ _defaultCellType = 'code';
15
+ _kernelInfo = null;
16
+ constructor(commands, panel, context) {
17
+ this._commands = commands;
18
+ this._panel = panel;
19
+ this._notebook = panel.content;
20
+ this._context = context;
83
21
  }
84
- async loadFromUrl(url) {
85
- return fetch(url)
86
- .then(response => {
87
- return response.text();
88
- })
89
- .then(nb => {
90
- return JSON.parse(nb);
91
- });
22
+ /**
23
+ * Get the command registry.
24
+ */
25
+ get commands() {
26
+ return this._commands;
92
27
  }
93
- notebookKeydownListener = (event) => {
94
- this._commands?.processKeydownEvent(event);
95
- };
96
- setupCompleter(notebookPanel) {
97
- const editor = notebookPanel.content.activeCell &&
98
- notebookPanel.content.activeCell.editor;
99
- const sessionContext = notebookPanel.context.sessionContext;
100
- const model = new CompleterModel();
101
- const completer = new Completer({ editor, model });
102
- const timeout = 1000;
103
- const provider = new KernelCompleterProvider();
104
- const reconciliator = new ProviderReconciliator({
105
- context: {
106
- widget: notebookPanel,
107
- editor,
108
- session: sessionContext.session,
109
- },
110
- providers: [provider],
111
- timeout,
112
- });
113
- const handler = new CompletionHandler({ completer, reconciliator });
114
- sessionContext.ready.then(() => {
115
- const provider = new KernelCompleterProvider();
116
- const reconciliator = new ProviderReconciliator({
117
- context: {
118
- widget: this._notebookPanel,
119
- editor,
120
- session: sessionContext.session,
121
- },
122
- providers: [provider],
123
- timeout: timeout,
124
- });
125
- handler.reconciliator = reconciliator;
126
- });
127
- handler.editor = editor;
128
- notebookPanel.content.activeCellChanged.connect((notebook, cell) => {
129
- if (cell) {
130
- cell.ready.then(() => {
131
- handler.editor = cell && cell.editor;
132
- });
133
- }
134
- });
135
- completer.hide();
136
- Widget.attach(completer, document.body);
137
- return handler;
138
- }
139
- initializeContext() {
140
- const isNbFormat = this._path !== undefined && this._path !== '' ? false : true;
141
- this._context = new Context({
142
- manager: this._serviceManager,
143
- factory: this._notebookModelFactory,
144
- path: this._path ?? FALLBACK_NOTEBOOK_PATH,
145
- kernelPreference: {
146
- id: this._kernel?.id,
147
- shouldStart: false,
148
- canStart: false,
149
- autoStartDefault: false,
150
- shutdownOnDispose: false,
151
- },
152
- });
153
- this._iPyWidgetsManager = new WidgetManager(this._context, this._rendermime, { saveState: false });
154
- const ipywidgetsRendererFactory = {
155
- safe: true,
156
- mimeTypes: [WIDGET_MIMETYPE],
157
- defaultRank: 1,
158
- createRenderer: options => new WidgetLabRenderer(options, this._iPyWidgetsManager),
159
- };
160
- this._rendermime.addFactory(ipywidgetsRendererFactory, 1);
161
- this._kernelClients?.map(kernelClient => {
162
- this._iPyWidgetsManager?.registerWithKernel(kernelClient);
163
- });
164
- // These are fixes on the Context and the SessionContext to have more control on the kernel launch.
165
- this._context.sessionContext._initialize =
166
- async () => {
167
- const manager = this._context.sessionContext
168
- .sessionManager;
169
- await manager.ready;
170
- await manager.refreshRunning();
171
- const model = find(manager.running(), model => {
172
- return model.kernel?.id === this._kernel?.id;
173
- });
174
- if (model) {
175
- try {
176
- const session = manager.connectTo({
177
- model: {
178
- ...model,
179
- path: this._path ?? model.path,
180
- name: this._path ?? model.name,
181
- },
182
- kernelConnectionOptions: {
183
- handleComms: true,
184
- },
185
- });
186
- this._context.sessionContext._handleNewSession(session);
187
- // Dispose the previous KernelConnection to avoid errors with Comms.
188
- this._kernel?.connection?.dispose();
189
- }
190
- catch (err) {
191
- void this._context.sessionContext._handleSessionError(err);
192
- return Promise.reject(err);
193
- }
194
- }
195
- return await this._context.sessionContext._startIfNecessary();
196
- };
197
- if (isNbFormat) {
198
- // If nbformat is provided and we don't want to interact with the Content Manager.
199
- this._context._populate = async () => {
200
- this._context._isPopulated = true;
201
- this._context._isReady = true;
202
- this._context._populatedPromise.resolve(void 0);
203
- // Add a checkpoint if none exists and the file is writable.
204
- // Force skip this step for nbformat notebooks.
205
- // await (this._context as any)._maybeCheckpoint(false);
206
- if (this._context.isDisposed) {
207
- return;
208
- }
209
- // Update the kernel preference.
210
- const name = this._context._model.defaultKernelName ||
211
- this._context.sessionContext.kernelPreference.name;
212
- this._context.sessionContext.kernelPreference = {
213
- ...this._context.sessionContext.kernelPreference,
214
- name,
215
- language: this._context._model.defaultKernelLanguage,
216
- };
217
- // Note: we don't wait on the session to initialize
218
- // so that the user can be shown the content before
219
- // any kernel has started.
220
- void this._context.sessionContext
221
- .initialize()
222
- .then((shouldSelect) => {
223
- if (shouldSelect) {
224
- void this._context._dialogs.selectKernel(this._context.sessionContext.sessionContext);
225
- }
226
- });
227
- };
228
- this._context.initialize = async (isNew) => {
229
- this._context.model.dirty = false;
230
- const now = new Date().toISOString();
231
- const model = {
232
- path: this._id,
233
- name: this._id,
234
- type: 'notebook',
235
- content: undefined,
236
- writable: true,
237
- created: now,
238
- last_modified: now,
239
- mimetype: 'application/x-ipynb+json',
240
- format: 'json',
241
- };
242
- this._context._updateContentsModel(model);
243
- await this._context._populate();
244
- this._context.model.sharedModel.clearUndoHistory();
245
- };
246
- }
247
- // Setup the context listeners.
248
- this._context.sessionContext.sessionChanged.connect((_, args) => {
249
- const session = args.newValue;
250
- console.log('Current Jupyter Session Connection', session);
251
- if (this._onSessionConnection) {
252
- if (session) {
253
- this._onSessionConnection(session);
254
- this._iPyWidgetsManager?.registerWithKernel(session.kernel);
255
- const model = this._notebookPanel?.model;
256
- if (model) {
257
- this._iPyWidgetsManager?.restoreWidgets(model);
258
- }
259
- }
260
- }
261
- });
262
- this._context.sessionContext.kernelChanged.connect((_, args) => {
263
- const kernelConnection = args.newValue;
264
- this._kernelConnection = kernelConnection;
265
- console.log('Current Jupyter Kernel Connection.', kernelConnection);
266
- if (kernelConnection && !kernelConnection.handleComms) {
267
- console.log('Updating the current Kernel Connection to enforce Comms support.', kernelConnection.handleComms);
268
- kernelConnection.handleComms = true;
269
- }
270
- /*
271
- this._iPyWidgetsManager?.registerWithKernel(kernelConnection);
272
- this._iPyWidgetsManager?.restoreWidgets(this._notebookPanel?.model!)
273
- if (this._onSessionConnection) {
274
- this._onSessionConnection(kernelConnection);
275
- }
276
- */
277
- });
278
- this._context.sessionContext.ready.then(() => {
279
- if (this._onSessionConnection) {
280
- this._onSessionConnection(this._context?.sessionContext.session ?? undefined);
281
- }
282
- const kernelConnection = this._context?.sessionContext.session?.kernel;
283
- this._kernelConnection = kernelConnection;
284
- if (this._kernelTransfer) {
285
- if (kernelConnection) {
286
- kernelConnection.connectionStatusChanged.connect((_, status) => {
287
- if (status === 'connected') {
288
- this._kernelTransfer.transfer(kernelConnection);
289
- }
290
- });
291
- }
292
- }
293
- });
294
- if (!this._notebookPanel) {
295
- // Create the Notebook Panel if not yet done.
296
- /*
297
- // Option 1 to create the Notebook Panel.
298
- const content = new Notebook({
299
- rendermime: this._rendermime!,
300
- contentFactory: this._contentFactory,
301
- mimeTypeService: this._mimeTypeService,
302
- notebookConfig: {
303
- ...StaticNotebook.defaultNotebookConfig,
304
- windowingMode: 'none',
305
- recordTiming: true,
306
- }
307
- });
308
- this._notebookPanel = new NotebookPanel({
309
- context: this._context,
310
- content,
311
- });
312
- */
313
- // Option 2 to create the Notebook Panel.
314
- const notebookFactory = this._documentRegistry?.getWidgetFactory('Notebook');
315
- this._notebookPanel = notebookFactory?.createNew(this._context);
316
- // Update panel provider with persistent references
317
- this._panelProvider.setPanel(this._notebookPanel, this._context);
318
- }
319
- const completerHandler = this.setupCompleter(this._notebookPanel);
320
- if (!this._readonly) {
321
- try {
322
- addNotebookCommands(this._commands, completerHandler, this._tracker, this._panelProvider, this._path);
323
- }
324
- catch {
325
- // no-op.
326
- // The commands may already be registered...
327
- }
328
- }
329
- this._boxPanel.addWidget(this._notebookPanel);
330
- BoxPanel.setStretch(this._notebookPanel, 0);
331
- window.addEventListener('resize', () => {
332
- this._notebookPanel?.update();
333
- });
334
- this._context.initialize(isNbFormat).then(() => {
335
- if (isNbFormat) {
336
- this._notebookPanel?.model?.fromJSON(this._nbformat);
337
- }
338
- });
28
+ /**
29
+ * Get the notebook panel.
30
+ */
31
+ get panel() {
32
+ return this._panel;
339
33
  }
340
- setupAdapter() {
341
- document.addEventListener('keydown', this.notebookKeydownListener, true);
342
- const initialFactories = standardRendererFactories.filter(factory => factory.mimeTypes[0] !== 'text/javascript');
343
- /*
344
- const ipywidgetsRendererFactory: IRenderMime.IRendererFactory = {
345
- safe: true,
346
- mimeTypes: [WIDGET_MIMETYPE],
347
- defaultRank: 1,
348
- createRenderer: options =>
349
- new WidgetLabRenderer(options, this._iPyWidgetsManager!),
350
- };
351
- initialFactories.push(ipywidgetsRendererFactory);
352
- */
353
- initialFactories.push(jsonRendererFactory);
354
- initialFactories.push(javascriptRendererFactory);
355
- this._renderers.map(renderer => initialFactories.push(renderer));
356
- const languages = new EditorLanguageRegistry();
357
- // Register default languages.
358
- for (const language of EditorLanguageRegistry.getDefaultLanguages()) {
359
- languages.addLanguage(language);
360
- }
361
- // Add Jupyter Markdown flavor here to support code block highlighting.
362
- languages.addLanguage({
363
- name: 'ipythongfm',
364
- mime: 'text/x-ipythongfm',
365
- load: async () => {
366
- // TODO: add support for LaTeX.
367
- const m = await import('@codemirror/lang-markdown');
368
- return m.markdown({
369
- codeLanguages: (info) => languages.findBest(info),
370
- });
371
- },
372
- });
373
- this._rendermime = new RenderMimeRegistry({
374
- initialFactories,
375
- latexTypesetter: new MathJaxTypesetter(),
376
- markdownParser: getMarked(languages),
377
- });
378
- this._documentRegistry = new DocumentRegistry({});
379
- this._mimeTypeService = new CodeMirrorMimeTypeService(languages);
380
- const themes = new EditorThemeRegistry();
381
- for (const theme of EditorThemeRegistry.getDefaultThemes()) {
382
- themes.addTheme(theme);
383
- }
384
- // Store useVSCodeTheme flag on window for the patch to access
385
- if (typeof window !== 'undefined') {
386
- window.__useVSCodeTheme = this._useVSCodeTheme;
387
- }
388
- const editorExtensions = () => {
389
- const registry = new EditorExtensionRegistry();
390
- for (const extensionFactory of EditorExtensionRegistry.getDefaultExtensions({ themes })) {
391
- registry.addExtension(extensionFactory);
392
- }
393
- registry.addExtension({
394
- name: 'shared-model-binding',
395
- factory: options => {
396
- const sharedModel = options.model.sharedModel;
397
- return EditorExtensionRegistry.createImmutableExtension(ybinding({
398
- ytext: sharedModel.ysource,
399
- undoManager: sharedModel.undoManager ?? undefined,
400
- }));
401
- },
402
- });
403
- return registry;
404
- };
405
- const factoryService = new CodeMirrorEditorFactory({
406
- extensions: editorExtensions(),
407
- languages,
408
- });
409
- const editorServices = {
410
- factoryService,
411
- mimeTypeService: this._mimeTypeService,
412
- };
413
- const editorFactory = editorServices.factoryService.newInlineEditor;
414
- this._contentFactory = new JupyterReactContentFactory({ editorFactory });
415
- this._tracker = new NotebookTracker({ namespace: this._id });
416
- const notebookWidgetFactory = new NotebookWidgetFactory({
417
- name: 'Notebook',
418
- label: 'Notebook',
419
- modelName: 'notebook',
420
- fileTypes: ['notebook'],
421
- defaultFor: ['notebook'],
422
- preferKernel: true,
423
- autoStartDefault: false,
424
- canStartKernel: false,
425
- shutdownOnClose: false,
426
- rendermime: this._rendermime,
427
- contentFactory: this._contentFactory,
428
- mimeTypeService: editorServices.mimeTypeService,
429
- notebookConfig: {
430
- ...StaticNotebook.defaultNotebookConfig,
431
- recordTiming: true,
432
- },
433
- });
434
- notebookWidgetFactory.widgetCreated.connect((sender, notebookPanel) => {
435
- notebookPanel.context.pathChanged.connect(() => {
436
- this._tracker?.save(notebookPanel);
437
- });
438
- this._tracker?.add(notebookPanel);
439
- });
440
- this._documentRegistry.addWidgetFactory(notebookWidgetFactory);
441
- this._notebookModelFactory = new JupyterReactNotebookModelFactory({
442
- nbformat: this._nbformat,
443
- readonly: this._readonly,
444
- });
445
- this._documentRegistry.addModelFactory(this._notebookModelFactory);
446
- this.initializeContext();
34
+ /**
35
+ * Get the notebook widget.
36
+ */
37
+ get notebook() {
38
+ return this._notebook;
447
39
  }
448
- get id() {
449
- return this._id;
40
+ /**
41
+ * Get the notebook context.
42
+ */
43
+ get context() {
44
+ return this._context;
450
45
  }
451
- get readonly() {
452
- return this._readonly;
46
+ /**
47
+ * Get the session context from the notebook panel.
48
+ */
49
+ get sessionContext() {
50
+ return this._panel.sessionContext;
453
51
  }
454
- get serverless() {
455
- return this._serverless;
52
+ /**
53
+ * Get the kernel connection from the session context.
54
+ */
55
+ get kernel() {
56
+ return this._panel.sessionContext?.session?.kernel ?? null;
456
57
  }
457
- get lite() {
458
- return this._lite;
58
+ /**
59
+ * Get the cached kernel info (language_info, etc.).
60
+ * Call fetchKernelInfo() first to populate this.
61
+ */
62
+ get kernelInfo() {
63
+ return this._kernelInfo;
459
64
  }
460
- get path() {
461
- return this._path;
65
+ /**
66
+ * Fetch and cache the kernel info.
67
+ * Returns the cached info if already fetched.
68
+ */
69
+ async fetchKernelInfo() {
70
+ if (this._kernelInfo) {
71
+ return this._kernelInfo;
72
+ }
73
+ const kernel = this.kernel;
74
+ if (kernel) {
75
+ this._kernelInfo = await kernel.info;
76
+ return this._kernelInfo;
77
+ }
78
+ return null;
462
79
  }
463
- get url() {
464
- return this._url;
80
+ /**
81
+ * Assign a new kernel to the notebook.
82
+ *
83
+ * @param kernel - The Kernel instance to assign to the notebook
84
+ *
85
+ * @remarks
86
+ * This method changes the kernel associated with the notebook's session context.
87
+ * It uses the kernel's id to request a kernel change through the session context.
88
+ * The kernel info cache is cleared when a new kernel is assigned.
89
+ */
90
+ assignKernel(kernel) {
91
+ // Clear the cached kernel info since we're changing kernels
92
+ this._kernelInfo = null;
93
+ // Change the kernel using the session context
94
+ this._context?.sessionContext.changeKernel({
95
+ id: kernel.id,
96
+ });
465
97
  }
466
- get nbformat() {
467
- return this._nbformat;
98
+ /**
99
+ * Set the default cell type for new cells.
100
+ */
101
+ setDefaultCellType(cellType) {
102
+ this._defaultCellType = cellType;
468
103
  }
469
- get kernel() {
470
- return this._kernel;
104
+ /**
105
+ * Get the default cell type for new cells.
106
+ */
107
+ get defaultCellType() {
108
+ return this._defaultCellType;
471
109
  }
472
- get kernelConnection() {
473
- return this._kernelConnection;
110
+ /**
111
+ * Insert a new cell above the active cell.
112
+ */
113
+ insertAbove(source) {
114
+ const notebook = this._notebook;
115
+ // Insert above using NotebookActions
116
+ NotebookActions.insertAbove(notebook);
117
+ // Always set the cell type to match _defaultCellType
118
+ // (NotebookActions may create cells with a different default type)
119
+ NotebookActions.changeCellType(notebook, this._defaultCellType);
120
+ // Set the source if provided
121
+ if (source && notebook.activeCell) {
122
+ notebook.activeCell.model.sharedModel.setSource(source);
123
+ }
124
+ // Enter edit mode
125
+ notebook.mode = 'edit';
474
126
  }
475
- get notebookPanel() {
476
- return this._notebookPanel;
127
+ /**
128
+ * Insert a new cell below the active cell.
129
+ */
130
+ insertBelow(source) {
131
+ const notebook = this._notebook;
132
+ // Insert below using NotebookActions
133
+ NotebookActions.insertBelow(notebook);
134
+ // Always set the cell type to match _defaultCellType
135
+ // (NotebookActions may create cells with a different default type)
136
+ NotebookActions.changeCellType(notebook, this._defaultCellType);
137
+ // Set the source if provided
138
+ if (source && notebook.activeCell) {
139
+ notebook.activeCell.model.sharedModel.setSource(source);
140
+ }
141
+ // Enter edit mode
142
+ notebook.mode = 'edit';
477
143
  }
478
- get context() {
479
- return this._context;
144
+ /**
145
+ * Change the type of the active cell.
146
+ */
147
+ changeCellType(cellType) {
148
+ const notebook = this._notebook;
149
+ if (notebook.activeCell && notebook.activeCell.model.type !== cellType) {
150
+ NotebookActions.changeCellType(notebook, cellType);
151
+ }
480
152
  }
481
- set notebookPanel(notebookPanel) {
482
- this._notebookPanel = notebookPanel;
153
+ /**
154
+ * Delete the currently selected cells.
155
+ */
156
+ deleteCells() {
157
+ const notebook = this._notebook;
158
+ NotebookActions.deleteCells(notebook);
483
159
  }
484
- get panel() {
485
- return this._boxPanel;
160
+ /**
161
+ * Get the notebook model.
162
+ */
163
+ get model() {
164
+ return this._context.model;
486
165
  }
487
- get commands() {
488
- return this._commands;
166
+ /**
167
+ * Undo the last change in the notebook.
168
+ *
169
+ * @remarks
170
+ * If there is no history to undo (e.g., at the beginning of the undo stack),
171
+ * this operation will have no effect. The notebook must be available and
172
+ * properly initialized for this operation to succeed.
173
+ */
174
+ undo() {
175
+ const notebook = this._notebook;
176
+ // If we're in edit mode and have an active cell with an editor,
177
+ // try to undo in the cell editor first
178
+ if (notebook.mode === 'edit' && notebook.activeCell?.editor) {
179
+ const editor = notebook.activeCell.editor;
180
+ // CodeMirror editor has an undo method
181
+ if (editor && typeof editor.undo === 'function') {
182
+ editor.undo();
183
+ return;
184
+ }
185
+ }
186
+ // Otherwise, undo at the notebook level (add/remove cells, etc.)
187
+ NotebookActions.undo(notebook);
489
188
  }
490
- get serviceManager() {
491
- return this._serviceManager;
189
+ /**
190
+ * Redo the last undone change in the notebook.
191
+ *
192
+ * @remarks
193
+ * If there is no history to redo (e.g., no prior undo operations or at the
194
+ * end of the redo stack), this operation will have no effect. The notebook
195
+ * must be available and properly initialized for this operation to succeed.
196
+ */
197
+ redo() {
198
+ const notebook = this._notebook;
199
+ // If we're in edit mode and have an active cell with an editor,
200
+ // try to redo in the cell editor first
201
+ if (notebook.mode === 'edit' && notebook.activeCell?.editor) {
202
+ const editor = notebook.activeCell.editor;
203
+ // CodeMirror editor has a redo method
204
+ if (editor && typeof editor.redo === 'function') {
205
+ editor.redo();
206
+ return;
207
+ }
208
+ }
209
+ // Otherwise, redo at the notebook level (add/remove cells, etc.)
210
+ NotebookActions.redo(notebook);
211
+ }
212
+ /**
213
+ * Set the active cell by index.
214
+ *
215
+ * @param index - The index of the cell to activate (0-based)
216
+ *
217
+ * @remarks
218
+ * This method programmatically selects a cell at the specified index.
219
+ * If the index is out of bounds, the operation has no effect.
220
+ */
221
+ setActiveCell(index) {
222
+ const notebook = this._notebook;
223
+ const cellCount = notebook.model?.cells.length ?? 0;
224
+ if (index >= 0 && index < cellCount) {
225
+ notebook.activeCellIndex = index;
226
+ }
492
227
  }
493
- /*
494
- * Only use this method to change an adapter with a nbformat.
228
+ /**
229
+ * Get all cells from the notebook.
230
+ *
231
+ * @returns Array of cell data including type, source, and outputs
232
+ *
233
+ * @remarks
234
+ * This method extracts cell information from the notebook model.
235
+ * For code cells, outputs are included. Returns an empty array if
236
+ * the notebook model is not available.
495
237
  */
496
- setNbformat(nbformat) {
497
- if (!nbformat) {
498
- throw new Error('The nbformat should first be set via the constructor of NotebookAdapter');
238
+ getCells() {
239
+ console.log('[NotebookAdapter.getCells] Called');
240
+ const cells = this._notebook.model?.cells;
241
+ if (!cells) {
242
+ console.log('[NotebookAdapter.getCells] No cells model, returning empty array');
243
+ return [];
499
244
  }
500
- if (this._nbformat !== nbformat) {
501
- this._nbformat = nbformat;
502
- this._notebookPanel?.model?.fromJSON(nbformat);
245
+ console.log(`[NotebookAdapter.getCells] Found ${cells.length} cells`);
246
+ const result = [];
247
+ for (let i = 0; i < cells.length; i++) {
248
+ const cell = cells.get(i);
249
+ if (cell) {
250
+ const cellData = {
251
+ index: i,
252
+ type: cell.type,
253
+ source: cell.sharedModel.getSource(),
254
+ outputs: cell.type === 'code' ? cell.outputs?.toJSON() : undefined,
255
+ };
256
+ console.log(`[NotebookAdapter.getCells] Cell ${i}:`, {
257
+ type: cellData.type,
258
+ sourceLength: cellData.source.length,
259
+ });
260
+ result.push(cellData);
261
+ }
503
262
  }
263
+ console.log(`[NotebookAdapter.getCells] Returning ${result.length} cells`);
264
+ return result;
504
265
  }
505
- setServiceManager(serviceManager, lite) {
506
- this._lite = lite;
507
- this._serviceManager = serviceManager;
508
- this._nbformat = this._notebookPanel?.model?.toJSON();
509
- // this.initializeContext();
266
+ /**
267
+ * Read all cells from the notebook (alias for getCells).
268
+ *
269
+ * @param format - Response format: 'brief' returns preview only, 'detailed' returns full content
270
+ * @returns Array of cell data - brief or detailed based on format
271
+ *
272
+ * @remarks
273
+ * This method is an alias for getCells() to match the readAllCells tool operation.
274
+ * Provides a consistent naming convention for read operations.
275
+ * Supports brief format (index, type, 40-char preview) and detailed format (full content).
276
+ */
277
+ readAllCells(format = 'brief') {
278
+ const cells = this.getCells();
279
+ return cells.map((cell, index) => {
280
+ // Get execution count for code cells
281
+ const cellModel = this._notebook.model?.cells.get(index);
282
+ const execution_count = cellModel?.type === 'code'
283
+ ? (cellModel.executionCount ?? null)
284
+ : null;
285
+ if (format === 'brief') {
286
+ // Brief format: index, type, 40-char preview
287
+ return {
288
+ index,
289
+ type: cell.type,
290
+ preview: cell.source.substring(0, 40),
291
+ };
292
+ }
293
+ else {
294
+ // Detailed format: full content with source, execution_count, outputs
295
+ return {
296
+ index,
297
+ type: cell.type,
298
+ source: cell.source,
299
+ execution_count,
300
+ outputs: cell.outputs,
301
+ };
302
+ }
303
+ });
510
304
  }
511
- setKernel(kernel) {
512
- if (this._kernel === kernel) {
513
- return;
305
+ /**
306
+ * Get the total number of cells in the notebook.
307
+ *
308
+ * @returns The number of cells, or 0 if the notebook model is not available
309
+ */
310
+ getCellCount() {
311
+ return this._notebook.model?.cells.length ?? 0;
312
+ }
313
+ /**
314
+ * Insert a new cell at a specific index.
315
+ *
316
+ * @param cellIndex - The index where the cell should be inserted (0-based)
317
+ * @param source - Optional source code/text for the new cell
318
+ *
319
+ * @remarks
320
+ * This method inserts a cell at the specified position by:
321
+ * 1. Setting the active cell to cellIndex
322
+ * 2. Calling insertAbove to insert before that cell
323
+ *
324
+ * Note: The cell type is determined by _defaultCellType, which should be set
325
+ * before calling this method (typically done by the store layer).
326
+ */
327
+ insertAt(cellIndex, source) {
328
+ const cellCount = this.getCellCount();
329
+ console.log('[NotebookAdapter.insertAt] Called with:', {
330
+ cellIndex,
331
+ sourceLength: source?.length || 0,
332
+ sourcePreview: source?.substring(0, 50),
333
+ currentActiveCell: this._notebook.activeCellIndex,
334
+ cellCount,
335
+ defaultCellType: this._defaultCellType,
336
+ });
337
+ // Validate cell index is within bounds (matches Jupyter MCP Server)
338
+ if (cellIndex < -1 || cellIndex > cellCount) {
339
+ throw new Error(`Index ${cellIndex} is outside valid range [-1, ${cellCount}]. ` +
340
+ `Use -1 to append at end.`);
514
341
  }
515
- this._kernel = kernel;
516
- this.initializeContext();
517
- }
518
- setReadonly(readonly) {
519
- if (this._readonly !== readonly) {
520
- this._readonly = readonly;
521
- this._notebookPanel?.content.widgets.forEach(cell => {
522
- cell.syncEditable = true;
523
- cell.model.sharedModel.setMetadata('editable', !readonly);
524
- });
525
- const cells = this._context?.model.cells;
526
- if (cells) {
527
- Array.from(cells).forEach(cell => {
528
- cell.setMetadata('editable', !readonly);
529
- });
342
+ // Normalize -1 to append position (matches Jupyter MCP Server)
343
+ const actualIndex = cellIndex === -1 ? cellCount : cellIndex;
344
+ console.log('[NotebookAdapter.insertAt] Normalized index:', {
345
+ originalIndex: cellIndex,
346
+ actualIndex,
347
+ cellCount,
348
+ });
349
+ // Insert at the actual index
350
+ if (actualIndex >= cellCount) {
351
+ // Append at end
352
+ console.log('[NotebookAdapter.insertAt] Appending at end');
353
+ if (cellCount > 0) {
354
+ this.setActiveCell(cellCount - 1);
530
355
  }
531
- this._notebookPanel?.content.widgets.forEach(cell => {
532
- cell.saveEditableState();
533
- });
356
+ this.insertBelow(source);
534
357
  }
358
+ else {
359
+ // Insert at specific position
360
+ console.log(`[NotebookAdapter.insertAt] Inserting at index ${actualIndex}`);
361
+ this.setActiveCell(actualIndex);
362
+ this.insertAbove(source);
363
+ }
364
+ console.log('[NotebookAdapter.insertAt] After insertion:', {
365
+ cellCount: this.getCellCount(),
366
+ activeCell: this._notebook.activeCellIndex,
367
+ });
535
368
  }
536
- setServerless(serverless) {
537
- if (this._serverless !== serverless) {
538
- this._serverless = serverless;
539
- // this.initializeContext();
369
+ /**
370
+ * NEW ALIGNED TOOL METHODS
371
+ * These methods align 1:1 with tool operation names for seamless integration
372
+ */
373
+ /**
374
+ * Insert a cell at a specific index (aligned with insertCell tool).
375
+ *
376
+ * @param cellType - Type of cell to insert (code, markdown, or raw)
377
+ * @param cellIndex - Index where to insert (0-based). If undefined, inserts at end.
378
+ * @param source - Optional source code/text for the cell
379
+ */
380
+ insertCell(cellType, cellIndex, source) {
381
+ this.setDefaultCellType(cellType);
382
+ // Default to cell count (end of notebook) if index not provided
383
+ const targetIndex = cellIndex ?? this.getCellCount();
384
+ this.insertAt(targetIndex, source);
385
+ }
386
+ /**
387
+ * Insert multiple cells at a specific index (aligned with insertCells tool).
388
+ *
389
+ * More efficient than calling insertCell multiple times.
390
+ * Cells are inserted sequentially starting at the given index.
391
+ *
392
+ * @param cells - Array of cells to insert (each with type and source)
393
+ * @param cellIndex - Index where to insert first cell (0-based). Use large number for end.
394
+ */
395
+ insertCells(cells, cellIndex) {
396
+ let currentIndex = cellIndex;
397
+ for (const cell of cells) {
398
+ this.setDefaultCellType(cell.type);
399
+ this.insertAt(currentIndex, cell.source);
400
+ currentIndex++;
540
401
  }
541
402
  }
542
- setPath(path) {
543
- if (this._path !== path) {
544
- this._path = path;
545
- this.initializeContext();
403
+ /**
404
+ * Delete cell(s) at the specified index/indices (aligned with deleteCell tool and Jupyter MCP Server).
405
+ *
406
+ * @param index - Single cell index, array of indices, or undefined.
407
+ * - Single number: Deletes that cell
408
+ * - Array: Deletes all cells at those indices (in reverse order to prevent shifting)
409
+ * - Undefined: Deletes the active cell if one exists
410
+ *
411
+ * @remarks
412
+ * This method matches the Jupyter MCP Server behavior:
413
+ * - Validates ALL indices are in range before deleting any
414
+ * - Deletes in reverse order (highest to lowest) to prevent index shifting
415
+ * - Throws error with MCP-compatible message format if any index is out of range
416
+ *
417
+ * @throws {Error} If any index is out of range
418
+ */
419
+ deleteCell(index) {
420
+ const cells = this._notebook.model?.cells;
421
+ const cellCount = cells?.length ?? 0;
422
+ if (index !== undefined) {
423
+ // Convert single index to array for unified handling
424
+ const indices = Array.isArray(index) ? index : [index];
425
+ // Validate ALL indices first (match Jupyter MCP Server error format)
426
+ for (const idx of indices) {
427
+ if (idx < 0 || idx >= cellCount) {
428
+ console.error(`[NotebookAdapter.deleteCell] Index ${idx} is out of range (cell count: ${cellCount})`);
429
+ throw new Error(`Cell index ${idx} is out of range. Notebook has ${cellCount} cells.`);
430
+ }
431
+ }
432
+ // Sort indices in REVERSE order (highest to lowest) to prevent index shifting
433
+ // This matches the Jupyter MCP Server behavior
434
+ const sortedIndices = [...indices].sort((a, b) => b - a);
435
+ console.log(`[NotebookAdapter.deleteCell] Deleting ${sortedIndices.length} cell(s) in reverse order:`, sortedIndices);
436
+ // Delete each cell in reverse order
437
+ for (const idx of sortedIndices) {
438
+ this.setActiveCell(idx);
439
+ this.deleteCells();
440
+ }
441
+ }
442
+ else {
443
+ // No index provided: check if there's an active cell to delete
444
+ const activeCell = this._notebook.activeCell;
445
+ if (!activeCell) {
446
+ console.warn('[NotebookAdapter.deleteCell] No active cell to delete');
447
+ return; // Safely return without deleting
448
+ }
449
+ // Active cell exists, safe to delete
450
+ this.deleteCells();
546
451
  }
547
452
  }
548
- assignKernel(kernel) {
549
- this._kernel = kernel;
550
- this._context?.sessionContext.changeKernel({
551
- id: kernel.id,
552
- });
453
+ /**
454
+ * Updates cell source at the specified index and returns a diff.
455
+ * Matches MCP server's overwrite_cell_source behavior.
456
+ *
457
+ * @param index - Cell index (0-based)
458
+ * @param source - New cell source content
459
+ * @returns Diff string showing changes made
460
+ * @throws Error if cell index is out of range or cell not found
461
+ */
462
+ updateCell(index, source) {
463
+ // Validate cell index
464
+ const cellCount = this._notebook.model?.sharedModel.cells.length ?? 0;
465
+ if (index < 0 || index >= cellCount) {
466
+ throw new Error(`Cell index ${index} is out of range. Notebook has ${cellCount} cells.`);
467
+ }
468
+ // Get the cell at the specified index
469
+ const cellModel = this._notebook.model?.cells.get(index);
470
+ if (!cellModel) {
471
+ throw new Error(`Cell at index ${index} not found.`);
472
+ }
473
+ // Store old source before updating
474
+ const oldSource = cellModel.sharedModel.getSource();
475
+ // Update the cell source
476
+ cellModel.sharedModel.setSource(source);
477
+ // Generate diff (matches MCP server behavior)
478
+ const patch = Diff.createPatch(`cell_${index}`, oldSource, source, 'before', 'after', { context: 3 });
479
+ return patch;
553
480
  }
554
- setDefaultCellType = (cellType) => {
555
- this._notebookPanel.content.notebookConfig.defaultCell = cellType;
556
- };
557
- changeCellType = (cellType) => {
558
- // NotebookActions.changeCellType(this._notebookPanel?.content!, cellType);
559
- const notebook = this._notebookPanel.content;
560
- const notebookSharedModel = notebook.model.sharedModel;
561
- notebook.widgets.forEach((child, index) => {
562
- if (!notebook.isSelectedOrActive(child)) {
563
- return;
564
- }
565
- if (child.model.type !== cellType) {
566
- const raw = child.model.toJSON();
567
- notebookSharedModel.transact(() => {
568
- notebookSharedModel.deleteCell(index);
569
- const newCell = notebookSharedModel.insertCell(index, {
570
- cell_type: cellType,
571
- source: raw.source,
572
- metadata: raw.metadata,
573
- });
574
- if (raw.attachments && ['markdown', 'raw'].includes(cellType)) {
575
- newCell.attachments =
576
- raw.attachments;
481
+ /**
482
+ * Get a cell's content by index or active cell (aligned with getCell tool and MCP Server).
483
+ *
484
+ * @param index - Optional cell index (0-based). If not provided, returns active cell.
485
+ * @param includeOutputs - Whether to include cell outputs (default: true)
486
+ * @returns Cell data or undefined if not found
487
+ */
488
+ getCell(index, includeOutputs = true) {
489
+ if (index !== undefined) {
490
+ // Get cell at specific index
491
+ const cells = this.getCells();
492
+ const cell = cells[index];
493
+ if (!cell)
494
+ return undefined;
495
+ // Get execution count for code cells
496
+ const cellModel = this._notebook.model?.cells.get(index);
497
+ const execution_count = cellModel?.type === 'code'
498
+ ? (cellModel.executionCount ?? null)
499
+ : null;
500
+ return {
501
+ type: cell.type,
502
+ source: cell.source,
503
+ execution_count,
504
+ outputs: includeOutputs ? cell.outputs : undefined,
505
+ };
506
+ }
507
+ else {
508
+ // Get active cell
509
+ const activeCell = this._notebook.activeCell;
510
+ if (!activeCell)
511
+ return undefined;
512
+ const execution_count = activeCell.model.type === 'code'
513
+ ? (activeCell.model.executionCount ?? null)
514
+ : null;
515
+ return {
516
+ type: activeCell.model.type,
517
+ source: activeCell.model.sharedModel.getSource(),
518
+ execution_count,
519
+ outputs: includeOutputs && activeCell.model.type === 'code'
520
+ ? activeCell.model.outputs?.toJSON()
521
+ : undefined,
522
+ };
523
+ }
524
+ }
525
+ /**
526
+ * Run a cell and optionally capture outputs (aligned with runCell tool).
527
+ *
528
+ * @param params - Parameters for cell execution
529
+ * @param params.index - Cell index to run (optional, defaults to active cell)
530
+ * @param params.timeoutSeconds - Timeout in seconds (optional, for future use)
531
+ * @param params.stream - Enable streaming progress (optional, for future use)
532
+ * @param params.progressInterval - Progress update interval (optional, for future use)
533
+ * @returns Promise resolving to execution result with outputs
534
+ */
535
+ async runCell(params) {
536
+ const { index } = params || {};
537
+ // Note: timeoutSeconds, stream, progressInterval are accepted for future use
538
+ // but timeout/streaming logic is handled at the operation layer
539
+ // Set active cell if index provided
540
+ if (index !== undefined) {
541
+ this.setActiveCell(index);
542
+ }
543
+ const targetIndex = index ?? this._notebook.activeCellIndex;
544
+ if (targetIndex === -1) {
545
+ throw new Error('No active cell to execute');
546
+ }
547
+ // Execute the cell using JupyterLab's NotebookActions
548
+ await NotebookActions.run(this._notebook, this._context.sessionContext);
549
+ // Wait a brief moment for outputs to be available
550
+ await new Promise(resolve => setTimeout(resolve, 100));
551
+ // Capture outputs after execution
552
+ const cellData = this.getCell(targetIndex, true);
553
+ if (!cellData) {
554
+ return {
555
+ execution_count: null,
556
+ outputs: [],
557
+ };
558
+ }
559
+ // Convert outputs to string array (matching MCP format)
560
+ const outputs = [];
561
+ if (cellData.outputs && Array.isArray(cellData.outputs)) {
562
+ for (const output of cellData.outputs) {
563
+ if (typeof output === 'string') {
564
+ outputs.push(output);
565
+ }
566
+ else if (output && typeof output === 'object') {
567
+ // Handle different output types
568
+ const outputObj = output;
569
+ if (outputObj.output_type === 'stream') {
570
+ const text = outputObj.text;
571
+ if (typeof text === 'string') {
572
+ outputs.push(text);
573
+ }
574
+ else if (Array.isArray(text)) {
575
+ outputs.push(text.join(''));
576
+ }
577
577
  }
578
- });
578
+ else if (outputObj.output_type === 'execute_result' ||
579
+ outputObj.output_type === 'display_data') {
580
+ const data = outputObj.data;
581
+ if (data) {
582
+ // Prefer text/plain output
583
+ if (data['text/plain']) {
584
+ const text = data['text/plain'];
585
+ if (typeof text === 'string') {
586
+ outputs.push(text);
587
+ }
588
+ else if (Array.isArray(text)) {
589
+ outputs.push(text.join(''));
590
+ }
591
+ }
592
+ }
593
+ }
594
+ else if (outputObj.output_type === 'error') {
595
+ // Format error output
596
+ const ename = outputObj.ename ?? 'Error';
597
+ const evalue = outputObj.evalue ?? '';
598
+ const traceback = outputObj.traceback;
599
+ if (Array.isArray(traceback) && traceback.length > 0) {
600
+ outputs.push(`[ERROR: ${ename}: ${evalue}]\n${traceback.join('\n')}`);
601
+ }
602
+ else {
603
+ outputs.push(`[ERROR: ${ename}: ${evalue}]`);
604
+ }
605
+ }
606
+ }
579
607
  }
580
- if (cellType === 'markdown') {
581
- // Fetch the new widget and unrender it.
582
- child = notebook.widgets[index];
583
- child.rendered = false;
608
+ }
609
+ return {
610
+ execution_count: cellData.execution_count,
611
+ outputs,
612
+ };
613
+ }
614
+ /**
615
+ * Run all cells in the notebook (aligned with runAllCells tool).
616
+ */
617
+ runAllCells() {
618
+ this._commands.execute(NotebookCommandIds.runAll);
619
+ }
620
+ /**
621
+ * Clear all outputs from all cells in the notebook.
622
+ *
623
+ * @remarks
624
+ * Removes all execution outputs from all cells. This operation:
625
+ * - Clears outputs but preserves cell source code
626
+ * - Resets execution counts
627
+ * - Cannot be undone
628
+ */
629
+ clearAllOutputs() {
630
+ NotebookActions.clearAllOutputs(this._notebook);
631
+ }
632
+ /**
633
+ * Execute code directly in the kernel without creating a cell.
634
+ *
635
+ * This method sends code execution requests directly to the kernel,
636
+ * bypassing the notebook cell model. Useful for:
637
+ * - Variable inspection
638
+ * - Environment setup
639
+ * - Background tasks
640
+ * - Tool introspection
641
+ *
642
+ * @param code - Code to execute
643
+ * @param options - Execution options
644
+ * @returns Promise with execution result including outputs
645
+ */
646
+ async executeCode(code, options = {}) {
647
+ const sessionContext = this._panel.sessionContext;
648
+ if (!sessionContext || !sessionContext.session?.kernel) {
649
+ return {
650
+ success: false,
651
+ error: 'No active kernel session',
652
+ };
653
+ }
654
+ const kernel = sessionContext.session.kernel;
655
+ try {
656
+ const future = kernel.requestExecute({
657
+ code,
658
+ stop_on_error: true, // Internal default: stop on error
659
+ store_history: false, // Internal default: don't store in history
660
+ silent: false, // Internal default: not silent (show outputs)
661
+ allow_stdin: false,
662
+ });
663
+ const outputs = [];
664
+ let executionCount;
665
+ // Collect outputs
666
+ future.onIOPub = msg => {
667
+ const msgType = msg.header.msg_type;
668
+ if (msgType === 'stream') {
669
+ outputs.push({
670
+ type: 'stream',
671
+ content: msg.content,
672
+ });
673
+ }
674
+ else if (msgType === 'execute_result') {
675
+ outputs.push({
676
+ type: 'execute_result',
677
+ content: msg.content,
678
+ });
679
+ executionCount = msg.content.execution_count;
680
+ }
681
+ else if (msgType === 'display_data') {
682
+ outputs.push({
683
+ type: 'display_data',
684
+ content: msg.content,
685
+ });
686
+ }
687
+ else if (msgType === 'error') {
688
+ outputs.push({
689
+ type: 'error',
690
+ content: msg.content,
691
+ });
692
+ }
693
+ };
694
+ // Handle timeout if specified (default: 30 seconds, max: 60)
695
+ const timeoutMs = (options.timeout ?? 30) * 1000;
696
+ const executionPromise = future.done;
697
+ const timeoutPromise = new Promise((_, reject) => {
698
+ setTimeout(() => {
699
+ reject(new Error(`Execution timeout after ${options.timeout ?? 30} seconds`));
700
+ }, timeoutMs);
701
+ });
702
+ try {
703
+ await Promise.race([executionPromise, timeoutPromise]);
584
704
  }
585
- });
586
- notebook.deselectAll();
587
- };
588
- insertAbove = (source) => {
589
- const notebook = this._notebookPanel.content;
590
- const model = this._notebookPanel.context.model;
591
- const newIndex = notebook.activeCell ? notebook.activeCellIndex : 0;
592
- model.sharedModel.insertCell(newIndex, {
593
- cell_type: notebook.notebookConfig.defaultCell,
594
- source,
595
- metadata: notebook.notebookConfig.defaultCell === 'code'
596
- ? {
597
- // This is an empty cell created by user, thus is trusted
598
- trusted: true,
705
+ catch (timeoutError) {
706
+ // Interrupt kernel on timeout
707
+ try {
708
+ await kernel.interrupt();
599
709
  }
600
- : {},
601
- });
602
- // Make the newly inserted cell active.
603
- notebook.activeCellIndex = newIndex;
604
- notebook.deselectAll();
605
- };
606
- insertBelow = (source) => {
607
- const notebook = this._notebookPanel.content;
608
- const model = this._notebookPanel.context.model;
609
- const newIndex = notebook.activeCell ? notebook.activeCellIndex + 1 : 0;
610
- model.sharedModel.insertCell(newIndex, {
611
- cell_type: notebook.notebookConfig.defaultCell,
612
- source,
613
- metadata: notebook.notebookConfig.defaultCell === 'code'
614
- ? {
615
- // This is an empty cell created by user, thus is trusted.
616
- trusted: true,
710
+ catch (interruptError) {
711
+ console.error('Failed to interrupt kernel:', interruptError);
617
712
  }
618
- : {},
619
- });
620
- // Make the newly inserted cell active.
621
- notebook.activeCellIndex = newIndex;
622
- notebook.deselectAll();
623
- };
624
- dispose = () => {
625
- document.removeEventListener('keydown', this.notebookKeydownListener, true);
626
- this._context?.dispose();
627
- this._notebookPanel?.dispose();
628
- this._boxPanel.dispose();
629
- };
713
+ return {
714
+ success: false,
715
+ error: `Execution exceeded ${options.timeout ?? 30} seconds and was interrupted`,
716
+ outputs,
717
+ };
718
+ }
719
+ return {
720
+ success: true,
721
+ outputs,
722
+ executionCount,
723
+ };
724
+ }
725
+ catch (error) {
726
+ return {
727
+ success: false,
728
+ error: error instanceof Error ? error.message : String(error),
729
+ };
730
+ }
731
+ }
732
+ /**
733
+ * Dispose of the adapter.
734
+ */
735
+ dispose() {
736
+ // Clean up any resources if needed
737
+ // The panel, notebook, and context are managed by NotebookBase
738
+ }
630
739
  }
631
740
  export default NotebookAdapter;
632
741
  //# sourceMappingURL=NotebookAdapter.js.map