@theia/plugin-ext 1.40.1 → 1.41.0

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 (292) hide show
  1. package/lib/common/collections.d.ts +4 -0
  2. package/lib/common/collections.d.ts.map +1 -1
  3. package/lib/common/collections.js +17 -1
  4. package/lib/common/collections.js.map +1 -1
  5. package/lib/common/errors.d.ts +14 -0
  6. package/lib/common/errors.d.ts.map +1 -1
  7. package/lib/common/errors.js +17 -1
  8. package/lib/common/errors.js.map +1 -1
  9. package/lib/common/plugin-api-rpc.d.ts +286 -6
  10. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  11. package/lib/common/plugin-api-rpc.js +20 -1
  12. package/lib/common/plugin-api-rpc.js.map +1 -1
  13. package/lib/common/plugin-protocol.d.ts +27 -5
  14. package/lib/common/plugin-protocol.d.ts.map +1 -1
  15. package/lib/common/plugin-protocol.js.map +1 -1
  16. package/lib/hosted/browser/hosted-plugin.d.ts +5 -2
  17. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  18. package/lib/hosted/browser/hosted-plugin.js +21 -12
  19. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  20. package/lib/hosted/node/hosted-plugin-deployer-handler.js +1 -1
  21. package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
  22. package/lib/hosted/node/plugin-reader.d.ts +1 -1
  23. package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
  24. package/lib/hosted/node/plugin-reader.js +1 -1
  25. package/lib/hosted/node/plugin-reader.js.map +1 -1
  26. package/lib/hosted/node/scanners/grammars-reader.d.ts +1 -1
  27. package/lib/hosted/node/scanners/grammars-reader.d.ts.map +1 -1
  28. package/lib/hosted/node/scanners/grammars-reader.js +5 -5
  29. package/lib/hosted/node/scanners/grammars-reader.js.map +1 -1
  30. package/lib/hosted/node/scanners/scanner-theia.d.ts +6 -6
  31. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  32. package/lib/hosted/node/scanners/scanner-theia.js +54 -41
  33. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  34. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts +1 -1
  35. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts.map +1 -1
  36. package/lib/main/browser/custom-editors/custom-editor-widget.js +1 -1
  37. package/lib/main/browser/custom-editors/custom-editor-widget.js.map +1 -1
  38. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +1 -1
  39. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  40. package/lib/main/browser/custom-editors/custom-editors-main.js +1 -1
  41. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  42. package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
  43. package/lib/main/browser/editors-and-documents-main.js +1 -0
  44. package/lib/main/browser/editors-and-documents-main.js.map +1 -1
  45. package/lib/main/browser/languages-main.d.ts.map +1 -1
  46. package/lib/main/browser/languages-main.js +6 -4
  47. package/lib/main/browser/languages-main.js.map +1 -1
  48. package/lib/main/browser/main-context.d.ts.map +1 -1
  49. package/lib/main/browser/main-context.js +18 -0
  50. package/lib/main/browser/main-context.js.map +1 -1
  51. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  52. package/lib/main/browser/menus/menus-contribution-handler.js +6 -3
  53. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  54. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts +50 -0
  55. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts.map +1 -0
  56. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +189 -0
  57. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -0
  58. package/lib/main/browser/notebooks/notebook-documents-main.d.ts +22 -0
  59. package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -0
  60. package/lib/main/browser/notebooks/notebook-documents-main.js +133 -0
  61. package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -0
  62. package/lib/main/browser/notebooks/notebook-dto.d.ts +15 -0
  63. package/lib/main/browser/notebooks/notebook-dto.d.ts.map +1 -0
  64. package/lib/main/browser/notebooks/notebook-dto.js +138 -0
  65. package/lib/main/browser/notebooks/notebook-dto.js.map +1 -0
  66. package/lib/main/browser/notebooks/notebook-editors-main.d.ts +20 -0
  67. package/lib/main/browser/notebooks/notebook-editors-main.d.ts.map +1 -0
  68. package/lib/main/browser/notebooks/notebook-editors-main.js +58 -0
  69. package/lib/main/browser/notebooks/notebook-editors-main.js.map +1 -0
  70. package/lib/main/browser/notebooks/notebook-kernels-main.d.ts +42 -0
  71. package/lib/main/browser/notebooks/notebook-kernels-main.d.ts.map +1 -0
  72. package/lib/main/browser/notebooks/notebook-kernels-main.js +230 -0
  73. package/lib/main/browser/notebooks/notebook-kernels-main.js.map +1 -0
  74. package/lib/main/browser/notebooks/notebook-renderers-main.d.ts +12 -0
  75. package/lib/main/browser/notebooks/notebook-renderers-main.d.ts.map +1 -0
  76. package/lib/main/browser/notebooks/notebook-renderers-main.js +39 -0
  77. package/lib/main/browser/notebooks/notebook-renderers-main.js.map +1 -0
  78. package/lib/main/browser/notebooks/notebooks-main.d.ts +20 -0
  79. package/lib/main/browser/notebooks/notebooks-main.d.ts.map +1 -0
  80. package/lib/main/browser/notebooks/notebooks-main.js +103 -0
  81. package/lib/main/browser/notebooks/notebooks-main.js.map +1 -0
  82. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts +35 -0
  83. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -0
  84. package/lib/main/browser/notebooks/renderers/cell-output-webview.js +204 -0
  85. package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -0
  86. package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts +13 -0
  87. package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts.map +1 -0
  88. package/lib/main/browser/notebooks/renderers/output-webview-internal.js +375 -0
  89. package/lib/main/browser/notebooks/renderers/output-webview-internal.js.map +1 -0
  90. package/lib/main/browser/notebooks/renderers/webview-communication.d.ts +52 -0
  91. package/lib/main/browser/notebooks/renderers/webview-communication.d.ts.map +1 -0
  92. package/{src/typings/index.d.ts → lib/main/browser/notebooks/renderers/webview-communication.js} +8 -11
  93. package/lib/main/browser/notebooks/renderers/webview-communication.js.map +1 -0
  94. package/lib/main/browser/plugin-contribution-handler.d.ts +3 -0
  95. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  96. package/lib/main/browser/plugin-contribution-handler.js +31 -3
  97. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  98. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  99. package/lib/main/browser/plugin-ext-frontend-module.js +3 -2
  100. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  101. package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
  102. package/lib/main/browser/plugin-icon-theme-service.js +6 -0
  103. package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
  104. package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
  105. package/lib/main/browser/plugin-shared-style.js +2 -1
  106. package/lib/main/browser/plugin-shared-style.js.map +1 -1
  107. package/lib/main/browser/tasks-main.js +2 -2
  108. package/lib/main/browser/tasks-main.js.map +1 -1
  109. package/lib/main/browser/terminal-main.d.ts +2 -2
  110. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  111. package/lib/main/browser/terminal-main.js +4 -4
  112. package/lib/main/browser/terminal-main.js.map +1 -1
  113. package/lib/main/browser/view/tree-view-widget.d.ts +3 -1
  114. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  115. package/lib/main/browser/view/tree-view-widget.js +32 -1
  116. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  117. package/lib/main/browser/view/tree-views-main.d.ts +2 -1
  118. package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
  119. package/lib/main/browser/view/tree-views-main.js +10 -0
  120. package/lib/main/browser/view/tree-views-main.js.map +1 -1
  121. package/lib/main/browser/webview/webview.d.ts +1 -0
  122. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  123. package/lib/main/browser/webview/webview.js +5 -0
  124. package/lib/main/browser/webview/webview.js.map +1 -1
  125. package/lib/main/node/errors.spec.d.ts +2 -0
  126. package/lib/main/node/errors.spec.d.ts.map +1 -0
  127. package/lib/main/node/errors.spec.js +36 -0
  128. package/lib/main/node/errors.spec.js.map +1 -0
  129. package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts +5 -2
  130. package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts.map +1 -1
  131. package/lib/main/node/handlers/plugin-theia-directory-handler.js +14 -8
  132. package/lib/main/node/handlers/plugin-theia-directory-handler.js.map +1 -1
  133. package/lib/main/node/handlers/plugin-theia-file-handler.d.ts +2 -1
  134. package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
  135. package/lib/main/node/handlers/plugin-theia-file-handler.js +13 -5
  136. package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
  137. package/lib/main/node/paths/plugin-paths-service.d.ts.map +1 -1
  138. package/lib/main/node/paths/plugin-paths-service.js +4 -9
  139. package/lib/main/node/paths/plugin-paths-service.js.map +1 -1
  140. package/lib/main/node/plugin-deployer-directory-handler-context-impl.js +8 -8
  141. package/lib/main/node/plugin-deployer-directory-handler-context-impl.js.map +1 -1
  142. package/lib/main/node/plugin-deployer-entry-impl.d.ts +2 -2
  143. package/lib/main/node/plugin-deployer-entry-impl.d.ts.map +1 -1
  144. package/lib/main/node/plugin-deployer-entry-impl.js +9 -7
  145. package/lib/main/node/plugin-deployer-entry-impl.js.map +1 -1
  146. package/lib/main/node/plugin-deployer-impl.d.ts +2 -2
  147. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  148. package/lib/main/node/plugin-deployer-impl.js +16 -24
  149. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  150. package/lib/main/node/plugin-deployer-proxy-entry-impl.d.ts +2 -2
  151. package/lib/main/node/plugin-deployer-proxy-entry-impl.d.ts.map +1 -1
  152. package/lib/main/node/plugin-github-resolver.d.ts.map +1 -1
  153. package/lib/main/node/plugin-github-resolver.js +14 -6
  154. package/lib/main/node/plugin-github-resolver.js.map +1 -1
  155. package/lib/main/node/plugin-http-resolver.d.ts.map +1 -1
  156. package/lib/main/node/plugin-http-resolver.js +14 -6
  157. package/lib/main/node/plugin-http-resolver.js.map +1 -1
  158. package/lib/main/node/temp-dir-util.d.ts +1 -0
  159. package/lib/main/node/temp-dir-util.d.ts.map +1 -1
  160. package/lib/main/node/temp-dir-util.js +12 -3
  161. package/lib/main/node/temp-dir-util.js.map +1 -1
  162. package/lib/plugin/editors-and-documents.d.ts +1 -1
  163. package/lib/plugin/editors-and-documents.d.ts.map +1 -1
  164. package/lib/plugin/editors-and-documents.js +1 -1
  165. package/lib/plugin/editors-and-documents.js.map +1 -1
  166. package/lib/plugin/notebook/notebook-document.d.ts +62 -0
  167. package/lib/plugin/notebook/notebook-document.d.ts.map +1 -0
  168. package/lib/plugin/notebook/notebook-document.js +373 -0
  169. package/lib/plugin/notebook/notebook-document.js.map +1 -0
  170. package/lib/plugin/notebook/notebook-documents.d.ts +17 -0
  171. package/lib/plugin/notebook/notebook-documents.d.ts.map +1 -0
  172. package/lib/plugin/notebook/notebook-documents.js +48 -0
  173. package/lib/plugin/notebook/notebook-documents.js.map +1 -0
  174. package/lib/plugin/notebook/notebook-editor.d.ts +21 -0
  175. package/lib/plugin/notebook/notebook-editor.d.ts.map +1 -0
  176. package/lib/plugin/notebook/notebook-editor.js +99 -0
  177. package/lib/plugin/notebook/notebook-editor.js.map +1 -0
  178. package/lib/plugin/notebook/notebook-editors.d.ts +14 -0
  179. package/lib/plugin/notebook/notebook-editors.d.ts.map +1 -0
  180. package/lib/plugin/notebook/notebook-editors.js +65 -0
  181. package/lib/plugin/notebook/notebook-editors.js.map +1 -0
  182. package/lib/plugin/notebook/notebook-kernels.d.ts +37 -0
  183. package/lib/plugin/notebook/notebook-kernels.d.ts.map +1 -0
  184. package/lib/plugin/notebook/notebook-kernels.js +516 -0
  185. package/lib/plugin/notebook/notebook-kernels.js.map +1 -0
  186. package/lib/plugin/notebook/notebook-renderers.d.ts +14 -0
  187. package/lib/plugin/notebook/notebook-renderers.d.ts.map +1 -0
  188. package/lib/plugin/notebook/notebook-renderers.js +63 -0
  189. package/lib/plugin/notebook/notebook-renderers.js.map +1 -0
  190. package/lib/plugin/notebook/notebooks.d.ts +57 -0
  191. package/lib/plugin/notebook/notebooks.d.ts.map +1 -0
  192. package/lib/plugin/notebook/notebooks.js +295 -0
  193. package/lib/plugin/notebook/notebooks.js.map +1 -0
  194. package/lib/plugin/plugin-context.d.ts +2 -2
  195. package/lib/plugin/plugin-context.d.ts.map +1 -1
  196. package/lib/plugin/plugin-context.js +79 -59
  197. package/lib/plugin/plugin-context.js.map +1 -1
  198. package/lib/plugin/plugin-manager.d.ts +2 -0
  199. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  200. package/lib/plugin/plugin-manager.js +9 -1
  201. package/lib/plugin/plugin-manager.js.map +1 -1
  202. package/lib/plugin/tasks/task-provider.d.ts +2 -2
  203. package/lib/plugin/tasks/task-provider.d.ts.map +1 -1
  204. package/lib/plugin/tasks/task-provider.js +7 -10
  205. package/lib/plugin/tasks/task-provider.js.map +1 -1
  206. package/lib/plugin/tasks/tasks.d.ts +3 -2
  207. package/lib/plugin/tasks/tasks.d.ts.map +1 -1
  208. package/lib/plugin/tasks/tasks.js +18 -13
  209. package/lib/plugin/tasks/tasks.js.map +1 -1
  210. package/lib/plugin/terminal-ext.d.ts +3 -0
  211. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  212. package/lib/plugin/terminal-ext.js +11 -1
  213. package/lib/plugin/terminal-ext.js.map +1 -1
  214. package/lib/plugin/tree/tree-views.d.ts +15 -5
  215. package/lib/plugin/tree/tree-views.d.ts.map +1 -1
  216. package/lib/plugin/tree/tree-views.js +52 -3
  217. package/lib/plugin/tree/tree-views.js.map +1 -1
  218. package/lib/plugin/type-converters.d.ts +60 -0
  219. package/lib/plugin/type-converters.d.ts.map +1 -1
  220. package/lib/plugin/type-converters.js +372 -13
  221. package/lib/plugin/type-converters.js.map +1 -1
  222. package/lib/plugin/types-impl.d.ts +68 -29
  223. package/lib/plugin/types-impl.d.ts.map +1 -1
  224. package/lib/plugin/types-impl.js +123 -44
  225. package/lib/plugin/types-impl.js.map +1 -1
  226. package/package.json +31 -29
  227. package/src/common/collections.ts +17 -0
  228. package/src/common/errors.ts +26 -0
  229. package/src/common/plugin-api-rpc.ts +340 -5
  230. package/src/common/plugin-protocol.ts +23 -5
  231. package/src/hosted/browser/hosted-plugin.ts +21 -14
  232. package/src/hosted/node/hosted-plugin-deployer-handler.ts +1 -1
  233. package/src/hosted/node/plugin-reader.ts +1 -1
  234. package/src/hosted/node/scanners/grammars-reader.ts +6 -5
  235. package/src/hosted/node/scanners/scanner-theia.ts +55 -41
  236. package/src/main/browser/custom-editors/custom-editor-widget.ts +1 -1
  237. package/src/main/browser/custom-editors/custom-editors-main.ts +1 -1
  238. package/src/main/browser/editors-and-documents-main.ts +1 -0
  239. package/src/main/browser/languages-main.ts +7 -4
  240. package/src/main/browser/main-context.ts +19 -0
  241. package/src/main/browser/menus/menus-contribution-handler.ts +7 -4
  242. package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +238 -0
  243. package/src/main/browser/notebooks/notebook-documents-main.ts +166 -0
  244. package/src/main/browser/notebooks/notebook-dto.ts +141 -0
  245. package/src/main/browser/notebooks/notebook-editors-main.ts +70 -0
  246. package/src/main/browser/notebooks/notebook-kernels-main.ts +291 -0
  247. package/src/main/browser/notebooks/notebook-renderers-main.ts +47 -0
  248. package/src/main/browser/notebooks/notebooks-main.ts +124 -0
  249. package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +198 -0
  250. package/src/main/browser/notebooks/renderers/output-webview-internal.ts +476 -0
  251. package/src/main/browser/notebooks/renderers/webview-communication.ts +79 -0
  252. package/src/main/browser/plugin-contribution-handler.ts +36 -3
  253. package/src/main/browser/plugin-ext-frontend-module.ts +7 -3
  254. package/src/main/browser/plugin-icon-theme-service.ts +6 -0
  255. package/src/main/browser/plugin-shared-style.ts +2 -1
  256. package/src/main/browser/tasks-main.ts +4 -4
  257. package/src/main/browser/terminal-main.ts +5 -5
  258. package/src/main/browser/view/tree-view-widget.tsx +36 -2
  259. package/src/main/browser/view/tree-views-main.ts +8 -0
  260. package/src/main/browser/webview/webview.ts +6 -0
  261. package/src/main/node/errors.spec.ts +37 -0
  262. package/src/main/node/handlers/plugin-theia-directory-handler.ts +18 -8
  263. package/src/main/node/handlers/plugin-theia-file-handler.ts +18 -6
  264. package/src/main/node/paths/plugin-paths-service.ts +5 -10
  265. package/src/main/node/plugin-deployer-directory-handler-context-impl.ts +8 -8
  266. package/src/main/node/plugin-deployer-entry-impl.ts +9 -7
  267. package/src/main/node/plugin-deployer-impl.ts +20 -28
  268. package/src/main/node/plugin-deployer-proxy-entry-impl.ts +2 -2
  269. package/src/main/node/plugin-github-resolver.ts +15 -8
  270. package/src/main/node/plugin-http-resolver.ts +15 -8
  271. package/src/main/node/temp-dir-util.ts +11 -2
  272. package/src/plugin/editors-and-documents.ts +1 -1
  273. package/src/plugin/notebook/notebook-document.ts +438 -0
  274. package/src/plugin/notebook/notebook-documents.ts +58 -0
  275. package/src/plugin/notebook/notebook-editor.ts +116 -0
  276. package/src/plugin/notebook/notebook-editors.ts +71 -0
  277. package/src/plugin/notebook/notebook-kernels.ts +616 -0
  278. package/src/plugin/notebook/notebook-renderers.ts +72 -0
  279. package/src/plugin/notebook/notebooks.ts +385 -0
  280. package/src/plugin/plugin-context.ts +77 -70
  281. package/src/plugin/plugin-manager.ts +9 -1
  282. package/src/plugin/tasks/task-provider.ts +9 -12
  283. package/src/plugin/tasks/tasks.ts +18 -13
  284. package/src/plugin/terminal-ext.ts +13 -1
  285. package/src/plugin/tree/tree-views.ts +57 -7
  286. package/src/plugin/type-converters.ts +370 -12
  287. package/src/plugin/types-impl.ts +162 -58
  288. package/lib/main/browser/custom-editors/undo-redo-service.d.ts +0 -24
  289. package/lib/main/browser/custom-editors/undo-redo-service.d.ts.map +0 -1
  290. package/lib/main/browser/custom-editors/undo-redo-service.js +0 -111
  291. package/lib/main/browser/custom-editors/undo-redo-service.js.map +0 -1
  292. package/src/main/browser/custom-editors/undo-redo-service.ts +0 -120
@@ -0,0 +1,71 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ /*---------------------------------------------------------------------------------------------
17
+ * Copyright (c) Microsoft Corporation. All rights reserved.
18
+ * Licensed under the MIT License. See License.txt in the project root for license information.
19
+ *--------------------------------------------------------------------------------------------*/
20
+
21
+ import { Emitter } from '@theia/core';
22
+ import { NotebookEditorPropertiesChangeData, NotebookEditorsExt, NotebookEditorViewColumnInfo } from '../../common';
23
+ import * as typeConverters from '../type-converters';
24
+ import * as theia from '@theia/plugin';
25
+ import { NotebooksExtImpl } from './notebooks';
26
+
27
+ export class NotebookEditorsExtImpl implements NotebookEditorsExt {
28
+
29
+ private readonly DidChangeNotebookEditorSelectionEmitter = new Emitter<theia.NotebookEditorSelectionChangeEvent>();
30
+ private readonly DidChangeNotebookEditorVisibleRangesEmitter = new Emitter<theia.NotebookEditorVisibleRangesChangeEvent>();
31
+
32
+ readonly onDidChangeNotebookEditorSelection = this.DidChangeNotebookEditorSelectionEmitter.event;
33
+ readonly onDidChangeNotebookEditorVisibleRanges = this.DidChangeNotebookEditorVisibleRangesEmitter.event;
34
+
35
+ constructor(
36
+ private readonly notebooksAndEditors: NotebooksExtImpl,
37
+ ) { }
38
+
39
+ $acceptEditorPropertiesChanged(id: string, data: NotebookEditorPropertiesChangeData): void {
40
+ const editor = this.notebooksAndEditors.getEditorById(id);
41
+ // ONE: make all state updates
42
+ if (data.visibleRanges) {
43
+ editor.acceptVisibleRanges(data.visibleRanges.ranges.map(typeConverters.NotebookRange.to));
44
+ }
45
+ if (data.selections) {
46
+ editor.acceptSelections(data.selections.selections.map(typeConverters.NotebookRange.to));
47
+ }
48
+
49
+ // TWO: send all events after states have been updated
50
+ if (data.visibleRanges) {
51
+ this.DidChangeNotebookEditorVisibleRangesEmitter.fire({
52
+ notebookEditor: editor.apiEditor,
53
+ visibleRanges: editor.apiEditor.visibleRanges
54
+ });
55
+ }
56
+ if (data.selections) {
57
+ this.DidChangeNotebookEditorSelectionEmitter.fire(Object.freeze({
58
+ notebookEditor: editor.apiEditor,
59
+ selections: editor.apiEditor.selections
60
+ }));
61
+ }
62
+ }
63
+
64
+ $acceptEditorViewColumns(data: NotebookEditorViewColumnInfo): void {
65
+ // eslint-disable-next-line guard-for-in
66
+ for (const id in data) {
67
+ const editor = this.notebooksAndEditors.getEditorById(id);
68
+ editor.acceptViewColumn(typeConverters.ViewColumn.to(data[id]));
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,616 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ /*---------------------------------------------------------------------------------------------
17
+ * Copyright (c) Microsoft Corporation. All rights reserved.
18
+ * Licensed under the MIT License. See License.txt in the project root for license information.
19
+ *--------------------------------------------------------------------------------------------*/
20
+
21
+ import { CancellationToken } from '@theia/plugin';
22
+ import {
23
+ CellExecuteUpdateDto, NotebookKernelDto, NotebookKernelsExt, NotebookKernelsMain, NotebookKernelSourceActionDto, NotebookOutputDto, PLUGIN_RPC_CONTEXT
24
+ } from '../../common';
25
+ import { RPCProtocol } from '../../common/rpc-protocol';
26
+ import { UriComponents } from '../../common/uri-components';
27
+ import * as theia from '@theia/plugin';
28
+ import { CancellationTokenSource, Disposable, DisposableCollection, Emitter } from '@theia/core';
29
+ import { Cell } from './notebook-document';
30
+ import { NotebooksExtImpl } from './notebooks';
31
+ import { NotebookCellOutputConverter, NotebookCellOutputItem, NotebookKernelSourceAction } from '../type-converters';
32
+ import { timeout, Deferred } from '@theia/core/lib/common/promise-util';
33
+ import { CellExecutionUpdateType, NotebookCellExecutionState } from '@theia/notebook/lib/common';
34
+ import { CommandRegistryImpl } from '../command-registry';
35
+ import { NotebookCellOutput, NotebookRendererScript, URI } from '../types-impl';
36
+
37
+ interface KernelData {
38
+ extensionId: string;
39
+ controller: theia.NotebookController;
40
+ onDidChangeSelection: Emitter<{ selected: boolean; notebook: theia.NotebookDocument }>;
41
+ onDidReceiveMessage: Emitter<{ editor: theia.NotebookEditor; message: unknown }>;
42
+ associatedNotebooks: Map<string, boolean>;
43
+ }
44
+
45
+ export class NotebookKernelsExtImpl implements NotebookKernelsExt {
46
+
47
+ private readonly activeExecutions = new Map<string, NotebookCellExecutionTask>();
48
+
49
+ private readonly kernelData = new Map<number, KernelData>();
50
+
51
+ private readonly proxy: NotebookKernelsMain;
52
+
53
+ private kernelDetectionTasks = new Map<number, theia.NotebookControllerDetectionTask>();
54
+ private currentKernelDetectionTaskHandle = 0;
55
+
56
+ private kernelSourceActionProviders = new Map<number, theia.NotebookKernelSourceActionProvider>();
57
+ private currentSourceActionProviderHandle = 0;
58
+
59
+ private readonly onDidChangeCellExecutionStateEmitter = new Emitter<theia.NotebookCellExecutionStateChangeEvent>();
60
+ readonly onDidChangeNotebookCellExecutionState = this.onDidChangeCellExecutionStateEmitter.event;
61
+
62
+ constructor(
63
+ rpc: RPCProtocol,
64
+ private readonly notebooks: NotebooksExtImpl,
65
+ private readonly commands: CommandRegistryImpl
66
+ ) {
67
+ this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.NOTEBOOK_KERNELS_MAIN);
68
+ }
69
+
70
+ private currentHandle = 0;
71
+
72
+ createNotebookController(extensionId: string, id: string, viewType: string, label: string, handler?: (cells: theia.NotebookCell[],
73
+ notebook: theia.NotebookDocument, controller: theia.NotebookController) => void | Thenable<void>, rendererScripts?: NotebookRendererScript[]): theia.NotebookController {
74
+
75
+ for (const kernelData of this.kernelData.values()) {
76
+ if (kernelData.controller.id === id && extensionId === kernelData.extensionId) {
77
+ throw new Error(`notebook controller with id '${id}' ALREADY exist`);
78
+ }
79
+ }
80
+
81
+ const handle = this.currentHandle++;
82
+ const that = this;
83
+
84
+ console.debug(`NotebookController[${handle}], CREATED by ${extensionId}, ${id}`);
85
+
86
+ const defaultExecuteHandler = () => console.warn(`NO execute handler from notebook controller '${data.id}' of extension: '${extensionId}'`);
87
+
88
+ let isDisposed = false;
89
+ const commandDisposables = new DisposableCollection();
90
+
91
+ const onDidChangeSelection = new Emitter<{ selected: boolean; notebook: theia.NotebookDocument }>();
92
+ const onDidReceiveMessage = new Emitter<{ editor: theia.NotebookEditor; message: unknown }>();
93
+
94
+ const data: NotebookKernelDto = {
95
+ id: createKernelId(extensionId, id),
96
+ notebookType: viewType,
97
+ extensionId: extensionId,
98
+ label: label || extensionId,
99
+ };
100
+
101
+ //
102
+ let executeHandler = handler ?? defaultExecuteHandler;
103
+ let interruptHandler: ((this: theia.NotebookController, notebook: theia.NotebookDocument) => void | Thenable<void>) | undefined;
104
+
105
+ this.proxy.$addKernel(handle, data).catch(err => {
106
+ // this can happen when a kernel with that ID is already registered
107
+ console.log(err);
108
+ isDisposed = true;
109
+ });
110
+
111
+ // update: all setters write directly into the dto object
112
+ // and trigger an update. the actual update will only happen
113
+ // once per event loop execution
114
+ let tokenPool = 0;
115
+ const update = () => {
116
+ if (isDisposed) {
117
+ return;
118
+ }
119
+ const myToken = ++tokenPool;
120
+ Promise.resolve().then(() => {
121
+ if (myToken === tokenPool) {
122
+ this.proxy.$updateKernel(handle, data);
123
+ }
124
+ });
125
+ };
126
+
127
+ // notebook documents that are associated to this controller
128
+ const associatedNotebooks = new Map<string, boolean>();
129
+
130
+ const controller: theia.NotebookController = {
131
+ get id(): string { return id; },
132
+ get notebookType(): string { return data.notebookType; },
133
+ onDidChangeSelectedNotebooks: onDidChangeSelection.event,
134
+ onDidReceiveMessage: onDidReceiveMessage.event,
135
+ get label(): string {
136
+ return data.label;
137
+ },
138
+ set label(value) {
139
+ data.label = value ?? extensionId;
140
+ update();
141
+ },
142
+ get detail(): string {
143
+ return data.detail ?? '';
144
+ },
145
+ set detail(value) {
146
+ data.detail = value;
147
+ update();
148
+ },
149
+ get description(): string {
150
+ return data.description ?? '';
151
+ },
152
+ set description(value) {
153
+ data.description = value;
154
+ update();
155
+ },
156
+ get supportedLanguages(): string[] | undefined {
157
+ return data.supportedLanguages;
158
+ },
159
+ set supportedLanguages(value) {
160
+ data.supportedLanguages = value;
161
+ update();
162
+ },
163
+ get supportsExecutionOrder(): boolean {
164
+ return data.supportsExecutionOrder ?? false;
165
+ },
166
+ set supportsExecutionOrder(value) {
167
+ data.supportsExecutionOrder = value;
168
+ update();
169
+ },
170
+ get rendererScripts(): NotebookRendererScript[] {
171
+ return data.rendererScripts ?? [];
172
+ },
173
+ set rendererScripts(value) {
174
+ data.rendererScripts = value;
175
+ update();
176
+ },
177
+ get executeHandler(): (cells: theia.NotebookCell[], notebook: theia.NotebookDocument, controller: theia.NotebookController) => void | Thenable<void> {
178
+ return executeHandler;
179
+ },
180
+ set executeHandler(value) {
181
+ executeHandler = value ?? defaultExecuteHandler;
182
+ },
183
+ get interruptHandler(): ((this: theia.NotebookController, notebook: theia.NotebookDocument) => void | Thenable<void>) | undefined {
184
+ return interruptHandler;
185
+ },
186
+ set interruptHandler(value) {
187
+ interruptHandler = value;
188
+ data.supportsInterrupt = Boolean(value);
189
+ update();
190
+ },
191
+ createNotebookCellExecution(cell): theia.NotebookCellExecution {
192
+ if (isDisposed) {
193
+ throw new Error('notebook controller is DISPOSED');
194
+ }
195
+ if (!associatedNotebooks.has(cell.notebook.uri.toString())) {
196
+ console.debug(`NotebookController[${handle}] NOT associated to notebook, associated to THESE notebooks:`,
197
+ Array.from(associatedNotebooks.keys()).map(u => u.toString()));
198
+ throw new Error(`notebook controller is NOT associated to notebook: ${cell.notebook.uri.toString()}`);
199
+ }
200
+ return that.createNotebookCellExecution(cell, createKernelId(extensionId, this.id));
201
+ },
202
+ dispose: () => {
203
+ if (!isDisposed) {
204
+ console.debug(`NotebookController[${handle}], DISPOSED`);
205
+ isDisposed = true;
206
+ this.kernelData.delete(handle);
207
+ commandDisposables.dispose();
208
+ onDidChangeSelection.dispose();
209
+ onDidReceiveMessage.dispose();
210
+ this.proxy.$removeKernel(handle);
211
+ }
212
+ },
213
+ updateNotebookAffinity(notebook, priority): void {
214
+ that.proxy.$updateNotebookPriority(handle, notebook.uri, priority);
215
+ },
216
+ async postMessage(message: unknown, editor?: theia.NotebookEditor): Promise<boolean> {
217
+ return Promise.resolve(true); // TODO needs implementation
218
+ },
219
+ asWebviewUri(localResource: theia.Uri): theia.Uri {
220
+ throw new Error('Method not implemented.');
221
+ }
222
+ };
223
+
224
+ this.kernelData.set(handle, {
225
+ extensionId: extensionId,
226
+ controller,
227
+ onDidReceiveMessage,
228
+ onDidChangeSelection,
229
+ associatedNotebooks
230
+ });
231
+ return controller;
232
+ }
233
+
234
+ createNotebookCellExecution(cell: theia.NotebookCell, controllerId: string): theia.NotebookCellExecution {
235
+ if (cell.index < 0) {
236
+ throw new Error('CANNOT execute cell that has been REMOVED from notebook');
237
+ }
238
+ const notebook = this.notebooks.getNotebookDocument(URI.from(cell.notebook.uri));
239
+ const cellObj = notebook.getCellFromApiCell(cell);
240
+ if (!cellObj) {
241
+ throw new Error('invalid cell');
242
+ }
243
+ if (this.activeExecutions.has(cellObj.uri.toString())) {
244
+ throw new Error(`duplicate execution for ${cellObj.uri}`);
245
+ }
246
+ const execution = new NotebookCellExecutionTask(controllerId, cellObj, this.proxy);
247
+ this.activeExecutions.set(cellObj.uri.toString(), execution);
248
+ const listener = execution.onDidChangeState(() => {
249
+ if (execution.state === NotebookCellExecutionTaskState.Resolved) {
250
+ execution.dispose();
251
+ listener.dispose();
252
+ this.activeExecutions.delete(cellObj.uri.toString());
253
+ }
254
+ });
255
+ return execution.asApiObject();
256
+ }
257
+
258
+ createNotebookControllerDetectionTask(viewType: string): theia.NotebookControllerDetectionTask {
259
+ const handle = this.currentKernelDetectionTaskHandle++;
260
+ const that = this;
261
+
262
+ this.proxy.$addKernelDetectionTask(handle, viewType);
263
+
264
+ const detectionTask: theia.NotebookControllerDetectionTask = {
265
+ dispose: () => {
266
+ this.kernelDetectionTasks.delete(handle);
267
+ that.proxy.$removeKernelDetectionTask(handle);
268
+ }
269
+ };
270
+
271
+ this.kernelDetectionTasks.set(handle, detectionTask);
272
+ return detectionTask;
273
+ }
274
+
275
+ registerKernelSourceActionProvider(viewType: string, provider: theia.NotebookKernelSourceActionProvider): Disposable {
276
+ const handle = this.currentSourceActionProviderHandle++;
277
+ const eventHandle = typeof provider.onDidChangeNotebookKernelSourceActions === 'function' ? handle : undefined;
278
+ const that = this;
279
+
280
+ this.kernelSourceActionProviders.set(handle, provider);
281
+ this.proxy.$addKernelSourceActionProvider(handle, handle, viewType);
282
+
283
+ let subscription: theia.Disposable | undefined;
284
+ if (eventHandle !== undefined) {
285
+ subscription = provider.onDidChangeNotebookKernelSourceActions!(_ => this.proxy.$emitNotebookKernelSourceActionsChangeEvent(eventHandle));
286
+ }
287
+
288
+ return {
289
+ dispose: () => {
290
+ this.kernelSourceActionProviders.delete(handle);
291
+ that.proxy.$removeKernelSourceActionProvider(handle, handle);
292
+ subscription?.dispose();
293
+ }
294
+ };
295
+ }
296
+
297
+ $acceptNotebookAssociation(handle: number, uri: UriComponents, value: boolean): void {
298
+ const obj = this.kernelData.get(handle);
299
+ if (obj) {
300
+ // update data structure
301
+ const notebook = this.notebooks.getNotebookDocument(URI.from(uri))!;
302
+ if (value) {
303
+ obj.associatedNotebooks.set(notebook.uri.toString(), true);
304
+ } else {
305
+ obj.associatedNotebooks.delete(notebook.uri.toString());
306
+ }
307
+ console.debug(`NotebookController[${handle}] ASSOCIATE notebook`, notebook.uri.toString(), value);
308
+ // send event
309
+ obj.onDidChangeSelection.fire({
310
+ selected: value,
311
+ notebook: notebook.apiNotebook
312
+ });
313
+ }
314
+
315
+ }
316
+
317
+ async $executeCells(handle: number, uri: UriComponents, handles: number[]): Promise<void> {
318
+ const obj = this.kernelData.get(handle);
319
+ if (!obj) {
320
+ // extension can dispose kernels in the meantime
321
+ return Promise.resolve();
322
+ }
323
+ const document = this.notebooks.getNotebookDocument(URI.from(uri));
324
+ const cells: theia.NotebookCell[] = [];
325
+ for (const cellHandle of handles) {
326
+ const cell = document.getCell(cellHandle);
327
+ if (cell) {
328
+ cells.push(cell.apiCell);
329
+ }
330
+ }
331
+
332
+ try {
333
+ console.debug(`NotebookController[${handle}] EXECUTE cells`, document.uri.toString(), cells.length);
334
+ await obj.controller.executeHandler.call(obj.controller, cells, document.apiNotebook, obj.controller);
335
+ } catch (err) {
336
+ console.error(`NotebookController[${handle}] execute cells FAILED`, err);
337
+ console.error(err);
338
+ }
339
+
340
+ }
341
+
342
+ async $cancelCells(handle: number, uri: UriComponents, handles: number[]): Promise<void> {
343
+ const obj = this.kernelData.get(handle);
344
+ if (!obj) {
345
+ // extension can dispose kernels in the meantime
346
+ return Promise.resolve();
347
+ }
348
+
349
+ // cancel or interrupt depends on the controller. When an interrupt handler is used we
350
+ // don't trigger the cancelation token of executions.N
351
+ const document = this.notebooks.getNotebookDocument(URI.from(uri));
352
+ if (obj.controller.interruptHandler) {
353
+ await obj.controller.interruptHandler.call(obj.controller, document.apiNotebook);
354
+
355
+ } else {
356
+ for (const cellHandle of handles) {
357
+ const cell = document.getCell(cellHandle);
358
+ if (cell) {
359
+ this.activeExecutions.get(cell.uri.toString())?.cancel();
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ $acceptKernelMessageFromRenderer(handle: number, editorId: string, message: unknown): void {
366
+ const obj = this.kernelData.get(handle);
367
+ if (!obj) {
368
+ // extension can dispose kernels in the meantime
369
+ return;
370
+ }
371
+
372
+ const editor = this.notebooks.getEditorById(editorId);
373
+ obj.onDidReceiveMessage.fire(Object.freeze({ editor: editor.apiEditor, message }));
374
+ }
375
+
376
+ $cellExecutionChanged(uri: UriComponents, cellHandle: number, state: NotebookCellExecutionState | undefined): void {
377
+ // Proposed Api though seems needed by jupyter for telemetry
378
+ }
379
+
380
+ async $provideKernelSourceActions(handle: number, token: CancellationToken): Promise<NotebookKernelSourceActionDto[]> {
381
+ const provider = this.kernelSourceActionProviders.get(handle);
382
+ if (provider) {
383
+ const disposables = new DisposableCollection();
384
+ const ret = await provider.provideNotebookKernelSourceActions(token);
385
+ return (ret ?? []).map(item => NotebookKernelSourceAction.from(item, this.commands.converter, disposables));
386
+ }
387
+ return [];
388
+
389
+ }
390
+
391
+ }
392
+
393
+ enum NotebookCellExecutionTaskState {
394
+ Init,
395
+ Started,
396
+ Resolved
397
+ }
398
+
399
+ class NotebookCellExecutionTask implements Disposable {
400
+ private static HANDLE = 0;
401
+ private _handle = NotebookCellExecutionTask.HANDLE++;
402
+
403
+ private _onDidChangeState = new Emitter<void>();
404
+ readonly onDidChangeState = this._onDidChangeState.event;
405
+
406
+ private _state = NotebookCellExecutionTaskState.Init;
407
+ get state(): NotebookCellExecutionTaskState { return this._state; }
408
+
409
+ private readonly tokenSource = new CancellationTokenSource();
410
+
411
+ private readonly collector: TimeoutBasedCollector<CellExecuteUpdateDto>;
412
+
413
+ private executionOrder: number | undefined;
414
+
415
+ constructor(
416
+ controllerId: string,
417
+ private readonly cell: Cell,
418
+ private readonly proxy: NotebookKernelsMain
419
+ ) {
420
+ this.collector = new TimeoutBasedCollector(10, updates => this.update(updates));
421
+
422
+ this.executionOrder = cell.internalMetadata.executionOrder;
423
+ this.proxy.$createExecution(this._handle, controllerId, this.cell.notebookDocument.uri, this.cell.handle);
424
+ }
425
+
426
+ cancel(): void {
427
+ this.tokenSource.cancel();
428
+ }
429
+
430
+ private async updateSoon(update: CellExecuteUpdateDto): Promise<void> {
431
+ await this.collector.addItem(update);
432
+ }
433
+
434
+ private async update(update: CellExecuteUpdateDto | CellExecuteUpdateDto[]): Promise<void> {
435
+ const updates = Array.isArray(update) ? update : [update];
436
+ return this.proxy.$updateExecution(this._handle, updates);
437
+ }
438
+
439
+ private verifyStateForOutput(): void {
440
+ if (this._state === NotebookCellExecutionTaskState.Init) {
441
+ throw new Error('Must call start before modifying cell output');
442
+ }
443
+
444
+ if (this._state === NotebookCellExecutionTaskState.Resolved) {
445
+ throw new Error('Cannot modify cell output after calling resolve');
446
+ }
447
+ }
448
+
449
+ private cellIndexToHandle(cellOrCellIndex: theia.NotebookCell | undefined): number {
450
+ let cell: Cell | undefined = this.cell;
451
+ if (cellOrCellIndex) {
452
+ cell = this.cell.notebookDocument.getCellFromApiCell(cellOrCellIndex);
453
+ }
454
+ if (!cell) {
455
+ throw new Error('INVALID cell');
456
+ }
457
+ return cell.handle;
458
+ }
459
+
460
+ private validateAndConvertOutputs(items: NotebookCellOutput[]): NotebookOutputDto[] {
461
+ return items.map(output => {
462
+ const newOutput = NotebookCellOutputConverter.ensureUniqueMimeTypes(output.items, true);
463
+ if (newOutput === output.items) {
464
+ return NotebookCellOutputConverter.from(output);
465
+ }
466
+ return NotebookCellOutputConverter.from({
467
+ items: newOutput,
468
+ outputId: output.outputId,
469
+ metadata: output.metadata
470
+ });
471
+ });
472
+ }
473
+
474
+ private async updateOutputs(outputs: NotebookCellOutput | NotebookCellOutput[], cell: theia.NotebookCell | undefined, append: boolean): Promise<void> {
475
+ const handle = this.cellIndexToHandle(cell);
476
+ const outputDtos = this.validateAndConvertOutputs(Array.isArray(outputs) ? outputs : [outputs]);
477
+ return this.updateSoon(
478
+ {
479
+ editType: CellExecutionUpdateType.Output,
480
+ cellHandle: handle,
481
+ append,
482
+ outputs: outputDtos
483
+ });
484
+ }
485
+
486
+ private async updateOutputItems(items: theia.NotebookCellOutputItem | theia.NotebookCellOutputItem[], output: theia.NotebookCellOutput, append: boolean): Promise<void> {
487
+ items = NotebookCellOutputConverter.ensureUniqueMimeTypes(Array.isArray(items) ? items : [items], true);
488
+ return this.updateSoon({
489
+ editType: CellExecutionUpdateType.OutputItems,
490
+ items: items.map(NotebookCellOutputItem.from),
491
+ append
492
+ });
493
+ }
494
+
495
+ asApiObject(): theia.NotebookCellExecution {
496
+ const that = this;
497
+ const result: theia.NotebookCellExecution = {
498
+ get token(): CancellationToken { return that.tokenSource.token; },
499
+ get cell(): theia.NotebookCell { return that.cell.apiCell; },
500
+ get executionOrder(): number | undefined { return that.executionOrder; },
501
+ set executionOrder(v: number | undefined) {
502
+ that.executionOrder = v;
503
+ that.update([{
504
+ editType: CellExecutionUpdateType.ExecutionState,
505
+ executionOrder: that.executionOrder
506
+ }]);
507
+ },
508
+
509
+ start(startTime?: number): void {
510
+ if (that._state === NotebookCellExecutionTaskState.Resolved || that._state === NotebookCellExecutionTaskState.Started) {
511
+ throw new Error('Cannot call start again');
512
+ }
513
+
514
+ that._state = NotebookCellExecutionTaskState.Started;
515
+ that._onDidChangeState.fire();
516
+
517
+ that.update({
518
+ editType: CellExecutionUpdateType.ExecutionState,
519
+ runStartTime: startTime
520
+ });
521
+ },
522
+
523
+ end(success: boolean | undefined, endTime?: number): void {
524
+ if (that._state === NotebookCellExecutionTaskState.Resolved) {
525
+ throw new Error('Cannot call resolve twice');
526
+ }
527
+
528
+ that._state = NotebookCellExecutionTaskState.Resolved;
529
+ that._onDidChangeState.fire();
530
+
531
+ // The last update needs to be ordered correctly and applied immediately,
532
+ // so we use updateSoon and immediately flush.
533
+ that.collector.flush();
534
+
535
+ that.proxy.$completeExecution(that._handle, {
536
+ runEndTime: endTime,
537
+ lastRunSuccess: success
538
+ });
539
+ },
540
+
541
+ clearOutput(cell?: theia.NotebookCell): Thenable<void> {
542
+ that.verifyStateForOutput();
543
+ return that.updateOutputs([], cell, false);
544
+ },
545
+
546
+ appendOutput(outputs: NotebookCellOutput | NotebookCellOutput[], cell?: theia.NotebookCell): Promise<void> {
547
+ that.verifyStateForOutput();
548
+ return that.updateOutputs(outputs, cell, true);
549
+ },
550
+
551
+ replaceOutput(outputs: NotebookCellOutput | NotebookCellOutput[], cell?: theia.NotebookCell): Promise<void> {
552
+ that.verifyStateForOutput();
553
+ return that.updateOutputs(outputs, cell, false);
554
+ },
555
+
556
+ appendOutputItems(items: theia.NotebookCellOutputItem | theia.NotebookCellOutputItem[], output: theia.NotebookCellOutput): Promise<void> {
557
+ that.verifyStateForOutput();
558
+ return that.updateOutputItems(items, output, true);
559
+ },
560
+
561
+ replaceOutputItems(items: theia.NotebookCellOutputItem | theia.NotebookCellOutputItem[], output: theia.NotebookCellOutput): Promise<void> {
562
+ that.verifyStateForOutput();
563
+ return that.updateOutputItems(items, output, false);
564
+ }
565
+ };
566
+ return Object.freeze(result);
567
+ }
568
+
569
+ dispose(): void {
570
+
571
+ }
572
+ }
573
+
574
+ class TimeoutBasedCollector<T> {
575
+ private batch: T[] = [];
576
+ private startedTimer = Date.now();
577
+ private currentDeferred: Deferred<void> | undefined;
578
+
579
+ constructor(
580
+ private readonly delay: number,
581
+ private readonly callback: (items: T[]) => Promise<void>) { }
582
+
583
+ addItem(item: T): Promise<void> {
584
+ this.batch.push(item);
585
+ if (!this.currentDeferred) {
586
+ this.currentDeferred = new Deferred<void>();
587
+ this.startedTimer = Date.now();
588
+ timeout(this.delay).then(() => this.flush());
589
+ }
590
+
591
+ // This can be called by the extension repeatedly for a long time before the timeout is able to run.
592
+ // Force a flush after the delay.
593
+ if (Date.now() - this.startedTimer > this.delay) {
594
+ return this.flush();
595
+ }
596
+
597
+ return this.currentDeferred.promise;
598
+ }
599
+
600
+ flush(): Promise<void> {
601
+ if (this.batch.length === 0 || !this.currentDeferred) {
602
+ return Promise.resolve();
603
+ }
604
+
605
+ const deferred = this.currentDeferred;
606
+ this.currentDeferred = undefined;
607
+ const batch = this.batch;
608
+ this.batch = [];
609
+ return this.callback(batch)
610
+ .finally(() => deferred.resolve());
611
+ }
612
+ }
613
+
614
+ export function createKernelId(extensionIdentifier: string, id: string): string {
615
+ return `${extensionIdentifier}/${id}`;
616
+ }