@bokeh/bokehjs
Version:
Interactive, novel data visualization
176 lines • 5.7 kB
JavaScript
import { assert } from "../util/assert";
import { entries } from "../util/object";
import { isPlainObject, isObject, isArray, isTypedArray, isBoolean, isNumber, isString, isSymbol } from "../util/types";
import { map } from "../util/iterator";
import { BYTE_ORDER } from "../util/platform";
import { Buffer, Base64Buffer } from "./buffer";
// TypedArray?
export const serialize = Symbol("serialize");
function is_Serializable(obj) {
return isObject(obj) && serialize in obj;
}
export class SerializationError extends Error {
static __name__ = "SerializationError";
}
class Serialized {
value;
static __name__ = "Serialized";
constructor(value) {
this.value = value;
}
to_json() {
return JSON.stringify(this.value);
}
}
export class Serializer {
static __name__ = "Serializer";
_references;
binary;
include_defaults;
_circular = new WeakSet();
constructor(options) {
this.binary = options?.binary ?? false;
this.include_defaults = options?.include_defaults ?? false;
const references = options?.references;
this._references = references != null ? new Map(references) : new Map();
}
get_ref(obj) {
return this._references.get(obj);
}
add_ref(obj, ref) {
assert(!this._references.has(obj));
this._references.set(obj, ref);
}
to_serializable(obj) {
return new Serialized(this.encode(obj));
}
encode(obj) {
const ref = this.get_ref(obj);
if (ref != null) {
return ref;
}
if (!isObject(obj)) {
return this._encode(obj);
}
else {
if (this._circular.has(obj)) {
this.error("circular reference");
}
this._circular.add(obj);
try {
return this._encode(obj);
}
finally {
this._circular.delete(obj);
}
}
}
_encode(obj) {
if (is_Serializable(obj)) {
return obj[serialize](this);
}
else if (isArray(obj)) {
const n = obj.length;
const result = new Array(n);
for (let i = 0; i < n; i++) {
const value = obj[i];
result[i] = this.encode(value);
}
return result;
}
else if (isTypedArray(obj)) {
return this._encode_typed_array(obj);
}
else if (obj instanceof ArrayBuffer) {
const data = this.binary ? new Buffer(obj) : new Base64Buffer(obj);
return { type: "bytes", data };
}
else if (isPlainObject(obj)) {
const items = entries(obj);
if (items.length == 0) {
return { type: "map" };
}
else {
return { type: "map", entries: [...map(items, ([key, val]) => [this.encode(key), this.encode(val)])] };
}
}
else if (obj === null || isBoolean(obj) || isString(obj)) {
return obj;
}
else if (isNumber(obj)) {
if (isNaN(obj)) {
return { type: "number", value: "nan" };
}
else if (!isFinite(obj)) {
return { type: "number", value: `${obj < 0 ? "-" : "+"}inf` };
}
else {
return obj;
}
}
else if (obj instanceof Date) {
const iso = obj.toISOString();
return { type: "date", iso };
}
else if (obj instanceof Set) {
if (obj.size == 0) {
return { type: "set" };
}
else {
return { type: "set", entries: [...map(obj.values(), (val) => this.encode(val))] };
}
}
else if (obj instanceof Map) {
if (obj.size == 0) {
return { type: "map" };
}
else {
return { type: "map", entries: [...map(obj.entries(), ([key, val]) => [this.encode(key), this.encode(val)])] };
}
}
else if (isSymbol(obj) && obj.description != null) {
return { type: "symbol", name: obj.description };
}
else {
throw new SerializationError(`${Object.prototype.toString.call(obj)} is not serializable`);
}
}
encode_struct(struct) {
const result = {};
for (const [key, val] of entries(struct)) {
if (val !== undefined) {
result[key] = this.encode(val);
}
}
return result;
}
error(message) {
throw new SerializationError(message);
}
_encode_typed_array(obj) {
const array = this.encode(obj.buffer);
const dtype = (() => {
switch (obj.constructor) {
case Uint8Array: return "uint8";
case Int8Array: return "int8";
case Uint16Array: return "uint16";
case Int16Array: return "int16";
case Uint32Array: return "uint32";
case Int32Array: return "int32";
// case BigUint64Array: return "uint64"
// case BigInt64Array: return "int64"
case Float32Array: return "float32";
case Float64Array: return "float64";
default:
this.error(`can't serialize typed array of type '${obj[Symbol.toStringTag]}'`);
}
})();
return {
type: "typed_array",
array,
order: BYTE_ORDER,
dtype,
};
}
}
//# sourceMappingURL=serializer.js.map