@theia/core 1.27.0-next.9 → 1.27.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/README.md +6 -7
- package/i18n/nls.cs.json +52 -6
- package/i18n/nls.de.json +52 -6
- package/i18n/nls.es.json +52 -6
- package/i18n/nls.fr.json +52 -6
- package/i18n/nls.hu.json +55 -9
- package/i18n/nls.it.json +52 -6
- package/i18n/nls.ja.json +52 -6
- package/i18n/nls.json +52 -6
- package/i18n/nls.pl.json +52 -6
- package/i18n/nls.pt-br.json +52 -6
- package/i18n/nls.pt-pt.json +52 -6
- package/i18n/nls.ru.json +52 -6
- package/i18n/nls.zh-cn.json +52 -6
- package/lib/browser/color-application-contribution.d.ts +2 -2
- package/lib/browser/color-application-contribution.d.ts.map +1 -1
- package/lib/browser/color-application-contribution.js +15 -16
- package/lib/browser/color-application-contribution.js.map +1 -1
- package/lib/browser/color-registry.d.ts +0 -4
- package/lib/browser/color-registry.d.ts.map +1 -1
- package/lib/browser/color-registry.js +0 -14
- package/lib/browser/color-registry.js.map +1 -1
- package/lib/browser/common-frontend-contribution.d.ts +4 -0
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +157 -163
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/common-styling-participants.d.ts +28 -0
- package/lib/browser/common-styling-participants.d.ts.map +1 -0
- package/lib/browser/common-styling-participants.js +319 -0
- package/lib/browser/common-styling-participants.js.map +1 -0
- package/lib/browser/connection-status-service.d.ts.map +1 -1
- package/lib/browser/connection-status-service.js +2 -2
- package/lib/browser/connection-status-service.js.map +1 -1
- package/lib/browser/connection-status-service.spec.js +1 -2
- package/lib/browser/connection-status-service.spec.js.map +1 -1
- package/lib/browser/context-menu-renderer.d.ts +1 -5
- package/lib/browser/context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/context-menu-renderer.js +10 -30
- package/lib/browser/context-menu-renderer.js.map +1 -1
- package/lib/browser/core-preferences.d.ts +1 -0
- package/lib/browser/core-preferences.d.ts.map +1 -1
- package/lib/browser/core-preferences.js +5 -0
- package/lib/browser/core-preferences.js.map +1 -1
- package/lib/browser/decoration-style.d.ts +1 -0
- package/lib/browser/decoration-style.d.ts.map +1 -1
- package/lib/browser/decoration-style.js +6 -2
- package/lib/browser/decoration-style.js.map +1 -1
- package/lib/browser/frontend-application-bindings.d.ts.map +1 -1
- package/lib/browser/frontend-application-bindings.js +1 -3
- package/lib/browser/frontend-application-bindings.js.map +1 -1
- package/lib/browser/frontend-application-config-provider.d.ts +1 -0
- package/lib/browser/frontend-application-config-provider.d.ts.map +1 -1
- package/lib/browser/frontend-application-config-provider.js +2 -1
- package/lib/browser/frontend-application-config-provider.js.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +9 -3
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/i18n/i18n-frontend-module.d.ts.map +1 -1
- package/lib/browser/i18n/i18n-frontend-module.js +2 -0
- package/lib/browser/i18n/i18n-frontend-module.js.map +1 -1
- package/lib/browser/i18n/language-quick-pick-service.d.ts +17 -0
- package/lib/browser/i18n/language-quick-pick-service.d.ts.map +1 -0
- package/lib/browser/i18n/language-quick-pick-service.js +142 -0
- package/lib/browser/i18n/language-quick-pick-service.js.map +1 -0
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +1 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/keybinding.d.ts.map +1 -1
- package/lib/browser/keybinding.js +2 -1
- package/lib/browser/keybinding.js.map +1 -1
- package/lib/browser/keybinding.spec.js +18 -21
- package/lib/browser/keybinding.spec.js.map +1 -1
- package/lib/browser/label-provider.d.ts +0 -12
- package/lib/browser/label-provider.d.ts.map +1 -1
- package/lib/browser/label-provider.js +1 -13
- package/lib/browser/label-provider.js.map +1 -1
- package/lib/browser/logger-frontend-module.d.ts.map +1 -1
- package/lib/browser/logger-frontend-module.js +8 -1
- package/lib/browser/logger-frontend-module.js.map +1 -1
- package/lib/browser/messaging/ws-connection-provider.d.ts +5 -4
- package/lib/browser/messaging/ws-connection-provider.d.ts.map +1 -1
- package/lib/browser/messaging/ws-connection-provider.js +30 -23
- package/lib/browser/messaging/ws-connection-provider.js.map +1 -1
- package/lib/browser/preferences/preference-contribution.d.ts +2 -19
- package/lib/browser/preferences/preference-contribution.d.ts.map +1 -1
- package/lib/browser/preferences/preference-contribution.js +1 -24
- package/lib/browser/preferences/preference-contribution.js.map +1 -1
- package/lib/browser/preferences/preference-proxy.d.ts +0 -4
- package/lib/browser/preferences/preference-proxy.d.ts.map +1 -1
- package/lib/browser/preferences/preference-proxy.js.map +1 -1
- package/lib/browser/preferences/preference-proxy.spec.js +3 -102
- package/lib/browser/preferences/preference-proxy.spec.js.map +1 -1
- package/lib/browser/preferences/preference-schema-provider.spec.js +4 -3
- package/lib/browser/preferences/preference-schema-provider.spec.js.map +1 -1
- package/lib/browser/preferences/preference-service.spec.js +1 -2
- package/lib/browser/preferences/preference-service.spec.js.map +1 -1
- package/lib/browser/preferences/preference-validation-service.d.ts +2 -2
- package/lib/browser/preferences/preference-validation-service.d.ts.map +1 -1
- package/lib/browser/preferences/preference-validation-service.spec.js.map +1 -1
- package/lib/browser/preloader.d.ts.map +1 -1
- package/lib/browser/preloader.js +7 -1
- package/lib/browser/preloader.js.map +1 -1
- package/lib/browser/progress-status-bar-item.d.ts +1 -1
- package/lib/browser/progress-status-bar-item.d.ts.map +1 -1
- package/lib/browser/quick-input/quick-command-service.d.ts.map +1 -1
- package/lib/browser/quick-input/quick-command-service.js +2 -2
- package/lib/browser/quick-input/quick-command-service.js.map +1 -1
- package/lib/browser/saveable.d.ts.map +1 -1
- package/lib/browser/saveable.js +5 -4
- package/lib/browser/saveable.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +4 -0
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +42 -36
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/shell/shell-layout-restorer.d.ts +2 -0
- package/lib/browser/shell/shell-layout-restorer.d.ts.map +1 -1
- package/lib/browser/shell/shell-layout-restorer.js +5 -1
- package/lib/browser/shell/shell-layout-restorer.js.map +1 -1
- package/lib/browser/shell/side-panel-handler.d.ts.map +1 -1
- package/lib/browser/shell/side-panel-handler.js +3 -2
- package/lib/browser/shell/side-panel-handler.js.map +1 -1
- package/lib/browser/shell/tab-bars.d.ts +4 -2
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +12 -4
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/source-tree/source-tree-widget.js +1 -1
- package/lib/browser/source-tree/source-tree-widget.js.map +1 -1
- package/lib/browser/source-tree/tree-source.d.ts +2 -1
- package/lib/browser/source-tree/tree-source.d.ts.map +1 -1
- package/lib/browser/source-tree/tree-source.js.map +1 -1
- package/lib/browser/styling-service.d.ts +26 -0
- package/lib/browser/styling-service.d.ts.map +1 -0
- package/lib/browser/styling-service.js +76 -0
- package/lib/browser/styling-service.js.map +1 -0
- package/lib/browser/theming.d.ts +4 -8
- package/lib/browser/theming.d.ts.map +1 -1
- package/lib/browser/theming.js +38 -53
- package/lib/browser/theming.js.map +1 -1
- package/lib/browser/tree/search-box.d.ts.map +1 -1
- package/lib/browser/tree/search-box.js +5 -4
- package/lib/browser/tree/search-box.js.map +1 -1
- package/lib/browser/tree/test/tree-test-container.d.ts.map +1 -1
- package/lib/browser/tree/test/tree-test-container.js +2 -0
- package/lib/browser/tree/test/tree-test-container.js.map +1 -1
- package/lib/browser/tree/tree-compression/compressed-tree-model.d.ts +1 -1
- package/lib/browser/tree/tree-compression/compressed-tree-model.d.ts.map +1 -1
- package/lib/browser/tree/tree-compression/compressed-tree-model.js +4 -2
- package/lib/browser/tree/tree-compression/compressed-tree-model.js.map +1 -1
- package/lib/browser/tree/tree-compression/compressed-tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-compression/compressed-tree-widget.js +4 -2
- package/lib/browser/tree/tree-compression/compressed-tree-widget.js.map +1 -1
- package/lib/browser/tree/tree-container.d.ts +2 -0
- package/lib/browser/tree/tree-container.d.ts.map +1 -1
- package/lib/browser/tree/tree-container.js +3 -0
- package/lib/browser/tree/tree-container.js.map +1 -1
- package/lib/browser/tree/tree-focus-service.d.ts +20 -0
- package/lib/browser/tree/tree-focus-service.d.ts.map +1 -0
- package/lib/browser/tree/tree-focus-service.js +62 -0
- package/lib/browser/tree/tree-focus-service.js.map +1 -0
- package/lib/browser/tree/tree-model.d.ts +11 -2
- package/lib/browser/tree/tree-model.d.ts.map +1 -1
- package/lib/browser/tree/tree-model.js +29 -8
- package/lib/browser/tree/tree-model.js.map +1 -1
- package/lib/browser/tree/tree-selection-impl.d.ts +4 -1
- package/lib/browser/tree/tree-selection-impl.d.ts.map +1 -1
- package/lib/browser/tree/tree-selection-impl.js +13 -2
- package/lib/browser/tree/tree-selection-impl.js.map +1 -1
- package/lib/browser/tree/tree-selection-state.d.ts +1 -0
- package/lib/browser/tree/tree-selection-state.d.ts.map +1 -1
- package/lib/browser/tree/tree-selection-state.js +8 -2
- package/lib/browser/tree/tree-selection-state.js.map +1 -1
- package/lib/browser/tree/tree-selection.d.ts +9 -0
- package/lib/browser/tree/tree-selection.d.ts.map +1 -1
- package/lib/browser/tree/tree-selection.js +3 -0
- package/lib/browser/tree/tree-selection.js.map +1 -1
- package/lib/browser/tree/tree-widget-selection.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget-selection.js +9 -1
- package/lib/browser/tree/tree-widget-selection.js.map +1 -1
- package/lib/browser/tree/tree-widget.d.ts +14 -0
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +80 -40
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/browser/tree/tree.d.ts +2 -1
- package/lib/browser/tree/tree.d.ts.map +1 -1
- package/lib/browser/tree/tree.js +12 -2
- package/lib/browser/tree/tree.js.map +1 -1
- package/lib/browser/view-container.d.ts +9 -4
- package/lib/browser/view-container.d.ts.map +1 -1
- package/lib/browser/view-container.js +36 -6
- package/lib/browser/view-container.js.map +1 -1
- package/lib/common/cancellation.d.ts +1 -0
- package/lib/common/cancellation.d.ts.map +1 -1
- package/lib/common/cancellation.js +8 -0
- package/lib/common/cancellation.js.map +1 -1
- package/lib/common/command.d.ts +1 -1
- package/lib/common/command.d.ts.map +1 -1
- package/lib/common/command.js +13 -16
- package/lib/common/command.js.map +1 -1
- package/lib/common/index.d.ts +1 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +1 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/message-rpc/channel.d.ts +106 -0
- package/lib/common/message-rpc/channel.d.ts.map +1 -0
- package/lib/common/message-rpc/channel.js +195 -0
- package/lib/common/message-rpc/channel.js.map +1 -0
- package/lib/common/message-rpc/channel.spec.d.ts +9 -0
- package/lib/common/message-rpc/channel.spec.d.ts.map +1 -0
- package/lib/common/message-rpc/channel.spec.js +80 -0
- package/lib/common/message-rpc/channel.spec.js.map +1 -0
- package/lib/common/message-rpc/index.d.ts +4 -0
- package/lib/common/message-rpc/index.d.ts.map +1 -0
- package/lib/{node/messaging/logger.js → common/message-rpc/index.js} +6 -19
- package/lib/common/message-rpc/index.js.map +1 -0
- package/lib/common/message-rpc/message-buffer.d.ts +50 -0
- package/lib/common/message-rpc/message-buffer.d.ts.map +1 -0
- package/lib/common/message-rpc/message-buffer.js +56 -0
- package/lib/common/message-rpc/message-buffer.js.map +1 -0
- package/lib/common/message-rpc/rpc-message-encoder.d.ts +171 -0
- package/lib/common/message-rpc/rpc-message-encoder.d.ts.map +1 -0
- package/lib/common/message-rpc/rpc-message-encoder.js +409 -0
- package/lib/common/message-rpc/rpc-message-encoder.js.map +1 -0
- package/lib/common/message-rpc/rpc-message-encoder.spec.d.ts +2 -0
- package/lib/common/message-rpc/rpc-message-encoder.spec.d.ts.map +1 -0
- package/lib/common/message-rpc/rpc-message-encoder.spec.js +49 -0
- package/lib/common/message-rpc/rpc-message-encoder.spec.js.map +1 -0
- package/lib/common/message-rpc/rpc-protocol.d.ts +61 -0
- package/lib/common/message-rpc/rpc-protocol.d.ts.map +1 -0
- package/lib/common/message-rpc/rpc-protocol.js +183 -0
- package/lib/common/message-rpc/rpc-protocol.js.map +1 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.d.ts +52 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.d.ts.map +1 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.js +169 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.js.map +1 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.spec.d.ts +2 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.spec.d.ts.map +1 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.spec.js +39 -0
- package/lib/common/message-rpc/uint8-array-message-buffer.spec.js.map +1 -0
- package/lib/common/messaging/abstract-connection-provider.d.ts +9 -8
- package/lib/common/messaging/abstract-connection-provider.d.ts.map +1 -1
- package/lib/common/messaging/abstract-connection-provider.js +20 -35
- package/lib/common/messaging/abstract-connection-provider.js.map +1 -1
- package/lib/common/messaging/connection-error-handler.d.ts +1 -2
- package/lib/common/messaging/connection-error-handler.d.ts.map +1 -1
- package/lib/common/messaging/connection-error-handler.js +1 -1
- package/lib/common/messaging/connection-error-handler.js.map +1 -1
- package/lib/common/messaging/handler.d.ts +2 -2
- package/lib/common/messaging/handler.d.ts.map +1 -1
- package/lib/common/messaging/proxy-factory.d.ts +13 -7
- package/lib/common/messaging/proxy-factory.d.ts.map +1 -1
- package/lib/common/messaging/proxy-factory.js +18 -13
- package/lib/common/messaging/proxy-factory.js.map +1 -1
- package/lib/common/messaging/proxy-factory.spec.js +4 -15
- package/lib/common/messaging/proxy-factory.spec.js.map +1 -1
- package/lib/common/messaging/web-socket-channel.d.ts +54 -48
- package/lib/common/messaging/web-socket-channel.d.ts.map +1 -1
- package/lib/common/messaging/web-socket-channel.js +41 -105
- package/lib/common/messaging/web-socket-channel.js.map +1 -1
- package/lib/common/nls.d.ts +2 -0
- package/lib/common/nls.d.ts.map +1 -1
- package/lib/common/nls.js +11 -0
- package/lib/common/nls.js.map +1 -1
- package/lib/common/preferences/preference-schema.d.ts +1 -5
- package/lib/common/preferences/preference-schema.d.ts.map +1 -1
- package/lib/common/preferences/preference-schema.js.map +1 -1
- package/lib/common/promise-util.d.ts +2 -1
- package/lib/common/promise-util.d.ts.map +1 -1
- package/lib/common/promise-util.js +8 -13
- package/lib/common/promise-util.js.map +1 -1
- package/lib/common/resource.d.ts +5 -0
- package/lib/common/resource.d.ts.map +1 -1
- package/lib/common/resource.js +28 -1
- package/lib/common/resource.js.map +1 -1
- package/lib/common/theme.d.ts +3 -2
- package/lib/common/theme.d.ts.map +1 -1
- package/lib/common/theme.js +5 -0
- package/lib/common/theme.js.map +1 -1
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.d.ts +2 -2
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.d.ts.map +1 -1
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.js +18 -7
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.js.map +1 -1
- package/lib/electron-browser/messaging/electron-ws-connection-provider.d.ts +2 -2
- package/lib/electron-browser/messaging/electron-ws-connection-provider.d.ts.map +1 -1
- package/lib/electron-browser/messaging/electron-ws-connection-provider.js +5 -7
- package/lib/electron-browser/messaging/electron-ws-connection-provider.js.map +1 -1
- package/lib/electron-main/event-utils.d.ts +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts +37 -9
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.js +83 -68
- package/lib/electron-main/messaging/electron-messaging-contribution.js.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-service.d.ts +2 -8
- package/lib/electron-main/messaging/electron-messaging-service.d.ts.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-service.js.map +1 -1
- package/lib/node/messaging/binary-message-pipe.d.ts +45 -0
- package/lib/node/messaging/binary-message-pipe.d.ts.map +1 -0
- package/lib/node/messaging/binary-message-pipe.js +152 -0
- package/lib/node/messaging/binary-message-pipe.js.map +1 -0
- package/lib/node/messaging/ipc-bootstrap.js +2 -11
- package/lib/node/messaging/ipc-bootstrap.js.map +1 -1
- package/lib/node/messaging/ipc-channel.d.ts +26 -0
- package/lib/node/messaging/ipc-channel.d.ts.map +1 -0
- package/lib/node/messaging/ipc-channel.js +86 -0
- package/lib/node/messaging/ipc-channel.js.map +1 -0
- package/lib/node/messaging/ipc-connection-provider.d.ts +3 -5
- package/lib/node/messaging/ipc-connection-provider.d.ts.map +1 -1
- package/lib/node/messaging/ipc-connection-provider.js +14 -31
- package/lib/node/messaging/ipc-connection-provider.js.map +1 -1
- package/lib/node/messaging/ipc-protocol.d.ts +2 -2
- package/lib/node/messaging/ipc-protocol.d.ts.map +1 -1
- package/lib/node/messaging/messaging-contribution.d.ts +6 -9
- package/lib/node/messaging/messaging-contribution.d.ts.map +1 -1
- package/lib/node/messaging/messaging-contribution.js +23 -68
- package/lib/node/messaging/messaging-contribution.js.map +1 -1
- package/lib/node/messaging/messaging-service.d.ts +4 -23
- package/lib/node/messaging/messaging-service.d.ts.map +1 -1
- package/lib/node/messaging/messaging-service.js +1 -15
- package/lib/node/messaging/messaging-service.js.map +1 -1
- package/lib/node/messaging/test/test-web-socket-channel.d.ts +4 -2
- package/lib/node/messaging/test/test-web-socket-channel.d.ts.map +1 -1
- package/lib/node/messaging/test/test-web-socket-channel.js +25 -12
- package/lib/node/messaging/test/test-web-socket-channel.js.map +1 -1
- package/lib/node/request/proxy-cli-contribution.js +1 -1
- package/lib/node/request/proxy-cli-contribution.js.map +1 -1
- package/package.json +7 -10
- package/src/browser/color-application-contribution.ts +10 -17
- package/src/browser/color-registry.ts +0 -5
- package/src/browser/common-frontend-contribution.ts +26 -33
- package/src/browser/common-styling-participants.ts +307 -0
- package/src/browser/connection-status-service.spec.ts +1 -4
- package/src/browser/connection-status-service.ts +3 -3
- package/src/browser/context-menu-renderer.ts +13 -29
- package/src/browser/core-preferences.ts +6 -0
- package/src/browser/decoration-style.ts +6 -2
- package/src/browser/frontend-application-bindings.ts +1 -3
- package/src/browser/frontend-application-config-provider.ts +2 -0
- package/src/browser/frontend-application-module.ts +11 -4
- package/src/browser/i18n/i18n-frontend-module.ts +2 -0
- package/src/browser/i18n/language-quick-pick-service.ts +128 -0
- package/src/browser/index.ts +1 -0
- package/src/browser/keybinding.spec.ts +22 -27
- package/src/browser/keybinding.ts +2 -1
- package/src/browser/label-provider.ts +0 -13
- package/src/browser/logger-frontend-module.ts +8 -1
- package/src/browser/messaging/ws-connection-provider.ts +34 -25
- package/src/browser/preferences/preference-contribution.ts +3 -28
- package/src/browser/preferences/preference-proxy.spec.ts +3 -113
- package/src/browser/preferences/preference-proxy.ts +0 -4
- package/src/browser/preferences/preference-schema-provider.spec.ts +1 -4
- package/src/browser/preferences/preference-service.spec.ts +1 -5
- package/src/browser/preferences/preference-validation-service.spec.ts +2 -2
- package/src/browser/preferences/preference-validation-service.ts +2 -2
- package/src/browser/preloader.ts +9 -2
- package/src/browser/progress-status-bar-item.ts +1 -1
- package/src/browser/quick-input/quick-command-service.ts +3 -3
- package/src/browser/saveable.ts +5 -4
- package/src/browser/shell/application-shell.ts +42 -35
- package/src/browser/shell/shell-layout-restorer.ts +4 -6
- package/src/browser/shell/side-panel-handler.ts +3 -2
- package/src/browser/shell/tab-bars.ts +14 -4
- package/src/browser/source-tree/source-tree-widget.tsx +1 -1
- package/src/browser/source-tree/tree-source.ts +2 -1
- package/src/browser/style/breadcrumbs.css +0 -1
- package/src/browser/style/index.css +66 -29
- package/src/browser/style/menus.css +4 -2
- package/src/browser/style/select-component.css +2 -0
- package/src/browser/style/sidepanel.css +11 -25
- package/src/browser/style/status-bar.css +8 -17
- package/src/browser/style/tabs.css +0 -16
- package/src/browser/style/tooltip.css +3 -3
- package/src/browser/style/tree.css +27 -11
- package/src/browser/style/view-container.css +4 -0
- package/src/browser/styling-service.ts +76 -0
- package/src/browser/theming.ts +18 -45
- package/src/browser/tree/search-box.ts +5 -4
- package/src/browser/tree/test/tree-test-container.ts +2 -0
- package/src/browser/tree/tree-compression/compressed-tree-model.ts +8 -2
- package/src/browser/tree/tree-compression/compressed-tree-widget.tsx +4 -2
- package/src/browser/tree/tree-container.ts +4 -0
- package/src/browser/tree/tree-focus-service.ts +55 -0
- package/src/browser/tree/tree-model.ts +32 -8
- package/src/browser/tree/tree-selection-impl.ts +13 -4
- package/src/browser/tree/tree-selection-state.ts +7 -2
- package/src/browser/tree/tree-selection.ts +10 -0
- package/src/browser/tree/tree-widget-selection.ts +10 -1
- package/src/browser/tree/tree-widget.tsx +83 -43
- package/src/browser/tree/tree.ts +8 -2
- package/src/browser/view-container.ts +41 -4
- package/src/common/cancellation.ts +8 -0
- package/src/common/command.ts +14 -16
- package/src/common/index.ts +1 -0
- package/src/common/message-rpc/channel.spec.ts +88 -0
- package/src/common/message-rpc/channel.ts +260 -0
- package/src/{node/messaging/logger.ts → common/message-rpc/index.ts} +4 -23
- package/src/common/message-rpc/message-buffer.ts +99 -0
- package/src/common/message-rpc/rpc-message-encoder.spec.ts +55 -0
- package/src/common/message-rpc/rpc-message-encoder.ts +552 -0
- package/src/common/message-rpc/rpc-protocol.ts +217 -0
- package/src/common/message-rpc/uint8-array-message-buffer.spec.ts +41 -0
- package/src/common/message-rpc/uint8-array-message-buffer.ts +206 -0
- package/src/common/messaging/abstract-connection-provider.ts +28 -37
- package/src/common/messaging/connection-error-handler.ts +1 -2
- package/src/common/messaging/handler.ts +2 -2
- package/src/common/messaging/proxy-factory.spec.ts +4 -17
- package/src/common/messaging/proxy-factory.ts +27 -16
- package/src/common/messaging/web-socket-channel.ts +79 -135
- package/src/common/nls.ts +11 -0
- package/src/common/preferences/preference-schema.ts +1 -6
- package/src/common/promise-util.ts +13 -14
- package/src/common/resource.ts +29 -2
- package/src/common/theme.ts +6 -2
- package/src/electron-browser/messaging/electron-ipc-connection-provider.ts +21 -7
- package/src/electron-browser/messaging/electron-ws-connection-provider.ts +5 -8
- package/src/electron-main/messaging/electron-messaging-contribution.ts +87 -65
- package/src/electron-main/messaging/electron-messaging-service.ts +2 -8
- package/src/node/messaging/binary-message-pipe.ts +168 -0
- package/src/node/messaging/ipc-bootstrap.ts +3 -11
- package/src/node/messaging/ipc-channel.ts +97 -0
- package/src/node/messaging/ipc-connection-provider.ts +18 -35
- package/src/node/messaging/ipc-protocol.ts +2 -2
- package/src/node/messaging/messaging-contribution.ts +29 -74
- package/src/node/messaging/messaging-service.ts +4 -31
- package/src/node/messaging/test/test-web-socket-channel.ts +26 -17
- package/src/node/request/proxy-cli-contribution.ts +1 -1
- package/lib/browser/preferences/validated-preference-proxy.d.ts +0 -21
- package/lib/browser/preferences/validated-preference-proxy.d.ts.map +0 -1
- package/lib/browser/preferences/validated-preference-proxy.js +0 -118
- package/lib/browser/preferences/validated-preference-proxy.js.map +0 -1
- package/lib/node/messaging/logger.d.ts +0 -8
- package/lib/node/messaging/logger.d.ts.map +0 -1
- package/lib/node/messaging/logger.js.map +0 -1
- package/shared/vscode-ws-jsonrpc/index.d.ts +0 -1
- package/shared/vscode-ws-jsonrpc/index.js +0 -1
- package/src/browser/preferences/validated-preference-proxy.ts +0 -111
- package/src/browser/style/variables-bright.useable.css +0 -93
- package/src/browser/style/variables-dark.useable.css +0 -93
|
@@ -16,24 +16,23 @@
|
|
|
16
16
|
|
|
17
17
|
import { IpcMainEvent, ipcMain, WebContents } from '@theia/electron/shared/electron';
|
|
18
18
|
import { inject, injectable, named, postConstruct } from 'inversify';
|
|
19
|
-
import { MessageConnection } from 'vscode-ws-jsonrpc';
|
|
20
|
-
import { createWebSocketConnection } from 'vscode-ws-jsonrpc/lib/socket/connection';
|
|
21
19
|
import { ContributionProvider } from '../../common/contribution-provider';
|
|
22
|
-
import { WebSocketChannel } from '../../common/messaging/web-socket-channel';
|
|
23
20
|
import { MessagingContribution } from '../../node/messaging/messaging-contribution';
|
|
24
|
-
import { ConsoleLogger } from '../../node/messaging/logger';
|
|
25
21
|
import { ElectronConnectionHandler, THEIA_ELECTRON_IPC_CHANNEL_NAME } from '../../electron-common/messaging/electron-connection-handler';
|
|
26
22
|
import { ElectronMainApplicationContribution } from '../electron-main-application';
|
|
27
23
|
import { ElectronMessagingService } from './electron-messaging-service';
|
|
24
|
+
import { Channel, ChannelCloseEvent, ChannelMultiplexer, MessageProvider } from '../../common/message-rpc/channel';
|
|
25
|
+
import { Emitter, Event, WriteBuffer } from '../../common';
|
|
26
|
+
import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '../../common/message-rpc/uint8-array-message-buffer';
|
|
28
27
|
|
|
29
28
|
/**
|
|
30
29
|
* This component replicates the role filled by `MessagingContribution` but for Electron.
|
|
31
30
|
* Unlike the WebSocket based implementation, we do not expect to receive
|
|
32
31
|
* connection events. Instead, we'll create channels based on incoming `open`
|
|
33
32
|
* events on the `ipcMain` channel.
|
|
34
|
-
*
|
|
35
33
|
* This component allows communication between renderer process (frontend) and electron main process.
|
|
36
34
|
*/
|
|
35
|
+
|
|
37
36
|
@injectable()
|
|
38
37
|
export class ElectronMessagingContribution implements ElectronMainApplicationContribution, ElectronMessagingService {
|
|
39
38
|
|
|
@@ -43,89 +42,112 @@ export class ElectronMessagingContribution implements ElectronMainApplicationCon
|
|
|
43
42
|
@inject(ContributionProvider) @named(ElectronConnectionHandler)
|
|
44
43
|
protected readonly connectionHandlers: ContributionProvider<ElectronConnectionHandler>;
|
|
45
44
|
|
|
46
|
-
protected readonly channelHandlers = new MessagingContribution.ConnectionHandlers<
|
|
47
|
-
|
|
45
|
+
protected readonly channelHandlers = new MessagingContribution.ConnectionHandlers<Channel>();
|
|
46
|
+
/**
|
|
47
|
+
* Each electron window has a main chanel and its own multiplexer to route multiple client messages the same IPC connection.
|
|
48
|
+
*/
|
|
49
|
+
protected readonly windowChannelMultiplexer = new Map<number, { channel: ElectronWebContentChannel, multiPlexer: ChannelMultiplexer }>();
|
|
48
50
|
|
|
49
51
|
@postConstruct()
|
|
50
52
|
protected init(): void {
|
|
51
|
-
ipcMain.on(THEIA_ELECTRON_IPC_CHANNEL_NAME, (event: IpcMainEvent, data:
|
|
52
|
-
this.
|
|
53
|
+
ipcMain.on(THEIA_ELECTRON_IPC_CHANNEL_NAME, (event: IpcMainEvent, data: Uint8Array) => {
|
|
54
|
+
this.handleIpcEvent(event, data);
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
protected handleIpcEvent(event: IpcMainEvent, data: Uint8Array): void {
|
|
59
|
+
const sender = event.sender;
|
|
60
|
+
// Get the multiplexer for a given window id
|
|
61
|
+
try {
|
|
62
|
+
const windowChannelData = this.windowChannelMultiplexer.get(sender.id) ?? this.createWindowChannelData(sender);
|
|
63
|
+
windowChannelData!.channel.onMessageEmitter.fire(() => new Uint8ArrayReadBuffer(data));
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('IPC: Failed to handle message', { error, data });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Creates a new multiplexer for a given sender/window
|
|
70
|
+
protected createWindowChannelData(sender: Electron.WebContents): { channel: ElectronWebContentChannel, multiPlexer: ChannelMultiplexer } {
|
|
71
|
+
const mainChannel = this.createWindowMainChannel(sender);
|
|
72
|
+
const multiPlexer = new ChannelMultiplexer(mainChannel);
|
|
73
|
+
multiPlexer.onDidOpenChannel(openEvent => {
|
|
74
|
+
const { channel, id } = openEvent;
|
|
75
|
+
if (this.channelHandlers.route(id, channel)) {
|
|
76
|
+
console.debug(`Opening channel for service path '${id}'.`);
|
|
77
|
+
channel.onClose(() => console.debug(`Closing channel on service path '${id}'.`));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
sender.once('did-navigate', () => multiPlexer.onUnderlyingChannelClose({ reason: 'Window was refreshed' })); // When refreshing the browser window.
|
|
82
|
+
sender.once('destroyed', () => multiPlexer.onUnderlyingChannelClose({ reason: 'Window was closed' })); // When closing the browser window.
|
|
83
|
+
const data = { channel: mainChannel, multiPlexer };
|
|
84
|
+
this.windowChannelMultiplexer.set(sender.id, data);
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Creates the main channel to a window.
|
|
90
|
+
* @param sender The window that the channel should be established to.
|
|
91
|
+
*/
|
|
92
|
+
protected createWindowMainChannel(sender: WebContents): ElectronWebContentChannel {
|
|
93
|
+
return new ElectronWebContentChannel(sender);
|
|
94
|
+
}
|
|
95
|
+
|
|
56
96
|
onStart(): void {
|
|
57
97
|
for (const contribution of this.messagingContributions.getContributions()) {
|
|
58
98
|
contribution.configure(this);
|
|
59
99
|
}
|
|
60
100
|
for (const connectionHandler of this.connectionHandlers.getContributions()) {
|
|
61
101
|
this.channelHandlers.push(connectionHandler.path, (params, channel) => {
|
|
62
|
-
|
|
63
|
-
connectionHandler.onConnection(connection);
|
|
102
|
+
connectionHandler.onConnection(channel);
|
|
64
103
|
});
|
|
65
104
|
}
|
|
66
105
|
}
|
|
67
106
|
|
|
68
|
-
listen(spec: string, callback: (params: ElectronMessagingService.PathParams, connection: MessageConnection) => void): void {
|
|
69
|
-
this.ipcChannel(spec, (params, channel) => {
|
|
70
|
-
const connection = createWebSocketConnection(channel, new ConsoleLogger());
|
|
71
|
-
callback(params, connection);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
107
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
-
ipcChannel(spec: string, callback: (params: any, channel:
|
|
108
|
+
ipcChannel(spec: string, callback: (params: any, channel: Channel) => void): void {
|
|
77
109
|
this.channelHandlers.push(spec, callback);
|
|
78
110
|
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Used to establish a connection between the ipcMain and the Electron frontend (window).
|
|
115
|
+
* Messages a transferred via electron IPC.
|
|
116
|
+
*/
|
|
117
|
+
export class ElectronWebContentChannel implements Channel {
|
|
118
|
+
protected readonly onCloseEmitter: Emitter<ChannelCloseEvent> = new Emitter();
|
|
119
|
+
get onClose(): Event<ChannelCloseEvent> {
|
|
120
|
+
return this.onCloseEmitter.event;
|
|
121
|
+
}
|
|
79
122
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const { id, path } = message;
|
|
93
|
-
const channel = this.createChannel(id, sender);
|
|
94
|
-
if (this.channelHandlers.route(path, channel)) {
|
|
95
|
-
channel.ready();
|
|
96
|
-
channels.set(id, channel);
|
|
97
|
-
channel.onClose(() => channels.delete(id));
|
|
98
|
-
} else {
|
|
99
|
-
console.error('Cannot find a service for the path: ' + path);
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
const { id } = message;
|
|
103
|
-
const channel = channels.get(id);
|
|
104
|
-
if (channel) {
|
|
105
|
-
channel.handleMessage(message);
|
|
106
|
-
} else {
|
|
107
|
-
console.error('The ipc channel does not exist', id);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
const close = () => {
|
|
111
|
-
for (const channel of Array.from(channels.values())) {
|
|
112
|
-
channel.close(undefined, 'webContent destroyed');
|
|
113
|
-
}
|
|
114
|
-
channels.clear();
|
|
115
|
-
};
|
|
116
|
-
sender.once('did-navigate', close); // When refreshing the browser window.
|
|
117
|
-
sender.once('destroyed', close); // When closing the browser window.
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error('IPC: Failed to handle message', { error, data });
|
|
120
|
-
}
|
|
123
|
+
// Make the message emitter public so that we can easily forward messages received from the ipcMain.
|
|
124
|
+
readonly onMessageEmitter: Emitter<MessageProvider> = new Emitter();
|
|
125
|
+
get onMessage(): Event<MessageProvider> {
|
|
126
|
+
return this.onMessageEmitter.event;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
protected readonly onErrorEmitter: Emitter<unknown> = new Emitter();
|
|
130
|
+
get onError(): Event<unknown> {
|
|
131
|
+
return this.onErrorEmitter.event;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
constructor(protected readonly sender: Electron.WebContents) {
|
|
121
135
|
}
|
|
122
136
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
getWriteBuffer(): WriteBuffer {
|
|
138
|
+
const writer = new Uint8ArrayWriteBuffer();
|
|
139
|
+
|
|
140
|
+
writer.onCommit(buffer => {
|
|
141
|
+
if (!this.sender.isDestroyed()) {
|
|
142
|
+
this.sender.send(THEIA_ELECTRON_IPC_CHANNEL_NAME, buffer);
|
|
127
143
|
}
|
|
128
144
|
});
|
|
129
|
-
}
|
|
130
145
|
|
|
146
|
+
return writer;
|
|
147
|
+
}
|
|
148
|
+
close(): void {
|
|
149
|
+
this.onCloseEmitter.dispose();
|
|
150
|
+
this.onMessageEmitter.dispose();
|
|
151
|
+
this.onErrorEmitter.dispose();
|
|
152
|
+
}
|
|
131
153
|
}
|
|
@@ -14,20 +14,14 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import
|
|
18
|
-
import type { WebSocketChannel } from '../../common/messaging/web-socket-channel';
|
|
17
|
+
import { Channel } from '../../common/message-rpc/channel';
|
|
19
18
|
|
|
20
19
|
export interface ElectronMessagingService {
|
|
21
|
-
/**
|
|
22
|
-
* Accept a JSON-RPC connection on the given path.
|
|
23
|
-
* A path supports the route syntax: https://github.com/rcs/route-parser#what-can-i-use-in-my-routes.
|
|
24
|
-
*/
|
|
25
|
-
listen(path: string, callback: (params: ElectronMessagingService.PathParams, connection: MessageConnection) => void): void;
|
|
26
20
|
/**
|
|
27
21
|
* Accept an ipc channel on the given path.
|
|
28
22
|
* A path supports the route syntax: https://github.com/rcs/route-parser#what-can-i-use-in-my-routes.
|
|
29
23
|
*/
|
|
30
|
-
ipcChannel(path: string, callback: (params: ElectronMessagingService.PathParams, socket:
|
|
24
|
+
ipcChannel(path: string, callback: (params: ElectronMessagingService.PathParams, socket: Channel) => void): void;
|
|
31
25
|
}
|
|
32
26
|
export namespace ElectronMessagingService {
|
|
33
27
|
export interface PathParams {
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 STMicroelectronics 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 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { Duplex } from 'stream';
|
|
18
|
+
import { Disposable, Emitter, Event } from '../../common';
|
|
19
|
+
import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '../../common/message-rpc/uint8-array-message-buffer';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A `BinaryMessagePipe` is capable of sending and retrieving binary messages i.e. {@link Uint8Array}s over
|
|
23
|
+
* and underlying streamed process pipe/fd. The message length of individual messages is encoding at the beginning of
|
|
24
|
+
* a new message. This makes it possible to extract messages from the streamed data.
|
|
25
|
+
*/
|
|
26
|
+
export class BinaryMessagePipe implements Disposable {
|
|
27
|
+
static readonly MESSAGE_START_IDENTIFIER = '<MessageStart>';
|
|
28
|
+
protected dataHandler = (chunk: Uint8Array) => this.handleChunk(chunk);
|
|
29
|
+
|
|
30
|
+
protected onMessageEmitter = new Emitter<Uint8Array>();
|
|
31
|
+
protected cachedMessageData: StreamedMessageData = {
|
|
32
|
+
chunks: [],
|
|
33
|
+
missingBytes: 0
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
get onMessage(): Event<Uint8Array> {
|
|
37
|
+
return this.onMessageEmitter.event;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
constructor(protected readonly underlyingPipe: Duplex) {
|
|
41
|
+
underlyingPipe.on('data', this.dataHandler);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
send(message: Uint8Array): void {
|
|
45
|
+
this.underlyingPipe.write(this.encodeMessageStart(message));
|
|
46
|
+
this.underlyingPipe.write(message);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected handleChunk(chunk: Uint8Array): void {
|
|
50
|
+
if (this.cachedMessageData.missingBytes === 0) {
|
|
51
|
+
// There is no currently streamed message => We expect that the beginning of the chunk is the message start for a new message
|
|
52
|
+
this.handleNewMessage(chunk);
|
|
53
|
+
} else {
|
|
54
|
+
// The chunk contains message data intended for the currently cached message
|
|
55
|
+
this.handleMessageContentChunk(chunk);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected handleNewMessage(chunk: Uint8Array): void {
|
|
60
|
+
if (chunk.byteLength < this.messageStartByteLength) {
|
|
61
|
+
// The chunk only contains a part of the encoded message start
|
|
62
|
+
this.cachedMessageData.partialMessageStart = chunk;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const messageLength = this.readMessageStart(chunk);
|
|
67
|
+
|
|
68
|
+
if (chunk.length - this.messageStartByteLength > messageLength) {
|
|
69
|
+
// The initial chunk contains more than one binary message => Fire `onMessage` for first message and handle remaining content
|
|
70
|
+
const firstMessage = chunk.slice(this.messageStartByteLength, this.messageStartByteLength + messageLength);
|
|
71
|
+
this.onMessageEmitter.fire(firstMessage);
|
|
72
|
+
this.handleNewMessage(chunk.slice(this.messageStartByteLength + messageLength));
|
|
73
|
+
|
|
74
|
+
} else if (chunk.length - this.messageStartByteLength === messageLength) {
|
|
75
|
+
// The initial chunk contains exactly one complete message. => Directly fire the `onMessage` event.
|
|
76
|
+
this.onMessageEmitter.fire(chunk.slice(this.messageStartByteLength));
|
|
77
|
+
} else {
|
|
78
|
+
// The initial chunk contains only part of the message content => Cache message data
|
|
79
|
+
this.cachedMessageData.chunks = [chunk.slice(this.messageStartByteLength)];
|
|
80
|
+
this.cachedMessageData.missingBytes = messageLength - chunk.byteLength + this.messageStartByteLength;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected handleMessageContentChunk(chunk: Uint8Array): void {
|
|
85
|
+
if (this.cachedMessageData) {
|
|
86
|
+
if (chunk.byteLength < this.cachedMessageData.missingBytes) {
|
|
87
|
+
// The chunk only contains parts of the missing bytes for the cached message.
|
|
88
|
+
this.cachedMessageData.chunks.push(chunk);
|
|
89
|
+
this.cachedMessageData.missingBytes -= chunk.byteLength;
|
|
90
|
+
} else if (chunk.byteLength === this.cachedMessageData.missingBytes) {
|
|
91
|
+
// Chunk contains exactly the missing data for the cached message
|
|
92
|
+
this.cachedMessageData.chunks.push(chunk);
|
|
93
|
+
this.emitCachedMessage();
|
|
94
|
+
} else {
|
|
95
|
+
// Chunk contains missing data for the cached message + data for the next message
|
|
96
|
+
const messageEnd = this.cachedMessageData.missingBytes;
|
|
97
|
+
const missingData = chunk.slice(0, messageEnd);
|
|
98
|
+
this.cachedMessageData.chunks.push(missingData);
|
|
99
|
+
this.emitCachedMessage();
|
|
100
|
+
this.handleNewMessage(chunk.slice(messageEnd));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected emitCachedMessage(): void {
|
|
107
|
+
const message = Buffer.concat(this.cachedMessageData.chunks);
|
|
108
|
+
this.onMessageEmitter.fire(message);
|
|
109
|
+
this.cachedMessageData.chunks = [];
|
|
110
|
+
this.cachedMessageData.missingBytes = 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Encodes the start of a new message into a {@link Uint8Array}.
|
|
115
|
+
* The message start consists of a identifier string and the length of the following message.
|
|
116
|
+
* @returns the buffer contains the encoded message start
|
|
117
|
+
*/
|
|
118
|
+
protected encodeMessageStart(message: Uint8Array): Uint8Array {
|
|
119
|
+
const writer = new Uint8ArrayWriteBuffer()
|
|
120
|
+
.writeString(BinaryMessagePipe.MESSAGE_START_IDENTIFIER)
|
|
121
|
+
.writeUint32(message.length);
|
|
122
|
+
const messageStart = writer.getCurrentContents();
|
|
123
|
+
writer.dispose();
|
|
124
|
+
return messageStart;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
protected get messageStartByteLength(): number {
|
|
128
|
+
// 4 bytes for length of id + id string length + 4 bytes for length of message
|
|
129
|
+
return 4 + BinaryMessagePipe.MESSAGE_START_IDENTIFIER.length + 4;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Reads the start of a new message from a stream chunk (or cached message) received from the underlying pipe.
|
|
134
|
+
* The message start is expected to consist of an identifier string and the length of the message.
|
|
135
|
+
* @param chunk The stream chunk.
|
|
136
|
+
* @returns The length of the message content to read.
|
|
137
|
+
* @throws An error if the message start can not be read successfully.
|
|
138
|
+
*/
|
|
139
|
+
protected readMessageStart(chunk: Uint8Array): number {
|
|
140
|
+
const messageData = this.cachedMessageData.partialMessageStart ? Buffer.concat([this.cachedMessageData.partialMessageStart, chunk]) : chunk;
|
|
141
|
+
this.cachedMessageData.partialMessageStart = undefined;
|
|
142
|
+
|
|
143
|
+
const reader = new Uint8ArrayReadBuffer(messageData);
|
|
144
|
+
const identifier = reader.readString();
|
|
145
|
+
|
|
146
|
+
if (identifier !== BinaryMessagePipe.MESSAGE_START_IDENTIFIER) {
|
|
147
|
+
throw new Error(`Could not read message start. The start identifier should be '${BinaryMessagePipe.MESSAGE_START_IDENTIFIER}' but was '${identifier}`);
|
|
148
|
+
}
|
|
149
|
+
const length = reader.readUint32();
|
|
150
|
+
return length;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
dispose(): void {
|
|
154
|
+
this.underlyingPipe.removeListener('data', this.dataHandler);
|
|
155
|
+
this.underlyingPipe.end();
|
|
156
|
+
this.onMessageEmitter.dispose();
|
|
157
|
+
this.cachedMessageData = {
|
|
158
|
+
chunks: [],
|
|
159
|
+
missingBytes: 0
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface StreamedMessageData {
|
|
165
|
+
chunks: Uint8Array[];
|
|
166
|
+
missingBytes: number;
|
|
167
|
+
partialMessageStart?: Uint8Array;
|
|
168
|
+
}
|
|
@@ -16,20 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
import 'reflect-metadata';
|
|
18
18
|
import { dynamicRequire } from '../dynamic-require';
|
|
19
|
-
import {
|
|
20
|
-
import { createMessageConnection, IPCMessageReader, IPCMessageWriter, Trace } from 'vscode-ws-jsonrpc';
|
|
19
|
+
import { IPCChannel } from './ipc-channel';
|
|
21
20
|
import { checkParentAlive, IPCEntryPoint } from './ipc-protocol';
|
|
22
21
|
|
|
23
22
|
checkParentAlive();
|
|
24
23
|
|
|
25
24
|
const entryPoint = IPCEntryPoint.getScriptFromEnv();
|
|
26
|
-
const reader = new IPCMessageReader(process);
|
|
27
|
-
const writer = new IPCMessageWriter(process);
|
|
28
|
-
const logger = new ConsoleLogger();
|
|
29
|
-
const connection = createMessageConnection(reader, writer, logger);
|
|
30
|
-
connection.trace(Trace.Off, {
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
-
log: (message: any, data?: string) => console.log(message, data)
|
|
33
|
-
});
|
|
34
25
|
|
|
35
|
-
dynamicRequire<{ default: IPCEntryPoint }>(entryPoint).default(
|
|
26
|
+
dynamicRequire<{ default: IPCEntryPoint }>(entryPoint).default(new IPCChannel());
|
|
27
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 STMicroelectronics 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 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
17
|
+
|
|
18
|
+
import * as cp from 'child_process';
|
|
19
|
+
import { Socket } from 'net';
|
|
20
|
+
import { Duplex } from 'stream';
|
|
21
|
+
import { Channel, ChannelCloseEvent, Disposable, DisposableCollection, Emitter, Event, MessageProvider, WriteBuffer } from '../../common';
|
|
22
|
+
import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '../../common/message-rpc/uint8-array-message-buffer';
|
|
23
|
+
import { BinaryMessagePipe } from './binary-message-pipe';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A {@link Channel} to send messages between two processes using a dedicated pipe/fd for binary messages.
|
|
27
|
+
* This fd is opened as 5th channel in addition to the default stdios (stdin, stdout, stderr, ipc). This means the default channels
|
|
28
|
+
* are not blocked and can be used by the respective process for additional custom message handling.
|
|
29
|
+
*/
|
|
30
|
+
export class IPCChannel implements Channel {
|
|
31
|
+
|
|
32
|
+
protected readonly onCloseEmitter: Emitter<ChannelCloseEvent> = new Emitter();
|
|
33
|
+
get onClose(): Event<ChannelCloseEvent> {
|
|
34
|
+
return this.onCloseEmitter.event;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected readonly onMessageEmitter: Emitter<MessageProvider> = new Emitter();
|
|
38
|
+
get onMessage(): Event<MessageProvider> {
|
|
39
|
+
return this.onMessageEmitter.event;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected readonly onErrorEmitter: Emitter<unknown> = new Emitter();
|
|
43
|
+
get onError(): Event<unknown> {
|
|
44
|
+
return this.onErrorEmitter.event;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected messagePipe: BinaryMessagePipe;
|
|
48
|
+
protected toDispose = new DisposableCollection();
|
|
49
|
+
|
|
50
|
+
protected ipcErrorListener: (error: Error) => void = error => this.onErrorEmitter.fire(error);
|
|
51
|
+
|
|
52
|
+
constructor(childProcess?: cp.ChildProcess) {
|
|
53
|
+
if (childProcess) {
|
|
54
|
+
this.setupChildProcess(childProcess);
|
|
55
|
+
} else {
|
|
56
|
+
this.setupProcess();
|
|
57
|
+
}
|
|
58
|
+
this.messagePipe.onMessage(message => {
|
|
59
|
+
this.onMessageEmitter.fire(() => new Uint8ArrayReadBuffer(message));
|
|
60
|
+
});
|
|
61
|
+
this.toDispose.pushAll([this.onCloseEmitter, this.onMessageEmitter, this.onErrorEmitter]);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected setupChildProcess(childProcess: cp.ChildProcess): void {
|
|
65
|
+
childProcess.once('exit', code => this.onCloseEmitter.fire({ reason: 'Child process has been terminated', code: code ?? undefined }));
|
|
66
|
+
this.messagePipe = new BinaryMessagePipe(childProcess.stdio[4] as Duplex);
|
|
67
|
+
childProcess.on('error', this.ipcErrorListener);
|
|
68
|
+
this.toDispose.push(Disposable.create(() => {
|
|
69
|
+
childProcess.removeListener('error', this.ipcErrorListener);
|
|
70
|
+
this.messagePipe.dispose();
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected setupProcess(): void {
|
|
75
|
+
process.once('beforeExit', code => this.onCloseEmitter.fire({ reason: 'Process is about to be terminated', code }));
|
|
76
|
+
this.messagePipe = new BinaryMessagePipe(new Socket({ fd: 4 }));
|
|
77
|
+
process.on('uncaughtException', this.ipcErrorListener);
|
|
78
|
+
this.toDispose.push(Disposable.create(() => {
|
|
79
|
+
(process as NodeJS.EventEmitter).removeListener('uncaughtException', this.ipcErrorListener);
|
|
80
|
+
this.messagePipe.dispose();
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
getWriteBuffer(): WriteBuffer {
|
|
85
|
+
const result = new Uint8ArrayWriteBuffer();
|
|
86
|
+
result.onCommit(buffer => {
|
|
87
|
+
this.messagePipe.send(buffer);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
close(): void {
|
|
94
|
+
this.toDispose.dispose();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import * as cp from 'child_process';
|
|
18
|
+
import { inject, injectable } from 'inversify';
|
|
18
19
|
import * as path from 'path';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { createInterface } from 'readline';
|
|
21
|
+
import { Channel, ConnectionErrorHandler, Disposable, DisposableCollection, ILogger } from '../../common';
|
|
22
|
+
import { IPCChannel } from './ipc-channel';
|
|
22
23
|
import { createIpcEnv } from './ipc-protocol';
|
|
23
24
|
|
|
24
25
|
export interface ResolvedIPCConnectionOptions {
|
|
@@ -40,7 +41,7 @@ export class IPCConnectionProvider {
|
|
|
40
41
|
@inject(ILogger)
|
|
41
42
|
protected readonly logger: ILogger;
|
|
42
43
|
|
|
43
|
-
listen(options: IPCConnectionOptions, acceptor: (connection:
|
|
44
|
+
listen(options: IPCConnectionOptions, acceptor: (connection: Channel) => void): Disposable {
|
|
44
45
|
return this.doListen({
|
|
45
46
|
logger: this.logger,
|
|
46
47
|
args: [],
|
|
@@ -48,19 +49,21 @@ export class IPCConnectionProvider {
|
|
|
48
49
|
}, acceptor);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
protected doListen(options: ResolvedIPCConnectionOptions, acceptor: (connection:
|
|
52
|
+
protected doListen(options: ResolvedIPCConnectionOptions, acceptor: (connection: Channel) => void): Disposable {
|
|
52
53
|
const childProcess = this.fork(options);
|
|
53
|
-
const
|
|
54
|
+
const channel = new IPCChannel(childProcess);
|
|
54
55
|
const toStop = new DisposableCollection();
|
|
55
56
|
const toCancelStop = toStop.push(Disposable.create(() => childProcess.kill()));
|
|
56
57
|
const errorHandler = options.errorHandler;
|
|
57
58
|
if (errorHandler) {
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
let errorCount = 0;
|
|
60
|
+
channel.onError((err: Error) => {
|
|
61
|
+
errorCount++;
|
|
62
|
+
if (errorHandler.shouldStop(err, errorCount)) {
|
|
60
63
|
toStop.dispose();
|
|
61
64
|
}
|
|
62
65
|
});
|
|
63
|
-
|
|
66
|
+
channel.onClose(() => {
|
|
64
67
|
if (toStop.disposed) {
|
|
65
68
|
return;
|
|
66
69
|
}
|
|
@@ -70,36 +73,15 @@ export class IPCConnectionProvider {
|
|
|
70
73
|
}
|
|
71
74
|
});
|
|
72
75
|
}
|
|
73
|
-
acceptor(
|
|
76
|
+
acceptor(channel);
|
|
74
77
|
return toStop;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
protected createConnection(childProcess: cp.ChildProcess, options: ResolvedIPCConnectionOptions): MessageConnection {
|
|
78
|
-
const reader = new IPCMessageReader(childProcess);
|
|
79
|
-
const writer = new IPCMessageWriter(childProcess);
|
|
80
|
-
const connection = createMessageConnection(reader, writer, {
|
|
81
|
-
error: (message: string) => this.logger.error(`[${options.serverName}: ${childProcess.pid}] ${message}`),
|
|
82
|
-
warn: (message: string) => this.logger.warn(`[${options.serverName}: ${childProcess.pid}] ${message}`),
|
|
83
|
-
info: (message: string) => this.logger.info(`[${options.serverName}: ${childProcess.pid}] ${message}`),
|
|
84
|
-
log: (message: string) => this.logger.info(`[${options.serverName}: ${childProcess.pid}] ${message}`)
|
|
85
|
-
});
|
|
86
|
-
const tracer: Tracer = {
|
|
87
|
-
log: (message: unknown, data?: string) => this.logger.debug(`[${options.serverName}: ${childProcess.pid}] ${message}` + (typeof data === 'string' ? ' ' + data : ''))
|
|
88
|
-
};
|
|
89
|
-
connection.trace(Trace.Verbose, tracer);
|
|
90
|
-
this.logger.isDebug().then(isDebug => {
|
|
91
|
-
if (!isDebug) {
|
|
92
|
-
connection.trace(Trace.Off, tracer);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
return connection;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
80
|
protected fork(options: ResolvedIPCConnectionOptions): cp.ChildProcess {
|
|
99
81
|
const forkOptions: cp.ForkOptions = {
|
|
100
|
-
silent: true,
|
|
101
82
|
env: createIpcEnv(options),
|
|
102
|
-
execArgv: []
|
|
83
|
+
execArgv: [],
|
|
84
|
+
stdio: ['pipe', 'pipe', 'pipe', 'ipc', 'pipe']
|
|
103
85
|
};
|
|
104
86
|
const inspectArgPrefix = `--${options.serverName}-inspect`;
|
|
105
87
|
const inspectArg = process.argv.find(v => v.startsWith(inspectArgPrefix));
|
|
@@ -108,8 +90,9 @@ export class IPCConnectionProvider {
|
|
|
108
90
|
}
|
|
109
91
|
|
|
110
92
|
const childProcess = cp.fork(path.join(__dirname, 'ipc-bootstrap'), options.args, forkOptions);
|
|
111
|
-
|
|
112
|
-
childProcess.
|
|
93
|
+
|
|
94
|
+
createInterface(childProcess.stdout!).on('line', line => this.logger.info(`[${options.serverName}: ${childProcess.pid}] ${line}`));
|
|
95
|
+
createInterface(childProcess.stderr!).on('line', line => this.logger.error(`[${options.serverName}: ${childProcess.pid}] ${line}`));
|
|
113
96
|
|
|
114
97
|
this.logger.debug(`[${options.serverName}: ${childProcess.pid}] IPC started`);
|
|
115
98
|
childProcess.once('exit', () => this.logger.debug(`[${options.serverName}: ${childProcess.pid}] IPC exited`));
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { Channel } from '../../common/message-rpc/channel';
|
|
19
19
|
|
|
20
20
|
const THEIA_PARENT_PID = 'THEIA_PARENT_PID';
|
|
21
21
|
const THEIA_ENTRY_POINT = 'THEIA_ENTRY_POINT';
|
|
22
22
|
|
|
23
23
|
export const ipcEntryPoint: string | undefined = process.env[THEIA_ENTRY_POINT];
|
|
24
24
|
|
|
25
|
-
export type IPCEntryPoint = (connection:
|
|
25
|
+
export type IPCEntryPoint = (connection: Channel) => void;
|
|
26
26
|
export namespace IPCEntryPoint {
|
|
27
27
|
/**
|
|
28
28
|
* Throws if `THEIA_ENTRY_POINT` is undefined or empty.
|