UNPKG

7.22 kBJavaScriptView Raw
1/* -----------------------------------------------------------------------------
2| Copyright (c) Jupyter Development Team.
3| Distributed under the terms of the Modified BSD License.
4|----------------------------------------------------------------------------*/
5import * as nbformat from '@jupyterlab/nbformat';
6import { ObservableJSON } from '@jupyterlab/observables';
7import { JSONExt } from '@lumino/coreutils';
8import { Signal } from '@lumino/signaling';
9/**
10 * The default implementation of a notebook output model.
11 */
12export class OutputModel {
13 /**
14 * Construct a new output model.
15 */
16 constructor(options) {
17 this._changed = new Signal(this);
18 this._raw = {};
19 const { data, metadata, trusted } = Private.getBundleOptions(options);
20 this._data = new ObservableJSON({ values: data });
21 this._rawData = data;
22 this._metadata = new ObservableJSON({ values: metadata });
23 this._rawMetadata = metadata;
24 this.trusted = trusted;
25 // Make a copy of the data.
26 const value = options.value;
27 for (const key in value) {
28 // Ignore data and metadata that were stripped.
29 switch (key) {
30 case 'data':
31 case 'metadata':
32 break;
33 default:
34 this._raw[key] = Private.extract(value, key);
35 }
36 }
37 this.type = value.output_type;
38 if (nbformat.isExecuteResult(value)) {
39 this.executionCount = value.execution_count;
40 }
41 else {
42 this.executionCount = null;
43 }
44 }
45 /**
46 * A signal emitted when the output model changes.
47 */
48 get changed() {
49 return this._changed;
50 }
51 /**
52 * Dispose of the resources used by the output model.
53 */
54 dispose() {
55 this._data.dispose();
56 this._metadata.dispose();
57 Signal.clearData(this);
58 }
59 /**
60 * The data associated with the model.
61 */
62 get data() {
63 return this._rawData;
64 }
65 /**
66 * The metadata associated with the model.
67 */
68 get metadata() {
69 return this._rawMetadata;
70 }
71 /**
72 * Set the data associated with the model.
73 *
74 * #### Notes
75 * Depending on the implementation of the mime model,
76 * this call may or may not have deferred effects,
77 */
78 setData(options) {
79 if (options.data) {
80 this._updateObservable(this._data, options.data);
81 this._rawData = options.data;
82 }
83 if (options.metadata) {
84 this._updateObservable(this._metadata, options.metadata);
85 this._rawMetadata = options.metadata;
86 }
87 this._changed.emit(void 0);
88 }
89 /**
90 * Serialize the model to JSON.
91 */
92 toJSON() {
93 const output = {};
94 for (const key in this._raw) {
95 output[key] = Private.extract(this._raw, key);
96 }
97 switch (this.type) {
98 case 'display_data':
99 case 'execute_result':
100 case 'update_display_data':
101 output['data'] = this.data;
102 output['metadata'] = this.metadata;
103 break;
104 default:
105 break;
106 }
107 // Remove transient data.
108 delete output['transient'];
109 return output;
110 }
111 /**
112 * Update an observable JSON object using a readonly JSON object.
113 */
114 _updateObservable(observable, data) {
115 const oldKeys = observable.keys();
116 const newKeys = Object.keys(data);
117 // Handle removed keys.
118 for (const key of oldKeys) {
119 if (newKeys.indexOf(key) === -1) {
120 observable.delete(key);
121 }
122 }
123 // Handle changed data.
124 for (const key of newKeys) {
125 const oldValue = observable.get(key);
126 const newValue = data[key];
127 if (oldValue !== newValue) {
128 observable.set(key, newValue);
129 }
130 }
131 }
132}
133/**
134 * The namespace for OutputModel statics.
135 */
136(function (OutputModel) {
137 /**
138 * Get the data for an output.
139 *
140 * @params output - A kernel output message payload.
141 *
142 * @returns - The data for the payload.
143 */
144 function getData(output) {
145 return Private.getData(output);
146 }
147 OutputModel.getData = getData;
148 /**
149 * Get the metadata from an output message.
150 *
151 * @params output - A kernel output message payload.
152 *
153 * @returns - The metadata for the payload.
154 */
155 function getMetadata(output) {
156 return Private.getMetadata(output);
157 }
158 OutputModel.getMetadata = getMetadata;
159})(OutputModel || (OutputModel = {}));
160/**
161 * The namespace for module private data.
162 */
163var Private;
164(function (Private) {
165 /**
166 * Get the data from a notebook output.
167 */
168 function getData(output) {
169 let bundle = {};
170 if (nbformat.isExecuteResult(output) ||
171 nbformat.isDisplayData(output) ||
172 nbformat.isDisplayUpdate(output)) {
173 bundle = output.data;
174 }
175 else if (nbformat.isStream(output)) {
176 if (output.name === 'stderr') {
177 bundle['application/vnd.jupyter.stderr'] = output.text;
178 }
179 else {
180 bundle['application/vnd.jupyter.stdout'] = output.text;
181 }
182 }
183 else if (nbformat.isError(output)) {
184 bundle['application/vnd.jupyter.error'] = output;
185 const traceback = output.traceback.join('\n');
186 bundle['application/vnd.jupyter.stderr'] =
187 traceback || `${output.ename}: ${output.evalue}`;
188 }
189 return convertBundle(bundle);
190 }
191 Private.getData = getData;
192 /**
193 * Get the metadata from an output message.
194 */
195 function getMetadata(output) {
196 const value = Object.create(null);
197 if (nbformat.isExecuteResult(output) || nbformat.isDisplayData(output)) {
198 for (const key in output.metadata) {
199 value[key] = extract(output.metadata, key);
200 }
201 }
202 return value;
203 }
204 Private.getMetadata = getMetadata;
205 /**
206 * Get the bundle options given output model options.
207 */
208 function getBundleOptions(options) {
209 const data = getData(options.value);
210 const metadata = getMetadata(options.value);
211 const trusted = !!options.trusted;
212 return { data, metadata, trusted };
213 }
214 Private.getBundleOptions = getBundleOptions;
215 /**
216 * Extract a value from a JSONObject.
217 */
218 function extract(value, key) {
219 const item = value[key];
220 if (item === undefined || JSONExt.isPrimitive(item)) {
221 return item;
222 }
223 return JSON.parse(JSON.stringify(item));
224 }
225 Private.extract = extract;
226 /**
227 * Convert a mime bundle to mime data.
228 */
229 function convertBundle(bundle) {
230 const map = Object.create(null);
231 for (const mimeType in bundle) {
232 map[mimeType] = extract(bundle, mimeType);
233 }
234 return map;
235 }
236})(Private || (Private = {}));
237//# sourceMappingURL=outputmodel.js.map
\No newline at end of file