thebe-core
Version:
Typescript based core functionality for Thebe
161 lines • 6.11 kB
JavaScript
import { __awaiter } from "tslib";
import PassiveCellRenderer from './passive';
import { CellStatusEvent, ErrorStatusEvent, errorToMessage, EventSubject } from './events';
import { EventEmitter } from './emitter';
import { ensureString, shortId } from './utils';
class ThebeCodeCell extends PassiveCellRenderer {
constructor(id, notebookId, source, config, metadata, rendermime) {
super(id, rendermime);
this.kind = 'code';
this.events = new EventEmitter(id, config, EventSubject.cell, this);
this.notebookId = notebookId;
this.source = source;
this.metadata = metadata;
this.busy = false;
this.executionCount = null;
this.initialOutputs = [];
console.debug('thebe:cell constructor', this);
}
static fromICodeCell(icc, notebookId, config, rendermime) {
var _a;
const cell = new ThebeCodeCell((_a = icc.id) !== null && _a !== void 0 ? _a : shortId(), notebookId, ensureString(icc.source), config, icc.metadata, rendermime);
Object.assign(cell.metadata, icc.metadata);
return cell;
}
get isBusy() {
return this.busy;
}
get isAttached() {
return this.session !== undefined;
}
get tags() {
var _a;
return (_a = this.metadata.tags) !== null && _a !== void 0 ? _a : [];
}
/**
* Attaches to the session and adds the widgets factory to the rendermine registry
* call this version if using ThebeCell in isolation, otherwise call ThebeNotebook::attachSession
*
* @param session
*/
attachSession(session) {
this.session = session;
this.events.triggerStatus({
status: CellStatusEvent.attached,
message: 'Attached to session',
});
}
/**
* Detaches from the session and removes the widgets factory from the rendermine registry
* call this version if using ThebeCell in isolation, otherwise call ThebeNotebook::detachSession
*
*/
detachSession() {
this.session = undefined;
this.events.triggerStatus({
status: CellStatusEvent.detached,
message: 'Detached from session',
});
}
setAsBusy() {
console.debug(`thebe:renderer:message:busy ${this.id}`);
this.busy = true;
this.events.triggerStatus({
status: CellStatusEvent.executing,
message: 'Executing...',
});
}
setAsIdle() {
console.debug(`thebe:renderer:message:completed ${this.id}`);
this.busy = false;
this.events.triggerStatus({
status: CellStatusEvent.idle,
message: 'Completed',
});
}
/**
* reset the DOM representation of the cell to the initial state
* along with the execution count
*
* @param hideWidgets boolean - if true, hide widgets
*/
initOutputs(initialOutputs) {
this.initialOutputs = initialOutputs;
this.render(initialOutputs);
this.executionCount = null;
}
/**
* reset the DOM representation of the cell to the initial state
* along with the execution count
*
* @param hideWidgets boolean - if true, hide widgets
*/
reset() {
this.render(this.initialOutputs);
this.executionCount = null;
}
/**
* TODO
* - pass execute_count or timestamp or something back to redux on success/failure?
*
* @param source?
* @returns
*/
execute(source) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.session || !this.session.kernel) {
console.warn('Attempting to execute on a cell without an attached kernel');
return null;
}
const code = source !== null && source !== void 0 ? source : this.source;
try {
console.debug(`thebe:renderer:execute ${this.id}`);
if (!this.isBusy)
this.setAsBusy();
this.area.future = this.session.kernel.requestExecute({ code });
// TODO consider how to enable execution without the await here
const reply = yield this.area.future.done;
this.executionCount = reply.content.execution_count;
let executeErrors;
for (let i = 0; i < this.model.length; i++) {
const out = this.model.get(i);
console.debug('thebecell:execute:output', { out: out.toJSON() });
if (out.type === 'error') {
const json = out.toJSON();
if (json.ename === 'stderr') {
this.events.triggerError({
status: ErrorStatusEvent.warning,
message: errorToMessage(json),
});
}
else {
if (!executeErrors)
executeErrors = [json];
else
executeErrors === null || executeErrors === void 0 ? void 0 : executeErrors.push(json);
this.events.triggerError({
status: ErrorStatusEvent.executeError,
message: errorToMessage(json),
});
}
}
}
this.setAsIdle();
return {
id: this.id,
height: this.area.node.offsetHeight,
width: this.area.node.offsetWidth,
error: executeErrors,
};
}
catch (err) {
console.error('thebe:renderer:execute Error:', err);
this.clearOnError(err);
this.events.triggerError(err.message);
return null;
}
});
}
}
export default ThebeCodeCell;
//# sourceMappingURL=cell.js.map