ucsc-xena-client
Version:
UCSC Xena Client. Functional genomics visualizations.
80 lines (70 loc) • 2.54 kB
JavaScript
// ad hoc reversible state transforms that make it more compressable.
var _ = require('./underscore_ext');
var arrays = require('./arrays');
var to32BinStr = function to32BinStr(arr) {
return arrays.ab2str(Uint32Array.from(arr).buffer);
};
var from32BinStr = function from32BinStr(str) {
return Array.from(new Uint32Array(arrays.str2ab(str)));
};
var to16BinStr = function to16BinStr(arr) {
return arrays.ab2str(Uint16Array.from(arr).buffer);
};
var from16BinStr = function from16BinStr(str) {
return Array.from(new Uint16Array(arrays.str2ab(str)));
};
// Store segmented data as columns, and encode into binary strings.
//
// We tag the encoding (not the fieldType) so if we switch to a different
// encoding (e.g. 'binarySegmented2'), we can still decode old bookmarks
// and sessionStorage. Also, this way we don't assume the data is encoded,
// so we work with existing bookmarks and state.
//
// We should preserve all keys except req.rows.
var segmentedToBinary = function segmentedToBinary(data) {
return _.updateIn(data, ['req', 'rows'], function (rows) {
return {
encoding: 'binarySegmented',
sample: to16BinStr(_.pluck(rows, 'sample')),
start: to32BinStr(_.pluck(rows, 'start')),
end: to32BinStr(_.pluck(rows, 'end')),
value: _.pluck(rows, 'value')
};
});
};
var encodings = {
segmented: segmentedToBinary
};
var encode = function encode(type, data) {
return (encodings[type] || _.identity)(data);
};
var segmentedFromBinary = function segmentedFromBinary(data) {
return _.updateIn(data, ['req', 'rows'], function (rows) {
return _.mmap(from16BinStr(rows.sample), from32BinStr(rows.start), from32BinStr(rows.end), rows.value, function (sample, start, end, value) {
return { sample: sample, start: start, end: end, value: value };
});
});
};
var decodings = {
binarySegmented: segmentedFromBinary
};
var decode = function decode(data) {
return (decodings[_.getIn(data, ['req', 'rows', 'encoding'])] || _.identity)(data);
};
var compactState = function compactState(state) {
return state.spreadsheet ? _.updateIn(state, ['spreadsheet', 'data'], function (data) {
return _.fmap(data, function (colData, uuid) {
return encode(_.getIn(state, ['columns', uuid, 'fieldType']), colData);
});
}) : state;
};
var expandState = function expandState(state) {
return state.spreadsheet ? _.updateIn(state, ['spreadsheet', 'data'], function (data) {
return _.fmap(data, decode);
}) : state;
};
module.exports = {
compactState: compactState,
expandState: expandState
};
;