jupyterlab-emrys
Version:
A computational environment for Jupyter. Powered by Emrys
218 lines (217 loc) • 7.04 kB
JavaScript
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
"use strict";
var jupyter_js_services_1 = require('jupyter-js-services');
var phosphor_signaling_1 = require('phosphor-signaling');
var observablelist_1 = require('../../common/observablelist');
var nbformat_1 = require('../notebook/nbformat');
/**
* An model that maintains a list of output data.
*/
var OutputAreaModel = (function () {
/**
* Construct a new observable outputs instance.
*/
function OutputAreaModel() {
this._clearNext = false;
this._list = null;
this._list = new observablelist_1.ObservableList();
this._list.changed.connect(this._onListChanged, this);
}
Object.defineProperty(OutputAreaModel.prototype, "changed", {
/**
* A signal emitted when the model changes.
*/
get: function () {
return Private.changedSignal.bind(this);
},
enumerable: true,
configurable: true
});
Object.defineProperty(OutputAreaModel.prototype, "disposed", {
/**
* A signal emitted when the model is disposed.
*/
get: function () {
return Private.disposedSignal.bind(this);
},
enumerable: true,
configurable: true
});
Object.defineProperty(OutputAreaModel.prototype, "length", {
/**
* Get the length of the items in the model.
*
* #### Notes
* This is a read-only property.
*/
get: function () {
return this._list ? this._list.length : 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(OutputAreaModel.prototype, "isDisposed", {
/**
* Test whether the model is disposed.
*
* #### Notes
* This is a read-only property.
*/
get: function () {
return this._list === null;
},
enumerable: true,
configurable: true
});
/**
* Dispose of the resources used by the model.
*/
OutputAreaModel.prototype.dispose = function () {
if (this.isDisposed) {
return;
}
this.disposed.emit(void 0);
this._list.clear();
this._list = null;
phosphor_signaling_1.clearSignalData(this);
};
/**
* Get an item at the specified index.
*/
OutputAreaModel.prototype.get = function (index) {
return this._list.get(index);
};
/**
* Add an output, which may be combined with previous output.
*
* #### Notes
* The output bundle is copied.
* Contiguous stream outputs of the same `name` are combined.
*/
OutputAreaModel.prototype.add = function (output) {
// If we received a delayed clear message, then clear now.
if (this._clearNext) {
this.clear();
this._clearNext = false;
}
if (output.output_type === 'input_request') {
this._list.add(output);
}
// Make a copy of the output bundle.
var value = JSON.parse(JSON.stringify(output));
// Join multiline text outputs.
if (nbformat_1.nbformat.isStream(value)) {
if (Array.isArray(value.text)) {
value.text = value.text.join('\n');
}
}
// Consolidate outputs if they are stream outputs of the same kind.
var index = this.length - 1;
var lastOutput = this.get(index);
if (nbformat_1.nbformat.isStream(value)
&& lastOutput && nbformat_1.nbformat.isStream(lastOutput)
&& value.name === lastOutput.name) {
// In order to get a list change event, we add the previous
// text to the current item and replace the previous item.
// This also replaces the metadata of the last item.
var text = value.text;
value.text = lastOutput.text + text;
this._list.set(index, output);
return index;
}
else {
switch (value.output_type) {
case 'stream':
case 'execute_result':
case 'display_data':
case 'error':
return this._list.add(value);
default:
break;
}
}
return -1;
};
/**
* Clear all of the output.
*
* @param wait Delay clearing the output until the next message is added.
*/
OutputAreaModel.prototype.clear = function (wait) {
if (wait === void 0) { wait = false; }
if (wait) {
this._clearNext = true;
return [];
}
return this._list.clear();
};
/**
* Execute code on a kernel and send outputs to the model.
*/
OutputAreaModel.prototype.execute = function (code, kernel) {
var _this = this;
// Override the default for `stop_on_error`.
var content = {
code: code,
stop_on_error: true
};
this.clear();
return new Promise(function (resolve, reject) {
var future = kernel.execute(content);
// Handle published messages.
future.onIOPub = function (msg) {
var msgType = msg.header.msg_type;
switch (msgType) {
case 'execute_result':
case 'display_data':
case 'stream':
case 'error':
var model = msg.content;
model.output_type = msgType;
_this.add(model);
break;
default:
break;
}
};
// Handle the execute reply.
future.onReply = function (msg) {
resolve(msg);
};
// Handle stdin.
future.onStdin = function (msg) {
if (jupyter_js_services_1.KernelMessage.isInputRequestMsg(msg)) {
_this.add({
output_type: 'input_request',
prompt: msg.content.prompt,
password: msg.content.password,
kernel: kernel
});
}
};
});
};
/**
* Handle a change to the list.
*/
OutputAreaModel.prototype._onListChanged = function (sender, args) {
this.changed.emit(args);
};
return OutputAreaModel;
}());
exports.OutputAreaModel = OutputAreaModel;
/**
* A namespace for private data.
*/
var Private;
(function (Private) {
/**
* A signal emitted when the model changes.
*/
Private.changedSignal = new phosphor_signaling_1.Signal();
/**
* A signal emitted when the model is disposed.
*/
Private.disposedSignal = new phosphor_signaling_1.Signal();
})(Private || (Private = {}));