Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { VSBuffer } from '../../../../../base/common/buffer.js';
7
import { Emitter } from '../../../../../base/common/event.js';
8
import { Disposable } from '../../../../../base/common/lifecycle.js';
9
import { ICellOutput, IOutputDto, IOutputItemDto, compressOutputItemStreams } from '../notebookCommon.js';
10
import { isTextStreamMime } from '../../../../../base/common/mime.js';
11
12
export class NotebookCellOutputTextModel extends Disposable implements ICellOutput {
13
14
private _onDidChangeData = this._register(new Emitter<void>());
15
onDidChangeData = this._onDidChangeData.event;
16
17
get outputs() {
18
return this._rawOutput.outputs || [];
19
}
20
21
get metadata(): Record<string, any> | undefined {
22
return this._rawOutput.metadata;
23
}
24
25
get outputId(): string {
26
return this._rawOutput.outputId;
27
}
28
29
/**
30
* Alternative output id that's reused when the output is updated.
31
*/
32
private _alternativeOutputId: string;
33
34
get alternativeOutputId(): string {
35
return this._alternativeOutputId;
36
}
37
38
private _versionId = 0;
39
40
get versionId() {
41
return this._versionId;
42
}
43
44
constructor(
45
private _rawOutput: IOutputDto
46
) {
47
super();
48
49
this._alternativeOutputId = this._rawOutput.outputId;
50
}
51
52
replaceData(rawData: IOutputDto) {
53
this.versionedBufferLengths = {};
54
this._rawOutput = rawData;
55
this.optimizeOutputItems();
56
this._versionId = this._versionId + 1;
57
this._onDidChangeData.fire();
58
}
59
60
appendData(items: IOutputItemDto[]) {
61
this.trackBufferLengths();
62
this._rawOutput.outputs.push(...items);
63
this.optimizeOutputItems();
64
this._versionId = this._versionId + 1;
65
this._onDidChangeData.fire();
66
}
67
68
private trackBufferLengths() {
69
this.outputs.forEach(output => {
70
if (isTextStreamMime(output.mime)) {
71
if (!this.versionedBufferLengths[output.mime]) {
72
this.versionedBufferLengths[output.mime] = {};
73
}
74
this.versionedBufferLengths[output.mime][this.versionId] = output.data.byteLength;
75
}
76
});
77
}
78
79
// mime: versionId: buffer length
80
private versionedBufferLengths: Record<string, Record<number, number>> = {};
81
82
appendedSinceVersion(versionId: number, mime: string): VSBuffer | undefined {
83
const bufferLength = this.versionedBufferLengths[mime]?.[versionId];
84
const output = this.outputs.find(output => output.mime === mime);
85
if (bufferLength && output) {
86
return output.data.slice(bufferLength);
87
}
88
89
return undefined;
90
}
91
92
private optimizeOutputItems() {
93
if (this.outputs.length > 1 && this.outputs.every(item => isTextStreamMime(item.mime))) {
94
// Look for the mimes in the items, and keep track of their order.
95
// Merge the streams into one output item, per mime type.
96
const mimeOutputs = new Map<string, Uint8Array[]>();
97
const mimeTypes: string[] = [];
98
this.outputs.forEach(item => {
99
let items: Uint8Array[];
100
if (mimeOutputs.has(item.mime)) {
101
items = mimeOutputs.get(item.mime)!;
102
} else {
103
items = [];
104
mimeOutputs.set(item.mime, items);
105
mimeTypes.push(item.mime);
106
}
107
items.push(item.data.buffer);
108
});
109
this.outputs.length = 0;
110
mimeTypes.forEach(mime => {
111
const compressionResult = compressOutputItemStreams(mimeOutputs.get(mime)!);
112
this.outputs.push({
113
mime,
114
data: compressionResult.data
115
});
116
if (compressionResult.didCompression) {
117
// we can't rely on knowing buffer lengths if we've erased previous lines
118
this.versionedBufferLengths = {};
119
}
120
});
121
}
122
}
123
124
asDto(): IOutputDto {
125
return {
126
// data: this._data,
127
metadata: this._rawOutput.metadata,
128
outputs: this._rawOutput.outputs,
129
outputId: this._rawOutput.outputId
130
};
131
}
132
133
bumpVersion() {
134
this._versionId = this._versionId + 1;
135
}
136
137
}
138
139