@nteract/messaging
Version:
Messaging mechanics for nteract apps (jupyter spec)
192 lines • 8.45 kB
JavaScript
;
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