Skip to content

Commit

Permalink
Handle binary state values when serializing/deserializing the widget …
Browse files Browse the repository at this point in the history
…manager state.

Fixes jupyter-widgets#1282
  • Loading branch information
jasongrout committed Apr 19, 2017
1 parent c28ba08 commit 4f7f87f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 27 deletions.
1 change: 1 addition & 0 deletions jupyter-js-widgets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"@types/semver": "^5.3.30",
"ajv": "^4.9.0",
"backbone": "1.2.0",
"base64-js": "1.2.0",
"d3-format": "^0.5.1",
"font-awesome": "^4.5.0",
"jquery": "^3.1.1",
Expand Down
64 changes: 37 additions & 27 deletions jupyter-js-widgets/src/manager-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import * as semver from 'semver';
import * as Backbone from 'backbone';
import * as services from '@jupyterlab/services';

import {
toByteArray, fromByteArray
} from 'base64-js';

import {
WidgetModel
} from './widget';
Expand Down Expand Up @@ -375,21 +379,22 @@ abstract class ManagerBase<T> {
* @returns Promise for a state dictionary
*/
get_state(options: StateOptions): Promise<any> {
var that = this;
return utils.resolvePromisesDict(this._models).then(function(models) {
var state = {};
for (var model_id in models) {
if (models.hasOwnProperty(model_id)) {
var model = models[model_id];
state[model_id] = utils.resolvePromisesDict({
model_name: model.name,
model_module: model.module,
model_module_version: model.get('_model_module_version'),
state: model.constructor._serialize_state(model.get_state(options.drop_defaults), that)
});
}
}
return utils.resolvePromisesDict(state);
return utils.resolvePromisesDict(this._models).then((models) => {
let state = {};
Object.keys(models).forEach(model_id => {
let model = models[model_id];
let split = utils.remove_buffers(model.serialize(model.get_state(options.drop_defaults)));
let base64Buffers = split.buffers.map(fromByteArray);
state[model_id] = {
model_name: model.name,
model_module: model.module,
model_module_version: model.get('_model_module_version'),
state: split.state,
buffer_paths: split.buffer_paths,
buffers: base64Buffers
};
});
return state;
}).catch(utils.reject('Could not get state of widget manager', true));
};

Expand All @@ -401,39 +406,44 @@ abstract class ManagerBase<T> {
* state.
*/
set_state(state, displayOptions) {
var that = this;

// Recreate all the widget models for the given widget manager state.
var all_models = that._get_comm_info().then(function(live_comms) {
return Promise.all(_.map(Object.keys(state), function (model_id) {
let all_models = this._get_comm_info().then(live_comms => {
return Promise.all(Object.keys(state).map(model_id => {

// First put back the binary buffers
let modelState = state[model_id].state;
let buffer_paths = modelState.buffer_paths || [];
let buffers = (modelState.buffers || []).map(toByteArray);
utils.put_buffers(modelState, buffer_paths, buffers);

// If the model has already been created, set it's state and then
// If the model has already been created, set its state and then
// return it.
if (that._models[model_id]) {
return that._models[model_id].then(function(model) {
return model.constructor._deserialize_state(state[model_id].state || {}, that).then(function(attributes) {
if (this._models[model_id]) {
return this._models[model_id].then(model => {
// deserialize state
return model.constructor._deserialize_state(modelState || {}, this).then(attributes => {
model.set_state(attributes);
return model;
});
});
}

if (live_comms.hasOwnProperty(model_id)) { // live comm
return that._create_comm(that.comm_target_name, model_id).then(function(new_comm) {
return that.new_model({
return this._create_comm(this.comm_target_name, model_id).then(new_comm => {
return this.new_model({
comm: new_comm,
model_name: state[model_id].model_name,
model_module: state[model_id].model_module,
model_module_version: state[model_id].model_module_version
});
});
} else { // dead comm
return that.new_model({
return this.new_model({
model_id: model_id,
model_name: state[model_id].model_name,
model_module: state[model_id].model_module,
model_module_version: state[model_id].model_module_version
}, state[model_id].state);
}, modelState);
}
}));
});
Expand Down

0 comments on commit 4f7f87f

Please sign in to comment.