Path: blob/main/extensions/ipynb/src/notebookSerializer.web.ts
3292 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as vscode from 'vscode';6import { DeferredPromise, generateUuid } from './helper';7import { NotebookSerializerBase } from './notebookSerializer';89export class NotebookSerializer extends NotebookSerializerBase {10private experimentalSave = vscode.workspace.getConfiguration('ipynb').get('experimental.serialization', true);11private worker?: Worker;12private tasks = new Map<string, DeferredPromise<Uint8Array>>();1314constructor(context: vscode.ExtensionContext) {15super(context);16context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => {17if (e.affectsConfiguration('ipynb.experimental.serialization')) {18this.experimentalSave = vscode.workspace.getConfiguration('ipynb').get('experimental.serialization', true);19}20}));21}2223override dispose() {24try {25void this.worker?.terminate();26} catch {27//28}29super.dispose();30}3132public override async serializeNotebook(data: vscode.NotebookData, token: vscode.CancellationToken): Promise<Uint8Array> {33if (this.disposed) {34return new Uint8Array(0);35}3637if (this.experimentalSave) {38return this.serializeViaWorker(data);39}4041return super.serializeNotebook(data, token);42}4344private async startWorker() {45if (this.disposed) {46throw new Error('Serializer disposed');47}48if (this.worker) {49return this.worker;50}51const entry = vscode.Uri.joinPath(this.context.extensionUri, 'dist', 'browser', 'notebookSerializerWorker.js');52this.worker = new Worker(entry.toString());53this.worker.addEventListener('exit', (exitCode) => {54if (!this.disposed) {55console.error(`IPynb Notebook Serializer Worker exited unexpectedly`, exitCode);56}57this.worker = undefined;58});59this.worker.onmessage = (e) => {60const result = e.data as { id: string; data: Uint8Array };61const task = this.tasks.get(result.id);62if (task) {63task.complete(result.data);64this.tasks.delete(result.id);65}66};67this.worker.onerror = (err) => {68if (!this.disposed) {69console.error(`IPynb Notebook Serializer Worker errored unexpectedly`, err);70}71};72return this.worker;73}74private async serializeViaWorker(data: vscode.NotebookData): Promise<Uint8Array> {75const worker = await this.startWorker();76const id = generateUuid();7778const deferred = new DeferredPromise<Uint8Array>();79this.tasks.set(id, deferred);80worker.postMessage({ data, id });8182return deferred.p;83}84}858687