{"action":"created","comment":{"url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/comments/33730630","id":33730630,"diff_hunk":"@@ -1,1069 +1,803 @@\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n \n-\"use strict\";\n-\n-import $ = require('jquery');\n-import utils = require('base/js/utils');\n-import comm = require('./comm');\n import serialize = require('./serialize');\n-import events = require('base/js/events');\n-\n-\n-/**\n-     * A Kernel class to communicate with the Python kernel. This\n-     * should generally not be constructed directly, but be created\n-     * by.  the `Session` object. Once created, this object should be\n-     * used to communicate with the kernel.\n-     * \n-     * @class Kernel\n-     * @param {string} kernel_service_url - the URL to access the kernel REST api\n-     * @param {string} ws_url - the websockets URL\n-     * @param {string} name - the kernel type (e.g. python3)\n-     */\n-export class Kernel {\n-\n-    constructor(kernel_service_url: string, ws_url: string, name: string) {\n-\n-        this.id = null;\n-        this.name = name;\n-        this.ws = null;\n-\n-        this.kernel_service_url = kernel_service_url;\n-        this.kernel_url = null;\n-        this.ws_url = ws_url || utils.get_body_data(\"wsUrl\");\n-        if (!this.ws_url) {\n-            // trailing 's' in https will become wss for secure web sockets\n-            this.ws_url = location.protocol.replace('http', 'ws') + \"//\" + location.host;\n-        }\n-\n-        this.username = \"username\";\n-        this.session_id = utils.uuid();\n-        this._msg_callbacks = {};\n-        this._msg_queue = Promise.resolve();\n-        this.info_reply = {}; // kernel_info_reply stored here after starting\n-\n-        if (typeof(WebSocket) === 'undefined') {\n-            alert('Your browser does not have WebSocket support, please try Chrome, Safari, or Firefox ≥ 11.');\n-        }\n-        \n-        this.bind_events();\n-        this.init_iopub_handlers();\n-        this.comm_manager = new comm.CommManager(this);\n-        \n-        this.last_msg_id = null;\n-        this.last_msg_callbacks = {};\n-\n-        this._autorestart_attempt = 0;\n-        this._reconnect_attempt = 0;\n-        this.reconnect_limit = 7;\n-    }\n+import utils = require('./utils');\n \n-    /**\n-     * @function _get_msg\n-     */\n-    _get_msg(msg_type: string, content, metadata?, buffers?): any {\n-        var msg: any = {\n-            header : {\n-                msg_id : utils.uuid(),\n-                username : this.username,\n-                session : this.session_id,\n-                msg_type : msg_type,\n-                version : \"5.0\"\n-            },\n-            metadata : metadata || {},\n-            content : content,\n-            buffers : buffers || [],\n-            parent_header : {}\n-        };\n-        return msg;\n-    }\n-\n-    /**\n-     * @function bind_events\n-     */\n-    bind_events(): void {\n-        events.on('send_input_reply.Kernel', (evt, data) => { \n-            this.send_input_reply(data);\n-        });\n+import Signal = phosphor.core.Signal;\n+import emit = phosphor.core.emit;\n+import IDisposable = phosphor.utility.IDisposable;\n+import Disposable = phosphor.utility.Disposable;\n \n-        var record_status = (evt, info) => {\n-            console.log('Kernel: ' + evt.type + ' (' + info.kernel.id + ')');\n-        };\n-\n-        events.on('kernel_created.Kernel', record_status);\n-        events.on('kernel_reconnecting.Kernel', record_status);\n-        events.on('kernel_connected.Kernel', record_status);\n-        events.on('kernel_starting.Kernel', record_status);\n-        events.on('kernel_restarting.Kernel', record_status);\n-        events.on('kernel_autorestarting.Kernel', record_status);\n-        events.on('kernel_interrupting.Kernel', record_status);\n-        events.on('kernel_disconnected.Kernel', record_status);\n-        // these are commented out because they are triggered a lot, but can\n-        // be uncommented for debugging purposes\n-        //events.on('kernel_idle.Kernel', record_status);\n-        //events.on('kernel_busy.Kernel', record_status);\n-        events.on('kernel_ready.Kernel', record_status);\n-        events.on('kernel_killed.Kernel', record_status);\n-        events.on('kernel_dead.Kernel', record_status);\n-\n-        events.on('kernel_ready.Kernel', () => {\n-            this._autorestart_attempt = 0;\n-        });\n-        events.on('kernel_connected.Kernel', () => {\n-            this._reconnect_attempt = 0;\n-        });\n-    }\n-\n-    /**\n-     * Initialize the iopub handlers.\n-     *\n-     * @function init_iopub_handlers\n-     */\n-    init_iopub_handlers(): void {\n-        var output_msg_types = ['stream', 'display_data', 'execute_result', 'error'];\n-        this._iopub_handlers = {};\n-        this.register_iopub_handler('status', $.proxy(this._handle_status_message, this));\n-        this.register_iopub_handler('clear_output', $.proxy(this._handle_clear_output, this));\n-        this.register_iopub_handler('execute_input', $.proxy(this._handle_input_message, this));\n-        \n-        for (var i=0; i < output_msg_types.length; i++) {\n-            this.register_iopub_handler(output_msg_types[i], $.proxy(this._handle_output_message, this));\n-        }\n-    }\n \n-    /**\n-     * GET /api/kernels\n-     *\n-     * Get the list of running kernels.\n-     *\n-     * @function list\n-     * @param {function} [success] - function executed on ajax success\n-     * @param {function} [error] - functon executed on ajax error\n-     */\n-    list(success, error): void {\n-        $.ajax(this.kernel_service_url, {\n-            processData: false,\n-            cache: false,\n-            type: \"GET\",\n-            dataType: \"json\",\n-            success: success,\n-            error: this._on_error(error)\n-        });\n-    }\n-\n-    /**\n-     * POST /api/kernels\n-     *\n-     * Start a new kernel.\n-     *\n-     * In general this shouldn't be used -- the kernel should be\n-     * started through the session API. If you use this function and\n-     * are also using the session API then your session and kernel\n-     * WILL be out of sync!\n-     *\n-     * @function start\n-     * @param {params} [Object] - parameters to include in the query string\n-     * @param {function} [success] - function executed on ajax success\n-     * @param {function} [error] - functon executed on ajax error\n-     */\n-    start(params, success, error): string {\n-        var url: string = this.kernel_service_url;\n-        var qs = $.param(params || {}); // query string for sage math stuff\n-        if (qs !== \"\") {\n-            url = url + \"?\" + qs;\n-        }\n-\n-        events.trigger('kernel_starting.Kernel', {kernel: this});\n-        var on_success = (data, status, xhr) => {\n-            events.trigger('kernel_created.Kernel', {kernel: this});\n-            this._kernel_created(data);\n-            if (success) {\n-                success(data, status, xhr);\n-            }\n-        };\n-\n-        $.ajax(url, {\n-            processData: false,\n-            cache: false,\n-            type: \"POST\",\n-            data: JSON.stringify({name: this.name}),\n-            contentType: 'application/json',\n-            dataType: \"json\",\n-            success: this._on_success(on_success),\n-            error: this._on_error(error)\n-        });\n-\n-        return url;\n-    }\n-\n-    /**\n-     * GET /api/kernels/[:kernel_id]\n-     *\n-     * Get information about the kernel.\n-     *\n-     * @function get_info\n-     * @param {function} [success] - function executed on ajax success\n-     * @param {function} [error] - functon executed on ajax error\n-     */\n-    get_info(success, error): void {\n-        $.ajax(this.kernel_url, {\n-            processData: false,\n-            cache: false,\n-            type: \"GET\",\n-            dataType: \"json\",\n-            success: this._on_success(success),\n-            error: this._on_error(error)\n-        });\n-    }\n-\n-    /**\n-     * DELETE /api/kernels/[:kernel_id]\n-     *\n-     * Shutdown the kernel.\n-     *\n-     * If you are also using sessions, then this function shoul NOT be\n-     * used. Instead, use Session.delete. Otherwise, the session and\n-     * kernel WILL be out of sync.\n-     *\n-     * @function kill\n-     * @param {function} [success] - function executed on ajax success\n-     * @param {function} [error] - functon executed on ajax error\n-     */\n-    kill(success, error): void {\n-        events.trigger('kernel_killed.Kernel', {kernel: this});\n-        this._kernel_dead();\n-        $.ajax(this.kernel_url, {\n-            processData: false,\n-            cache: false,\n-            type: \"DELETE\",\n-            dataType: \"json\",\n-            success: this._on_success(success),\n-            error: this._on_error(error)\n-        });\n-    }\n-\n-    /**\n-     * POST /api/kernels/[:kernel_id]/interrupt\n-     *\n-     * Interrupt the kernel.\n-     *\n-     * @function interrupt\n-     * @param {function} [success] - function executed on ajax success\n-     * @param {function} [error] - functon executed on ajax error\n-     */\n-    interrupt(success, error): void {\n-        events.trigger('kernel_interrupting.Kernel', {kernel: this});\n-\n-        var on_success = (data, status, xhr) => {\n-            /**\n-             * get kernel info so we know what state the kernel is in\n-             */\n-            this.kernel_info();\n-            if (success) {\n-                success(data, status, xhr);\n-            }\n-        };\n-\n-        var url = utils.url_join_encode(this.kernel_url, 'interrupt');\n-        $.ajax(url, {\n-            processData: false,\n-            cache: false,\n-            type: \"POST\",\n-            contentType: false,  // there's no data with this\n-            dataType: \"json\",\n-            success: this._on_success(on_success),\n-            error: this._on_error(error)\n-        });\n-    }\n+/**\n+ * Kernel message header content.\n+ */\n+export\n+interface IKernelMsgHeader {\n+  username: string;\n+  version: string;\n+  session: string;\n+  msgId: string;\n+  msgType: string;\n+}\n \n-    restart(success, error): void {\n-        /**\n-         * POST /api/kernels/[:kernel_id]/restart\n-         *\n-         * Restart the kernel.\n-         *\n-         * @function interrupt\n-         * @param {function} [success] - function executed on ajax success\n-         * @param {function} [error] - functon executed on ajax error\n-         */\n-        events.trigger('kernel_restarting.Kernel', {kernel: this});\n-        this.stop_channels();\n-\n-        var on_success = (data, status, xhr) => {\n-            events.trigger('kernel_created.Kernel', {kernel: this});\n-            this._kernel_created(data);\n-            if (success) {\n-                success(data, status, xhr);\n-            }\n-        };\n-\n-        var on_error = (xhr, status, err) => {\n-            events.trigger('kernel_dead.Kernel', {kernel: this});\n-            this._kernel_dead();\n-            if (error) {\n-                error(xhr, status, err);\n-            }\n-        };\n-\n-        var url = utils.url_join_encode(this.kernel_url, 'restart');\n-        $.ajax(url, {\n-            processData: false,\n-            cache: false,\n-            type: \"POST\",\n-            contentType: false,  // there's no data with this\n-            dataType: \"json\",\n-            success: this._on_success(on_success),\n-            error: this._on_error(on_error)\n-        });\n-    }\n \n-    reconnect(): void {\n-        /**\n-         * Reconnect to a disconnected kernel. This is not actually a\n-         * standard HTTP request, but useful function nonetheless for\n-         * reconnecting to the kernel if the connection is somehow lost.\n-         *\n-         * @function reconnect\n-         */\n-        if (this.is_connected()) {\n-            return;\n-        }\n-        this._reconnect_attempt = this._reconnect_attempt + 1;\n-        events.trigger('kernel_reconnecting.Kernel', {\n-            kernel: this,\n-            attempt: this._reconnect_attempt,\n-        });\n-        this.start_channels();\n-    }\n+/**\n+ * Kernel message specification.\n+ */\n+export\n+interface IKernelMsg {\n+  header: IKernelMsgHeader;\n+  metadata: any;\n+  content: any;\n+  parentHeader: {} | IKernelMsgHeader;\n+  msgId?: string;\n+  msgType?: string;\n+  channel?: string;\n+  buffers?: string[] | ArrayBuffer[];\n+}\n \n-    _on_success(success): any {\n-        /**\n-         * Handle a successful AJAX request by updating the kernel id and\n-         * name from the response, and then optionally calling a provided\n-         * callback.\n-         *\n-         * @function _on_success\n-         * @param {function} success - callback\n-         */\n-        return (data, status, xhr) => {\n-            if (data) {\n-                this.id = data.id;\n-                this.name = data.name;\n-            }\n-            this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id);\n-            if (success) {\n-                success(data, status, xhr);\n-            }\n-        };\n-    }\n \n-    _on_error(error) {\n-        /**\n-         * Handle a failed AJAX request by logging the error message, and\n-         * then optionally calling a provided callback.\n-         *\n-         * @function _on_error\n-         * @param {function} error - callback\n-         */\n-        return (xhr, status, err) => {\n-            utils.log_ajax_error(xhr, status, err);\n-            if (error) {\n-                error(xhr, status, err);\n-            }\n-        };\n-    }\n+/**\n+ * Object providing a Future interface for message callbacks.\n+ *\n+ * Only one callback can be registered per type.\n+ * If `autoDispose` is set, the future will self-dispose after `isDone` is\n+ * set and the registered `onDone` handler is called.\n+ *\n+ * The Future is considered done when a `reply` message and a\n+ * an `idle` iopub status message have been received.\n+ */\n+export\n+interface IKernelFuture extends IDisposable {\n+  /**\n+   * The autoDispose behavior of the future.\n+   *\n+   * If True, it will self-dispose() after onDone() is called.\n+   */\n+  autoDispose: boolean;\n+\n+  /**\n+   * Set when the message is done.  \n+   */\n+  isDone: boolean;\n+\n+  /**\n+   * Register a reply handler. Returns `this`.\n+   */\n+  onReply(cb: (msg: IKernelMsg) => void): IKernelFuture;\n+\n+  /**\n+   * Register an output handler. Returns `this`.\n+   */\n+  onOutput(cb: (msg: IKernelMsg) => void): IKernelFuture;\n+\n+  /**\n+   * Register a done handler. Returns `this`.\n+   */\n+  onDone(cb: (msg: IKernelMsg) => void): IKernelFuture;\n+\n+  /**\n+   * Register an input handler. Returns `this`.\n+   */\n+  onInput(cb: (msg: IKernelMsg) => void): IKernelFuture;\n+}\n \n-    _kernel_created(data): void {\n-        /**\n-         * Perform necessary tasks once the kernel has been started,\n-         * including actually connecting to the kernel.\n-         *\n-         * @function _kernel_created\n-         * @param {Object} data - information about the kernel including id\n-         */\n-        this.id = data.id;\n-        this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id);\n-        this.start_channels();\n-    }\n \n-    _kernel_connected(): void {\n-        /**\n-         * Perform necessary tasks once the connection to the kernel has\n-         * been established. This includes requesting information about\n-         * the kernel.\n-         *\n-         * @function _kernel_connected\n-         */\n-        events.trigger('kernel_connected.Kernel', {kernel: this});\n-        // get kernel info so we know what state the kernel is in\n-        var that = this;\n-        this.kernel_info((reply?) => {\n-            this.info_reply = reply.content;\n-            events.trigger('kernel_ready.Kernel', {kernel: that});\n+/**\n+ * A Kernel class to communicate with the Python kernel. This\n+ * should generally not be constructed directly, but be created\n+ * by the `Session` object. Once created, this object should be\n+ * used to communicate with the kernel.\n+ */\n+export\n+class Kernel {\n+\n+  static statusChange = new Signal<Kernel, string>();\n+\n+  /**\n+   * GET /api/kernels\n+   *\n+   * Get the list of running kernels.\n+   */\n+  static list(kernelServiceUrl: string): Promise<string []> {\n+    return utils.ajaxRequest(kernelServiceUrl, {\n+      method: \"GET\",\n+      dataType: \"json\"\n+    });\n+  }\n+\n+  constructor(kernelServiceUrl: string, wsUrl: string, name: string) {\n+    this._id = null;\n+    this._name = name;\n+    this._ws = null;\n+\n+    this._kernelServiceUrl = kernelServiceUrl;\n+    this._kernelUrl = null;\n+    this._wsUrl = wsUrl;\n+    if (!this._wsUrl) {\n+      // trailing 's' in https will become wss for secure web sockets\n+      this._wsUrl = location.protocol.replace('http', 'ws') + \"//\" + location.host;\n+    }\n+\n+    this._username = \"username\";\n+    this._sessionId = utils.uuid();\n+    this._infoReply = {}; // kernel_info_reply stored here after starting\n+    this._handlerMap = new Map<string, KernelFutureHandler>();\n+\n+    if (typeof WebSocket === 'undefined') {\n+      alert('Your browser does not have WebSocket support, please try Chrome, Safari, or Firefox ≥ 11.');\n+    }\n+\n+    this._autorestartAttempt = 0;\n+    this._reconnectAttempt = 0;\n+    this._reconnectLimit = 7;\n+  }\n+\n+  /**\n+   * Get the Url for the Kernel service.\n+   */\n+  get kernelServiceUrl() : string {\n+    return this._kernelServiceUrl;\n+  }\n+\n+  /**\n+   * Check whether there is a connection to the kernel. This\n+   * function only returns true if websocket has been\n+   * created and has a state of WebSocket.OPEN.\n+   */\n+  get isConnected(): boolean {\n+    if (this._ws === null) {\n+      return false;\n+    }\n+    if (this._ws.readyState !== WebSocket.OPEN) {\n+      return false;\n+    }\n+    return true;\n+  }\n+\n+  /**\n+   * Check whether the connection to the kernel has been completely\n+   * severed. This function only returns true if the websocket is null.\n+   */\n+  get isFullyDisconnected(): boolean {\n+    return (this._ws === null);\n+  }\n+\n+  /**\n+   * Get the Info Reply Message from the Kernel.\n+   */\n+  get infoReply(): any {\n+    return this._infoReply\n+  }\n+\n+  /**\n+   * GET /api/kernels/[:kernel_id]\n+   *\n+   * Get information about the kernel.\n+   */\n+  getInfo(): Promise<any> {\n+    return utils.ajaxRequest(this._kernelUrl, {\n+      method: \"GET\",\n+      dataType: \"json\"\n+    }).then((data: any) => {\n+      this._onSuccess(data);\n+    }, (error) => {\n+      this._onError(error.status, error.error);\n+    });\n+  }\n+\n+  /**\n+   * POST /api/kernels/[:kernel_id]/interrupt\n+   *\n+   * Interrupt the kernel.\n+   */\n+  interrupt(): Promise<any> {\n+    this._handleStatus('interrupting');\n+\n+    var url = utils.urlJoinEncode(this._kernelUrl, 'interrupt');\n+    return utils.ajaxRequest(url, {\n+      method: \"POST\",\n+      dataType: \"json\",\n+      successCode: 204\n+    }).then((data: any) => {\n+      this._onSuccess(data);\n+    }, (error) => {\n+      this._onError(error.status, error.error);\n+    });\n+  }\n+\n+  /**\n+   * POST /api/kernels/[:kernel_id]/restart\n+   *\n+   * Restart the kernel.\n+   */\n+  restart(): Promise<any> {\n+    this._handleStatus('restarting');\n+    this._stopChannels();\n+\n+    var url = utils.urlJoinEncode(this._kernelUrl, 'restart');\n+    return utils.ajaxRequest(url, {\n+      method: \"POST\",\n+      dataType: \"json\",\n+      useHeader: 'Location'\n+    }).then((data: any) => {\n+      this._kernelCreated(data);\n+      this._onSuccess(data);\n+    }, (error) => {\n+      this._kernelDead();\n+      this._onError(error.status, error.error);\n+    });\n+  }\n+\n+  /**\n+   * Reconnect to a disconnected kernel. This is not actually a\n+   * standard HTTP request, but useful function nonetheless for\n+   * reconnecting to the kernel if the connection is somehow lost.\n+   */\n+  reconnect(): void {\n+    if (this.isConnected) {\n+      return;\n+    }\n+    this._reconnectAttempt = this._reconnectAttempt + 1;\n+    this._handleStatus('reconnecting');\n+    this._startChannels();\n+  }\n+\n+  /**\n+   * Send a message on the Kernel's shell channel.\n+   */\n+  sendShellMessage(msg_type: string, content: any, metadata = {}, buffers: string[] = []): IKernelFuture {\n+    if (!this.isConnected) {\n+      throw new Error(\"kernel is not connected\");\n+    }\n+    var msg = this._getMsg(msg_type, content, metadata, buffers);\n+    msg.channel = 'shell';\n+\n+    this._ws.send(serialize.serialize(msg));\n+\n+    var future = new KernelFutureHandler(() => {\n+      this._handlerMap.delete(msg.header.msgId);\n+    });\n+\n+    this._handlerMap.set(msg.header.msgId, future);\n+\n+    return future;\n+  }\n+\n+  /**\n+   * Get kernel info.\n+   *\n+   * Returns a KernelFuture that will resolve to a `kernel_info_reply` message documented\n+   * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#kernel-info)\n+   */\n+  kernelInfo(): IKernelFuture {\n+    return this.sendShellMessage(\"kernel_info_request\", {});\n+  }\n+\n+  /**\n+   * Get info on an object.\n+   *\n+   * Returns a KernelFuture that will resolve to a `inspect_reply` message documented\n+   * [here](http://ipython.org/ipython-doc/dev/development/messaging.html#object-information)\n+   */\n+  inspect(code: string, cursor_pos: number): IKernelFuture {\n+    var content = {\n+      code: code,\n+      cursor_pos: cursor_pos,\n+      detail_level: 0\n+    };\n+    return this.sendShellMessage(\"inspect_request\", content);\n+  }\n+\n+  /**\n+   * Execute given code into kernel, returning a KernelFuture.\n+   *\n+   * @example\n+   *\n+   * The options object should contain the options for the execute\n+   * call. Its default values are:\n+   *\n+   *      options = {\n+   *        silent : true,\n+   *        user_expressions : {},\n+   *        allow_stdin : false,\n+            store_history: false\n+   *      }\n+   *\n+   */\n+  execute(code: string, options?: { silent?: boolean; user_expressions?: any; allow_stdin?: boolean; store_history?: boolean; }): IKernelFuture {","path":"src/kernel.ts","position":700,"original_position":700,"commit_id":"22e728754a9af84e9ecfdfb4f0a7c9a9ca3fa9cc","original_commit_id":"22e728754a9af84e9ecfdfb4f0a7c9a9ca3fa9cc","user":{"login":"sccolbert","id":137289,"avatar_url":"https://avatars.githubusercontent.com/u/137289?v=3","gravatar_id":"","url":"https://api.github.com/users/sccolbert","html_url":"https://github.com/sccolbert","followers_url":"https://api.github.com/users/sccolbert/followers","following_url":"https://api.github.com/users/sccolbert/following{/other_user}","gists_url":"https://api.github.com/users/sccolbert/gists{/gist_id}","starred_url":"https://api.github.com/users/sccolbert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sccolbert/subscriptions","organizations_url":"https://api.github.com/users/sccolbert/orgs","repos_url":"https://api.github.com/users/sccolbert/repos","events_url":"https://api.github.com/users/sccolbert/events{/privacy}","received_events_url":"https://api.github.com/users/sccolbert/received_events","type":"User","site_admin":false},"body":"I think it would make sense to break that options type out into a separate interface.","created_at":"2015-07-01T22:15:42Z","updated_at":"2015-07-01T22:15:42Z","html_url":"https://github.com/jupyter/phosphor-notebook/pull/1#discussion_r33730630","pull_request_url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/comments/33730630"},"html":{"href":"https://github.com/jupyter/phosphor-notebook/pull/1#discussion_r33730630"},"pull_request":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1","id":38883606,"html_url":"https://github.com/jupyter/phosphor-notebook/pull/1","diff_url":"https://github.com/jupyter/phosphor-notebook/pull/1.diff","patch_url":"https://github.com/jupyter/phosphor-notebook/pull/1.patch","issue_url":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/1","number":1,"state":"open","locked":false,"title":"Upgrade Kernel.ts","user":{"login":"blink1073","id":2096628,"avatar_url":"https://avatars.githubusercontent.com/u/2096628?v=3","gravatar_id":"","url":"https://api.github.com/users/blink1073","html_url":"https://github.com/blink1073","followers_url":"https://api.github.com/users/blink1073/followers","following_url":"https://api.github.com/users/blink1073/following{/other_user}","gists_url":"https://api.github.com/users/blink1073/gists{/gist_id}","starred_url":"https://api.github.com/users/blink1073/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blink1073/subscriptions","organizations_url":"https://api.github.com/users/blink1073/orgs","repos_url":"https://api.github.com/users/blink1073/repos","events_url":"https://api.github.com/users/blink1073/events{/privacy}","received_events_url":"https://api.github.com/users/blink1073/received_events","type":"User","site_admin":false},"body":"- Removed use of callbacks in favor of `KernelFuture`\r\n- Removed use of `events` in favor of phosphor `Signal`\r\n- Added minimal `utils.ts` and `serialize.ts` in support of `kernel.ts`\r\n- Removed all traces of JQuery\r\n- Made attributes and methods private as appropriate\r\n- Added to `tsd.json` as required\r\n- General cleanup and style fixes\r\n- Ensured clean build of `gulp`\r\n\r\nNotes: \r\n- I intentionally removed the `comm_manager` from `kernel.ts`, to be handled in a future PR.\r\n- I will add `session.ts` in a separate PR, since that is needed to actually run the kernel.\r\n\r\nFor discussion:\r\n- What to do about `Kernel.sendInputReply`?  Previously, it was triggered by an `event` from `outputarea.js`. `OutputArea` has no reference to any kernel objects.\r\n","created_at":"2015-06-30T14:27:14Z","updated_at":"2015-07-01T22:15:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"dd9fd6e33f0e69f31567628a17ce82ff36785ff3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1/commits","review_comments_url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1/comments","review_comment_url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/1/comments","statuses_url":"https://api.github.com/repos/jupyter/phosphor-notebook/statuses/22e728754a9af84e9ecfdfb4f0a7c9a9ca3fa9cc","head":{"label":"blink1073:upgrade-kernel-ts","ref":"upgrade-kernel-ts","sha":"22e728754a9af84e9ecfdfb4f0a7c9a9ca3fa9cc","user":{"login":"blink1073","id":2096628,"avatar_url":"https://avatars.githubusercontent.com/u/2096628?v=3","gravatar_id":"","url":"https://api.github.com/users/blink1073","html_url":"https://github.com/blink1073","followers_url":"https://api.github.com/users/blink1073/followers","following_url":"https://api.github.com/users/blink1073/following{/other_user}","gists_url":"https://api.github.com/users/blink1073/gists{/gist_id}","starred_url":"https://api.github.com/users/blink1073/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blink1073/subscriptions","organizations_url":"https://api.github.com/users/blink1073/orgs","repos_url":"https://api.github.com/users/blink1073/repos","events_url":"https://api.github.com/users/blink1073/events{/privacy}","received_events_url":"https://api.github.com/users/blink1073/received_events","type":"User","site_admin":false},"repo":{"id":38313630,"name":"phosphor-notebook-1","full_name":"blink1073/phosphor-notebook-1","owner":{"login":"blink1073","id":2096628,"avatar_url":"https://avatars.githubusercontent.com/u/2096628?v=3","gravatar_id":"","url":"https://api.github.com/users/blink1073","html_url":"https://github.com/blink1073","followers_url":"https://api.github.com/users/blink1073/followers","following_url":"https://api.github.com/users/blink1073/following{/other_user}","gists_url":"https://api.github.com/users/blink1073/gists{/gist_id}","starred_url":"https://api.github.com/users/blink1073/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blink1073/subscriptions","organizations_url":"https://api.github.com/users/blink1073/orgs","repos_url":"https://api.github.com/users/blink1073/repos","events_url":"https://api.github.com/users/blink1073/events{/privacy}","received_events_url":"https://api.github.com/users/blink1073/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/blink1073/phosphor-notebook-1","description":"","fork":true,"url":"https://api.github.com/repos/blink1073/phosphor-notebook-1","forks_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/forks","keys_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/keys{/key_id}","collaborators_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/teams","hooks_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/hooks","issue_events_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/issues/events{/number}","events_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/events","assignees_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/assignees{/user}","branches_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/branches{/branch}","tags_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/tags","blobs_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/git/refs{/sha}","trees_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/git/trees{/sha}","statuses_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/statuses/{sha}","languages_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/languages","stargazers_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/stargazers","contributors_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/contributors","subscribers_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/subscribers","subscription_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/subscription","commits_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/commits{/sha}","git_commits_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/git/commits{/sha}","comments_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/comments{/number}","issue_comment_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/issues/comments{/number}","contents_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/contents/{+path}","compare_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/compare/{base}...{head}","merges_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/merges","archive_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/downloads","issues_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/issues{/number}","pulls_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/pulls{/number}","milestones_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/milestones{/number}","notifications_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/labels{/name}","releases_url":"https://api.github.com/repos/blink1073/phosphor-notebook-1/releases{/id}","created_at":"2015-06-30T14:23:36Z","updated_at":"2015-06-30T14:23:36Z","pushed_at":"2015-07-01T22:01:45Z","git_url":"git://github.com/blink1073/phosphor-notebook-1.git","ssh_url":"git@github.com:blink1073/phosphor-notebook-1.git","clone_url":"https://github.com/blink1073/phosphor-notebook-1.git","svn_url":"https://github.com/blink1073/phosphor-notebook-1","homepage":null,"size":521,"stargazers_count":0,"watchers_count":0,"language":"TypeScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"jupyter:master","ref":"master","sha":"6bb145a58b5d9a1ea17c6d3def7065079fab2909","user":{"login":"jupyter","id":7388996,"avatar_url":"https://avatars.githubusercontent.com/u/7388996?v=3","gravatar_id":"","url":"https://api.github.com/users/jupyter","html_url":"https://github.com/jupyter","followers_url":"https://api.github.com/users/jupyter/followers","following_url":"https://api.github.com/users/jupyter/following{/other_user}","gists_url":"https://api.github.com/users/jupyter/gists{/gist_id}","starred_url":"https://api.github.com/users/jupyter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jupyter/subscriptions","organizations_url":"https://api.github.com/users/jupyter/orgs","repos_url":"https://api.github.com/users/jupyter/repos","events_url":"https://api.github.com/users/jupyter/events{/privacy}","received_events_url":"https://api.github.com/users/jupyter/received_events","type":"Organization","site_admin":false},"repo":{"id":38249514,"name":"phosphor-notebook","full_name":"jupyter/phosphor-notebook","owner":{"login":"jupyter","id":7388996,"avatar_url":"https://avatars.githubusercontent.com/u/7388996?v=3","gravatar_id":"","url":"https://api.github.com/users/jupyter","html_url":"https://github.com/jupyter","followers_url":"https://api.github.com/users/jupyter/followers","following_url":"https://api.github.com/users/jupyter/following{/other_user}","gists_url":"https://api.github.com/users/jupyter/gists{/gist_id}","starred_url":"https://api.github.com/users/jupyter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jupyter/subscriptions","organizations_url":"https://api.github.com/users/jupyter/orgs","repos_url":"https://api.github.com/users/jupyter/repos","events_url":"https://api.github.com/users/jupyter/events{/privacy}","received_events_url":"https://api.github.com/users/jupyter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/jupyter/phosphor-notebook","description":"","fork":false,"url":"https://api.github.com/repos/jupyter/phosphor-notebook","forks_url":"https://api.github.com/repos/jupyter/phosphor-notebook/forks","keys_url":"https://api.github.com/repos/jupyter/phosphor-notebook/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jupyter/phosphor-notebook/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jupyter/phosphor-notebook/teams","hooks_url":"https://api.github.com/repos/jupyter/phosphor-notebook/hooks","issue_events_url":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/events{/number}","events_url":"https://api.github.com/repos/jupyter/phosphor-notebook/events","assignees_url":"https://api.github.com/repos/jupyter/phosphor-notebook/assignees{/user}","branches_url":"https://api.github.com/repos/jupyter/phosphor-notebook/branches{/branch}","tags_url":"https://api.github.com/repos/jupyter/phosphor-notebook/tags","blobs_url":"https://api.github.com/repos/jupyter/phosphor-notebook/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jupyter/phosphor-notebook/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jupyter/phosphor-notebook/git/refs{/sha}","trees_url":"https://api.github.com/repos/jupyter/phosphor-notebook/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jupyter/phosphor-notebook/statuses/{sha}","languages_url":"https://api.github.com/repos/jupyter/phosphor-notebook/languages","stargazers_url":"https://api.github.com/repos/jupyter/phosphor-notebook/stargazers","contributors_url":"https://api.github.com/repos/jupyter/phosphor-notebook/contributors","subscribers_url":"https://api.github.com/repos/jupyter/phosphor-notebook/subscribers","subscription_url":"https://api.github.com/repos/jupyter/phosphor-notebook/subscription","commits_url":"https://api.github.com/repos/jupyter/phosphor-notebook/commits{/sha}","git_commits_url":"https://api.github.com/repos/jupyter/phosphor-notebook/git/commits{/sha}","comments_url":"https://api.github.com/repos/jupyter/phosphor-notebook/comments{/number}","issue_comment_url":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/comments{/number}","contents_url":"https://api.github.com/repos/jupyter/phosphor-notebook/contents/{+path}","compare_url":"https://api.github.com/repos/jupyter/phosphor-notebook/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jupyter/phosphor-notebook/merges","archive_url":"https://api.github.com/repos/jupyter/phosphor-notebook/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jupyter/phosphor-notebook/downloads","issues_url":"https://api.github.com/repos/jupyter/phosphor-notebook/issues{/number}","pulls_url":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls{/number}","milestones_url":"https://api.github.com/repos/jupyter/phosphor-notebook/milestones{/number}","notifications_url":"https://api.github.com/repos/jupyter/phosphor-notebook/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jupyter/phosphor-notebook/labels{/name}","releases_url":"https://api.github.com/repos/jupyter/phosphor-notebook/releases{/id}","created_at":"2015-06-29T13:37:35Z","updated_at":"2015-07-01T15:17:33Z","pushed_at":"2015-07-01T22:01:46Z","git_url":"git://github.com/jupyter/phosphor-notebook.git","ssh_url":"git@github.com:jupyter/phosphor-notebook.git","clone_url":"https://github.com/jupyter/phosphor-notebook.git","svn_url":"https://github.com/jupyter/phosphor-notebook","homepage":null,"size":1060,"stargazers_count":3,"watchers_count":3,"language":"TypeScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1"},"html":{"href":"https://github.com/jupyter/phosphor-notebook/pull/1"},"issue":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/1"},"comments":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/jupyter/phosphor-notebook/statuses/22e728754a9af84e9ecfdfb4f0a7c9a9ca3fa9cc"}}}}