Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nteract/commutable

Package Overview
Dependencies
Maintainers
14
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nteract/commutable - npm Package Compare versions

Comparing version 6.0.0-alpha.0 to 6.0.2-alpha.0

lib/cells.d.ts

19

lib/index.d.ts

@@ -1,11 +0,8 @@

import { Map as ImmutableMap } from "immutable";
import * as v4 from "./v4";
import * as v3 from "./v3";
export * from "./types";
export { emptyCodeCell, emptyMarkdownCell, emptyNotebook, monocellNotebook, createCodeCell, insertCellAt, insertCellAfter, deleteCell, appendCellToNotebook } from "./structures";
export { StreamOutput, Output, createImmutableMimeBundle, createImmutableOutput } from "./v4";
export declare type Notebook = v4.Notebook | v3.Notebook;
export declare const parseNotebook: (notebookString: string) => Notebook;
export declare const fromJS: (notebook: ImmutableMap<string, any> | v4.Notebook | v3.Notebook) => ImmutableMap<string, any>;
export declare const toJS: (immnb: ImmutableMap<string, any>) => v4.Notebook;
export declare const stringifyNotebook: (notebook: v4.Notebook) => string;
/**
* @module commutable
*/
export * from "./primitives";
export * from "./structures";
export * from "./outputs";
export * from "./cells";
export * from "./notebook";
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
exports.__esModule = true;
var immutable_1 = require("immutable");
var v4 = __importStar(require("./v4"));
var v3 = __importStar(require("./v3"));
/**
* @module commutable
*/
// .....................................
// API Exports
//
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./primitives"));
__export(require("./structures"));
__export(require("./outputs"));
__export(require("./cells"));
__export(require("./notebook"));
/*
// from structures
var structures_1 = require("./structures");
exports.emptyCodeCell = structures_1.emptyCodeCell;
exports.emptyMarkdownCell = structures_1.emptyMarkdownCell;
exports.emptyNotebook = structures_1.emptyNotebook;
exports.monocellNotebook = structures_1.monocellNotebook;
exports.createCodeCell = structures_1.createCodeCell;
exports.insertCellAt = structures_1.insertCellAt;
exports.insertCellAfter = structures_1.insertCellAfter;
exports.deleteCell = structures_1.deleteCell;
exports.appendCellToNotebook = structures_1.appendCellToNotebook;
export {
emptyCodeCell,
emptyMarkdownCell,
emptyNotebook,
monocellNotebook,
createCodeCell,
insertCellAt,
insertCellAfter,
deleteCell,
appendCellToNotebook
} from "./structures";
// v4
var v4_1 = require("./v4");
exports.createImmutableMimeBundle = v4_1.createImmutableMimeBundle;
exports.createImmutableOutput = v4_1.createImmutableOutput;
var freezeReviver = function (k, v) {
return Object.freeze(v);
};
// Expected usage of below is fromJS(parseNotebook(string|buffer))
exports.parseNotebook = function (notebookString) {
return JSON.parse(notebookString, freezeReviver);
};
exports.fromJS = function (notebook) {
if (immutable_1.Map.isMap(notebook)) {
if (notebook.has("cellOrder") && notebook.has("cellMap")) {
return notebook;
}
throw new TypeError("commutable was passed an Immutable.Map structure that is not a notebook");
}
if (notebook.nbformat === 4 && notebook.nbformat_minor >= 0) {
if (Array.isArray(notebook.cells) &&
typeof notebook.metadata === "object") {
return v4.fromJS(notebook);
}
}
else if (notebook.nbformat === 3 && notebook.nbformat_minor >= 0) {
return v3.fromJS(notebook);
}
if (notebook.nbformat) {
throw new TypeError("nbformat v" + notebook.nbformat + "." + notebook.nbformat_minor + " not recognized");
}
throw new TypeError("This notebook format is not supported");
};
exports.toJS = function (immnb) {
var minorVersion = immnb.get("nbformat_minor", null);
if (immnb.get("nbformat") === 4 &&
typeof minorVersion === "number" &&
minorVersion >= 0) {
return v4.toJS(immnb);
}
throw new TypeError("Only notebook formats 3 and 4 are supported!");
};
// Expected usage is stringifyNotebook(toJS(immutableNotebook))
exports.stringifyNotebook = function (notebook) {
return JSON.stringify(notebook, null, 2);
};
export { StreamOutput, Output, createImmutableOutput } from "./v4";
export {
createImmutableMimeBundle,
makeDisplayData,
makeErrorOutput,
makeStreamOutput,
makeExecuteResult,
MimeBundle
} from "./outputs";
export {
makeRawCell,
makeCodeCell,
makeMarkdownCell,
ImmutableCodeCell,
ImmutableMarkdownCell,
ImmutableRawCell,
ImmutableCell,
CellType
} from "./cells";
export {
toJS,
stringifyNotebook,
fromJS,
parseNotebook,
makeNotebookRecord,
Notebook,
ImmutableNotebook
} from "./notebook";
*/

@@ -0,43 +1,101 @@

import { CellId } from "./primitives";
import { ImmutableNotebook } from "./notebook";
import { ImmutableCell } from "./cells";
import { Map as ImmutableMap, List as ImmutableList } from "immutable";
import { ImmutableOutput, ImmutableCell, ImmutableCellOrder, ImmutableCellMap, ImmutableJSONType, ExecutionCount } from "./types";
interface Notebook {
nbformat: 4;
nbformat_minor: 4;
metadata: ImmutableMap<string, ImmutableJSONType>;
cellOrder: ImmutableList<string>;
cellMap: ImmutableMap<string, ImmutableCell>;
}
interface CodeCell {
export declare const createCodeCell: import("immutable").Record.Factory<{
cell_type: "code";
metadata: ImmutableMap<string, any>;
execution_count: ExecutionCount;
execution_count: number | null;
source: string;
outputs: ImmutableList<ImmutableOutput>;
}
interface MarkdownCell {
outputs: ImmutableList<import("./outputs").ImmutableOutput>;
}>;
export declare const createMarkdownCell: import("immutable").Record.Factory<{
cell_type: "markdown";
source: string;
metadata: ImmutableMap<string, any>;
}
export declare const createCodeCell: (cell?: CodeCell) => ImmutableMap<string, any>;
export declare const createMarkdownCell: (cell?: MarkdownCell) => ImmutableMap<string, any>;
export declare const emptyCodeCell: ImmutableMap<string, any>;
export declare const emptyMarkdownCell: ImmutableMap<string, any>;
export declare const defaultNotebook: Notebook;
export declare const createNotebook: (notebook?: Notebook) => ImmutableMap<string, any>;
export declare const emptyNotebook: ImmutableMap<string, any>;
}>;
export declare const emptyCodeCell: import("immutable").RecordOf<{
cell_type: "code";
metadata: ImmutableMap<string, any>;
execution_count: number | null;
source: string;
outputs: ImmutableList<import("./outputs").ImmutableOutput>;
}>;
export declare const emptyMarkdownCell: import("immutable").RecordOf<{
cell_type: "markdown";
source: string;
metadata: ImmutableMap<string, any>;
}>;
export declare const defaultNotebook: ImmutableNotebook;
export declare const createNotebook: import("immutable").Record.Factory<import("./notebook").NotebookRecordParams>;
export declare const emptyNotebook: ImmutableNotebook;
export declare type CellStructure = {
cellOrder: ImmutableCellOrder;
cellMap: ImmutableCellMap;
cellOrder: ImmutableList<CellId>;
cellMap: ImmutableMap<CellId, ImmutableCell>;
};
export declare const appendCell: (cellStructure: CellStructure, immutableCell: ImmutableMap<string, any>, id?: string) => CellStructure;
export declare const appendCellToNotebook: (immnb: ImmutableMap<string, any>, immCell: ImmutableMap<string, any>) => ImmutableMap<string, any>;
export declare const insertCellAt: (notebook: ImmutableMap<string, any>, cell: ImmutableMap<string, any>, cellID: string, index: number) => ImmutableMap<string, any>;
export declare const insertCellAfter: (notebook: ImmutableMap<string, any>, cell: ImmutableMap<string, any>, cellID: string, priorCellID: string) => ImmutableMap<string, any>;
/**
* A function that appends a new cell to a CellStructure object.
*
* @param cellStructure The cellOrder and cellMap of the current notebook
* @param immutableCell The cell that will be inserted into the cellStructure
* @param id The id of the new cell, defaults to a new UUID
*
* @returns Cell structure with the new cell appended at the end
*/
export declare const appendCell: (cellStructure: CellStructure, immutableCell: ImmutableCell, id?: string) => CellStructure;
/**
* A function that appends a cell to an immutable notebook.
*
* @param immnb An immutable data structure representing the notebook that will be modified
* @param immCell The new cell that will be inserted into the notebook
*
* @returns The modified notebook
*/
export declare const appendCellToNotebook: (immnb: ImmutableNotebook, immCell: ImmutableCell) => ImmutableNotebook;
/**
* Inserts a cell with cellID at a given index within the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param index The position we would like to insert the cell at
*
* @returns The modified notebook.
*/
export declare const insertCellAt: (notebook: ImmutableNotebook, cell: ImmutableCell, cellId: string, index: number) => ImmutableNotebook;
/**
* Inserts a new cell with cellID before an existing cell with priorCellID
* in the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param priorCellID The ID of the existing cell.
*/
export declare const insertCellAfter: (notebook: ImmutableNotebook, cell: ImmutableCell, cellId: string, priorCellId: string) => ImmutableNotebook;
/**
* Delete a cell with CellID at a given location. Note that this function
* is deprecated in favor of `deleteCell`.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*
* @deprecated use `deleteCell()` instead
*/
export declare const removeCell: (notebook: ImmutableMap<string, any>, cellID: string) => ImmutableMap<string, any>;
export declare const deleteCell: (notebook: ImmutableMap<string, any>, cellID: string) => ImmutableMap<string, any>;
export declare const monocellNotebook: ImmutableMap<string, any>;
export {};
export declare const removeCell: (notebook: ImmutableNotebook, cellId: string) => ImmutableNotebook;
/**
* Delete a cell with CellID at a given location.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*/
export declare const deleteCell: (notebook: ImmutableNotebook, cellId: string) => ImmutableNotebook;
/**
* A new notebook with a single empty code cell. This function is useful
* if you are looking to initialize a fresh, new notebook.
*/
export declare const monocellNotebook: ImmutableNotebook;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var v4_1 = __importDefault(require("uuid/v4"));
var immutable_1 = require("immutable");
var defaultCodeCell = Object.freeze({
cell_type: "code",
execution_count: null,
metadata: immutable_1.Map({
collapsed: false,
outputHidden: false,
inputHidden: false
}),
source: "",
outputs: immutable_1.List()
});
var defaultMarkdownCell = Object.freeze({
cell_type: "markdown",
metadata: immutable_1.Map(),
source: ""
});
exports.createCodeCell = function (cell) {
if (cell === void 0) { cell = defaultCodeCell; }
return immutable_1.Map(cell);
};
exports.createMarkdownCell = function (cell) {
if (cell === void 0) { cell = defaultMarkdownCell; }
return immutable_1.Map(cell);
};
Object.defineProperty(exports, "__esModule", { value: true });
const primitives_1 = require("./primitives");
const notebook_1 = require("./notebook");
const cells_1 = require("./cells");
// The cell creators here are a bit duplicative
exports.createCodeCell = cells_1.makeCodeCell;
exports.createMarkdownCell = cells_1.makeMarkdownCell;
exports.emptyCodeCell = exports.createCodeCell();
exports.emptyMarkdownCell = exports.createMarkdownCell();
exports.defaultNotebook = Object.freeze({
nbformat: 4,
nbformat_minor: 4,
metadata: immutable_1.Map(),
cellOrder: immutable_1.List(),
cellMap: immutable_1.Map()
// These are all kind of duplicative now that we're on records.
// Since we export these though, they're left for
// backwards compatiblity
exports.defaultNotebook = notebook_1.makeNotebookRecord();
exports.createNotebook = notebook_1.makeNotebookRecord;
exports.emptyNotebook = notebook_1.makeNotebookRecord();
/**
* A function that appends a new cell to a CellStructure object.
*
* @param cellStructure The cellOrder and cellMap of the current notebook
* @param immutableCell The cell that will be inserted into the cellStructure
* @param id The id of the new cell, defaults to a new UUID
*
* @returns Cell structure with the new cell appended at the end
*/
exports.appendCell = (cellStructure, immutableCell, id = primitives_1.createCellId()) => ({
cellOrder: cellStructure.cellOrder.push(id),
cellMap: cellStructure.cellMap.set(id, immutableCell)
});
exports.createNotebook = function (notebook) {
if (notebook === void 0) { notebook = exports.defaultNotebook; }
return immutable_1.Map(notebook);
};
exports.emptyNotebook = exports.createNotebook();
// Intended to make it easy to use this with (temporary mutable cellOrder +
// cellMap)
exports.appendCell = function (cellStructure, immutableCell, id) {
if (id === void 0) { id = v4_1["default"](); }
return ({
cellOrder: cellStructure.cellOrder.push(id),
cellMap: cellStructure.cellMap.set(id, immutableCell)
});
};
exports.appendCellToNotebook = function (immnb, immCell) {
return immnb.withMutations(function (nb) {
// $FlowFixMe: Fixed by making ImmutableNotebook a typed Record.
var cellStructure = {
cellOrder: nb.get("cellOrder"),
// $FlowFixMe: Fixed by making ImmutableNotebook a typed Record.
cellMap: nb.get("cellMap")
};
var _a = exports.appendCell(cellStructure, immCell), cellOrder = _a.cellOrder, cellMap = _a.cellMap;
return nb.set("cellOrder", cellOrder).set("cellMap", cellMap);
});
};
exports.insertCellAt = function (notebook, cell, cellID, index) {
return notebook.withMutations(function (nb) {
return nb
.setIn(["cellMap", cellID], cell)
// $FlowFixMe: Fixed by making ImmutableNotebook a typed record.
.set("cellOrder", nb.get("cellOrder").insert(index, cellID));
});
};
exports.insertCellAfter = function (notebook, cell, cellID, priorCellID) {
return exports.insertCellAt(notebook, cell, cellID,
// $FlowFixMe: Fixed by making ImmutableNotebook a typed record.
notebook.get("cellOrder").indexOf(priorCellID) + 1);
};
/**
* A function that appends a cell to an immutable notebook.
*
* @param immnb An immutable data structure representing the notebook that will be modified
* @param immCell The new cell that will be inserted into the notebook
*
* @returns The modified notebook
*/
exports.appendCellToNotebook = (immnb, immCell) => immnb.withMutations(nb => {
const cellStructure = {
cellOrder: nb.get("cellOrder"),
cellMap: nb.get("cellMap")
};
const { cellOrder, cellMap } = exports.appendCell(cellStructure, immCell);
return nb.set("cellOrder", cellOrder).set("cellMap", cellMap);
});
/**
* Inserts a cell with cellID at a given index within the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param index The position we would like to insert the cell at
*
* @returns The modified notebook.
*/
exports.insertCellAt = (notebook, cell, cellId, index) => notebook.withMutations(nb => nb
.setIn(["cellMap", cellId], cell)
.set("cellOrder", nb.get("cellOrder").insert(index, cellId)));
/**
* Inserts a new cell with cellID before an existing cell with priorCellID
* in the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param priorCellID The ID of the existing cell.
*/
exports.insertCellAfter = (notebook, cell, cellId, priorCellId) => exports.insertCellAt(notebook, cell, cellId, notebook.get("cellOrder").indexOf(priorCellId) + 1);
/**
* Delete a cell with CellID at a given location. Note that this function
* is deprecated in favor of `deleteCell`.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*
* @deprecated use `deleteCell()` instead
*/
exports.removeCell = function (notebook, cellID) {
exports.removeCell = (notebook, cellId) => {
console.log("Deprecation Warning: removeCell() is being deprecated. Please use deleteCell() instead");
return notebook
.removeIn(["cellMap", cellID])
.update("cellOrder", function (cellOrder) {
return cellOrder.filterNot(function (id) { return id === cellID; });
});
return exports.deleteCell(notebook, cellId);
};
exports.deleteCell = function (notebook, cellID) {
return notebook
.removeIn(["cellMap", cellID])
.update("cellOrder", function (cellOrder) {
return cellOrder.filterNot(function (id) { return id === cellID; });
});
};
/**
* Delete a cell with CellID at a given location.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*/
exports.deleteCell = (notebook, cellId) => notebook
.removeIn(["cellMap", cellId])
.update("cellOrder", cellOrder => cellOrder.filterNot(id => id === cellId));
/**
* A new notebook with a single empty code cell. This function is useful
* if you are looking to initialize a fresh, new notebook.
*/
exports.monocellNotebook = exports.appendCellToNotebook(exports.emptyNotebook, exports.emptyCodeCell);

@@ -1,4 +0,4 @@

import { Map as ImmutableMap } from "immutable";
import { MultiLineString, JSONObject } from "./types";
import { ErrorOutput, RawCell, MarkdownCell } from "./v4";
import { MultiLineString, JSONObject } from "./primitives";
import { ErrorOutput } from "./outputs";
import { RawCell, MarkdownCell } from "./v4";
declare const VALID_MIMETYPES: {

@@ -54,3 +54,3 @@ text: string;

}
export interface Notebook {
export declare type Notebook = {
worksheets: Worksheet[];

@@ -60,9 +60,4 @@ metadata: object;

nbformat_minor: number;
}
export declare const sanitize: (o: ExecuteResult | DisplayData) => {
metadata: any;
} | {
metadata?: undefined;
};
export declare const fromJS: (notebook: Notebook) => ImmutableMap<string, any>;
export declare const fromJS: (notebook: Notebook) => import("./notebook").ImmutableNotebook;
export {};
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
var immutable_1 = require("immutable");
var structures_1 = require("./structures");
var v4_1 = require("./v4");
var VALID_MIMETYPES = {
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @module commutable
*/
const immutable_1 = require("immutable");
const notebook_1 = require("./notebook");
const cells_1 = require("./cells");
const outputs_1 = require("./outputs");
const structures_1 = require("./structures");
const VALID_MIMETYPES = {
text: "text/plain",

@@ -28,13 +22,11 @@ latex: "text/latex",

};
var createImmutableMarkdownCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: v4_1.demultiline(cell.source),
metadata: immutable_1.fromJS(cell.metadata)
});
};
var createImmutableMimeBundle = function (output) {
var mimeBundle = {};
for (var _i = 0, _a = Object.keys(output); _i < _a.length; _i++) {
var key = _a[_i];
const createImmutableMarkdownCell = (cell) => cells_1.makeMarkdownCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.source),
metadata: immutable_1.fromJS(cell.metadata)
});
const createImmutableMimeBundle = (output) => {
const mimeBundle = {};
for (const key of Object.keys(output)) {
// v3 had non-media types for rich media
if (key in VALID_MIMETYPES) {

@@ -45,22 +37,27 @@ mimeBundle[VALID_MIMETYPES[key]] =

}
return Object.keys(mimeBundle).reduce(v4_1.cleanMimeAtKey.bind(null, mimeBundle), immutable_1.Map());
return Object.keys(mimeBundle).reduce(outputs_1.cleanMimeAtKey.bind(null, mimeBundle), immutable_1.Map());
};
exports.sanitize = function (o) {
return o.metadata ? { metadata: immutable_1.fromJS(o.metadata) } : {};
};
var createImmutableOutput = function (output) {
const createImmutableOutput = (output) => {
switch (output.output_type) {
case "pyout":
return immutable_1.Map(__assign({ output_type: output.output_type, execution_count: output.prompt_number, data: createImmutableMimeBundle(output) }, exports.sanitize(output)));
return outputs_1.makeExecuteResult({
execution_count: output.prompt_number,
// Note strangeness with v4 API
data: createImmutableMimeBundle(output),
metadata: immutable_1.fromJS(output.metadata)
});
case "display_data":
return immutable_1.Map(__assign({ output_type: output.output_type, data: createImmutableMimeBundle(output) }, exports.sanitize(output)));
return outputs_1.makeDisplayData({
data: createImmutableMimeBundle(output),
metadata: immutable_1.fromJS(output.metadata)
});
case "stream":
return immutable_1.Map({
output_type: output.output_type,
name: output.stream,
text: v4_1.demultiline(output.text)
// Default to stdout in all cases unless it's stderr
const name = output.stream === "stderr" ? "stderr" : "stdout";
return outputs_1.makeStreamOutput({
name,
text: outputs_1.demultiline(output.text)
});
case "pyerr":
return immutable_1.Map({
output_type: "error",
return outputs_1.makeErrorOutput({
ename: output.ename,

@@ -71,36 +68,30 @@ evalue: output.evalue,

default:
throw new TypeError("Output type " + output.output_type + " not recognized");
throw new TypeError(`Output type ${output.output_type} not recognized`);
}
};
var createImmutableCodeCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: v4_1.demultiline(cell.input),
outputs: immutable_1.List(cell.outputs.map(createImmutableOutput)),
execution_count: cell.prompt_number,
metadata: immutable_1.fromJS(cell.metadata)
});
};
var createImmutableRawCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: v4_1.demultiline(cell.source),
metadata: immutable_1.fromJS(cell.metadata)
});
};
var createImmutableHeadingCell = function (cell) {
return immutable_1.Map({
cell_type: "markdown",
source: Array.isArray(cell.source)
? v4_1.demultiline(cell.source.map(function (line) {
return Array(cell.level)
.join("#")
.concat(" ")
.concat(line);
}))
: cell.source,
metadata: immutable_1.fromJS(cell.metadata)
});
};
var createImmutableCell = function (cell) {
const createImmutableCodeCell = (cell) => cells_1.makeCodeCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.input),
outputs: immutable_1.List(cell.outputs.map(createImmutableOutput)),
execution_count: cell.prompt_number,
metadata: immutable_1.fromJS(cell.metadata)
});
const createImmutableRawCell = (cell) => cells_1.makeRawCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.source),
metadata: immutable_1.fromJS(cell.metadata)
});
const createImmutableHeadingCell = (cell) =>
// v3 heading cells are just markdown cells in v4+
cells_1.makeMarkdownCell({
cell_type: "markdown",
source: Array.isArray(cell.source)
? outputs_1.demultiline(cell.source.map(line => Array(cell.level)
.join("#")
.concat(" ")
.concat(line)))
: cell.source,
metadata: immutable_1.fromJS(cell.metadata)
});
const createImmutableCell = (cell) => {
switch (cell.cell_type) {

@@ -116,17 +107,16 @@ case "markdown":

default:
throw new TypeError("Cell type " + cell.cell_type + " unknown");
throw new TypeError(`Cell type ${cell.cell_type} unknown`);
}
};
exports.fromJS = function (notebook) {
exports.fromJS = (notebook) => {
if (notebook.nbformat !== 3 || notebook.nbformat_minor < 0) {
throw new TypeError("Notebook is not a valid v3 notebook. v3 notebooks must be of form 3.x\n It lists nbformat v" + notebook.nbformat + "." + notebook.nbformat_minor);
throw new TypeError(`Notebook is not a valid v3 notebook. v3 notebooks must be of form 3.x
It lists nbformat v${notebook.nbformat}.${notebook.nbformat_minor}`);
}
var starterCellStructure = {
const starterCellStructure = {
cellOrder: immutable_1.List().asMutable(),
cellMap: immutable_1.Map().asMutable()
};
var cellStructure = [].concat.apply([], notebook.worksheets.map(function (worksheet) {
return worksheet.cells.reduce(function (cellStruct, cell) { return structures_1.appendCell(cellStruct, createImmutableCell(cell)); }, starterCellStructure);
}))[0];
return immutable_1.Map({
const cellStructure = [].concat.apply([], notebook.worksheets.map(worksheet => worksheet.cells.reduce((cellStruct, cell) => structures_1.appendCell(cellStruct, createImmutableCell(cell)), starterCellStructure)))[0];
return notebook_1.makeNotebookRecord({
cellOrder: cellStructure.cellOrder.asImmutable(),

@@ -133,0 +123,0 @@ cellMap: cellStructure.cellMap.asImmutable(),

@@ -1,33 +0,8 @@

import { Map as ImmutableMap } from "immutable";
import { ExecutionCount, JSONObject, MultiLineString } from "./types";
export declare type MimeBundle = {
[key: string]: string | string[] | Object;
};
/**
* @module commutable
*/
import { ImmutableNotebook } from "./notebook";
import { JSONObject, MultiLineString, ExecutionCount } from "./primitives";
import { Output } from "./outputs";
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Output Types
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
export interface ExecuteResult {
output_type: "execute_result";
execution_count: ExecutionCount;
data: MimeBundle;
metadata: JSONObject;
}
export interface DisplayData {
output_type: "display_data";
data: MimeBundle;
metadata: JSONObject;
}
export interface StreamOutput {
output_type: "stream";
name: "stdout" | "stderr";
text: MultiLineString;
}
export interface ErrorOutput {
output_type: "error" | "pyerr";
ename: string;
evalue: string;
traceback: string[];
}
export declare type Output = ExecuteResult | DisplayData | StreamOutput | ErrorOutput;
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Cell Types

@@ -53,3 +28,3 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

export declare type Cell = CodeCell | MarkdownCell | RawCell;
export interface Notebook {
export declare type Notebook = {
cells: Array<Cell>;

@@ -59,19 +34,11 @@ metadata: Object;

nbformat_minor: number;
}
export declare const demultiline: (s: string | string[]) => string;
};
export declare const fromJS: (notebook: Notebook) => ImmutableNotebook;
/**
* Split string into a list of strings delimited by newlines
* Converts an immutable representation of a notebook to a JSON representation.
*
* @param immnb The immutable representation of a notebook.
*
* @returns The JSON representation of a notebook.
*/
export declare const remultiline: (s: string | string[]) => string[];
export declare const isJSONKey: (key: string) => boolean;
export declare const cleanMimeData: (key: string, data: string | object | string[]) => string | object;
export declare const cleanMimeAtKey: (mimeBundle: MimeBundle, previous: ImmutableMap<string, any>, key: string) => ImmutableMap<string, any>;
export declare const createImmutableMimeBundle: (mimeBundle: MimeBundle) => ImmutableMap<string, any>;
export declare const sanitize: (o: ExecuteResult | DisplayData) => {
metadata: any;
} | {
metadata?: undefined;
};
export declare const createImmutableOutput: (output: Output) => ImmutableMap<string, any>;
export declare const fromJS: (notebook: Notebook) => ImmutableMap<string, any>;
export declare const toJS: (immnb: ImmutableMap<string, any>) => Notebook;
export declare const toJS: (immnb: ImmutableNotebook) => Notebook;
"use strict";
/**
* @module commutable
*/
/*

@@ -13,129 +16,52 @@ * Functions in this module are provided for converting from Jupyter Notebook

*
* To assist in the developer experience, types are included through the use of
* flow.
*
*/
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
var immutable_1 = require("immutable");
var structures_1 = require("./structures");
exports.demultiline = function (s) {
return Array.isArray(s) ? s.join("") : s;
};
Object.defineProperty(exports, "__esModule", { value: true });
const immutable_1 = require("immutable");
const notebook_1 = require("./notebook");
const cells_1 = require("./cells");
const outputs_1 = require("./outputs");
const structures_1 = require("./structures");
/**
* Split string into a list of strings delimited by newlines
* Converts a mutable representation of metadata to an immutable representation.
*
* @param metadata A JSON representation of notebook metadata.
*
* @returns ImmutableMetadata An immutable representation of the metadata.
*/
exports.remultiline = function (s) {
return Array.isArray(s) ? s : s.split(/(.+?(?:\r\n|\n))/g).filter(function (x) { return x !== ""; });
};
exports.isJSONKey = function (key) {
return /^application\/(.*\+)?json$/.test(key);
};
exports.cleanMimeData = function (key, data) {
// See https://github.com/jupyter/nbformat/blob/62d6eb8803616d198eaa2024604d1fe923f2a7b3/nbformat/v4/nbformat.v4.schema.json#L368
if (exports.isJSONKey(key)) {
// Data stays as is for JSON types
return data;
const createImmutableMetadata = (metadata) => immutable_1.Map(metadata).map((v, k) => {
if (k !== "tags") {
return v;
}
if (typeof data === "string" || Array.isArray(data)) {
return exports.demultiline(data);
if (Array.isArray(v)) {
return immutable_1.Set(v);
}
throw new TypeError("Data for " + key + " is expected to be a string or an Array of strings");
};
exports.cleanMimeAtKey = function (mimeBundle, previous, key) {
return previous.set(key, exports.cleanMimeData(key, mimeBundle[key]));
};
// Map over all the mimetypes, turning them into our in-memory format
//
// {
// "application/json": {"a": 3, "b": 2},
// "text/html": ["<p>\n", "Hey\n", "</p>"],
// "text/plain": "Hey"
// }
//
// to
//
// {
// "application/json": {"a": 3, "b": 2},
// "text/html": "<p>\nHey\n</p>",
// "text/plain": "Hey"
// }
//
exports.createImmutableMimeBundle = function (mimeBundle) {
return Object.keys(mimeBundle).reduce(exports.cleanMimeAtKey.bind(null, mimeBundle), immutable_1.Map());
};
exports.sanitize = function (o) {
return o.metadata ? { metadata: immutable_1.fromJS(o.metadata) } : {};
};
exports.createImmutableOutput = function (output) {
switch (output.output_type) {
case "execute_result":
return immutable_1.Map(__assign({ output_type: output.output_type, execution_count: output.execution_count, data: exports.createImmutableMimeBundle(output.data) }, exports.sanitize(output)));
case "display_data":
return immutable_1.Map(__assign({ output_type: output.output_type, data: exports.createImmutableMimeBundle(output.data) }, exports.sanitize(output)));
case "stream":
return immutable_1.Map({
output_type: output.output_type,
name: output.name,
text: exports.demultiline(output.text)
});
case "error":
return immutable_1.Map({
output_type: "error",
ename: output.ename,
evalue: output.evalue,
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
traceback: immutable_1.List(output.traceback)
});
default:
throw new TypeError("Output type " + output.output_type + " not recognized");
}
};
var createImmutableMetadata = function (metadata) {
return immutable_1.Map(metadata).map(function (v, k) {
if (k !== "tags") {
return v;
}
if (Array.isArray(v)) {
return immutable_1.Set(v);
}
// The notebook spec requires that this field is an Array of strings
return immutable_1.Set();
});
};
var createImmutableRawCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: exports.demultiline(cell.source),
metadata: createImmutableMetadata(cell.metadata)
});
};
var createImmutableMarkdownCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: exports.demultiline(cell.source),
metadata: createImmutableMetadata(cell.metadata)
});
};
var createImmutableCodeCell = function (cell) {
return immutable_1.Map({
cell_type: cell.cell_type,
source: exports.demultiline(cell.source),
outputs: immutable_1.List(cell.outputs.map(exports.createImmutableOutput)),
execution_count: cell.execution_count,
metadata: createImmutableMetadata(cell.metadata)
});
};
var createImmutableCell = function (cell) {
// The notebook spec requires that this field is an Array of strings
return immutable_1.Set();
});
const createImmutableRawCell = (cell) => cells_1.makeRawCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.source),
metadata: createImmutableMetadata(cell.metadata)
});
const createImmutableMarkdownCell = (cell) => cells_1.makeMarkdownCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.source),
metadata: createImmutableMetadata(cell.metadata)
});
const createImmutableCodeCell = (cell) => cells_1.makeCodeCell({
cell_type: cell.cell_type,
source: outputs_1.demultiline(cell.source),
outputs: immutable_1.List(cell.outputs.map(outputs_1.createImmutableOutput)),
execution_count: cell.execution_count,
metadata: createImmutableMetadata(cell.metadata)
});
/**
* Converts a JSON representation of a cell of any type to the correct
* immutable representation, per the v4 nbformat specification.
*
* @param cell A JSON representation of a cell.
*
* @returns An immutable representation of the same cell.
*/
const createImmutableCell = (cell) => {
switch (cell.cell_type) {

@@ -149,17 +75,18 @@ case "markdown":

default:
throw new TypeError("Cell type " + cell.cell_type + " unknown");
throw new TypeError(`Cell type ${cell.cell_type} unknown`);
}
};
exports.fromJS = function (notebook) {
exports.fromJS = (notebook) => {
if (notebook.nbformat !== 4 || notebook.nbformat_minor < 0) {
throw new TypeError("Notebook is not a valid v4 notebook. v4 notebooks must be of form 4.x\n It lists nbformat v" + notebook.nbformat + "." + notebook.nbformat_minor);
throw new TypeError(`Notebook is not a valid v4 notebook. v4 notebooks must be of form 4.x
It lists nbformat v${notebook.nbformat}.${notebook.nbformat_minor}`);
}
// Since we're doing N cell operations all at once, switch to mutable then
// switch back after.
var starterCellStructure = {
const starterCellStructure = {
cellOrder: immutable_1.List().asMutable(),
cellMap: immutable_1.Map().asMutable()
};
var cellStructure = notebook.cells.reduce(function (cellStruct, cell) { return structures_1.appendCell(cellStruct, createImmutableCell(cell)); }, starterCellStructure);
return immutable_1.Map({
const cellStructure = notebook.cells.reduce((cellStruct, cell) => structures_1.appendCell(cellStruct, createImmutableCell(cell)), starterCellStructure);
return notebook_1.makeNotebookRecord({
cellOrder: cellStructure.cellOrder.asImmutable(),

@@ -172,14 +99,7 @@ cellMap: cellStructure.cellMap.asImmutable(),

};
var metadataToJS = function (immMetadata) {
return immMetadata.toJS();
};
var markdownCellToJS = function (immCell) { return ({
cell_type: "markdown",
source: exports.remultiline(immCell.get("source", "")),
metadata: metadataToJS(immCell.get("metadata", immutable_1.Map()))
}); };
var mimeBundleToJS = function (immMimeBundle) {
var bundle = immMimeBundle.toObject();
Object.keys(bundle).map(function (key) {
if (exports.isJSONKey(key)) {
const metadataToJS = (immMetadata) => immMetadata.toJS();
const mimeBundleToJS = (immMimeBundle) => {
const bundle = immMimeBundle.toObject();
Object.keys(bundle).map(key => {
if (outputs_1.isJSONKey(key)) {
if (immutable_1.Map.isMap(bundle[key])) {

@@ -190,14 +110,12 @@ bundle[key] = bundle[key].toJS();

}
var data = bundle[key];
const data = bundle[key];
if (typeof data === "string" || Array.isArray(data)) {
bundle[key] = exports.remultiline(data);
bundle[key] = outputs_1.remultiline(data);
return bundle;
}
throw new TypeError("Data for " + key + " is expected to be a string or an Array of strings");
throw new TypeError(`Data for ${key} is expected to be a string or an Array of strings`);
});
return bundle;
};
var outputToJS = function (immOutput) {
// Technically this is an intermediate output with Immutables inside
var output = immOutput.toObject();
const outputToJS = (output) => {
switch (output.output_type) {

@@ -221,33 +139,59 @@ case "execute_result":

name: output.name,
text: exports.remultiline(output.text)
text: outputs_1.remultiline(output.text)
};
case "error":
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
return immOutput.toJS();
default:
throw new TypeError("Output type " + output.output_type + " not recognized");
return {
output_type: output.output_type,
ename: output.ename,
evalue: output.evalue,
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
traceback: output.traceback.toJS()
};
}
};
var codeCellToJS = function (immCell) {
var cell = immCell.toObject();
const markdownCellToJS = (immCell) => ({
cell_type: "markdown",
source: outputs_1.remultiline(immCell.source),
metadata: metadataToJS(immCell.metadata)
});
/**
* Converts an immutable representation of a code cell to a JSON representation.
*
* @param immCell An immutable representation of a code cell.
*
* @returns A JSON representation of the same code cell.
*/
const codeCellToJS = (immCell) => {
return {
cell_type: "code",
source: exports.remultiline(cell.source),
outputs: cell.outputs.map(outputToJS).toArray(),
execution_count: cell.execution_count,
metadata: metadataToJS(immCell.get("metadata", immutable_1.Map()))
source: outputs_1.remultiline(immCell.source),
outputs: immCell.outputs.map(outputToJS).toArray(),
execution_count: immCell.execution_count,
metadata: metadataToJS(immCell.metadata)
};
};
var rawCellToJS = function (immCell) {
var cell = immCell.toObject();
/**
* Converts an immutable representation of a raw cell to a JSON representation.
*
* @param immCell An immutable representation of a raw cell.
*
* @returns A JSON representation of the same raw cell.
*/
const rawCellToJS = (immCell) => {
return {
cell_type: "raw",
source: exports.remultiline(cell.source),
source: outputs_1.remultiline(immCell.source),
metadata: metadataToJS(immCell.get("metadata", immutable_1.Map()))
};
};
var cellToJS = function (immCell) {
var cellType = immCell.get("cell_type");
switch (cellType) {
/**
* Converts an immutable cell to a JSON cell.
*
* @param immCell An immutable representation of a cell.
*
* @returns A JSON representation of the same cell.
*/
const cellToJS = (immCell) => {
switch (immCell.cell_type) {
case "markdown":

@@ -260,18 +204,23 @@ return markdownCellToJS(immCell);

default:
throw new TypeError("Cell type " + cellType + " unknown");
throw new TypeError(`Cell type unknown at runtime`);
}
};
exports.toJS = function (immnb) {
var plainNotebook = immnb.toObject();
var plainCellOrder = plainNotebook.cellOrder.toArray();
var plainCellMap = plainNotebook.cellMap.toObject();
var cells = plainCellOrder.map(function (cellID) {
return cellToJS(plainCellMap[cellID]);
});
/**
* Converts an immutable representation of a notebook to a JSON representation.
*
* @param immnb The immutable representation of a notebook.
*
* @returns The JSON representation of a notebook.
*/
exports.toJS = (immnb) => {
const plainNotebook = immnb.toObject();
const plainCellOrder = plainNotebook.cellOrder.toArray();
const plainCellMap = plainNotebook.cellMap.toObject();
const cells = plainCellOrder.map((cellId) => cellToJS(plainCellMap[cellId]));
return {
cells: cells,
cells,
metadata: plainNotebook.metadata.toJS(),
nbformat: plainNotebook.nbformat,
nbformat: 4,
nbformat_minor: plainNotebook.nbformat_minor
};
};
{
"name": "@nteract/commutable",
"version": "6.0.0-alpha.0",
"version": "6.0.2-alpha.0",
"description": "library for immutable notebook operations",

@@ -8,11 +8,3 @@ "main": "lib/index.js",

"nteractDesktop": "src/index.ts",
"scripts": {
"prepare": "npm run build",
"prepublishOnly": "npm run build",
"build": "npm run build:clean && npm run build:lib",
"build:clean": "tsc -b --clean",
"build:lib": "tsc -b",
"build:lib:watch": "tsc -b --watch",
"build:watch": "npm run build:clean && npm run build:lib:watch"
},
"scripts": {},
"repository": "https://github.com/nteract/nteract/tree/master/packages/commutable",

@@ -30,3 +22,3 @@ "keywords": [

"dependencies": {
"immutable": "^4.0.0-rc.9",
"immutable": "^4.0.0-rc.12",
"uuid": "^3.1.0"

@@ -37,3 +29,3 @@ },

},
"gitHead": "fe5b95c8bc364388f37a7aacfcb22cee01864bf9"
"gitHead": "9ef8b723c581862d5c56b7ffd62a21393e7d83b9"
}

@@ -1,32 +0,48 @@

# com·mut·a·ble
# @nteract/commutable
> /kəˈmyo͞otəbəl/
>
> 1. (of a place or journey) allowing regular commuting to and from work.
> 2. **capable of being exchanged or converted.**
This is a package for Jupyter Notebook operations, helping to enable history stored as a series of immutable notebooks.
`commutable` is a library for Jupyter Notebook operations, helping to enable
history stored as a series of immutable notebooks.
This package follows the principles below, based on [Tom MacWright](http://www.macwright.org/2015/05/18/practical-undo.html)'s outline for practical undo.
## Principles
- **A notebook document is immutable**. It is never mutated in-place.
- Changes to a notebook document are encapsulated into **operations** that take a previous version and return a new one.
- History is represented as a **list of states**, with past on one end, the present on the other, and an index that can back up into 'undo states'.
- Modifying a notebook document causes any **future states to be thrown away**.
* **A notebook document is immutable**. It is never mutated in-place.
* Changes to a notebook document are encapsulated into **operations** that take a previous version and return a new one.
* History is represented as a **list of states**, with past on one end, the present on the other, and an index that can back up into 'undo states'.
* Modifying a notebook document causes any **future states to be thrown away**.
## Installation
Credits to [Tom MacWright](http://www.macwright.org/2015/05/18/practical-undo.html) for the outline.
```
$ yarn add @nteract/commutable
```
## Installation
```
$ npm install --save @nteract/commutable
```
You may use whichever package manager (`npm` or `yarn`) best suits your workflow. The `nteract` team internally uses `yarn`.
## Usage
```bash
npm install --save @nteract/commutable
# OR
yarn add @nteract/commutable
The example below shows how we can use the `emptyMarkdownCell` immutable object exported from this package to quickly create an empty Markdown cell in our nteract application.
```javascript
import { emptyMarkdownCell } from "@nteract/commutable";
export default () => (
<MarkdownPreview
id="a-random-cell-id"
cell={emptyMarkdownCell}
editorFocused={false}
/>
);
```
## Docs
## Documentation
Check out our [docs](https://nteract.github.io/docs/commutable/) for getting started.
You can view the reference documentation for `@nteract/commutable` in the [package docs](https://packages.nteract.io/modules/commutable).
## Support
If you experience an issue while using this package or have a feature request, please file an issue on the [issue board](https://github.com/nteract/nteract/issues/new/choose) and add the `pkg:commutable` label.
## License
[BSD-3-Clause](https://choosealicense.com/licenses/bsd-3-clause/)

@@ -1,14 +0,15 @@

import { Map as ImmutableMap } from "immutable";
import * as v4 from "./v4";
import * as v3 from "./v3";
import { ImmutableNotebook, JSONType } from "./types";
/**
* @module commutable
*/
// .....................................
// API Exports
// Make sure the index.js.flow types stay in sync with this section
//
// from types
export * from "./types";
export * from "./primitives";
export * from "./structures";
export * from "./outputs";
export * from "./cells";
export * from "./notebook";
/*
// from structures

@@ -28,67 +29,34 @@ export {

// v4
export { StreamOutput, Output, createImmutableOutput } from "./v4";
export {
StreamOutput,
Output,
createImmutableMimeBundle,
createImmutableOutput
} from "./v4";
makeDisplayData,
makeErrorOutput,
makeStreamOutput,
makeExecuteResult,
MimeBundle
} from "./outputs";
// general
export {
makeRawCell,
makeCodeCell,
makeMarkdownCell,
ImmutableCodeCell,
ImmutableMarkdownCell,
ImmutableRawCell,
ImmutableCell,
CellType
} from "./cells";
export type Notebook = v4.Notebook | v3.Notebook;
export {
toJS,
stringifyNotebook,
fromJS,
parseNotebook,
makeNotebookRecord,
Notebook,
ImmutableNotebook
} from "./notebook";
const freezeReviver = <T extends JSONType>(k: string, v: T) =>
Object.freeze(v) as T;
// Expected usage of below is fromJS(parseNotebook(string|buffer))
export const parseNotebook = (notebookString: string): Notebook =>
JSON.parse(notebookString, freezeReviver);
export const fromJS = (
notebook: Notebook | ImmutableNotebook
): ImmutableNotebook => {
if (ImmutableMap.isMap(notebook)) {
if (notebook.has("cellOrder") && notebook.has("cellMap")) {
return notebook;
}
throw new TypeError(
`commutable was passed an Immutable.Map structure that is not a notebook`
);
}
if (notebook.nbformat === 4 && notebook.nbformat_minor >= 0) {
if (
Array.isArray(notebook.cells) &&
typeof notebook.metadata === "object"
) {
return v4.fromJS(notebook);
}
} else if (notebook.nbformat === 3 && notebook.nbformat_minor >= 0) {
return v3.fromJS(notebook);
}
if (notebook.nbformat) {
throw new TypeError(
`nbformat v${notebook.nbformat}.${notebook.nbformat_minor} not recognized`
);
}
throw new TypeError("This notebook format is not supported");
};
export const toJS = (immnb: ImmutableNotebook): v4.Notebook => {
const minorVersion: null | number = immnb.get("nbformat_minor", null);
if (
immnb.get("nbformat") === 4 &&
typeof minorVersion === "number" &&
minorVersion >= 0
) {
return v4.toJS(immnb);
}
throw new TypeError("Only notebook formats 3 and 4 are supported!");
};
// Expected usage is stringifyNotebook(toJS(immutableNotebook))
export const stringifyNotebook = (notebook: v4.Notebook) =>
JSON.stringify(notebook, null, 2);
*/

@@ -0,91 +1,46 @@

/**
* @module commutable
*/
import uuid from "uuid/v4";
import { Map as ImmutableMap, List as ImmutableList } from "immutable";
import {
ImmutableOutput,
ImmutableCell,
ImmutableCodeCell,
ImmutableMarkdownCell,
ImmutableNotebook,
ImmutableCellOrder,
ImmutableCellMap,
ImmutableJSONType,
ExecutionCount
} from "./types";
import { CellId, createCellId } from "./primitives";
// We're hardset to nbformat v4.4 for what we use in-memory
interface Notebook {
nbformat: 4;
nbformat_minor: 4;
metadata: ImmutableMap<string, ImmutableJSONType>;
cellOrder: ImmutableList<string>;
cellMap: ImmutableMap<string, ImmutableCell>;
}
import { makeNotebookRecord, ImmutableNotebook } from "./notebook";
interface CodeCell {
cell_type: "code";
metadata: ImmutableMap<string, any>;
execution_count: ExecutionCount;
source: string;
outputs: ImmutableList<ImmutableOutput>;
}
import { makeCodeCell, makeMarkdownCell, ImmutableCell } from "./cells";
interface MarkdownCell {
cell_type: "markdown";
source: string;
metadata: ImmutableMap<string, any>;
}
import { Map as ImmutableMap, List as ImmutableList } from "immutable";
const defaultCodeCell = Object.freeze({
cell_type: "code",
execution_count: null,
metadata: ImmutableMap({
collapsed: false,
outputHidden: false,
inputHidden: false
}),
source: "",
outputs: ImmutableList()
}) as CodeCell;
// The cell creators here are a bit duplicative
export const createCodeCell = makeCodeCell;
export const createMarkdownCell = makeMarkdownCell;
const defaultMarkdownCell = Object.freeze({
cell_type: "markdown",
metadata: ImmutableMap(),
source: ""
}) as MarkdownCell;
export const createCodeCell = (cell = defaultCodeCell): ImmutableCodeCell =>
ImmutableMap(cell);
export const createMarkdownCell = (
cell = defaultMarkdownCell
): ImmutableMarkdownCell => ImmutableMap(cell);
export const emptyCodeCell = createCodeCell();
export const emptyMarkdownCell = createMarkdownCell();
export const defaultNotebook = Object.freeze({
nbformat: 4,
nbformat_minor: 4,
metadata: ImmutableMap(),
cellOrder: ImmutableList(),
cellMap: ImmutableMap()
}) as Notebook;
// These are all kind of duplicative now that we're on records.
// Since we export these though, they're left for
// backwards compatiblity
export const defaultNotebook = makeNotebookRecord();
export const createNotebook = makeNotebookRecord;
export const emptyNotebook = makeNotebookRecord();
export const createNotebook = (notebook = defaultNotebook): ImmutableNotebook =>
ImmutableMap(notebook);
export const emptyNotebook = createNotebook();
export type CellStructure = {
cellOrder: ImmutableCellOrder;
cellMap: ImmutableCellMap;
cellOrder: ImmutableList<CellId>;
cellMap: ImmutableMap<CellId, ImmutableCell>;
};
// Intended to make it easy to use this with (temporary mutable cellOrder +
// cellMap)
/**
* A function that appends a new cell to a CellStructure object.
*
* @param cellStructure The cellOrder and cellMap of the current notebook
* @param immutableCell The cell that will be inserted into the cellStructure
* @param id The id of the new cell, defaults to a new UUID
*
* @returns Cell structure with the new cell appended at the end
*/
export const appendCell = (
cellStructure: CellStructure,
immutableCell: ImmutableCell,
id: string = uuid()
id: CellId = createCellId()
): CellStructure => ({

@@ -96,2 +51,10 @@ cellOrder: cellStructure.cellOrder.push(id),

/**
* A function that appends a cell to an immutable notebook.
*
* @param immnb An immutable data structure representing the notebook that will be modified
* @param immCell The new cell that will be inserted into the notebook
*
* @returns The modified notebook
*/
export const appendCellToNotebook = (

@@ -102,6 +65,4 @@ immnb: ImmutableNotebook,

immnb.withMutations(nb => {
// $FlowFixMe: Fixed by making ImmutableNotebook a typed Record.
const cellStructure: CellStructure = {
cellOrder: nb.get("cellOrder"),
// $FlowFixMe: Fixed by making ImmutableNotebook a typed Record.
cellMap: nb.get("cellMap")

@@ -113,6 +74,16 @@ };

/**
* Inserts a cell with cellID at a given index within the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param index The position we would like to insert the cell at
*
* @returns The modified notebook.
*/
export const insertCellAt = (
notebook: ImmutableNotebook,
cell: ImmutableCell,
cellID: string,
cellId: string,
index: number

@@ -122,12 +93,20 @@ ): ImmutableNotebook =>

nb
.setIn(["cellMap", cellID], cell)
// $FlowFixMe: Fixed by making ImmutableNotebook a typed record.
.set("cellOrder", nb.get("cellOrder").insert(index, cellID))
.setIn(["cellMap", cellId], cell)
.set("cellOrder", nb.get("cellOrder").insert(index, cellId))
);
/**
* Inserts a new cell with cellID before an existing cell with priorCellID
* in the notebook.
*
* @param notebook The notebook the cell will be inserted into.
* @param cell The cell that will be inserted
* @param cellID The ID of the cell.
* @param priorCellID The ID of the existing cell.
*/
export const insertCellAfter = (
notebook: ImmutableNotebook,
cell: ImmutableCell,
cellID: string,
priorCellID: string
cellId: string,
priorCellId: string
): ImmutableNotebook =>

@@ -137,8 +116,15 @@ insertCellAt(

cell,
cellID,
// $FlowFixMe: Fixed by making ImmutableNotebook a typed record.
notebook.get("cellOrder").indexOf(priorCellID) + 1
cellId,
notebook.get("cellOrder").indexOf(priorCellId) + 1
);
/**
* Delete a cell with CellID at a given location. Note that this function
* is deprecated in favor of `deleteCell`.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*
* @deprecated use `deleteCell()` instead

@@ -148,3 +134,3 @@ */

notebook: ImmutableNotebook,
cellID: string
cellId: string
): ImmutableNotebook => {

@@ -154,19 +140,26 @@ console.log(

);
return notebook
.removeIn(["cellMap", cellID])
.update("cellOrder", (cellOrder: ImmutableCellOrder) =>
cellOrder.filterNot(id => id === cellID)
);
return deleteCell(notebook, cellId);
};
/**
* Delete a cell with CellID at a given location.
*
* @param notebook The notebook containing the cell.
* @param cellID The ID of the cell that will be deleted.
*
* @returns The modified notebook
*/
export const deleteCell = (
notebook: ImmutableNotebook,
cellID: string
cellId: string
): ImmutableNotebook =>
notebook
.removeIn(["cellMap", cellID])
.update("cellOrder", (cellOrder: ImmutableCellOrder) =>
cellOrder.filterNot(id => id === cellID)
);
.removeIn(["cellMap", cellId])
.update("cellOrder", cellOrder => cellOrder.filterNot(id => id === cellId));
/**
* A new notebook with a single empty code cell. This function is useful
* if you are looking to initialize a fresh, new notebook.
*/
export const monocellNotebook = appendCellToNotebook(

@@ -173,0 +166,0 @@ emptyNotebook,

@@ -0,1 +1,4 @@

/**
* @module commutable
*/
import {

@@ -7,21 +10,30 @@ Map as ImmutableMap,

import { MultiLineString, JSONObject } from "./primitives";
import { makeNotebookRecord } from "./notebook";
import {
ImmutableNotebook,
ImmutableCodeCell,
ImmutableMarkdownCell,
ImmutableRawCell,
makeCodeCell,
makeRawCell,
makeMarkdownCell
} from "./cells";
import {
ImmutableOutput,
ImmutableMimeBundle,
MultiLineString,
JSONObject
} from "./types";
import { CellStructure, appendCell } from "./structures";
import {
makeExecuteResult,
makeDisplayData,
makeStreamOutput,
makeErrorOutput,
demultiline,
cleanMimeAtKey,
ErrorOutput,
RawCell,
MarkdownCell
} from "./v4";
ErrorOutput
} from "./outputs";
import { CellStructure, appendCell } from "./structures";
import { RawCell, MarkdownCell } from "./v4";
const VALID_MIMETYPES = {

@@ -82,3 +94,3 @@ text: "text/plain",

export interface Notebook {
export type Notebook = {
worksheets: Worksheet[];

@@ -88,3 +100,3 @@ metadata: object;

nbformat_minor: number;
}
};

@@ -94,3 +106,3 @@ const createImmutableMarkdownCell = (

): ImmutableMarkdownCell =>
ImmutableMap({
makeMarkdownCell({
cell_type: cell.cell_type,

@@ -104,2 +116,3 @@ source: demultiline(cell.source),

for (const key of Object.keys(output)) {
// v3 had non-media types for rich media
if (key in VALID_MIMETYPES) {

@@ -116,29 +129,26 @@ mimeBundle[VALID_MIMETYPES[key as MimeTypeKey]] =

export const sanitize = (o: ExecuteResult | DisplayData) =>
o.metadata ? { metadata: immutableFromJS(o.metadata) } : {};
const createImmutableOutput = (output: Output): ImmutableOutput => {
switch (output.output_type) {
case "pyout":
return ImmutableMap({
output_type: output.output_type,
return makeExecuteResult({
execution_count: output.prompt_number,
// Note strangeness with v4 API
data: createImmutableMimeBundle(output),
...sanitize(output)
metadata: immutableFromJS(output.metadata)
});
case "display_data":
return ImmutableMap({
output_type: output.output_type,
return makeDisplayData({
data: createImmutableMimeBundle(output),
...sanitize(output)
metadata: immutableFromJS(output.metadata)
});
case "stream":
return ImmutableMap({
output_type: output.output_type,
name: output.stream,
// Default to stdout in all cases unless it's stderr
const name = output.stream === "stderr" ? "stderr" : "stdout";
return makeStreamOutput({
name,
text: demultiline(output.text)
});
case "pyerr":
return ImmutableMap({
output_type: "error",
return makeErrorOutput({
ename: output.ename,

@@ -154,3 +164,3 @@ evalue: output.evalue,

const createImmutableCodeCell = (cell: CodeCell): ImmutableCodeCell =>
ImmutableMap({
makeCodeCell({
cell_type: cell.cell_type,

@@ -164,3 +174,3 @@ source: demultiline(cell.input),

const createImmutableRawCell = (cell: RawCell): ImmutableRawCell =>
ImmutableMap({
makeRawCell({
cell_type: cell.cell_type,

@@ -172,3 +182,4 @@ source: demultiline(cell.source),

const createImmutableHeadingCell = (cell: HeadingCell): ImmutableMarkdownCell =>
ImmutableMap({
// v3 heading cells are just markdown cells in v4+
makeMarkdownCell({
cell_type: "markdown",

@@ -203,3 +214,3 @@ source: Array.isArray(cell.source)

export const fromJS = (notebook: Notebook): ImmutableNotebook => {
export const fromJS = (notebook: Notebook) => {
if (notebook.nbformat !== 3 || notebook.nbformat_minor < 0) {

@@ -217,3 +228,3 @@ throw new TypeError(

const cellStructure = [].concat.apply(
const cellStructure = ([] as CellStructure[]).concat.apply(
[],

@@ -228,3 +239,3 @@ notebook.worksheets.map(worksheet =>

return ImmutableMap({
return makeNotebookRecord({
cellOrder: cellStructure.cellOrder.asImmutable(),

@@ -231,0 +242,0 @@ cellMap: cellStructure.cellMap.asImmutable(),

@@ -0,1 +1,4 @@

/**
* @module commutable
*/
/*

@@ -12,5 +15,2 @@ * Functions in this module are provided for converting from Jupyter Notebook

*
* To assist in the developer experience, types are included through the use of
* flow.
*
*/

@@ -26,3 +26,10 @@

import {
makeNotebookRecord,
ImmutableNotebook,
NotebookRecordParams
} from "./notebook";
import { JSONObject, MultiLineString, ExecutionCount } from "./primitives";
import {
ImmutableCodeCell,

@@ -32,56 +39,27 @@ ImmutableMarkdownCell,

ImmutableCell,
makeCodeCell,
makeRawCell,
makeMarkdownCell
} from "./cells";
import {
createImmutableMimeBundle,
ImmutableOutput,
makeExecuteResult,
makeDisplayData,
makeStreamOutput,
makeErrorOutput,
demultiline,
remultiline,
isJSONKey,
MimeBundle,
ImmutableMimeBundle,
ExecutionCount,
JSONObject,
JSONType,
MultiLineString
} from "./types";
Output,
StreamOutput,
createImmutableOutput
} from "./outputs";
import { appendCell, CellStructure } from "./structures";
//
// MimeBundle example (disk format)
//
// {
// "application/json": {"a": 3, "b": 2},
// "text/html": ["<p>\n", "Hey\n", "</p>"],
// "text/plain": "Hey"
// }
//
export type MimeBundle = { [key: string]: string | string[] | Object };
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Output Types
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
export interface ExecuteResult {
output_type: "execute_result";
execution_count: ExecutionCount;
data: MimeBundle;
metadata: JSONObject;
}
export interface DisplayData {
output_type: "display_data";
data: MimeBundle;
metadata: JSONObject;
}
export interface StreamOutput {
output_type: "stream";
name: "stdout" | "stderr";
text: MultiLineString;
}
export interface ErrorOutput {
output_type: "error" | "pyerr";
ename: string;
evalue: string;
traceback: string[];
}
export type Output = ExecuteResult | DisplayData | StreamOutput | ErrorOutput;
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Cell Types

@@ -112,3 +90,3 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

export interface Notebook {
export type Notebook = {
cells: Array<Cell>;

@@ -118,104 +96,11 @@ metadata: Object;

nbformat_minor: number;
}
};
export const demultiline = (s: string | string[]) =>
Array.isArray(s) ? s.join("") : s;
/**
* Split string into a list of strings delimited by newlines
* Converts a mutable representation of metadata to an immutable representation.
*
* @param metadata A JSON representation of notebook metadata.
*
* @returns ImmutableMetadata An immutable representation of the metadata.
*/
export const remultiline = (s: string | string[]): string[] =>
Array.isArray(s) ? s : s.split(/(.+?(?:\r\n|\n))/g).filter(x => x !== "");
export const isJSONKey = (key: string) =>
/^application\/(.*\+)?json$/.test(key);
export const cleanMimeData = (
key: string,
data: string | string[] | object
) => {
// See https://github.com/jupyter/nbformat/blob/62d6eb8803616d198eaa2024604d1fe923f2a7b3/nbformat/v4/nbformat.v4.schema.json#L368
if (isJSONKey(key)) {
// Data stays as is for JSON types
return data;
}
if (typeof data === "string" || Array.isArray(data)) {
return demultiline(data);
}
throw new TypeError(
`Data for ${key} is expected to be a string or an Array of strings`
);
};
export const cleanMimeAtKey = (
mimeBundle: MimeBundle,
previous: ImmutableMimeBundle,
key: string
): ImmutableMimeBundle =>
previous.set(key, cleanMimeData(key, mimeBundle[key]));
// Map over all the mimetypes, turning them into our in-memory format
//
// {
// "application/json": {"a": 3, "b": 2},
// "text/html": ["<p>\n", "Hey\n", "</p>"],
// "text/plain": "Hey"
// }
//
// to
//
// {
// "application/json": {"a": 3, "b": 2},
// "text/html": "<p>\nHey\n</p>",
// "text/plain": "Hey"
// }
//
export const createImmutableMimeBundle = (
mimeBundle: MimeBundle
): ImmutableMimeBundle =>
Object.keys(mimeBundle).reduce(
cleanMimeAtKey.bind(null, mimeBundle),
ImmutableMap()
);
export const sanitize = (o: ExecuteResult | DisplayData) =>
o.metadata ? { metadata: immutableFromJS(o.metadata) } : {};
export const createImmutableOutput = (output: Output): ImmutableOutput => {
switch (output.output_type) {
case "execute_result":
return ImmutableMap({
output_type: output.output_type,
execution_count: output.execution_count,
data: createImmutableMimeBundle(output.data),
...sanitize(output)
});
case "display_data":
return ImmutableMap({
output_type: output.output_type,
data: createImmutableMimeBundle(output.data),
...sanitize(output)
});
case "stream":
return ImmutableMap({
output_type: output.output_type,
name: output.name,
text: demultiline(output.text)
});
case "error":
return ImmutableMap({
output_type: "error",
ename: output.ename,
evalue: output.evalue,
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
traceback: ImmutableList(output.traceback)
});
default:
throw new TypeError(`Output type ${output.output_type} not recognized`);
}
};
const createImmutableMetadata = (metadata: JSONObject) =>

@@ -236,3 +121,3 @@ ImmutableMap(metadata).map((v, k: string) => {

const createImmutableRawCell = (cell: RawCell): ImmutableRawCell =>
ImmutableMap({
makeRawCell({
cell_type: cell.cell_type,

@@ -246,3 +131,3 @@ source: demultiline(cell.source),

): ImmutableMarkdownCell =>
ImmutableMap({
makeMarkdownCell({
cell_type: cell.cell_type,

@@ -254,3 +139,3 @@ source: demultiline(cell.source),

const createImmutableCodeCell = (cell: CodeCell): ImmutableCodeCell =>
ImmutableMap({
makeCodeCell({
cell_type: cell.cell_type,

@@ -263,2 +148,10 @@ source: demultiline(cell.source),

/**
* Converts a JSON representation of a cell of any type to the correct
* immutable representation, per the v4 nbformat specification.
*
* @param cell A JSON representation of a cell.
*
* @returns An immutable representation of the same cell.
*/
const createImmutableCell = (cell: Cell): ImmutableCell => {

@@ -277,3 +170,3 @@ switch (cell.cell_type) {

export const fromJS = (notebook: Notebook): ImmutableNotebook => {
export const fromJS = (notebook: Notebook) => {
if (notebook.nbformat !== 4 || notebook.nbformat_minor < 0) {

@@ -298,3 +191,3 @@ throw new TypeError(

return ImmutableMap({
return makeNotebookRecord({
cellOrder: cellStructure.cellOrder.asImmutable(),

@@ -308,19 +201,5 @@ cellMap: cellStructure.cellMap.asImmutable(),

interface PlainNotebook {
cellOrder: ImmutableList<string>;
cellMap: ImmutableMap<string, ImmutableCell>;
metadata: ImmutableMap<string, any>;
nbformat: 4;
nbformat_minor: number;
}
const metadataToJS = (immMetadata: ImmutableMap<string, any>) =>
immMetadata.toJS() as JSONObject;
const markdownCellToJS = (immCell: ImmutableCell): MarkdownCell => ({
cell_type: "markdown",
source: remultiline(immCell.get("source", "")),
metadata: metadataToJS(immCell.get("metadata", ImmutableMap()))
});
const mimeBundleToJS = (immMimeBundle: ImmutableMimeBundle): MimeBundle => {

@@ -351,6 +230,3 @@ const bundle = immMimeBundle.toObject();

const outputToJS = (immOutput: ImmutableOutput): Output => {
// Technically this is an intermediate output with Immutables inside
const output = immOutput.toObject();
const outputToJS = (output: ImmutableOutput): Output => {
switch (output.output_type) {

@@ -377,35 +253,47 @@ case "execute_result":

case "error":
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
return immOutput.toJS() as any;
default:
throw new TypeError(`Output type ${output.output_type} not recognized`);
return {
output_type: output.output_type,
ename: output.ename,
evalue: output.evalue,
// Note: this is one of the cases where the Array of strings (for
// traceback) is part of the format, not a multiline string
traceback: output.traceback.toJS()
};
}
};
interface IntermediateCodeCell {
cell_type: "code";
metadata: ImmutableMap<string, JSONType>;
execution_count: ExecutionCount;
source: string;
outputs: ImmutableList<ImmutableOutput>;
}
const markdownCellToJS = (immCell: ImmutableMarkdownCell): MarkdownCell => ({
cell_type: "markdown",
source: remultiline(immCell.source),
metadata: metadataToJS(immCell.metadata)
});
const codeCellToJS = (immCell: ImmutableCell): CodeCell => {
const cell = immCell.toObject() as IntermediateCodeCell;
/**
* Converts an immutable representation of a code cell to a JSON representation.
*
* @param immCell An immutable representation of a code cell.
*
* @returns A JSON representation of the same code cell.
*/
const codeCellToJS = (immCell: ImmutableCodeCell): CodeCell => {
return {
cell_type: "code",
source: remultiline(cell.source),
outputs: cell.outputs.map(outputToJS).toArray(),
execution_count: cell.execution_count,
metadata: metadataToJS(immCell.get("metadata", ImmutableMap()))
source: remultiline(immCell.source),
outputs: immCell.outputs.map(outputToJS).toArray(),
execution_count: immCell.execution_count,
metadata: metadataToJS(immCell.metadata)
};
};
const rawCellToJS = (immCell: ImmutableCell): RawCell => {
const cell = immCell.toObject() as Cell;
/**
* Converts an immutable representation of a raw cell to a JSON representation.
*
* @param immCell An immutable representation of a raw cell.
*
* @returns A JSON representation of the same raw cell.
*/
const rawCellToJS = (immCell: ImmutableRawCell): RawCell => {
return {
cell_type: "raw",
source: remultiline(cell.source),
source: remultiline(immCell.source),
metadata: metadataToJS(immCell.get("metadata", ImmutableMap()))

@@ -415,5 +303,11 @@ };

/**
* Converts an immutable cell to a JSON cell.
*
* @param immCell An immutable representation of a cell.
*
* @returns A JSON representation of the same cell.
*/
const cellToJS = (immCell: ImmutableCell): Cell => {
const cellType: "markdown" | "raw" | "code" = immCell.get("cell_type");
switch (cellType) {
switch (immCell.cell_type) {
case "markdown":

@@ -426,8 +320,15 @@ return markdownCellToJS(immCell);

default:
throw new TypeError(`Cell type ${cellType} unknown`);
throw new TypeError(`Cell type unknown at runtime`);
}
};
/**
* Converts an immutable representation of a notebook to a JSON representation.
*
* @param immnb The immutable representation of a notebook.
*
* @returns The JSON representation of a notebook.
*/
export const toJS = (immnb: ImmutableNotebook): Notebook => {
const plainNotebook = immnb.toObject() as PlainNotebook;
const plainNotebook = immnb.toObject() as NotebookRecordParams;
const plainCellOrder: string[] = plainNotebook.cellOrder.toArray();

@@ -438,4 +339,4 @@ const plainCellMap: {

const cells = plainCellOrder.map((cellID: string) =>
cellToJS(plainCellMap[cellID])
const cells = plainCellOrder.map((cellId: string) =>
cellToJS(plainCellMap[cellId])
);

@@ -446,5 +347,5 @@

metadata: plainNotebook.metadata.toJS(),
nbformat: plainNotebook.nbformat,
nbformat: 4,
nbformat_minor: plainNotebook.nbformat_minor
};
};
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "lib"
"outDir": "lib",
"rootDir": "src"
},
"include": ["src"]
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc