UNPKG

thebe-core

Version:

Typescript based core functionality for Thebe

228 lines 8.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const cell_1 = tslib_1.__importDefault(require("./cell")); const utils_1 = require("./utils"); const events_1 = require("./events"); const emitter_1 = require("./emitter"); const markdown_1 = tslib_1.__importDefault(require("./markdown")); class ThebeNotebook { constructor(id, config, rendermime) { this.id = id; this.events = new emitter_1.EventEmitter(id, config, events_1.EventSubject.notebook, this); this.cells = []; this.metadata = {}; this.rendermime = rendermime; console.debug('thebe:notebook constructor', this); } static fromCodeBlocks(blocks, config, rendermime) { const id = (0, utils_1.shortId)(); const notebook = new ThebeNotebook(id, config, rendermime); notebook.cells = blocks.map((c) => { const metadata = {}; const cell = new cell_1.default(c.id, id, c.source, config, metadata, notebook.rendermime); console.debug(`thebe:notebook:fromCodeBlocks Initializing cell ${c.id}`); return cell; }); return notebook; } static fromIpynb(ipynb, config, rendermime) { const notebook = new ThebeNotebook((0, utils_1.shortId)(), config, rendermime); Object.assign(notebook.metadata, ipynb.metadata); notebook.cells = ipynb.cells.map((c) => { if (c.cell_type === 'code') return cell_1.default.fromICodeCell(c, notebook.id, config, notebook.rendermime); return markdown_1.default.fromICell(c, notebook.id, notebook.rendermime); }); return notebook; } get parameters() { const p = this.findCells('parameters'); if (!p || (p === null || p === void 0 ? void 0 : p.length) === 0) return undefined; if (p.length > 1) console.warn(`Mulitple parameter cells found in notebook ${this.id}`); return p; } get widgets() { var _a; return (_a = this.findCells('widget')) !== null && _a !== void 0 ? _a : []; } get last() { if (this.cells.length === 0) throw new Error('empty notebook'); return this.cells[this.cells.length - 1]; } get markdown() { return this.cells.filter((c) => c.kind === 'markdown'); } get code() { return this.cells.filter((c) => c.kind === 'code'); } /** * reset the notebook to its initial state by resetting each cell * * @param hideWidgets boolean */ reset() { this.cells.forEach((cell) => cell.reset()); } numCells() { var _a, _b; return (_b = (_a = this.cells) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0; } findCells(tag) { const found = this.cells.filter((c) => c.tags.includes(tag)); return found.length > 0 ? found : undefined; } getCell(idx) { if (!this.cells) throw Error('Dag not initialized'); if (idx >= this.cells.length) throw Error(`Notebook.cells index out of range: ${idx}:${this.cells.length}`); return this.cells[idx]; } getCellById(id) { var _a; const cell = (_a = this.cells) === null || _a === void 0 ? void 0 : _a.find((c) => c.id === id); return cell; } lastCell() { if (!this.cells) throw Error('Notebook not initialized'); return this.cells[this.cells.length - 1]; } updateParameters(newSource, interpolate = false) { if (interpolate) throw new Error('Not implemented yet'); if (this.parameters) this.parameters[0].source = newSource; } waitForKernel(kernel) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return kernel.then((k) => { this.attachSession(k); return k; }); }); } attachSession(session) { var _a; if (!session.kernel) throw Error('ThebeNotebook - cannot connect to session, no kernel'); // note all cells in a notebook share the rendermime registry // we only need to add the widgets factory once this.session = session; (_a = this.cells) === null || _a === void 0 ? void 0 : _a.forEach((cell) => (cell.session = session)); this.events.triggerStatus({ status: events_1.NotebookStatusEvent.attached, message: 'Attached to session', }); } detachSession() { var _a; (_a = this.cells) === null || _a === void 0 ? void 0 : _a.map((cell) => (cell.session = undefined)); this.session = undefined; this.events.triggerStatus({ status: events_1.NotebookStatusEvent.detached, message: 'Detached from session', }); } clear() { this.cells.forEach((cell) => cell.clear()); } executeUpTo(cellId, stopOnError = false, preprocessor) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!this.cells) return []; this.events.triggerStatus({ status: events_1.NotebookStatusEvent.executing, message: `executeUpTo ${cellId}`, }); const idx = this.cells.findIndex((c) => c.id === cellId); if (idx === -1) return []; const cellsToExecute = this.cells.slice(0, idx + 1); cellsToExecute.map((cell) => cell.setAsBusy()); const result = yield this.executeCells(cellsToExecute.map((c) => c.id), stopOnError, preprocessor); // TODO intercept errors here this.events.triggerStatus({ status: events_1.NotebookStatusEvent.idle, message: `executeUpTo ${cellId}`, }); return result; }); } executeOnly(cellId, preprocessor) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!this.cells) return null; this.events.triggerStatus({ status: events_1.NotebookStatusEvent.executing, message: `executeOnly ${cellId}`, }); const result = yield this.executeCells([cellId], false, preprocessor); this.events.triggerStatus({ status: events_1.NotebookStatusEvent.idle, message: `executeUpTo ${cellId}`, }); return result[0]; }); } executeCells(cellIds, stopOnError = false, preprocessor) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!this.cells) return []; this.events.triggerStatus({ status: events_1.NotebookStatusEvent.executing, message: `executeCells ${cellIds.length} cells`, }); const cells = this.cells.filter((c) => { const found = cellIds.find((id) => id === c.id); if (!found) { console.warn(`Cell ${c.id} not found in notebook`); } return Boolean(found); }); let result = []; if (stopOnError) { let skipRemaining = false; for (const cell of cells) { if (skipRemaining) continue; const cellReturn = yield cell.execute(preprocessor ? preprocessor(cell.source) : cell.source); if (cellReturn == null || cellReturn.error) skipRemaining = true; result.push(cellReturn); } } else { result = yield Promise.all(cells.map((cell) => cell.execute(preprocessor ? preprocessor(cell.source) : cell.source))); } this.events.triggerStatus({ status: events_1.NotebookStatusEvent.idle, message: `executeCells executed ${cellIds.length} cells`, }); return result; }); } executeAll(stopOnError = false, preprocessor) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!this.cells) return []; this.events.triggerStatus({ status: events_1.NotebookStatusEvent.executing, message: `executeAll`, }); this.cells.map((cell) => cell.setAsBusy()); const result = yield this.executeCells(this.cells.map((c) => c.id), stopOnError, preprocessor); this.events.triggerStatus({ status: events_1.NotebookStatusEvent.idle, message: `executeAll`, }); return result; }); } } exports.default = ThebeNotebook; //# sourceMappingURL=notebook.js.map