@theia/plugin-ext 1.40.1 → 1.42.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.
- package/lib/common/collections.d.ts +4 -0
- package/lib/common/collections.d.ts.map +1 -1
- package/lib/common/collections.js +17 -1
- package/lib/common/collections.js.map +1 -1
- package/lib/common/errors.d.ts +14 -0
- package/lib/common/errors.d.ts.map +1 -1
- package/lib/common/errors.js +17 -1
- package/lib/common/errors.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +286 -6
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +20 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +27 -5
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +5 -2
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +21 -12
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.js +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
- package/lib/hosted/node/plugin-reader.d.ts +1 -1
- package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
- package/lib/hosted/node/plugin-reader.js +1 -1
- package/lib/hosted/node/plugin-reader.js.map +1 -1
- package/lib/hosted/node/scanners/grammars-reader.d.ts +1 -1
- package/lib/hosted/node/scanners/grammars-reader.d.ts.map +1 -1
- package/lib/hosted/node/scanners/grammars-reader.js +5 -5
- package/lib/hosted/node/scanners/grammars-reader.js.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts +6 -6
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +54 -41
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.d.ts +1 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.js +1 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.js.map +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.d.ts +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.js +1 -1
- package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +1 -0
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +6 -4
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +18 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/menus/menus-contribution-handler.js +6 -3
- package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts +50 -0
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +189 -0
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -0
- package/lib/main/browser/notebooks/notebook-documents-main.d.ts +22 -0
- package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-documents-main.js +133 -0
- package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -0
- package/lib/main/browser/notebooks/notebook-dto.d.ts +15 -0
- package/lib/main/browser/notebooks/notebook-dto.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-dto.js +138 -0
- package/lib/main/browser/notebooks/notebook-dto.js.map +1 -0
- package/lib/main/browser/notebooks/notebook-editors-main.d.ts +20 -0
- package/lib/main/browser/notebooks/notebook-editors-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-editors-main.js +58 -0
- package/lib/main/browser/notebooks/notebook-editors-main.js.map +1 -0
- package/lib/main/browser/notebooks/notebook-kernels-main.d.ts +42 -0
- package/lib/main/browser/notebooks/notebook-kernels-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-kernels-main.js +230 -0
- package/lib/main/browser/notebooks/notebook-kernels-main.js.map +1 -0
- package/lib/main/browser/notebooks/notebook-renderers-main.d.ts +12 -0
- package/lib/main/browser/notebooks/notebook-renderers-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebook-renderers-main.js +39 -0
- package/lib/main/browser/notebooks/notebook-renderers-main.js.map +1 -0
- package/lib/main/browser/notebooks/notebooks-main.d.ts +20 -0
- package/lib/main/browser/notebooks/notebooks-main.d.ts.map +1 -0
- package/lib/main/browser/notebooks/notebooks-main.js +103 -0
- package/lib/main/browser/notebooks/notebooks-main.js.map +1 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts +35 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js +204 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -0
- package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts +13 -0
- package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts.map +1 -0
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js +375 -0
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js.map +1 -0
- package/lib/main/browser/notebooks/renderers/webview-communication.d.ts +52 -0
- package/lib/main/browser/notebooks/renderers/webview-communication.d.ts.map +1 -0
- package/{src/typings/index.d.ts → lib/main/browser/notebooks/renderers/webview-communication.js} +8 -11
- package/lib/main/browser/notebooks/renderers/webview-communication.js.map +1 -0
- package/lib/main/browser/plugin-contribution-handler.d.ts +3 -0
- package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.js +31 -3
- package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +3 -2
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.js +6 -0
- package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
- package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
- package/lib/main/browser/plugin-shared-style.js +2 -1
- package/lib/main/browser/plugin-shared-style.js.map +1 -1
- package/lib/main/browser/tasks-main.js +2 -2
- package/lib/main/browser/tasks-main.js.map +1 -1
- package/lib/main/browser/terminal-main.d.ts +2 -2
- package/lib/main/browser/terminal-main.d.ts.map +1 -1
- package/lib/main/browser/terminal-main.js +4 -4
- package/lib/main/browser/terminal-main.js.map +1 -1
- package/lib/main/browser/view/tree-view-widget.d.ts +3 -1
- package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
- package/lib/main/browser/view/tree-view-widget.js +32 -1
- package/lib/main/browser/view/tree-view-widget.js.map +1 -1
- package/lib/main/browser/view/tree-views-main.d.ts +2 -1
- package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
- package/lib/main/browser/view/tree-views-main.js +10 -0
- package/lib/main/browser/view/tree-views-main.js.map +1 -1
- package/lib/main/browser/webview/webview.d.ts +1 -0
- package/lib/main/browser/webview/webview.d.ts.map +1 -1
- package/lib/main/browser/webview/webview.js +5 -0
- package/lib/main/browser/webview/webview.js.map +1 -1
- package/lib/main/node/errors.spec.d.ts +2 -0
- package/lib/main/node/errors.spec.d.ts.map +1 -0
- package/lib/main/node/errors.spec.js +36 -0
- package/lib/main/node/errors.spec.js.map +1 -0
- package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts +5 -2
- package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-directory-handler.js +14 -8
- package/lib/main/node/handlers/plugin-theia-directory-handler.js.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts +2 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
- package/lib/main/node/handlers/plugin-theia-file-handler.js +13 -5
- package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
- package/lib/main/node/paths/plugin-paths-service.d.ts.map +1 -1
- package/lib/main/node/paths/plugin-paths-service.js +4 -9
- package/lib/main/node/paths/plugin-paths-service.js.map +1 -1
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.js +8 -8
- package/lib/main/node/plugin-deployer-directory-handler-context-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-entry-impl.d.ts +2 -2
- package/lib/main/node/plugin-deployer-entry-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-entry-impl.js +9 -7
- package/lib/main/node/plugin-deployer-entry-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-impl.d.ts +2 -2
- package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-impl.js +16 -24
- package/lib/main/node/plugin-deployer-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-proxy-entry-impl.d.ts +2 -2
- package/lib/main/node/plugin-deployer-proxy-entry-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-ext-backend-module.js +3 -3
- package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
- package/lib/main/node/plugin-github-resolver.d.ts.map +1 -1
- package/lib/main/node/plugin-github-resolver.js +14 -6
- package/lib/main/node/plugin-github-resolver.js.map +1 -1
- package/lib/main/node/plugin-http-resolver.d.ts.map +1 -1
- package/lib/main/node/plugin-http-resolver.js +14 -6
- package/lib/main/node/plugin-http-resolver.js.map +1 -1
- package/lib/main/node/{plugin-localization-backend-contribution.d.ts → plugin-localization-server.d.ts} +3 -3
- package/lib/main/node/plugin-localization-server.d.ts.map +1 -0
- package/lib/main/node/{plugin-localization-backend-contribution.js → plugin-localization-server.js} +8 -8
- package/lib/main/node/plugin-localization-server.js.map +1 -0
- package/lib/main/node/temp-dir-util.d.ts +1 -0
- package/lib/main/node/temp-dir-util.d.ts.map +1 -1
- package/lib/main/node/temp-dir-util.js +12 -3
- package/lib/main/node/temp-dir-util.js.map +1 -1
- package/lib/plugin/editors-and-documents.d.ts +1 -1
- package/lib/plugin/editors-and-documents.d.ts.map +1 -1
- package/lib/plugin/editors-and-documents.js +1 -1
- package/lib/plugin/editors-and-documents.js.map +1 -1
- package/lib/plugin/notebook/notebook-document.d.ts +62 -0
- package/lib/plugin/notebook/notebook-document.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-document.js +373 -0
- package/lib/plugin/notebook/notebook-document.js.map +1 -0
- package/lib/plugin/notebook/notebook-documents.d.ts +17 -0
- package/lib/plugin/notebook/notebook-documents.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-documents.js +48 -0
- package/lib/plugin/notebook/notebook-documents.js.map +1 -0
- package/lib/plugin/notebook/notebook-editor.d.ts +21 -0
- package/lib/plugin/notebook/notebook-editor.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-editor.js +99 -0
- package/lib/plugin/notebook/notebook-editor.js.map +1 -0
- package/lib/plugin/notebook/notebook-editors.d.ts +14 -0
- package/lib/plugin/notebook/notebook-editors.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-editors.js +65 -0
- package/lib/plugin/notebook/notebook-editors.js.map +1 -0
- package/lib/plugin/notebook/notebook-kernels.d.ts +37 -0
- package/lib/plugin/notebook/notebook-kernels.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-kernels.js +516 -0
- package/lib/plugin/notebook/notebook-kernels.js.map +1 -0
- package/lib/plugin/notebook/notebook-renderers.d.ts +14 -0
- package/lib/plugin/notebook/notebook-renderers.d.ts.map +1 -0
- package/lib/plugin/notebook/notebook-renderers.js +63 -0
- package/lib/plugin/notebook/notebook-renderers.js.map +1 -0
- package/lib/plugin/notebook/notebooks.d.ts +57 -0
- package/lib/plugin/notebook/notebooks.d.ts.map +1 -0
- package/lib/plugin/notebook/notebooks.js +295 -0
- package/lib/plugin/notebook/notebooks.js.map +1 -0
- package/lib/plugin/plugin-context.d.ts +2 -2
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +80 -59
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +2 -0
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +9 -1
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/quick-open.d.ts.map +1 -1
- package/lib/plugin/quick-open.js +1 -0
- package/lib/plugin/quick-open.js.map +1 -1
- package/lib/plugin/stubs/tests-api.d.ts +1 -0
- package/lib/plugin/stubs/tests-api.d.ts.map +1 -1
- package/lib/plugin/stubs/tests-api.js +3 -1
- package/lib/plugin/stubs/tests-api.js.map +1 -1
- package/lib/plugin/tasks/task-provider.d.ts +2 -2
- package/lib/plugin/tasks/task-provider.d.ts.map +1 -1
- package/lib/plugin/tasks/task-provider.js +7 -10
- package/lib/plugin/tasks/task-provider.js.map +1 -1
- package/lib/plugin/tasks/tasks.d.ts +3 -2
- package/lib/plugin/tasks/tasks.d.ts.map +1 -1
- package/lib/plugin/tasks/tasks.js +18 -13
- package/lib/plugin/tasks/tasks.js.map +1 -1
- package/lib/plugin/terminal-ext.d.ts +3 -0
- package/lib/plugin/terminal-ext.d.ts.map +1 -1
- package/lib/plugin/terminal-ext.js +11 -1
- package/lib/plugin/terminal-ext.js.map +1 -1
- package/lib/plugin/tree/tree-views.d.ts +15 -5
- package/lib/plugin/tree/tree-views.d.ts.map +1 -1
- package/lib/plugin/tree/tree-views.js +52 -3
- package/lib/plugin/tree/tree-views.js.map +1 -1
- package/lib/plugin/type-converters.d.ts +60 -0
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +374 -14
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +68 -29
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +123 -44
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +31 -29
- package/src/common/collections.ts +17 -0
- package/src/common/errors.ts +26 -0
- package/src/common/plugin-api-rpc.ts +340 -5
- package/src/common/plugin-protocol.ts +23 -5
- package/src/hosted/browser/hosted-plugin.ts +21 -14
- package/src/hosted/node/hosted-plugin-deployer-handler.ts +1 -1
- package/src/hosted/node/plugin-reader.ts +1 -1
- package/src/hosted/node/scanners/grammars-reader.ts +6 -5
- package/src/hosted/node/scanners/scanner-theia.ts +55 -41
- package/src/main/browser/custom-editors/custom-editor-widget.ts +1 -1
- package/src/main/browser/custom-editors/custom-editors-main.ts +1 -1
- package/src/main/browser/editors-and-documents-main.ts +1 -0
- package/src/main/browser/languages-main.ts +7 -4
- package/src/main/browser/main-context.ts +19 -0
- package/src/main/browser/menus/menus-contribution-handler.ts +7 -4
- package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +238 -0
- package/src/main/browser/notebooks/notebook-documents-main.ts +166 -0
- package/src/main/browser/notebooks/notebook-dto.ts +141 -0
- package/src/main/browser/notebooks/notebook-editors-main.ts +70 -0
- package/src/main/browser/notebooks/notebook-kernels-main.ts +291 -0
- package/src/main/browser/notebooks/notebook-renderers-main.ts +47 -0
- package/src/main/browser/notebooks/notebooks-main.ts +124 -0
- package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +198 -0
- package/src/main/browser/notebooks/renderers/output-webview-internal.ts +476 -0
- package/src/main/browser/notebooks/renderers/webview-communication.ts +79 -0
- package/src/main/browser/plugin-contribution-handler.ts +36 -3
- package/src/main/browser/plugin-ext-frontend-module.ts +7 -3
- package/src/main/browser/plugin-icon-theme-service.ts +6 -0
- package/src/main/browser/plugin-shared-style.ts +2 -1
- package/src/main/browser/tasks-main.ts +4 -4
- package/src/main/browser/terminal-main.ts +5 -5
- package/src/main/browser/view/tree-view-widget.tsx +36 -2
- package/src/main/browser/view/tree-views-main.ts +8 -0
- package/src/main/browser/webview/webview.ts +6 -0
- package/src/main/node/errors.spec.ts +37 -0
- package/src/main/node/handlers/plugin-theia-directory-handler.ts +18 -8
- package/src/main/node/handlers/plugin-theia-file-handler.ts +18 -6
- package/src/main/node/paths/plugin-paths-service.ts +5 -10
- package/src/main/node/plugin-deployer-directory-handler-context-impl.ts +8 -8
- package/src/main/node/plugin-deployer-entry-impl.ts +9 -7
- package/src/main/node/plugin-deployer-impl.ts +20 -28
- package/src/main/node/plugin-deployer-proxy-entry-impl.ts +2 -2
- package/src/main/node/plugin-ext-backend-module.ts +3 -3
- package/src/main/node/plugin-github-resolver.ts +15 -8
- package/src/main/node/plugin-http-resolver.ts +15 -8
- package/src/main/node/{plugin-localization-backend-contribution.ts → plugin-localization-server.ts} +2 -2
- package/src/main/node/temp-dir-util.ts +11 -2
- package/src/plugin/editors-and-documents.ts +1 -1
- package/src/plugin/notebook/notebook-document.ts +438 -0
- package/src/plugin/notebook/notebook-documents.ts +58 -0
- package/src/plugin/notebook/notebook-editor.ts +116 -0
- package/src/plugin/notebook/notebook-editors.ts +71 -0
- package/src/plugin/notebook/notebook-kernels.ts +616 -0
- package/src/plugin/notebook/notebook-renderers.ts +72 -0
- package/src/plugin/notebook/notebooks.ts +385 -0
- package/src/plugin/plugin-context.ts +80 -71
- package/src/plugin/plugin-manager.ts +9 -1
- package/src/plugin/quick-open.ts +1 -0
- package/src/plugin/stubs/tests-api.ts +4 -0
- package/src/plugin/tasks/task-provider.ts +9 -12
- package/src/plugin/tasks/tasks.ts +18 -13
- package/src/plugin/terminal-ext.ts +13 -1
- package/src/plugin/tree/tree-views.ts +57 -7
- package/src/plugin/type-converters.ts +372 -13
- package/src/plugin/types-impl.ts +162 -58
- package/lib/main/browser/custom-editors/undo-redo-service.d.ts +0 -24
- package/lib/main/browser/custom-editors/undo-redo-service.d.ts.map +0 -1
- package/lib/main/browser/custom-editors/undo-redo-service.js +0 -111
- package/lib/main/browser/custom-editors/undo-redo-service.js.map +0 -1
- package/lib/main/node/plugin-localization-backend-contribution.d.ts.map +0 -1
- package/lib/main/node/plugin-localization-backend-contribution.js.map +0 -1
- package/src/main/browser/custom-editors/undo-redo-service.ts +0 -120
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
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 { NotebookRenderersExt, NotebookRenderersMain, PLUGIN_RPC_CONTEXT } from '../../common';
|
|
22
|
+
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
23
|
+
import { NotebooksExtImpl } from './notebooks';
|
|
24
|
+
import * as theia from '@theia/plugin';
|
|
25
|
+
import { NotebookEditor } from './notebook-editor';
|
|
26
|
+
import { Emitter } from '@theia/core';
|
|
27
|
+
|
|
28
|
+
export class NotebookRenderersExtImpl implements NotebookRenderersExt {
|
|
29
|
+
private readonly rendererMessageEmitters = new Map<string /* rendererId */, Emitter<{ editor: theia.NotebookEditor; message: unknown }>>();
|
|
30
|
+
private readonly proxy: NotebookRenderersMain;
|
|
31
|
+
|
|
32
|
+
constructor(rpc: RPCProtocol, private readonly notebooksExt: NotebooksExtImpl) {
|
|
33
|
+
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.NOTEBOOK_RENDERERS_MAIN);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public $postRendererMessage(editorId: string, rendererId: string, message: unknown): void {
|
|
37
|
+
const editor = this.notebooksExt.getEditorById(editorId);
|
|
38
|
+
this.rendererMessageEmitters.get(rendererId)?.fire({ editor: editor.apiEditor, message });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public createRendererMessaging(rendererId: string): theia.NotebookRendererMessaging {
|
|
42
|
+
|
|
43
|
+
const messaging: theia.NotebookRendererMessaging = {
|
|
44
|
+
onDidReceiveMessage: (listener, thisArg, disposables) => this.getOrCreateEmitterFor(rendererId).event(listener, thisArg, disposables),
|
|
45
|
+
postMessage: (message, editorOrAlias) => {
|
|
46
|
+
|
|
47
|
+
const extHostEditor = editorOrAlias && NotebookEditor.apiEditorsToExtHost.get(editorOrAlias);
|
|
48
|
+
return this.proxy.$postMessage(extHostEditor?.id, rendererId, message);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return messaging;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private getOrCreateEmitterFor(rendererId: string): Emitter<{ editor: theia.NotebookEditor, message: unknown }> {
|
|
56
|
+
let emitter = this.rendererMessageEmitters.get(rendererId);
|
|
57
|
+
if (emitter) {
|
|
58
|
+
return emitter;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
emitter = new Emitter({
|
|
62
|
+
onLastListenerRemove: () => {
|
|
63
|
+
emitter?.dispose();
|
|
64
|
+
this.rendererMessageEmitters.delete(rendererId);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.rendererMessageEmitters.set(rendererId, emitter);
|
|
69
|
+
|
|
70
|
+
return emitter;
|
|
71
|
+
}
|
|
72
|
+
}
|