UNPKG

@nteract/messaging

Version:

Messaging mechanics for nteract apps (jupyter spec)

192 lines 8.45 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.wireProtocol = exports.inputRequests = exports.kernelStatuses = exports.executionCounts = exports.payloads = exports.updatedOutputs = exports.outputs = exports.convertOutputMessageToNotebookFormat = exports.ofMessageType = exports.withCommId = exports.childOf = exports.createCommCloseMessage = exports.createCommMessage = exports.createCommOpenMessage = exports.createMessage = void 0; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const messages_1 = require("./messages"); __exportStar(require("./types"), exports); // TODO: Deprecate function createMessage(msg_type, fields = {}) { return Object.assign(Object.assign({}, messages_1.message({ msg_type })), fields); } exports.createMessage = createMessage; /** * creates a comm open message * @param {string} comm_id uuid * @param {string} target_name comm handler * @param {any} data up to the target handler * @param {string} target_module [Optional] used to select a module that is responsible for handling the target_name * @return {jmp.Message} Message ready to send on the shell channel */ function createCommOpenMessage(comm_id, target_name, data = {}, target_module) { const msg = createMessage("comm_open", { content: { comm_id, target_name, data } }); if (target_module) { msg.content.target_module = target_module; } return msg; } exports.createCommOpenMessage = createCommOpenMessage; /** * creates a comm message for sending to a kernel * @param {string} comm_id unique identifier for the comm * @param {Object} data any data to send for the comm * @param {Uint8Array} buffers arbitrary binary data to send on the comm * @return {jmp.Message} jupyter message for comm_msg */ function createCommMessage(comm_id, data = {}, buffers) { return createMessage("comm_msg", { content: { comm_id, data }, buffers }); } exports.createCommMessage = createCommMessage; /** * creates a comm close message for sending to a kernel * @param {Object} parent_header header from a parent jupyter message * @param {string} comm_id unique identifier for the comm * @param {Object} data any data to send for the comm * @return {jmp.Message} jupyter message for comm_msg */ function createCommCloseMessage(parent_header, comm_id, data = {}) { return createMessage("comm_close", { content: { comm_id, data }, parent_header }); } exports.createCommCloseMessage = createCommCloseMessage; /** * operator for getting all messages that declare their parent header as * parentMessage's header. * * @param parentMessage The parent message whose children we should fetch * * @returns A function that takes an Observable of kernel messages and returns * messages that are children of parentMessage. */ function childOf(parentMessage) { return (source) => { const parentMessageID = parentMessage.header.msg_id; return rxjs_1.Observable.create((subscriber) => source.subscribe(msg => { // strictly speaking, in order for the message to be a child of the // parent message, it has to both be a message and have a parent to // begin with if (!msg || !msg.parent_header || !msg.parent_header.msg_id) { if (process.env.DEBUG === "true") { console.warn("no parent_header.msg_id on message", msg); } return; } if (parentMessageID === msg.parent_header.msg_id) { subscriber.next(msg); } }, // be sure to handle errors and completions as appropriate and // send them along err => subscriber.error(err), () => subscriber.complete())); }; } exports.childOf = childOf; /** * operator for getting all messages with the given comm id * * @param comm_id The comm id that we are filtering by * * @returns A function that takes an Observable of kernel messages and returns * messages that have the given comm id */ function withCommId(comm_id) { return (source) => { return rxjs_1.Observable.create((subscriber) => source.subscribe(msg => { if (msg && msg.content && msg.content.comm_id === comm_id) { subscriber.next(msg); } }, // be sure to handle errors and completions as appropriate and // send them along err => subscriber.error(err), () => subscriber.complete())); }; } exports.withCommId = withCommId; /** * ofMessageType is an Rx Operator that filters on msg.header.msg_type * being one of messageTypes. * * @param messageTypes The message types to filter on * * @returns An Observable containing only messages of the specified types */ exports.ofMessageType = (...messageTypes) => { // Switch to the splat mode if (messageTypes.length === 1 && Array.isArray(messageTypes[0])) { return exports.ofMessageType(...messageTypes[0]); } return (source) => rxjs_1.Observable.create((subscriber) => source.subscribe(msg => { if (!msg.header || !msg.header.msg_type) { subscriber.error(new Error("no header.msg_type on message")); return; } if (messageTypes.includes(msg.header.msg_type)) { subscriber.next(msg); } }, // be sure to handle errors and completions as appropriate and // send them along err => subscriber.error(err), () => subscriber.complete())); }; /** * Create an object that adheres to the jupyter notebook specification. * http://jupyter-client.readthedocs.io/en/latest/messaging.html * * @param msg Message that has content which can be converted to nbformat * * @returns Message with the associated output type */ function convertOutputMessageToNotebookFormat(msg) { return Object.assign(Object.assign({}, msg.content), { output_type: msg.header.msg_type }); } exports.convertOutputMessageToNotebookFormat = convertOutputMessageToNotebookFormat; /** * Convert raw Jupyter messages that are output messages into nbformat style * outputs * * > o$ = iopub$.pipe( * childOf(originalMessage), * outputs() * ) */ exports.outputs = () => (source) => source.pipe(exports.ofMessageType("execute_result", "display_data", "stream", "error"), operators_1.map(convertOutputMessageToNotebookFormat)); /** * Get all messages for updating a display output. */ exports.updatedOutputs = () => (source) => source.pipe(exports.ofMessageType("update_display_data"), operators_1.map(msg => (Object.assign(Object.assign({}, msg.content), { output_type: "display_data" })))); /** * Get all the payload message content from an observable of jupyter messages * * > p$ = shell$.pipe( * childOf(originalMessage), * payloads() * ) */ exports.payloads = () => (source) => source.pipe(exports.ofMessageType("execute_reply"), operators_1.map(entry => entry.content.payload), operators_1.filter(p => !!p), operators_1.mergeMap((p) => rxjs_1.from(p))); /** * Get all the execution counts from an observable of jupyter messages */ exports.executionCounts = () => (source) => source.pipe(exports.ofMessageType("execute_input", "execute_reply"), operators_1.map(entry => entry.content.execution_count)); /** * Get all statuses of all running kernels. */ exports.kernelStatuses = () => (source) => source.pipe(exports.ofMessageType("status"), operators_1.map(entry => entry.content.execution_state)); exports.inputRequests = () => (source) => source.pipe(exports.ofMessageType("input_request"), operators_1.map(entry => entry.content)); __exportStar(require("./messages"), exports); const wire_protocol_1 = require("./wire-protocol"); exports.wireProtocol = { encode: wire_protocol_1.encode, decode: wire_protocol_1.decode }; //# sourceMappingURL=index.js.map